Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Jekyll and Hugo post templates to accept unknown properties #680

Merged
merged 4 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions helpers/fixtures/jf2/post-template-properties.jf2
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"type": "entry",
"url": "https://website.example/posts/cheese-sandwich",
"name": "What I had for lunch",
"content": {
"html": "<p>I ate a <a href=\"https://en.wikipedia.org/wiki/Cheese\">cheese</a> sandwich, which was nice.</p>",
"text": "I ate a [cheese](https://en.wikipedia.org/wiki/Cheese) sandwich, which was nice."
},
"summary": "A very satisfactory meal.",
"published": "2020-02-02",
"category": ["lunch", "food"],
"audio": [{
"url": "https://website.example/audio.mp3"
}],
"photo": [{
"alt": "Alternative text",
"url": "https://website.example/photo.jpg"
}],
"video": [{
"url": "https://website.example/video.mp4"
}],
"start": "2020-02-02",
"end": "2020-02-20",
"rsvp": "Yes",
"location": {
"type": "geo",
"latitude": "37.780080",
"longitude": "-122.420160",
"name": "37° 46′ 48.29″ N 122° 25′ 12.576″ W"
},
"checkin": {
"type": "card",
"latitude": "50",
"longitude": "0"
},
"bookmark-of": "https://website.example",
"like-of": "https://website.example",
"repost-of": "https://website.example",
"in-reply-to": "https://website.example",
"visibility": "private",
"syndication": "https://website.example/post/12345"
}
8 changes: 7 additions & 1 deletion packages/endpoint-micropub/lib/post-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ export const postContent = {
fileType: "post",
postType: properties["post-type"],
};
const content = await postTemplate(properties);

// Remove server commands from post template properties
const templateProperties = Object.keys(properties).filter(
(key) => !key.startsWith("mp-"),
);

const content = await postTemplate(templateProperties);
const message = storeMessageTemplate(metaData);

await store.createFile(path, content, { message });
Expand Down
96 changes: 52 additions & 44 deletions packages/preset-hugo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ export default class HugoPreset {
];
}

/**
* Get content
* @access private
* @param {object} properties - JF2 properties
* @returns {string} Content
*/
#content(properties) {
if (properties.content) {
const content =
properties.content.text ||
properties.content.html ||
properties.content;
return `\n${content}\n`;
} else {
return "";
}
}

/**
* Get front matter
* @access private
Expand All @@ -55,6 +73,39 @@ export default class HugoPreset {
let delimiters;
let frontMatter;

/*
* Go templates don’t accept hyphens in property names
* and Hugo camelCases its predefined front matter keys
* @see {link: https://gohugo.io/content-management/front-matter/}
*/
properties = camelcaseKeys(properties, { deep: true });

/*
* Replace Microformat properties with Hugo equivalents
* @see {link: https://gohugo.io/content-management/front-matter/}
*/
properties = {
date: properties.published,
publishDate: properties.published,
...(properties.postStatus === "draft" && { draft: true }),
...(properties.updated && { lastmod: properties.updated }),
...(properties.deleted && { expiryDate: properties.deleted }),
...(properties.name && { title: properties.name }),
...(properties.photo && {
images: properties.photo.map((image) => image.url),
}),
...properties,
};

delete properties.content; // Shown below front matter
delete properties.deleted; // Use `expiryDate`
delete properties.name; // Use `title`
delete properties.postStatus; // Use `draft`
delete properties.published; // Use `date`
delete properties.type; // Not required
delete properties.updated; // Use `lastmod`
delete properties.url; // Not required

switch (this.options.frontMatterFormat) {
case "json": {
delimiters = ["", "\n"];
Expand Down Expand Up @@ -205,50 +256,7 @@ export default class HugoPreset {
* @returns {string} Rendered template
*/
postTemplate(properties) {
/*
* Go templates don’t accept hyphens in property names
* and Hugo camelCases its predefined front matter keys
* https://gohugo.io/content-management/front-matter/
*/
properties = camelcaseKeys(properties, { deep: true });

let content;
if (properties.content) {
content =
properties.content.text ||
properties.content.html ||
properties.content;
content = `\n${content}\n`;
} else {
content = "";
}

properties = {
date: properties.published,
publishDate: properties.published,
...(properties.updated && { lastmod: properties.updated }),
...(properties.deleted && { expiryDate: properties.deleted }),
...(properties.name && { title: properties.name }),
...(properties.summary && { summary: properties.summary }),
...(properties.category && { category: properties.category }),
...(properties.start && { start: properties.start }),
...(properties.end && { end: properties.end }),
...(properties.rsvp && { rsvp: properties.rsvp }),
...(properties.location && { location: properties.location }),
...(properties.checkin && { checkin: properties.checkin }),
...(properties.audio && { audio: properties.audio }),
...(properties.photo && { images: properties.photo }),
...(properties.video && { videos: properties.video }),
...(properties.bookmarkOf && { bookmarkOf: properties.bookmarkOf }),
...(properties.likeOf && { likeOf: properties.likeOf }),
...(properties.repostOf && { repostOf: properties.repostOf }),
...(properties.inReplyTo && { inReplyTo: properties.inReplyTo }),
...(properties.postStatus === "draft" && { draft: true }),
...(properties.visibility && { visibility: properties.visibility }),
...(properties.syndication && { syndication: properties.syndication }),
...(properties.references && { references: properties.references }),
};

const content = this.#content(properties);
const frontMatter = this.#frontMatter(properties);

return frontMatter + content;
Expand Down
83 changes: 44 additions & 39 deletions packages/preset-hugo/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { Indiekit } from "@indiekit/indiekit";
import { getFixture } from "@indiekit-test/fixtures";
import HugoPreset from "../index.js";

describe("preset-jekyll", () => {
describe("preset-hugo", () => {
const hugo = new HugoPreset();

const properties = JSON.parse(getFixture("jf2/all-properties.jf2"));
const properties = JSON.parse(getFixture("jf2/post-template-properties.jf2"));

it("Gets plug-in info", () => {
assert.equal(hugo.name, "Hugo preset");
Expand Down Expand Up @@ -55,19 +55,21 @@ title: What I had for lunch
);
});

it("Renders post template with basic content", () => {
it("Renders post template with basic draft content", () => {
const result = hugo.postTemplate({
published: "2020-02-02",
name: "What I had for lunch",
content:
"I ate a [cheese](https://en.wikipedia.org/wiki/Cheese) sandwich, which was nice.",
"post-status": "draft",
});

assert.equal(
result,
`---
date: 2020-02-02
publishDate: 2020-02-02
draft: true
title: What I had for lunch
---

Expand Down Expand Up @@ -108,46 +110,48 @@ title: What I had for lunch
"date": "2020-02-02",
"publishDate": "2020-02-02",
"title": "What I had for lunch",
"images": [
"https://website.example/photo.jpg"
],
"summary": "A very satisfactory meal.",
"category": [
"lunch",
"food"
],
"start": "2020-02-02",
"end": "2020-02-20",
"rsvp": "Yes",
"location": {
"type": "geo",
"latitude": "37.780080",
"longitude": "-122.420160",
"name": "37° 46′ 48.29″ N 122° 25′ 12.576″ W"
},
"checkin": {
"type": "card",
"latitude": "50",
"longitude": "0"
},
"audio": [
{
"url": "https://website.example/audio.mp3"
}
],
"images": [
"photo": [
{
"alt": "Alternative text",
"url": "https://website.example/photo.jpg"
}
],
"videos": [
"video": [
{
"url": "https://website.example/video.mp4"
}
],
"start": "2020-02-02",
"end": "2020-02-20",
"rsvp": "Yes",
"location": {
"type": "geo",
"latitude": "37.780080",
"longitude": "-122.420160",
"name": "37° 46′ 48.29″ N 122° 25′ 12.576″ W"
},
"checkin": {
"type": "card",
"latitude": "50",
"longitude": "0"
},
"bookmarkOf": "https://website.example",
"likeOf": "https://website.example",
"repostOf": "https://website.example",
"inReplyTo": "https://website.example",
"draft": true,
"visibility": "private",
"syndication": "https://website.example/post/12345"
}
Expand All @@ -167,6 +171,7 @@ I ate a [cheese](https://en.wikipedia.org/wiki/Cheese) sandwich, which was nice.
date = "2020-02-02"
publishDate = "2020-02-02"
title = "What I had for lunch"
images = [ "https://website.example/photo.jpg" ]
summary = "A very satisfactory meal."
category = [ "lunch", "food" ]
start = "2020-02-02"
Expand All @@ -176,10 +181,19 @@ bookmarkOf = "https://website.example"
likeOf = "https://website.example"
repostOf = "https://website.example"
inReplyTo = "https://website.example"
draft = true
visibility = "private"
syndication = "https://website.example/post/12345"

[[audio]]
url = "https://website.example/audio.mp3"

[[photo]]
alt = "Alternative text"
url = "https://website.example/photo.jpg"

[[video]]
url = "https://website.example/video.mp4"

[location]
type = "geo"
latitude = "37.780080"
Expand All @@ -190,16 +204,6 @@ name = "37° 46′ 48.29″ N 122° 25′ 12.576″ W"
type = "card"
latitude = "50"
longitude = "0"

[[audio]]
url = "https://website.example/audio.mp3"

[[images]]
alt = "Alternative text"
url = "https://website.example/photo.jpg"

[[videos]]
url = "https://website.example/video.mp4"
+++

I ate a [cheese](https://en.wikipedia.org/wiki/Cheese) sandwich, which was nice.
Expand All @@ -217,10 +221,19 @@ I ate a [cheese](https://en.wikipedia.org/wiki/Cheese) sandwich, which was nice.
date: 2020-02-02
publishDate: 2020-02-02
title: What I had for lunch
images:
- https://website.example/photo.jpg
summary: A very satisfactory meal.
category:
- lunch
- food
audio:
- url: https://website.example/audio.mp3
photo:
- alt: Alternative text
url: https://website.example/photo.jpg
video:
- url: https://website.example/video.mp4
start: 2020-02-02
end: 2020-02-20
rsvp: Yes
Expand All @@ -233,18 +246,10 @@ checkin:
type: card
latitude: "50"
longitude: "0"
audio:
- url: https://website.example/audio.mp3
images:
- alt: Alternative text
url: https://website.example/photo.jpg
videos:
- url: https://website.example/video.mp4
bookmarkOf: https://website.example
likeOf: https://website.example
repostOf: https://website.example
inReplyTo: https://website.example
draft: true
visibility: private
syndication: https://website.example/post/12345
---
Expand Down
Loading