create-berna-stencil 2.5.0 → 2.6.1

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 (188) hide show
  1. package/.eleventy.js +1 -1
  2. package/.gitignore +5 -4
  3. package/README.md +5 -6
  4. package/_tools/assistant.js +92 -88
  5. package/_tools/modules/constants.js +23 -0
  6. package/_tools/modules/pageComponents.js +77 -0
  7. package/_tools/modules/updateData.js +25 -44
  8. package/_tools/modules/updateOutputPath.js +59 -63
  9. package/_tools/modules/updatePage.js +131 -104
  10. package/_tools/modules/utils.js +16 -19
  11. package/_tools/modules/validation.js +20 -0
  12. package/_tools/res/templates/template.njk +2 -2
  13. package/bin/create.js +76 -14
  14. package/docs/Assistant CLI.md +3 -3
  15. package/docs/Components.md +4 -4
  16. package/docs/Creating pages.md +3 -3
  17. package/docs/Styling with SCSS.md +1 -1
  18. package/package.json +50 -65
  19. package/src/backend/_core/vendor/composer/autoload_static.php +10 -10
  20. package/src/backend/_core/vendor/composer/installed.json +6 -6
  21. package/src/backend/_core/vendor/composer/installed.php +2 -2
  22. package/src/backend/_core/vendor/graham-campbell/result-type/.gitattributes +9 -0
  23. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CODE_OF_CONDUCT.md +132 -0
  24. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CONTRIBUTING.md +31 -0
  25. package/src/backend/_core/vendor/graham-campbell/result-type/.github/FUNDING.yml +2 -0
  26. package/src/backend/_core/vendor/graham-campbell/result-type/.github/SECURITY.md +14 -0
  27. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/stale.yml +11 -0
  28. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/tests.yml +40 -0
  29. package/src/backend/_core/vendor/graham-campbell/result-type/CHANGELOG.md +53 -0
  30. package/src/backend/_core/vendor/graham-campbell/result-type/LICENSE +21 -21
  31. package/src/backend/_core/vendor/graham-campbell/result-type/README.md +42 -0
  32. package/src/backend/_core/vendor/graham-campbell/result-type/composer.json +33 -33
  33. package/src/backend/_core/vendor/graham-campbell/result-type/phpunit.xml.dist +13 -0
  34. package/src/backend/_core/vendor/graham-campbell/result-type/src/Error.php +121 -121
  35. package/src/backend/_core/vendor/graham-campbell/result-type/src/Result.php +69 -69
  36. package/src/backend/_core/vendor/graham-campbell/result-type/src/Success.php +120 -120
  37. package/src/backend/_core/vendor/graham-campbell/result-type/tests/ResultTest.php +95 -0
  38. package/src/backend/_core/vendor/phpoption/phpoption/.gitattributes +13 -0
  39. package/src/backend/_core/vendor/phpoption/phpoption/.github/CODE_OF_CONDUCT.md +132 -0
  40. package/src/backend/_core/vendor/phpoption/phpoption/.github/CONTRIBUTING.md +30 -0
  41. package/src/backend/_core/vendor/phpoption/phpoption/.github/FUNDING.yml +2 -0
  42. package/src/backend/_core/vendor/phpoption/phpoption/.github/SECURITY.md +14 -0
  43. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/static.yml +40 -0
  44. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/tests.yml +40 -0
  45. package/src/backend/_core/vendor/phpoption/phpoption/LICENSE +200 -200
  46. package/src/backend/_core/vendor/phpoption/phpoption/Makefile +17 -0
  47. package/src/backend/_core/vendor/phpoption/phpoption/README.md +201 -0
  48. package/src/backend/_core/vendor/phpoption/phpoption/composer.json +50 -50
  49. package/src/backend/_core/vendor/phpoption/phpoption/phpstan-baseline.neon +44 -0
  50. package/src/backend/_core/vendor/phpoption/phpoption/phpstan.neon.dist +7 -0
  51. package/src/backend/_core/vendor/phpoption/phpoption/phpunit.xml.dist +13 -0
  52. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +175 -175
  53. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/None.php +136 -136
  54. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Option.php +434 -434
  55. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Some.php +169 -169
  56. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/EnsureTest.php +72 -0
  57. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/LazyOptionTest.php +357 -0
  58. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/NoneTest.php +153 -0
  59. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/OptionTest.php +166 -0
  60. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/SomeTest.php +194 -0
  61. package/src/backend/_core/vendor/phpoption/phpoption/tests/bootstrap.php +8 -0
  62. package/src/backend/_core/vendor/phpoption/phpoption/vendor-bin/phpstan/composer.json +8 -0
  63. package/src/backend/_core/vendor/symfony/polyfill-ctype/Ctype.php +232 -232
  64. package/src/backend/_core/vendor/symfony/polyfill-ctype/LICENSE +19 -19
  65. package/src/backend/_core/vendor/symfony/polyfill-ctype/README.md +12 -12
  66. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap.php +50 -50
  67. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap80.php +46 -46
  68. package/src/backend/_core/vendor/symfony/polyfill-ctype/composer.json +38 -38
  69. package/src/backend/_core/vendor/symfony/polyfill-mbstring/LICENSE +19 -19
  70. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Mbstring.php +1077 -1077
  71. package/src/backend/_core/vendor/symfony/polyfill-mbstring/README.md +13 -13
  72. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +119 -119
  73. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -1397
  74. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -5
  75. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -1489
  76. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap.php +171 -171
  77. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap80.php +167 -167
  78. package/src/backend/_core/vendor/symfony/polyfill-mbstring/composer.json +39 -39
  79. package/src/backend/_core/vendor/symfony/polyfill-php80/LICENSE +19 -19
  80. package/src/backend/_core/vendor/symfony/polyfill-php80/Php80.php +115 -115
  81. package/src/backend/_core/vendor/symfony/polyfill-php80/PhpToken.php +106 -106
  82. package/src/backend/_core/vendor/symfony/polyfill-php80/README.md +25 -25
  83. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +31 -31
  84. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +16 -16
  85. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +20 -20
  86. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +16 -16
  87. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +16 -16
  88. package/src/backend/_core/vendor/symfony/polyfill-php80/bootstrap.php +42 -42
  89. package/src/backend/_core/vendor/symfony/polyfill-php80/composer.json +37 -37
  90. package/src/backend/_core/vendor/vlucas/phpdotenv/.editorconfig +15 -0
  91. package/src/backend/_core/vendor/vlucas/phpdotenv/.gitattributes +15 -0
  92. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CODE_OF_CONDUCT.md +132 -0
  93. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CONTRIBUTING.md +30 -0
  94. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/FUNDING.yml +2 -0
  95. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/SECURITY.md +14 -0
  96. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/static.yml +40 -0
  97. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/tests.yml +70 -0
  98. package/src/backend/_core/vendor/vlucas/phpdotenv/LICENSE +30 -30
  99. package/src/backend/_core/vendor/vlucas/phpdotenv/Makefile +17 -0
  100. package/src/backend/_core/vendor/vlucas/phpdotenv/README.md +370 -0
  101. package/src/backend/_core/vendor/vlucas/phpdotenv/UPGRADING.md +196 -0
  102. package/src/backend/_core/vendor/vlucas/phpdotenv/composer.json +60 -60
  103. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan-baseline.neon +157 -0
  104. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan.neon.dist +7 -0
  105. package/src/backend/_core/vendor/vlucas/phpdotenv/phpunit.xml.dist +13 -0
  106. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Dotenv.php +267 -267
  107. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +12 -12
  108. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php +12 -12
  109. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php +12 -12
  110. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php +12 -12
  111. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php +12 -12
  112. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Loader.php +48 -48
  113. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +20 -20
  114. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +65 -65
  115. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Entry.php +59 -59
  116. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +299 -299
  117. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +58 -58
  118. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lines.php +127 -127
  119. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Parser.php +53 -53
  120. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +19 -19
  121. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Value.php +88 -88
  122. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +15 -15
  123. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +89 -89
  124. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +80 -80
  125. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +88 -88
  126. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +85 -85
  127. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +110 -110
  128. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +48 -48
  129. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +64 -64
  130. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +91 -91
  131. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +17 -17
  132. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +104 -104
  133. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +88 -88
  134. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +27 -27
  135. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php +107 -107
  136. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +272 -272
  137. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +51 -51
  138. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Paths.php +44 -44
  139. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Reader.php +81 -81
  140. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/FileStore.php +72 -72
  141. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +141 -141
  142. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +17 -17
  143. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StringStore.php +37 -37
  144. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Regex.php +112 -112
  145. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Str.php +108 -108
  146. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Validator.php +207 -207
  147. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/DotenvTest.php +387 -0
  148. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Loader/LoaderTest.php +86 -0
  149. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/EntryParserTest.php +234 -0
  150. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LexerTest.php +40 -0
  151. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LinesTest.php +53 -0
  152. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/ParserTest.php +98 -0
  153. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ArrayAdapterTest.php +57 -0
  154. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/EnvConstAdapterTest.php +75 -0
  155. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/PutenvAdapterTest.php +52 -0
  156. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ServerConstAdapterTest.php +75 -0
  157. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/RepositoryTest.php +305 -0
  158. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Store/StoreTest.php +141 -0
  159. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/ValidatorTest.php +479 -0
  160. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/.env +5 -0
  161. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/assertions.env +18 -0
  162. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/booleans.env +33 -0
  163. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/commented.env +15 -0
  164. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/empty.env +1 -0
  165. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/example.env +1 -0
  166. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/exported.env +7 -0
  167. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/immutable.env +1 -0
  168. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/integers.env +17 -0
  169. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/large.env +2 -0
  170. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multibyte.env +3 -0
  171. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiline.env +14 -0
  172. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiple.env +4 -0
  173. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/mutable.env +1 -0
  174. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/nested.env +15 -0
  175. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/quoted.env +11 -0
  176. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/specialchars.env +8 -0
  177. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/unicodevarnames.env +2 -0
  178. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/utf8-with-bom-encoding.env +3 -0
  179. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/windows.env +1 -0
  180. package/src/backend/_core/vendor/vlucas/phpdotenv/vendor-bin/phpstan/composer.json +15 -0
  181. package/src/backend/{config.example.php → config.php} +4 -13
  182. package/src/frontend/data/site.json +44 -44
  183. package/src/frontend/index.njk +2 -2
  184. package/src/frontend/{components/layouts → layouts}/base.njk +1 -1
  185. package/_tools/buildJs.js +0 -28
  186. package/_tools/cleanOutput.js +0 -20
  187. package/_tools/modules/updateIncludes.js +0 -81
  188. /package/src/frontend/{components/layouts/includes.njk → layouts/pageComponents.njk} +0 -0
package/bin/create.js CHANGED
@@ -4,6 +4,19 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const readline = require('readline');
6
6
  const { writeSync } = require('fs');
7
+ const { spawnSync } = require('child_process');
8
+
9
+ const color = {
10
+ reset: '\x1b[0m',
11
+ bold: '\x1b[1m',
12
+ dim: '\x1b[2m',
13
+ red: '\x1b[31m',
14
+ green: '\x1b[32m',
15
+ yellow: '\x1b[33m',
16
+ blue: '\x1b[34m',
17
+ magenta: '\x1b[35m',
18
+ cyan: '\x1b[36m',
19
+ };
7
20
 
8
21
  // ── PATHS ────────────────────────────────────────────────────────────────────
9
22
 
@@ -121,7 +134,7 @@ src/backend/config.php
121
134
 
122
135
  const PROJECT_PACKAGE = {
123
136
  name: path.basename(targetDir),
124
- version: '2.5.0',
137
+ version: '2.6.1',
125
138
  private: true,
126
139
  outputDir: 'out',
127
140
  "scripts": {
@@ -134,8 +147,7 @@ const PROJECT_PACKAGE = {
134
147
  "serve:11ty": "eleventy --serve --quiet",
135
148
  "clean": "node _tools/cleanOutput.js",
136
149
  "serve": "npm run clean && concurrently \"npm run serve:11ty\" \"npm run serve:css\" \"npm run serve:js\"",
137
- "assistant": "node _tools/assistant.js",
138
- "postinstall": "cd src/backend/_core && composer install --quiet"
150
+ "assistant": "node _tools/assistant.js"
139
151
  },
140
152
  dependencies: {
141
153
  '@11ty/eleventy': '^3.1.2',
@@ -161,6 +173,10 @@ function log(msg) {
161
173
  writeSync(1, msg + '\n');
162
174
  }
163
175
 
176
+ function logAdd(name) {
177
+ log(`${color.green}+${color.reset} ${name}`);
178
+ }
179
+
164
180
  function escapeRegex(str) {
165
181
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
166
182
  }
@@ -209,6 +225,48 @@ function njkUncomment(content, line) {
209
225
  return content.split(`{# ${line} #}`).join(line);
210
226
  }
211
227
 
228
+ function installDependencies() {
229
+ const backendCore = path.join(targetDir, 'src', 'backend', '_core');
230
+
231
+ log(`${color.blue}\n>> Installing Node modules...${color.reset}`);
232
+ const npm = spawnSync('npm', ['install'], {
233
+ cwd: targetDir,
234
+ stdio: 'inherit',
235
+ shell: process.platform === 'win32',
236
+ });
237
+
238
+ if (npm.status !== 0) {
239
+ log('\n(!) npm install failed. Finish manually:');
240
+ if (process.argv[2]) log(` cd ${process.argv[2]}`);
241
+ log(' npm install\n');
242
+ return false;
243
+ }
244
+
245
+ if (!fs.existsSync(path.join(backendCore, 'composer.json'))) {
246
+ return true;
247
+ }
248
+
249
+ const probe = spawnSync('composer', ['--version'], {
250
+ stdio: 'ignore',
251
+ shell: process.platform === 'win32',
252
+ });
253
+
254
+ if (probe.status !== 0) {
255
+ log('\n(!) Composer not found — skipping backend dependencies.');
256
+ log(' Install Composer, then run: cd src/backend/_core && composer install\n');
257
+ return true;
258
+ }
259
+
260
+ log(`\n${color.blue}>> Installing Composer modules...${color.reset}\n`);
261
+ spawnSync('composer', ['install'], {
262
+ cwd: backendCore,
263
+ stdio: 'inherit',
264
+ shell: process.platform === 'win32',
265
+ });
266
+
267
+ return true;
268
+ }
269
+
212
270
  // ── APPLY ─────────────────────────────────────────────────────────────────────
213
271
 
214
272
  function applyFramework(framework) {
@@ -226,7 +284,7 @@ function applyFramework(framework) {
226
284
  fs.writeFileSync(globalScssPath, content);
227
285
  }
228
286
 
229
- const baseNjkPath = path.join(targetDir, 'src/frontend/components/layouts/base.njk');
287
+ const baseNjkPath = path.join(targetDir, 'src/frontend/layouts/base.njk');
230
288
  if (fs.existsSync(baseNjkPath)) {
231
289
  let content = fs.readFileSync(baseNjkPath, 'utf8');
232
290
  ALL_FRAMEWORKS.forEach(fw => {
@@ -313,25 +371,27 @@ function askChoice(question, choices) {
313
371
  async function init() {
314
372
  if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
315
373
 
316
- log(`\n>> Creating berna-stencil project in ${targetDir}\n`);
374
+ log(`\n>> ${color.magenta}Creating berna-stencil project in ${targetDir}\n${color.reset}`);
317
375
 
318
376
  const language = await askChoice('Select a language', LANGUAGE_CHOICES);
319
377
  const framework = await askChoice('Select a CSS framework', FRAMEWORK_CHOICES);
320
378
 
379
+ log('');
380
+
321
381
  for (const target of MANDATORY_COPY) {
322
382
  const src = path.join(templateDir, target);
323
383
  const dest = path.join(targetDir, target);
324
384
  if (!fs.existsSync(src)) continue;
325
385
  const exclude = target === 'src/frontend' ? FRONTEND_EXCLUDE[language] : [];
326
386
  copyRecursive(src, dest, exclude);
327
- log(`+ ${target}`);
387
+ logAdd(target);
328
388
  }
329
389
 
330
390
  const configDest = path.join(targetDir, 'src/backend/config.php');
331
391
  const configExample = path.join(targetDir, 'src/backend/config.example.php');
332
392
  if (!fs.existsSync(configDest) && fs.existsSync(configExample)) {
333
393
  fs.copyFileSync(configExample, configDest);
334
- log('+ src/backend/config.php');
394
+ logAdd('src/backend/config.php');
335
395
  }
336
396
  deleteFileRecursive(targetDir, 'config.example.php');
337
397
 
@@ -341,15 +401,15 @@ async function init() {
341
401
  const tsSrc = path.join(templateDir, 'tsconfig.json');
342
402
  const tsDest = path.join(targetDir, 'tsconfig.json');
343
403
  fs.copyFileSync(tsSrc, tsDest);
344
- log('+ tsconfig.json');
404
+ logAdd('tsconfig.json');
345
405
  pkg.devDependencies = { ...pkg.devDependencies, typescript: 'latest' };
346
406
  }
347
407
 
348
408
  fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(pkg, null, 2));
349
- log('+ package.json');
409
+ logAdd('package.json');
350
410
 
351
411
  fs.writeFileSync(path.join(targetDir, '.gitignore'), GITIGNORE_CONTENT);
352
- log('+ .gitignore');
412
+ logAdd('.gitignore');
353
413
 
354
414
  for (const dir of CREATE_DIRS) {
355
415
  fs.mkdirSync(path.join(targetDir, dir), { recursive: true });
@@ -358,10 +418,12 @@ async function init() {
358
418
  applyFramework(framework);
359
419
  applyLanguage(language);
360
420
 
361
- log(`\n>> Done! Now run:\n`);
362
- if (process.argv[2]) log(`cd ${process.argv[2]}`);
363
- log('npm install');
364
- log('npm run serve\n');
421
+ installDependencies();
422
+
423
+ log(`\n${color.green}>> Done!${color.reset}`);
424
+ log(`${color.yellow}\nNow run:\n${color.reset}`);
425
+ if (process.argv[2]) log(` ${color.yellow}cd ${process.argv[2]}${color.reset}`);
426
+ log(` ${color.yellow}npm run serve${color.reset}\n`);
365
427
  }
366
428
 
367
429
  init();
@@ -31,7 +31,7 @@ For a page named `my-page`, the following files are created:
31
31
  | `src/frontend/js/pages/myPage.js` | JS entry point |
32
32
  | `src/frontend/_routes/my-page.njk` | Nunjucks template |
33
33
 
34
- It also adds an `elif` block in `includes.njk` and a stub entry in `site.json`:
34
+ It also adds an `elif` block in `pageComponents.njk` and a stub entry in `site.json`:
35
35
 
36
36
  ```json
37
37
  "myPage": {
@@ -48,11 +48,11 @@ It also adds an `elif` block in `includes.njk` and a stub entry in `site.json`:
48
48
 
49
49
  ## Remove page
50
50
 
51
- Deletes all source files for the page and cleans up the output directory, `includes.njk`, and `site.json`.
51
+ Deletes all source files for the page and cleans up the output directory, `pageComponents.njk`, and `site.json`.
52
52
 
53
53
  ## Rename page
54
54
 
55
- Renames all three source files, updates the `elif` block in `includes.njk`, and renames the record in `site.json` while preserving all existing fields.
55
+ Renames all three source files, updates the `elif` block in `pageComponents.njk`, and renames the record in `site.json` while preserving all existing fields.
56
56
 
57
57
  ## Configure output path
58
58
 
@@ -19,9 +19,9 @@ src/frontend/components/
19
19
 
20
20
  ## Include a component
21
21
 
22
- To render a component inside a page, navigate to `src/frontend/components/layouts/` and edit `includes.njk`
22
+ To render a component inside a page, navigate to `src/frontend/layouts/` and edit `pageComponents.njk`
23
23
 
24
- ### includes.njk <small>(`src/frontend/components/layouts/`)</small>
24
+ ### pageComponents.njk <small>(`src/frontend/layouts/`)</small>
25
25
 
26
26
  ```js
27
27
  {% if title == "homepage" %}
@@ -41,7 +41,7 @@ Add a new `{% elif %}` block for each page, listing its components in order. If
41
41
 
42
42
  > ⚠️ A new `elif` block is automatically added when you create a page via the Assistant CLI
43
43
 
44
- > ⚠️ If you move or delete a component, always update `includes.njk` or the site will break
44
+ > ⚠️ If you move or delete a component, always update `pageComponents.njk` or the site will break
45
45
 
46
46
  ### Using Markdown files in components
47
47
 
@@ -75,7 +75,7 @@ Header and footer live in `src/frontend/components/global/` and are automaticall
75
75
 
76
76
  ## Site data in components
77
77
 
78
- All values defined in `src/data/site.json` are globally available in every component via `{{ site.* }}`
78
+ All values defined in `src/frontend/data/site.json` are globally available in every component via `{{ site.* }}`
79
79
 
80
80
  ### site.json <small>(`src/data/`)</small>
81
81
  ```json
@@ -9,14 +9,14 @@ For a page named `my-page`:
9
9
 
10
10
  | File | Purpose |
11
11
  |---|---|
12
- | `src/frontend/pages/my-page.njk` | Template with front matter |
12
+ | `src/frontend/_routes_/my-page.njk` | Template with front matter |
13
13
  | `src/frontend/scss/pages/myPage.scss` | Imports framework + modules |
14
14
  | `src/frontend/js/pages/myPage.js` | Imports JS modules |
15
15
 
16
16
  ## Adding content
17
17
 
18
18
  1. Create a component in `src/frontend/components/` (e.g. `_myPage.njk`)
19
- 2. Include it in `src/frontend/components/layouts/includes.njk` inside the generated `elif` block:
19
+ 2. Include it in `src/frontend/layouts/pageComponents.njk` inside the generated `elif` block:
20
20
 
21
21
  ```njk
22
22
  {% elif title == "myPage" %}
@@ -37,7 +37,7 @@ To create a URL like `domain.it/about/team`, edit the `permalink` in `src/fronte
37
37
  ---
38
38
  title: "team"
39
39
  permalink: "about/team/"
40
- layout: includes.njk
40
+ layout: pageComponents.njk
41
41
  ---
42
42
  ```
43
43
 
@@ -97,7 +97,7 @@ To enable/disable them you have to modify 3 files around the project by just com
97
97
  // @import "../modules/frameworks/uikit";
98
98
  ```
99
99
 
100
- ### 2. base.njk <small>(`src/frontend/components/layouts/`)</small>
100
+ ### 2. base.njk <small>(`src/frontend/layouts/`)</small>
101
101
 
102
102
  ```html
103
103
  {# Bootstrap JS #}
package/package.json CHANGED
@@ -1,66 +1,51 @@
1
- {
2
- "name": "create-berna-stencil",
3
- "version": "2.5.0",
4
- "description": "Eleventy boilerplate with per-page SCSS/JS pipeline, esbuild bundling, multi-framework CSS support and a built-in page management CLI",
5
- "keywords": [],
6
- "author": "Michele Garofalo",
7
- "license": "Apache-2.0",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/rhaastrake/berna-stencil"
11
- },
12
- "homepage": "https://github.com/rhaastrake/berna-stencil#readme",
13
- "bugs": {
14
- "url": "https://github.com/rhaastrake/berna-stencil/issues"
15
- },
16
- "bin": {
17
- "create-berna-stencil": "bin/create.js"
18
- },
19
- "files": [
20
- "bin/",
21
- "docs/",
22
- "src/",
23
- "_tools/",
24
- ".eleventy.js",
25
- ".eleventyignore",
26
- "nginx.conf",
27
- ".gitignore",
28
- "tsconfig.json",
29
- "LICENSE",
30
- "NOTICE"
31
- ],
32
- "engines": {
33
- "node": ">=18.0.0"
34
- },
35
- "dependencies": {
36
- "@11ty/eleventy": "^3.1.2",
37
- "@11ty/eleventy-img": "^6.0.4",
38
- "bootstrap": "^5.3.8",
39
- "bootstrap-icons": "^1.13.1",
40
- "bulma": "^1.0.4",
41
- "foundation-sites": "^6.9.0",
42
- "github-markdown-css": "^5.9.0",
43
- "glob": "^13.0.6",
44
- "markdown-it": "^14.2.0",
45
- "uikit": "^3.25.13"
46
- },
47
- "devDependencies": {
48
- "concurrently": "^9.2.1",
49
- "esbuild": "^0.27.3",
50
- "sass": "^1.77.0"
51
- },
52
- "scripts": {
53
- "build:css": "sass src/frontend/scss:out/css --no-source-map --style=compressed --quiet",
54
- "build:js": "esbuild \"src/frontend/ts/pages/*.ts\" --bundle --outdir=out/js/pages --minify",
55
- "build:11ty": "eleventy",
56
- "build": "npm run clean && npm run build:css && npm run build:js && npm run build:11ty",
57
- "serve:css": "sass --watch src/frontend/scss:out/css --no-source-map --quiet",
58
- "serve:js": "esbuild \"src/frontend/ts/pages/*.ts\" --bundle --outdir=out/js/pages --watch",
59
- "serve:11ty": "eleventy --serve --quiet",
60
- "clean": "node _tools/cleanOutput.js",
61
- "serve": "npm run clean && concurrently \"npm run serve:11ty\" \"npm run serve:css\" \"npm run serve:js\"",
62
- "assistant": "node _tools/assistant.js",
63
- "postinstall": "cd src/backend/_core && composer install --quiet"
64
- },
65
- "outputDir": "out"
1
+ {
2
+ "name": "create-berna-stencil",
3
+ "version": "2.6.1",
4
+ "description": "Eleventy boilerplate with per-page SCSS/JS pipeline, esbuild bundling, multi-framework CSS support and a built-in page management CLI",
5
+ "author": "Michele Garofalo",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/rhaastrake/berna-stencil"
10
+ },
11
+ "homepage": "https://github.com/rhaastrake/berna-stencil#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/rhaastrake/berna-stencil/issues"
14
+ },
15
+ "bin": {
16
+ "create-berna-stencil": "bin/create.js"
17
+ },
18
+ "files": [
19
+ "bin/",
20
+ "docs/",
21
+ "src/",
22
+ "_tools/",
23
+ ".eleventy.js",
24
+ ".eleventyignore",
25
+ "nginx.conf",
26
+ ".gitignore",
27
+ "tsconfig.json",
28
+ "LICENSE",
29
+ "NOTICE"
30
+ ],
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@11ty/eleventy": "^3.1.2",
36
+ "@11ty/eleventy-img": "^6.0.4",
37
+ "bootstrap": "^5.3.8",
38
+ "bootstrap-icons": "^1.13.1",
39
+ "bulma": "^1.0.4",
40
+ "foundation-sites": "^6.9.0",
41
+ "github-markdown-css": "^5.9.0",
42
+ "glob": "^13.0.6",
43
+ "markdown-it": "^14.2.0",
44
+ "uikit": "^3.25.13"
45
+ },
46
+ "devDependencies": {
47
+ "concurrently": "^9.2.1",
48
+ "esbuild": "^0.27.3",
49
+ "sass": "^1.77.0"
50
+ }
66
51
  }
@@ -13,48 +13,48 @@ class ComposerStaticInit108be68e4e2b97fed51d36a10eed0849
13
13
  );
14
14
 
15
15
  public static $prefixLengthsPsr4 = array (
16
- 'S' =>
16
+ 'S' =>
17
17
  array (
18
18
  'Symfony\\Polyfill\\Php80\\' => 23,
19
19
  'Symfony\\Polyfill\\Mbstring\\' => 26,
20
20
  'Symfony\\Polyfill\\Ctype\\' => 23,
21
21
  ),
22
- 'P' =>
22
+ 'P' =>
23
23
  array (
24
24
  'PhpOption\\' => 10,
25
25
  ),
26
- 'G' =>
26
+ 'G' =>
27
27
  array (
28
28
  'GrahamCampbell\\ResultType\\' => 26,
29
29
  ),
30
- 'D' =>
30
+ 'D' =>
31
31
  array (
32
32
  'Dotenv\\' => 7,
33
33
  ),
34
34
  );
35
35
 
36
36
  public static $prefixDirsPsr4 = array (
37
- 'Symfony\\Polyfill\\Php80\\' =>
37
+ 'Symfony\\Polyfill\\Php80\\' =>
38
38
  array (
39
39
  0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
40
40
  ),
41
- 'Symfony\\Polyfill\\Mbstring\\' =>
41
+ 'Symfony\\Polyfill\\Mbstring\\' =>
42
42
  array (
43
43
  0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
44
44
  ),
45
- 'Symfony\\Polyfill\\Ctype\\' =>
45
+ 'Symfony\\Polyfill\\Ctype\\' =>
46
46
  array (
47
47
  0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
48
48
  ),
49
- 'PhpOption\\' =>
49
+ 'PhpOption\\' =>
50
50
  array (
51
51
  0 => __DIR__ . '/..' . '/phpoption/phpoption/src/PhpOption',
52
52
  ),
53
- 'GrahamCampbell\\ResultType\\' =>
53
+ 'GrahamCampbell\\ResultType\\' =>
54
54
  array (
55
55
  0 => __DIR__ . '/..' . '/graham-campbell/result-type/src',
56
56
  ),
57
- 'Dotenv\\' =>
57
+ 'Dotenv\\' =>
58
58
  array (
59
59
  0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src',
60
60
  ),
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "time": "2025-12-27T19:43:20+00:00",
26
26
  "type": "library",
27
- "installation-source": "dist",
27
+ "installation-source": "source",
28
28
  "autoload": {
29
29
  "psr-4": {
30
30
  "GrahamCampbell\\ResultType\\": "src/"
@@ -98,7 +98,7 @@
98
98
  "dev-master": "1.9-dev"
99
99
  }
100
100
  },
101
- "installation-source": "dist",
101
+ "installation-source": "source",
102
102
  "autoload": {
103
103
  "psr-4": {
104
104
  "PhpOption\\": "src/PhpOption/"
@@ -175,7 +175,7 @@
175
175
  "name": "symfony/polyfill"
176
176
  }
177
177
  },
178
- "installation-source": "dist",
178
+ "installation-source": "source",
179
179
  "autoload": {
180
180
  "files": [
181
181
  "bootstrap.php"
@@ -262,7 +262,7 @@
262
262
  "name": "symfony/polyfill"
263
263
  }
264
264
  },
265
- "installation-source": "dist",
265
+ "installation-source": "source",
266
266
  "autoload": {
267
267
  "files": [
268
268
  "bootstrap.php"
@@ -343,7 +343,7 @@
343
343
  "name": "symfony/polyfill"
344
344
  }
345
345
  },
346
- "installation-source": "dist",
346
+ "installation-source": "source",
347
347
  "autoload": {
348
348
  "files": [
349
349
  "bootstrap.php"
@@ -447,7 +447,7 @@
447
447
  "dev-master": "5.6-dev"
448
448
  }
449
449
  },
450
- "installation-source": "dist",
450
+ "installation-source": "source",
451
451
  "autoload": {
452
452
  "psr-4": {
453
453
  "Dotenv\\": "src/"
@@ -3,7 +3,7 @@
3
3
  'name' => '__root__',
4
4
  'pretty_version' => 'dev-main',
5
5
  'version' => 'dev-main',
6
- 'reference' => '9bbb36794fc27d6938523db2d4076661ad9ddab9',
6
+ 'reference' => '4719f94db95d3c803abf3cf434a4e47e38526a14',
7
7
  'type' => 'library',
8
8
  'install_path' => __DIR__ . '/../../',
9
9
  'aliases' => array(),
@@ -13,7 +13,7 @@
13
13
  '__root__' => array(
14
14
  'pretty_version' => 'dev-main',
15
15
  'version' => 'dev-main',
16
- 'reference' => '9bbb36794fc27d6938523db2d4076661ad9ddab9',
16
+ 'reference' => '4719f94db95d3c803abf3cf434a4e47e38526a14',
17
17
  'type' => 'library',
18
18
  'install_path' => __DIR__ . '/../../',
19
19
  'aliases' => array(),
@@ -0,0 +1,9 @@
1
+ * text=auto
2
+
3
+ /tests export-ignore
4
+ /.gitattributes export-ignore
5
+ /.github export-ignore
6
+ /.gitignore export-ignore
7
+ /phpunit.xml.dist export-ignore
8
+ /CHANGELOG.md export-ignore
9
+ /README.md export-ignore
@@ -0,0 +1,132 @@
1
+ # CONTRIBUTOR COVENANT CODE OF CONDUCT
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email
35
+ address, without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ hello@gjcampbell.co.uk.
64
+ All complaints will be reviewed and investigated promptly and fairly.
65
+
66
+ All community leaders are obligated to respect the privacy and security of the
67
+ reporter of any incident.
68
+
69
+ ## Enforcement Guidelines
70
+
71
+ Community leaders will follow these Community Impact Guidelines in determining
72
+ the consequences for any action they deem in violation of this Code of Conduct:
73
+
74
+ ### 1. Correction
75
+
76
+ **Community Impact**: Use of inappropriate language or other behavior deemed
77
+ unprofessional or unwelcome in the community.
78
+
79
+ **Consequence**: A private, written warning from community leaders, providing
80
+ clarity around the nature of the violation and an explanation of why the
81
+ behavior was inappropriate. A public apology may be requested.
82
+
83
+ ### 2. Warning
84
+
85
+ **Community Impact**: A violation through a single incident or series
86
+ of actions.
87
+
88
+ **Consequence**: A warning with consequences for continued behavior. No
89
+ interaction with the people involved, including unsolicited interaction with
90
+ those enforcing the Code of Conduct, for a specified period of time. This
91
+ includes avoiding interactions in community spaces as well as external channels
92
+ like social media. Violating these terms may lead to a temporary or
93
+ permanent ban.
94
+
95
+ ### 3. Temporary Ban
96
+
97
+ **Community Impact**: A serious violation of community standards, including
98
+ sustained inappropriate behavior.
99
+
100
+ **Consequence**: A temporary ban from any sort of interaction or public
101
+ communication with the community for a specified period of time. No public or
102
+ private interaction with the people involved, including unsolicited interaction
103
+ with those enforcing the Code of Conduct, is allowed during this period.
104
+ Violating these terms may lead to a permanent ban.
105
+
106
+ ### 4. Permanent Ban
107
+
108
+ **Community Impact**: Demonstrating a pattern of violation of community
109
+ standards, including sustained inappropriate behavior, harassment of an
110
+ individual, or aggression toward or disparagement of classes of individuals.
111
+
112
+ **Consequence**: A permanent ban from any sort of public interaction within
113
+ the community.
114
+
115
+ ## Attribution
116
+
117
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
+ version 2.1, available at
119
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
120
+
121
+ Community Impact Guidelines were inspired by
122
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
123
+
124
+ For answers to common questions about this code of conduct, see the FAQ at
125
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available
126
+ at [https://www.contributor-covenant.org/translations][translations].
127
+
128
+ [homepage]: https://www.contributor-covenant.org
129
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
130
+ [Mozilla CoC]: https://github.com/mozilla/diversity
131
+ [FAQ]: https://www.contributor-covenant.org/faq
132
+ [translations]: https://www.contributor-covenant.org/translations