@eclecticpassions/indiekit-preset-hugo 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +47 -0
- package/assets/icon.svg +4 -0
- package/index.js +56 -0
- package/lib/post-template.js +113 -0
- package/lib/post-types.js +31 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 Paul Robert Lloyd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Indiekit Plugin: preset-hugo
|
|
2
|
+
|
|
3
|
+
Forked from [@indiekit/preset-hugo](https://www.npmjs.com/package/@indiekit/preset-hugo). In order to get unquoted dates in front matter, the following changes were made:
|
|
4
|
+
|
|
5
|
+
- Ensure date value is a native JavaScript Date object before being stringified
|
|
6
|
+
- Modify the properties object mapping within getFrontMatter
|
|
7
|
+
|
|
8
|
+
> [!important]
|
|
9
|
+
> I asked an LLM to help me with the code. Please review before using in your setup.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
I personally wasn't able to use NPM's override feature for the exisiting Indiekit preset-hugo plugin.
|
|
14
|
+
|
|
15
|
+
1. Remove existing: `npm remove @indiekit/preset-hugo`
|
|
16
|
+
2. Install with: `npm install github:eclecticpassions/indiekit-preset-hugo`
|
|
17
|
+
3. Replace all existing configuration (e.g. `indiekit.config.js`) and `package.json`, from `@indiekit/preset-hugo` to `@eclecticpassions/indiekit-preset-hugo`
|
|
18
|
+
4. Remove and rebuild `rm -rf node_modules package-lock.json` and `npm install`
|
|
19
|
+
|
|
20
|
+
See below for the README of the original preset-hugo plugin.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
A [Hugo](https://gohugo.io) publication preset for Indiekit.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
`npm install @indiekit/preset-hugo`
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Add `@indiekit/preset-hugo` to your list of plug-ins, specifying options as required:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"plugins": ["@indiekit/preset-hugo"],
|
|
37
|
+
"@indiekit/preset-hugo": {
|
|
38
|
+
"frontMatterFormat": "json"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Options
|
|
44
|
+
|
|
45
|
+
| Option | Type | Description |
|
|
46
|
+
| :------------------ | :------- | :------------------------------------------------------------------------------------- |
|
|
47
|
+
| `frontMatterFormat` | `string` | Front matter format to use (`json`, `toml` or `yaml`). _Optional_, defaults to `yaml`. |
|
package/assets/icon.svg
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
|
|
2
|
+
<path fill="#FF4088" d="M0 0h96v96H0z"/>
|
|
3
|
+
<path fill="#FFF" fill-rule="nonzero" d="M47.2 8c-2.5 0-4.9.7-7 2L18.9 23.3A14.3 14.3 0 0 0 12 35.4v27c0 5 2.7 9.7 7 12.1l21.8 12.6a13 13 0 0 0 13 0l23.7-13.3c4-2.3 6.5-6.5 6.5-11.2V34.1a12 12 0 0 0-6-10.4L54.1 9.8a13.5 13.5 0 0 0-7-1.8Zm0 5.6a8 8 0 0 1 4 1.1l24 13.9c2 1.1 3.2 3.2 3.2 5.5v28.5c0 2.6-1.4 5-3.7 6.3L51 82.3a7.4 7.4 0 0 1-7.4 0L21.8 69.5a8.2 8.2 0 0 1-4.2-7.1v-27c0-3 1.6-5.9 4.2-7.4l21.4-13.3a7.8 7.8 0 0 1 4-1.2Zm-15.8 13v43.3h9v-19h15.1v19h9V26.6h-9v15.8h-15V26.6h-9Z"/>
|
|
4
|
+
</svg>
|
package/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getPostTemplate } from "./lib/post-template.js";
|
|
2
|
+
import { getPostTypes } from "./lib/post-types.js";
|
|
3
|
+
|
|
4
|
+
const defaults = {
|
|
5
|
+
frontMatterFormat: "toml",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default class HugoPreset {
|
|
9
|
+
name = "Hugo Custom Preset";
|
|
10
|
+
postTypes;
|
|
11
|
+
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.options = { ...defaults, ...options };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get info() {
|
|
17
|
+
return {
|
|
18
|
+
name: "Hugo Custom Unquoted", // <-- Indiekit reads this to display in your dashboard status
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get prompts() {
|
|
23
|
+
return [
|
|
24
|
+
{
|
|
25
|
+
type: "select",
|
|
26
|
+
name: "frontMatterFormat",
|
|
27
|
+
message: "Which front matter format are you using?",
|
|
28
|
+
choices: [
|
|
29
|
+
{
|
|
30
|
+
title: "JSON",
|
|
31
|
+
value: "json",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: "TOML",
|
|
35
|
+
value: "toml",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: "YAML",
|
|
39
|
+
value: "yaml",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
initial: 2,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
postTemplate(properties) {
|
|
48
|
+
return getPostTemplate(properties, this.options.frontMatterFormat);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
init(Indiekit) {
|
|
52
|
+
this.postTypes = getPostTypes(Indiekit.postTypes);
|
|
53
|
+
|
|
54
|
+
Indiekit.addPreset(this);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import TOML from "@iarna/toml";
|
|
2
|
+
import camelcaseKeys from "camelcase-keys";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get content
|
|
7
|
+
* @access private
|
|
8
|
+
* @param {object} properties - JF2 properties
|
|
9
|
+
* @returns {string} Content
|
|
10
|
+
*/
|
|
11
|
+
const getContent = (properties) => {
|
|
12
|
+
if (properties.content) {
|
|
13
|
+
const content =
|
|
14
|
+
properties.content.text || properties.content.html || properties.content;
|
|
15
|
+
return `\n${content}\n`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return "";
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get front matter
|
|
23
|
+
* @access private
|
|
24
|
+
* @param {object} properties - JF2 properties
|
|
25
|
+
* @param {string} frontMatterFormat - Front matter format
|
|
26
|
+
* @returns {string} Front matter in chosen format
|
|
27
|
+
*/
|
|
28
|
+
const getFrontMatter = (properties, frontMatterFormat) => {
|
|
29
|
+
let delimiters;
|
|
30
|
+
let frontMatter;
|
|
31
|
+
|
|
32
|
+
// 1. camelCase the incoming properties first
|
|
33
|
+
properties = camelcaseKeys(properties, { deep: true });
|
|
34
|
+
|
|
35
|
+
// 2. Capture clean Date objects first
|
|
36
|
+
const parsedDate = properties.published ? new Date(properties.published) : undefined;
|
|
37
|
+
const parsedLastmod = properties.updated ? new Date(properties.updated) : undefined;
|
|
38
|
+
const parsedExpiry = properties.deleted ? new Date(properties.deleted) : undefined;
|
|
39
|
+
|
|
40
|
+
// 3. Build the clean, final object mapping
|
|
41
|
+
properties = {
|
|
42
|
+
...(properties.postStatus === "draft" && { draft: true }),
|
|
43
|
+
...(properties.name && { title: properties.name }),
|
|
44
|
+
...(properties.photo && {
|
|
45
|
+
images: properties.photo.map((image) => image.url),
|
|
46
|
+
}),
|
|
47
|
+
...properties, // Pull everything else in safely early on
|
|
48
|
+
|
|
49
|
+
// Explicitly place the strict types at the bottom to guarantee they win
|
|
50
|
+
date: parsedDate,
|
|
51
|
+
publishDate: parsedDate,
|
|
52
|
+
...(parsedLastmod && { lastmod: parsedLastmod }),
|
|
53
|
+
...(parsedExpiry && { expiryDate: parsedExpiry }),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// 4. Wipe out all unused/overlapping raw string properties completely
|
|
57
|
+
delete properties.content;
|
|
58
|
+
delete properties.deleted;
|
|
59
|
+
delete properties.name;
|
|
60
|
+
delete properties.postStatus;
|
|
61
|
+
delete properties.published;
|
|
62
|
+
delete properties.slug;
|
|
63
|
+
delete properties.type;
|
|
64
|
+
delete properties.updated;
|
|
65
|
+
delete properties.url;
|
|
66
|
+
|
|
67
|
+
// 5. Make absolutely sure no string version leaked through
|
|
68
|
+
if (!properties.lastmod) delete properties.lastmod;
|
|
69
|
+
if (!properties.expiryDate) delete properties.expiryDate;
|
|
70
|
+
|
|
71
|
+
// 6. Before TOML.stringify(properties), convert param name category to tags and makes sure that an array [] is used even when there is only one tag
|
|
72
|
+
if (properties.category) {
|
|
73
|
+
properties.tags = Array.isArray(properties.category)
|
|
74
|
+
? properties.category
|
|
75
|
+
: [properties.category];
|
|
76
|
+
delete properties.category;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
switch (frontMatterFormat) {
|
|
80
|
+
case "json": {
|
|
81
|
+
delimiters = ["", "\n"];
|
|
82
|
+
frontMatter = JSON.stringify(properties, undefined, 2);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
case "toml": {
|
|
87
|
+
delimiters = ["+++\n", "+++\n"];
|
|
88
|
+
frontMatter = TOML.stringify(properties);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
default: {
|
|
93
|
+
delimiters = ["---\n", "---\n"];
|
|
94
|
+
frontMatter = YAML.stringify(properties, { lineWidth: 0 });
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return `${delimiters[0]}${frontMatter}${delimiters[1]}`;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get post template
|
|
104
|
+
* @param {object} properties - JF2 properties
|
|
105
|
+
* @param {string} [frontMatterFormat] - Front matter format
|
|
106
|
+
* @returns {string} Rendered template
|
|
107
|
+
*/
|
|
108
|
+
export const getPostTemplate = (properties, frontMatterFormat = "yaml") => {
|
|
109
|
+
const content = getContent(properties);
|
|
110
|
+
const frontMatter = getFrontMatter(properties, frontMatterFormat);
|
|
111
|
+
|
|
112
|
+
return frontMatter + content;
|
|
113
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import plur from "plur";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get paths and URLs for configured post types
|
|
5
|
+
* @param {Map} postTypes - Post type configuration
|
|
6
|
+
* @returns {object} Updated post type configuration
|
|
7
|
+
*/
|
|
8
|
+
export const getPostTypes = (postTypes) => {
|
|
9
|
+
for (const type of postTypes.keys()) {
|
|
10
|
+
const section = plur(type);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Follow Hugo content management guidelines
|
|
14
|
+
* @see {@link https://gohugo.io/content-management/organization/}
|
|
15
|
+
* @see {@link https://gohugo.io/content-management/static-files/}
|
|
16
|
+
*/
|
|
17
|
+
postTypes.set(type, {
|
|
18
|
+
...postTypes.get(type),
|
|
19
|
+
post: {
|
|
20
|
+
path: `content/${section}/{slug}.md`,
|
|
21
|
+
url: `${section}/{slug}`,
|
|
22
|
+
},
|
|
23
|
+
media: {
|
|
24
|
+
path: `static/${section}/{filename}`,
|
|
25
|
+
url: `${section}/{filename}`,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return postTypes;
|
|
31
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eclecticpassions/indiekit-preset-hugo",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Custom Hugo publication preset for Indiekit",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"homepage": "https://getindiekit.com",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Paul Robert Lloyd",
|
|
10
|
+
"url": "https://paulrobertlloyd.com"
|
|
11
|
+
},
|
|
12
|
+
"contributors": [
|
|
13
|
+
{
|
|
14
|
+
"name": "Naty S",
|
|
15
|
+
"url": "https://burgeonlab.com"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"assets",
|
|
20
|
+
"lib",
|
|
21
|
+
"index.js"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/eclecticpassions/indiekit-preset-hugo.git"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=24.17.0"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"indiekit",
|
|
33
|
+
"indiekit-plugin",
|
|
34
|
+
"frontmatter",
|
|
35
|
+
"toml"
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@iarna/toml": "^2.2.5",
|
|
39
|
+
"camelcase-keys": "^10.0.2",
|
|
40
|
+
"plur": "^6.0.0",
|
|
41
|
+
"yaml": "^2.9.0"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|