@jungvonmatt/cssg-plugin-hugo 1.0.4 → 1.2.0

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/index.js +96 -9
  3. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -3,6 +3,44 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.2.0](https://github.com/jungvonmatt/contentful-ssg/compare/v1.1.1...v1.2.0) (2021-12-21)
7
+
8
+
9
+ ### Features
10
+
11
+ * 🎸 Generates hugo's menu.toml ([27e95a3](https://github.com/jungvonmatt/contentful-ssg/commit/27e95a33452b1aa5158ee89070889383cee4b6c5))
12
+
13
+
14
+
15
+
16
+
17
+ # [1.1.0](https://github.com/jungvonmatt/contentful-ssg/compare/v1.0.6...v1.1.0) (2021-12-02)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * 🐛 Adds <rootDir>/data to managed directories ([d67de2b](https://github.com/jungvonmatt/contentful-ssg/commit/d67de2b4a78771076e5fd1d4e7beec0c1fb65a7d))
23
+
24
+
25
+
26
+
27
+
28
+ ## [1.0.6](https://github.com/jungvonmatt/contentful-ssg/compare/v1.0.5...v1.0.6) (2021-12-02)
29
+
30
+ **Note:** Version bump only for package @jungvonmatt/cssg-plugin-hugo
31
+
32
+
33
+
34
+
35
+
36
+ ## [1.0.5](https://github.com/jungvonmatt/contentful-ssg/compare/v1.0.4...v1.0.5) (2021-11-30)
37
+
38
+ **Note:** Version bump only for package @jungvonmatt/cssg-plugin-hugo
39
+
40
+
41
+
42
+
43
+
6
44
  ## [1.0.4](https://github.com/jungvonmatt/contentful-ssg/compare/v1.0.3...v1.0.4) (2021-11-29)
7
45
 
8
46
  **Note:** Version bump only for package @jungvonmatt/cssg-plugin-hugo
package/index.js CHANGED
@@ -3,7 +3,8 @@ import mergeOptionsModule from 'merge-options';
3
3
  import { snakeCaseKeys } from '@jungvonmatt/contentful-ssg/lib/object';
4
4
  import mm from 'micromatch';
5
5
  import { existsSync } from 'fs';
6
- import { writeFile, readFile } from 'fs/promises';
6
+ import { outputFile } from 'fs-extra';
7
+ import { readFile } from 'fs/promises';
7
8
  import path from 'path';
8
9
 
9
10
  const mergeOptions = mergeOptionsModule.bind({ ignoreUndefined: true });
@@ -18,10 +19,15 @@ const defaultOptions = {
18
19
  typeIdSettings: 'd-settings',
19
20
  translationStrategy: STRATEGY_DIRECTORY,
20
21
  typeIdI18n: 'd-i18n',
22
+ menuDepth: 2,
23
+ typeIdMenu: 'c-menu',
21
24
  languageConfig: true,
22
25
  fieldIdHome: 'home',
23
26
  fieldIdSlug: 'slug',
24
27
  fieldIdParent: 'parent_page',
28
+ fieldIdMenuEntries: 'entries',
29
+ fieldIdMenuHide: 'hide_in_menu',
30
+ fieldIdMenuPos: 'menu_pos',
25
31
  typeConfig: {
26
32
  [TYPE_CONTENT]: ['page'],
27
33
  },
@@ -60,7 +66,69 @@ export default (args) => {
60
66
  return type;
61
67
  };
62
68
 
69
+ const buildMenu = (transformContext, depth = 0) => {
70
+ const { entry, entryMap } = transformContext;
71
+
72
+ const entries = entry.fields?.entries ?? [];
73
+ const nodes = entries.map((node, index) => ({
74
+ identifier: node.sys.id,
75
+ weight: (index + 1) * -10,
76
+ params: {
77
+ id: node.sys.id,
78
+ // eslint-disable-next-line camelcase
79
+ content_type: node.sys.contentType.sys.id,
80
+ },
81
+ }));
82
+
83
+ const getChildnodes = (entry, depth) => {
84
+ const id = entry?.sys?.id ?? 0;
85
+ const contentType = entry?.sys?.contentType?.sys?.id ?? '';
86
+
87
+ if (!id || !contentType || depth <= 0) {
88
+ return [];
89
+ }
90
+
91
+ const childnodes = [...entryMap.values()].filter(
92
+ (entry) => (entry?.fields?.[options.fieldIdParent]?.sys?.id ?? '') === id
93
+ );
94
+
95
+ // Filter childnodes based on hide_in_menu field
96
+ const filtered = childnodes.filter(
97
+ (entry) => !(entry?.fields?.[options.fieldIdMenuHide] ?? false)
98
+ );
99
+
100
+ // Sort based on menuPos field
101
+ const sorted = [...filtered].sort(
102
+ (a, b) =>
103
+ (a?.fields?.[options.fieldIdMenuPos] ?? Number.MAX_SAFE_INTEGER) -
104
+ (b?.fields?.[options.fieldIdMenuPos] ?? Number.MAX_SAFE_INTEGER)
105
+ );
106
+
107
+ return [
108
+ ...sorted.map((node, index) => ({
109
+ identifier: node.sys.id,
110
+ parent: id,
111
+ weight: (index + 1) * -10,
112
+ params: {
113
+ id: node.sys.id,
114
+ // eslint-disable-next-line camelcase
115
+ content_type: node.sys.contentType.sys.id,
116
+ },
117
+ })),
118
+ ...sorted.flatMap((node) => getChildnodes(node, depth - 1)),
119
+ ];
120
+ };
121
+
122
+ return [...nodes, ...entries.flatMap((node) => getChildnodes(node, depth))];
123
+ };
124
+
63
125
  return {
126
+ config(prev) {
127
+ const { managedDirectories } = prev || {};
128
+
129
+ return { ...prev, managedDirectories: [...(managedDirectories || []), 'data'] };
130
+ },
131
+
64
132
  // Before hook
65
133
  async before(runtimeContext) {
66
134
  const { helper, converter, data, localized } = runtimeContext;
@@ -98,7 +166,7 @@ export default (args) => {
98
166
  ];
99
167
  })
100
168
  );
101
- await writeFile(dst, converter.toml.stringify(languageConfig));
169
+ await outputFile(dst, converter.toml.stringify(languageConfig));
102
170
  }
103
171
 
104
172
  // Find section pages and add them to the runtimeconfig
@@ -118,8 +186,9 @@ export default (args) => {
118
186
  );
119
187
 
120
188
  const i18n = Object.fromEntries(locales.map((locale) => [locale.code, {}]));
189
+ const menus = Object.fromEntries(locales.map((locale) => [locale.code, {}]));
121
190
 
122
- return { ...runtimeContext, helper, localized: enhancedLocalized, i18n };
191
+ return { ...runtimeContext, helper, localized: enhancedLocalized, i18n, menus };
123
192
  },
124
193
 
125
194
  /**
@@ -185,8 +254,8 @@ export default (args) => {
185
254
 
186
255
  if (contentTypeId === options.typeIdSettings) {
187
256
  return options.translationStrategy === STRATEGY_FILENAME
188
- ? `../settings.${locale.code}.json`
189
- : '../settings.json';
257
+ ? `../settings.${locale.code}.yaml`
258
+ : '../settings.yaml';
190
259
  }
191
260
 
192
261
  if (type === TYPE_CONTENT && sectionIds.has(id)) {
@@ -219,12 +288,12 @@ export default (args) => {
219
288
  }
220
289
 
221
290
  return options.translationStrategy === STRATEGY_FILENAME
222
- ? `${id}.${locale.code}.json`
223
- : `${id}.json`;
291
+ ? `${id}.${locale.code}.yaml`
292
+ : `${id}.yaml`;
224
293
  },
225
294
 
226
295
  async transform(transformContext, runtimeContext) {
227
- const { content, id, contentTypeId, locale } = transformContext;
296
+ const { content, id, contentTypeId, locale, entry } = transformContext;
228
297
 
229
298
  const type = getEntryType(transformContext);
230
299
 
@@ -240,6 +309,14 @@ export default (args) => {
240
309
  return undefined;
241
310
  }
242
311
 
312
+ // Automatically build hugo menus
313
+ // See https://gohugo.io/content-management/menus/
314
+ if (options.typeIdMenu && contentTypeId === options.typeIdMenu) {
315
+ const { name = 'main' } = entry.fields;
316
+ const menu = buildMenu(transformContext, options.menuDepth);
317
+ runtimeContext.menus[locale.code][name] = menu;
318
+ }
319
+
243
320
  if (type === TYPE_CONTENT) {
244
321
  return {
245
322
  ...snakeCaseKeys({
@@ -264,7 +341,17 @@ export default (args) => {
264
341
  ? toml.parse(await readFile(dictionaryPath, 'utf8'))
265
342
  : {};
266
343
 
267
- return writeFile(dictionaryPath, toml.stringify({ ...oldContent, ...translations }));
344
+ return outputFile(dictionaryPath, toml.stringify({ ...oldContent, ...translations }));
345
+ })
346
+ );
347
+
348
+ const { stringify } = await import('@jungvonmatt/contentful-ssg/converter/toml');
349
+ const menus = runtimeContext?.menus ?? {};
350
+ await Promise.all(
351
+ Object.entries(menus).map(([localeCode, menuData]) => {
352
+ const file = `config/_default/menus.${localeCode}.toml`;
353
+ const data = stringify(menuData);
354
+ return outputFile(file, data);
268
355
  })
269
356
  );
270
357
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jungvonmatt/cssg-plugin-hugo",
3
- "version": "1.0.4",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "typings": "./index.d.ts",
@@ -26,9 +26,10 @@
26
26
  },
27
27
  "homepage": "https://github.com/jungvonmatt/contentful-ssg#readme",
28
28
  "dependencies": {
29
- "@jungvonmatt/contentful-ssg": "^1.0.4",
29
+ "@jungvonmatt/contentful-ssg": "^1.1.0",
30
+ "fs-extra": "^10.0.0",
30
31
  "merge-options": "^3.0.4",
31
32
  "micromatch": "^4.0.4"
32
33
  },
33
- "gitHead": "9da40bcd4fa8124cf7ae3ff6a2dcfca91c82c4fb"
34
+ "gitHead": "9e0182ef7511c6ba80f6332e6f726eaadafca915"
34
35
  }