create-berna-stencil 1.0.52 → 1.0.54

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 (170) hide show
  1. package/.eleventy.js +2 -1
  2. package/README.md +32 -3
  3. package/docs/Assistant CLI.md +59 -1
  4. package/docs/Backend.md +210 -1
  5. package/docs/Styling with SCSS.md +53 -53
  6. package/package.json +58 -58
  7. package/src/backend/_core/vendor/composer/autoload_static.php +10 -10
  8. package/src/backend/_core/vendor/composer/installed.json +6 -6
  9. package/src/backend/_core/vendor/composer/installed.php +2 -2
  10. package/src/backend/_core/vendor/graham-campbell/result-type/.gitattributes +9 -0
  11. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CODE_OF_CONDUCT.md +132 -0
  12. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CONTRIBUTING.md +31 -0
  13. package/src/backend/_core/vendor/graham-campbell/result-type/.github/FUNDING.yml +2 -0
  14. package/src/backend/_core/vendor/graham-campbell/result-type/.github/SECURITY.md +14 -0
  15. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/stale.yml +11 -0
  16. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/tests.yml +40 -0
  17. package/src/backend/_core/vendor/graham-campbell/result-type/CHANGELOG.md +53 -0
  18. package/src/backend/_core/vendor/graham-campbell/result-type/LICENSE +21 -21
  19. package/src/backend/_core/vendor/graham-campbell/result-type/README.md +42 -0
  20. package/src/backend/_core/vendor/graham-campbell/result-type/composer.json +33 -33
  21. package/src/backend/_core/vendor/graham-campbell/result-type/phpunit.xml.dist +13 -0
  22. package/src/backend/_core/vendor/graham-campbell/result-type/src/Error.php +121 -121
  23. package/src/backend/_core/vendor/graham-campbell/result-type/src/Result.php +69 -69
  24. package/src/backend/_core/vendor/graham-campbell/result-type/src/Success.php +120 -120
  25. package/src/backend/_core/vendor/graham-campbell/result-type/tests/ResultTest.php +95 -0
  26. package/src/backend/_core/vendor/phpoption/phpoption/.gitattributes +13 -0
  27. package/src/backend/_core/vendor/phpoption/phpoption/.github/CODE_OF_CONDUCT.md +132 -0
  28. package/src/backend/_core/vendor/phpoption/phpoption/.github/CONTRIBUTING.md +30 -0
  29. package/src/backend/_core/vendor/phpoption/phpoption/.github/FUNDING.yml +2 -0
  30. package/src/backend/_core/vendor/phpoption/phpoption/.github/SECURITY.md +14 -0
  31. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/static.yml +40 -0
  32. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/tests.yml +40 -0
  33. package/src/backend/_core/vendor/phpoption/phpoption/LICENSE +200 -200
  34. package/src/backend/_core/vendor/phpoption/phpoption/Makefile +17 -0
  35. package/src/backend/_core/vendor/phpoption/phpoption/README.md +201 -0
  36. package/src/backend/_core/vendor/phpoption/phpoption/composer.json +50 -50
  37. package/src/backend/_core/vendor/phpoption/phpoption/phpstan-baseline.neon +44 -0
  38. package/src/backend/_core/vendor/phpoption/phpoption/phpstan.neon.dist +7 -0
  39. package/src/backend/_core/vendor/phpoption/phpoption/phpunit.xml.dist +13 -0
  40. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +175 -175
  41. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/None.php +136 -136
  42. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Option.php +434 -434
  43. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Some.php +169 -169
  44. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/EnsureTest.php +72 -0
  45. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/LazyOptionTest.php +357 -0
  46. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/NoneTest.php +153 -0
  47. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/OptionTest.php +166 -0
  48. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/SomeTest.php +194 -0
  49. package/src/backend/_core/vendor/phpoption/phpoption/tests/bootstrap.php +8 -0
  50. package/src/backend/_core/vendor/phpoption/phpoption/vendor-bin/phpstan/composer.json +8 -0
  51. package/src/backend/_core/vendor/symfony/polyfill-ctype/Ctype.php +232 -232
  52. package/src/backend/_core/vendor/symfony/polyfill-ctype/LICENSE +19 -19
  53. package/src/backend/_core/vendor/symfony/polyfill-ctype/README.md +12 -12
  54. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap.php +50 -50
  55. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap80.php +46 -46
  56. package/src/backend/_core/vendor/symfony/polyfill-ctype/composer.json +38 -38
  57. package/src/backend/_core/vendor/symfony/polyfill-mbstring/LICENSE +19 -19
  58. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Mbstring.php +1077 -1077
  59. package/src/backend/_core/vendor/symfony/polyfill-mbstring/README.md +13 -13
  60. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +119 -119
  61. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -1397
  62. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -5
  63. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -1489
  64. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap.php +171 -171
  65. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap80.php +167 -167
  66. package/src/backend/_core/vendor/symfony/polyfill-mbstring/composer.json +39 -39
  67. package/src/backend/_core/vendor/symfony/polyfill-php80/LICENSE +19 -19
  68. package/src/backend/_core/vendor/symfony/polyfill-php80/Php80.php +115 -115
  69. package/src/backend/_core/vendor/symfony/polyfill-php80/PhpToken.php +106 -106
  70. package/src/backend/_core/vendor/symfony/polyfill-php80/README.md +25 -25
  71. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +31 -31
  72. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +16 -16
  73. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +20 -20
  74. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +16 -16
  75. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +16 -16
  76. package/src/backend/_core/vendor/symfony/polyfill-php80/bootstrap.php +42 -42
  77. package/src/backend/_core/vendor/symfony/polyfill-php80/composer.json +37 -37
  78. package/src/backend/_core/vendor/vlucas/phpdotenv/.editorconfig +15 -0
  79. package/src/backend/_core/vendor/vlucas/phpdotenv/.gitattributes +15 -0
  80. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CODE_OF_CONDUCT.md +132 -0
  81. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CONTRIBUTING.md +30 -0
  82. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/FUNDING.yml +2 -0
  83. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/SECURITY.md +14 -0
  84. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/static.yml +40 -0
  85. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/tests.yml +70 -0
  86. package/src/backend/_core/vendor/vlucas/phpdotenv/LICENSE +30 -30
  87. package/src/backend/_core/vendor/vlucas/phpdotenv/Makefile +17 -0
  88. package/src/backend/_core/vendor/vlucas/phpdotenv/README.md +370 -0
  89. package/src/backend/_core/vendor/vlucas/phpdotenv/UPGRADING.md +196 -0
  90. package/src/backend/_core/vendor/vlucas/phpdotenv/composer.json +60 -60
  91. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan-baseline.neon +157 -0
  92. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan.neon.dist +7 -0
  93. package/src/backend/_core/vendor/vlucas/phpdotenv/phpunit.xml.dist +13 -0
  94. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Dotenv.php +267 -267
  95. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +12 -12
  96. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php +12 -12
  97. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php +12 -12
  98. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php +12 -12
  99. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php +12 -12
  100. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Loader.php +48 -48
  101. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +20 -20
  102. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +65 -65
  103. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Entry.php +59 -59
  104. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +299 -299
  105. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +58 -58
  106. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lines.php +127 -127
  107. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Parser.php +53 -53
  108. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +19 -19
  109. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Value.php +88 -88
  110. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +15 -15
  111. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +89 -89
  112. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +80 -80
  113. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +88 -88
  114. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +85 -85
  115. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +110 -110
  116. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +48 -48
  117. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +64 -64
  118. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +91 -91
  119. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +17 -17
  120. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +104 -104
  121. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +88 -88
  122. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +27 -27
  123. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php +107 -107
  124. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +272 -272
  125. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +51 -51
  126. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Paths.php +44 -44
  127. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Reader.php +81 -81
  128. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/FileStore.php +72 -72
  129. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +141 -141
  130. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +17 -17
  131. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StringStore.php +37 -37
  132. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Regex.php +112 -112
  133. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Str.php +108 -108
  134. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Validator.php +207 -207
  135. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/DotenvTest.php +387 -0
  136. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Loader/LoaderTest.php +86 -0
  137. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/EntryParserTest.php +234 -0
  138. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LexerTest.php +40 -0
  139. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LinesTest.php +53 -0
  140. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/ParserTest.php +98 -0
  141. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ArrayAdapterTest.php +57 -0
  142. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/EnvConstAdapterTest.php +75 -0
  143. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/PutenvAdapterTest.php +52 -0
  144. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ServerConstAdapterTest.php +75 -0
  145. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/RepositoryTest.php +305 -0
  146. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Store/StoreTest.php +141 -0
  147. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/ValidatorTest.php +479 -0
  148. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/.env +5 -0
  149. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/assertions.env +18 -0
  150. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/booleans.env +33 -0
  151. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/commented.env +15 -0
  152. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/empty.env +1 -0
  153. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/example.env +1 -0
  154. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/exported.env +7 -0
  155. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/immutable.env +1 -0
  156. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/integers.env +17 -0
  157. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/large.env +2 -0
  158. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multibyte.env +3 -0
  159. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiline.env +14 -0
  160. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiple.env +4 -0
  161. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/mutable.env +1 -0
  162. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/nested.env +15 -0
  163. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/quoted.env +11 -0
  164. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/specialchars.env +8 -0
  165. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/unicodevarnames.env +2 -0
  166. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/utf8-with-bom-encoding.env +3 -0
  167. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/windows.env +1 -0
  168. package/src/backend/_core/vendor/vlucas/phpdotenv/vendor-bin/phpstan/composer.json +15 -0
  169. package/src/frontend/components/welcome.njk +575 -28
  170. package/src/frontend/data/site.json +43 -43
package/.eleventy.js CHANGED
@@ -4,12 +4,13 @@ const Image = require("@11ty/eleventy-img");
4
4
  const fs = require("fs");
5
5
  const path = require("path");
6
6
 
7
- const OUTPUT_DIR = "out";
7
+ const OUTPUT_DIR = "c:/laragon/www/Berna-Stencil-out";
8
8
 
9
9
  module.exports = function (eleventyConfig) {
10
10
 
11
11
  function copyRecursiveSync(src, dest) {
12
12
  if (!fs.existsSync(src)) return;
13
+ if (src.includes('.git')) return;
13
14
  const stat = fs.statSync(src);
14
15
  if (stat.isDirectory()) {
15
16
  fs.mkdirSync(dest, { recursive: true });
package/README.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # 🏗️ Berna-Stencil
2
- A professional boilerplate for Eleventy, lightweight and structure-focused, ready to scale.
2
+ **Berna-Stencil** is an open source static site generator built on top of [Eleventy](https://www.11ty.dev/), designed with one clear mission: make web development simple, approachable, and enjoyable — for everyone.
3
+
4
+ Whether you're a seasoned developer looking for a clean starting point or a beginner taking your first steps into the world of web creation, Berna-Stencil gives you everything you need, right out of the box. No complicated setup, no hours spent reading documentation, no frustration — just a solid, well-structured foundation ready to become your next website.
5
+
6
+ ### ✨ Why Berna-Stencil?
7
+
8
+ Building a website from scratch involves a lot of moving parts: templating engines, build pipelines, asset management, backend logic, project structure. Berna-Stencil takes care of all of that for you, so you can focus on what actually matters — **your content and your ideas**.
9
+
10
+ - 🔧 **Zero-config ready** — clone, install, and you're live in minutes
11
+ - 🔗 **Integrated backend** — essential server-side functionality included, no extra setup required
12
+ - 📁 **Scalable structure** — a clean, opinionated project layout that grows with your needs
13
+ - 🌍 **Open source** — free to use, free to modify, free to share
3
14
 
4
15
  ![Version](https://img.shields.io/badge/version-1.0.0-blue)
5
16
  ![License](https://img.shields.io/badge/license-MIT-green)
@@ -7,15 +18,20 @@ A professional boilerplate for Eleventy, lightweight and structure-focused, read
7
18
 
8
19
  ## Prerequisites
9
20
  * **Node.js**: v18.0.0 or higher
21
+ * **Composer**: latest stable version
10
22
 
11
23
  ## Installation
12
24
  * Open your IDE (e.g. Visual Studio Code), open the folder that contains your websites and open a new terminal
13
25
  * Run the command for your system to download the project and install everything:
14
- #### Windows
15
26
  ```bash
16
27
  npm create berna-stencil@latest your-project
17
28
  ```
18
29
 
30
+ * Navigate into the project folder
31
+ ```bash
32
+ cd your-project
33
+ ```
34
+
19
35
  * Install all the node_modules
20
36
  ```bash
21
37
  npm install
@@ -24,4 +40,17 @@ A professional boilerplate for Eleventy, lightweight and structure-focused, read
24
40
  * Run the command to launch the live server and build the site, then visit localhost:8080:
25
41
  ```bash
26
42
  npm run serve
27
- ```
43
+ ```
44
+
45
+ ## Changelog
46
+
47
+ ### [1.0.0] - 2025-05-27
48
+ * Initial release
49
+ * Eleventy v3.1.2 support
50
+ * Base project structure and scaffolding CLI
51
+
52
+ ## Roadmap
53
+ * [ ] Add support for multiple themes
54
+ * [ ] Improve CLI with interactive prompts
55
+ * [ ] Add TypeScript support
56
+ * [ ] Extend documentation with advanced usage examples
@@ -1 +1,59 @@
1
- # ...
1
+ # Assistant CLI
2
+
3
+ An interactive CLI to manage pages without touching files manually.
4
+
5
+ ```
6
+ npm run assistant
7
+ ```
8
+
9
+ ## Menu
10
+
11
+ ```
12
+ 1. Create page
13
+ 2. Remove page
14
+ 3. Rename page
15
+ 4. Configure output path
16
+ ```
17
+
18
+ Use `CTRL/CMD + C` to exit.
19
+
20
+ ## Create page
21
+
22
+ Enter a page name in any format — the CLI converts it to kebab-case automatically.
23
+
24
+ For a page named `my-page`, the following files are created:
25
+
26
+ | File | Purpose |
27
+ |---|---|
28
+ | `src/frontend/scss/pages/myPage.scss` | SCSS entry point |
29
+ | `src/frontend/js/pages/myPage.js` | JS entry point |
30
+ | `src/frontend/_routes/my-page.njk` | Nunjucks template |
31
+
32
+ It also adds an `elif` block in `includes.njk` and a stub entry in `site.json`:
33
+
34
+ ```json
35
+ "myPage": {
36
+ "seo": {
37
+ "title": "My Page",
38
+ "description": "description"
39
+ },
40
+ "cdn": {
41
+ "css": [],
42
+ "js": []
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Remove page
48
+
49
+ Deletes all source files for the page and cleans up the output directory, `includes.njk`, and `site.json`.
50
+
51
+ ## Rename page
52
+
53
+ Renames all three source files, updates the `elif` block in `includes.njk`, and renames the record in `site.json` while preserving all existing fields.
54
+
55
+ ## Configure output path
56
+
57
+ Updates the output directory across `.eleventy.js` and all relevant `package.json` scripts in one shot. The old output folder is deleted automatically.
58
+
59
+ > ⚠️ `homepage` and `404` are protected — they cannot be created, removed, or renamed via the CLI.
package/docs/Backend.md CHANGED
@@ -1 +1,210 @@
1
- # ...
1
+ # Backend
2
+
3
+ The backend is a PHP REST API located in `src/backend/`, copied to the output directory automatically at build time.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ src/backend/
9
+ ├── api/
10
+ │ ├── public/ # Endpoints accessible without an API key
11
+ │ └── protected/ # Endpoints requiring X-Api-Key header
12
+ ├── database/
13
+ │ ├── Database.php
14
+ │ ├── models/
15
+ │ └── migrations/
16
+ ├── config.php # Your local config — never commit this
17
+ └── config.example.php
18
+ ```
19
+
20
+ ## Configuration
21
+
22
+ `config.php` works like a `.env` file — it holds secrets and environment settings that stay local and out of version control.
23
+
24
+ Copy `config.example.php` to `config.php` and fill in your values:
25
+
26
+ ### config.php <small>(`src/backend/`)</small>
27
+ ```php
28
+ return [
29
+ 'APP_ENV' => 'development', // or 'production'
30
+ 'API_KEY' => 'your-default-key',
31
+
32
+ 'ENDPOINT_KEYS' => [
33
+ 'subfolder/example-protected' => 'specific-key',
34
+ ],
35
+
36
+ 'DB_HOST' => '127.0.0.1',
37
+ 'DB_NAME' => 'example_db',
38
+ 'DB_USER' => 'root',
39
+ 'DB_PASS' => '',
40
+ ];
41
+ ```
42
+
43
+ `API_KEY` is the fallback key for all protected endpoints. Use `ENDPOINT_KEYS` to assign a different key to a specific endpoint — for subfolder endpoints, use the relative path as the key.
44
+
45
+ ## How routing works
46
+
47
+ The file path inside `api/` maps directly to the URL. Extra URL segments become route parameters available as `$requestParams[]`.
48
+
49
+ Every endpoint file has access to:
50
+
51
+ | Variable | Description |
52
+ |---|---|
53
+ | `$method` | HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`) |
54
+ | `$requestParams` | Extra URL segments (e.g. `/api/posts/42` → `['42']`) |
55
+
56
+ ## Creating a public endpoint
57
+
58
+ Create a `.php` file anywhere inside `api/public/`
59
+
60
+ ### api/public/posts.php
61
+ ```php
62
+ <?php
63
+ declare(strict_types=1);
64
+
65
+ require_once CORE_PATH . '/modules/Response.php';
66
+
67
+ if ($method !== 'GET') {
68
+ Response::error('Method not allowed', 405);
69
+ }
70
+
71
+ $id = isset($requestParams[0]) ? (int)$requestParams[0] : null;
72
+
73
+ Response::success(['id' => $id]);
74
+ ```
75
+
76
+ Reachable at `/api/posts` or `/api/posts/42`
77
+
78
+ ## Creating a protected endpoint
79
+
80
+ Create a `.php` file inside `api/protected/`. The API key check happens automatically before your file runs.
81
+
82
+ ### api/protected/admin/stats.php
83
+ ```php
84
+ <?php
85
+ declare(strict_types=1);
86
+
87
+ require_once CORE_PATH . '/modules/Response.php';
88
+
89
+ if ($method !== 'GET') {
90
+ Response::error('Method not allowed', 405);
91
+ }
92
+
93
+ Response::success(['visits' => 1024]);
94
+ ```
95
+
96
+ To assign a dedicated key, add it to `config.php`:
97
+
98
+ ```php
99
+ 'ENDPOINT_KEYS' => [
100
+ 'admin/stats' => 'secret-stats-key',
101
+ ],
102
+ ```
103
+
104
+ ## The Response helper
105
+
106
+ ```php
107
+ Response::success($data, $code); // default 200
108
+ Response::error($message, $code, $details); // default 400
109
+ Response::noContent(); // 204
110
+ ```
111
+
112
+ ## Handling multiple methods
113
+
114
+ ```php
115
+ $id = isset($requestParams[0]) ? (int)$requestParams[0] : null;
116
+ $input = json_decode(file_get_contents('php://input'), true) ?? [];
117
+
118
+ switch ($method) {
119
+ case 'GET':
120
+ Response::success(['id' => $id]);
121
+ break;
122
+
123
+ case 'POST':
124
+ if (empty($input['title'])) Response::error('Missing title', 400);
125
+ Response::success(['message' => 'Created'], 201);
126
+ break;
127
+
128
+ case 'DELETE':
129
+ if (!$id) Response::error('ID required', 400);
130
+ Response::success(['message' => 'Deleted']);
131
+ break;
132
+
133
+ default:
134
+ Response::error('Method not allowed', 405);
135
+ }
136
+ ```
137
+
138
+ ## Using the database
139
+
140
+ ### database/models/Post.php
141
+ ```php
142
+ <?php
143
+ declare(strict_types=1);
144
+
145
+ require_once __DIR__ . '/../Database.php';
146
+
147
+ class Post {
148
+ private PDO $db;
149
+
150
+ public function __construct() {
151
+ $this->db = Database::getInstance();
152
+ }
153
+
154
+ public function getAll(): array {
155
+ return $this->db->query("SELECT * FROM posts")->fetchAll();
156
+ }
157
+
158
+ public function getById(int $id): ?array {
159
+ $stmt = $this->db->prepare("SELECT * FROM posts WHERE id = :id");
160
+ $stmt->execute(['id' => $id]);
161
+ return $stmt->fetch() ?: null;
162
+ }
163
+
164
+ public function create(string $title): int {
165
+ $stmt = $this->db->prepare("INSERT INTO posts (title) VALUES (:title)");
166
+ $stmt->execute(['title' => htmlspecialchars(strip_tags(trim($title)))]);
167
+ return (int)$this->db->lastInsertId();
168
+ }
169
+ }
170
+ ```
171
+
172
+ Then use it inside an endpoint:
173
+
174
+ ```php
175
+ require_once __DIR__ . '/../../database/models/Post.php';
176
+
177
+ $post = new Post();
178
+ Response::success($post->getAll());
179
+ ```
180
+
181
+ Migrations live in `database/migrations/` as plain SQL files — run them manually against your database.
182
+
183
+ ## Calling endpoints from the frontend
184
+
185
+ ```js
186
+ // Public
187
+ const res = await fetch('/api/posts/42');
188
+
189
+ // Protected
190
+ const res = await fetch('/api/admin/stats', {
191
+ headers: { 'X-Api-Key': 'secret-stats-key' }
192
+ });
193
+
194
+ // POST
195
+ const res = await fetch('/api/posts', {
196
+ method: 'POST',
197
+ headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'your-key' },
198
+ body: JSON.stringify({ title: 'Hello world' })
199
+ });
200
+ ```
201
+
202
+ ## Pre-built endpoints
203
+
204
+ | Route | Auth | Methods | Description |
205
+ |---|---|---|---|
206
+ | `/api/example-public` | No | `GET` | Smoke test for public routing |
207
+ | `/api/subfolder/example-protected` | Yes | `GET` | Smoke test for protected routing |
208
+ | `/api/auth/register` | No | `POST` | Register a new user |
209
+ | `/api/auth/login` | No | `POST` | Login and retrieve user data |
210
+ | `/api/auth-system` | Yes | `GET POST PUT PATCH DELETE` | Full CRUD on users |
@@ -28,6 +28,58 @@ body {
28
28
  }
29
29
  ```
30
30
 
31
+ ## Global Variables
32
+
33
+ Instead of using `:root` in your custom modules or pages, the best thing to do is to centralize all your variables in a single file (that will be tree-shaken automatically by Sass)
34
+
35
+ ### _root.scss <small>(`src/frontend/scss/modules/`)</small>
36
+ ```scss
37
+ $header-height: 10vh;
38
+
39
+ // Usage example (in any other file):
40
+ header {
41
+ height: root.$header-height;
42
+ }
43
+ ```
44
+ ## Scss modules
45
+ You can create your custom css modules by creating a new `.scss` file in `src/frontend/scss/modules/` (the name of the file must start with `_`)
46
+
47
+ You can create subfolders if you want to refactor the structure, but be sure to update the relative paths in the pages that import them
48
+
49
+ ### _yourModule.scss <small>(`src/frontend/scss/modules/subfolder/`)</small>
50
+ ```scss
51
+ @use '../root' as root;
52
+
53
+ body {
54
+ background-color: root.$primary;
55
+ }
56
+ ```
57
+
58
+ ### examplePage.scss
59
+ ```scss
60
+ @import "../modules/subfolder/yourModule";
61
+
62
+ // This page will now inherit the body tag rules
63
+ // If the same property is declared in both, the last imported one wins
64
+ body {
65
+ color: root.$dark;
66
+ }
67
+ ```
68
+
69
+ ### Pre-existing modules
70
+
71
+ | File | Purpose |
72
+ |---|---|
73
+ | `_root.scss` | Global variables (colors, spacing) |
74
+ | `_global.scss` | Site-wide base rules and frameworks |
75
+ | `_typography.scss` | Font rules
76
+ | `_header.scss` | Header styles |
77
+ | `_footer.scss` | Footer styles |
78
+ | `_mobile.scss` | Media query rules |
79
+ | `_buttons.scss` | Style and hovers for buttons
80
+ | `_animations.scss` | Keyframe animations (`fade-in`, `spin`) |
81
+ | `_notification.scss` | Notification component style |
82
+
31
83
  ## CSS Framework
32
84
 
33
85
  Some of the most popular css frameworks that supports scss with modules are already installed in `node_modules`
@@ -85,56 +137,4 @@ To reduce the bundle size, open the corresponding framework file (`src/frontend/
85
137
  ```scss
86
138
  @import "bootstrap/scss/card"; // Cards
87
139
  @import "bootstrap/scss/carousel"; // Carousel
88
- ```
89
-
90
- ## Global Variables
91
-
92
- Instead of using `:root` in your custom modules or pages, the best thing to do is to centralize all your variables in a single file (that will be tree-shaken automatically by Sass)
93
-
94
- ### _root.scss <small>(`src/frontend/scss/modules/`)</small>
95
- ```scss
96
- $header-height: 10vh;
97
-
98
- // Usage example (in any other file):
99
- header {
100
- height: root.$header-height;
101
- }
102
- ```
103
- ## Scss modules
104
- You can create your custom css modules by creating a new `.scss` file in `src/frontend/scss/modules/` (the name of the file must start with `_`)
105
-
106
- You can create subfolders if you want to refactor the structure, but be sure to update the relative paths in the pages that import them
107
-
108
- ### _yourModule.scss <small>(`src/frontend/scss/modules/subfolder/`)</small>
109
- ```scss
110
- @use '../root' as root;
111
-
112
- body {
113
- background-color: root.$primary;
114
- }
115
- ```
116
-
117
- ### examplePage.scss
118
- ```scss
119
- @import "../modules/subfolder/yourModule";
120
-
121
- // This page will now inherit the body tag rules
122
- // If the same property is declared in both, the last imported one wins
123
- body {
124
- color: root.$dark;
125
- }
126
- ```
127
-
128
- ### Pre-existing modules
129
-
130
- | File | Purpose |
131
- |---|---|
132
- | `_root.scss` | Global variables (colors, spacing) |
133
- | `_global.scss` | Site-wide base rules and frameworks |
134
- | `_typography.scss` | Font rules
135
- | `_header.scss` | Header styles |
136
- | `_footer.scss` | Footer styles |
137
- | `_mobile.scss` | Media query rules |
138
- | `_buttons.scss` | Style and hovers for buttons
139
- | `_animations.scss` | Keyframe animations (`fade-in`, `spin`) |
140
- | `_notification.scss` | Notification component style |
140
+ ```
package/package.json CHANGED
@@ -1,59 +1,59 @@
1
- {
2
- "name": "create-berna-stencil",
3
- "version": "1.0.52",
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": "MIT",
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
- ".gitignore"
27
- ],
28
- "engines": {
29
- "node": ">=18.0.0"
30
- },
31
- "dependencies": {
32
- "@11ty/eleventy": "^3.1.2",
33
- "@11ty/eleventy-img": "^6.0.4",
34
- "bootstrap": "^5.3.8",
35
- "bootstrap-icons": "^1.13.1",
36
- "bulma": "^1.0.4",
37
- "foundation-sites": "^6.9.0",
38
- "glob": "^13.0.6",
39
- "uikit": "^3.25.13"
40
- },
41
- "devDependencies": {
42
- "concurrently": "^9.2.1",
43
- "esbuild": "^0.27.3",
44
- "sass": "^1.77.0"
45
- },
46
- "scripts": {
47
- "build:css": "sass src/frontend/scss:out/css --no-source-map --style=compressed --quiet",
48
- "build:js": "esbuild \"src/frontend/js/pages/*.js\" --bundle --outdir=out/js/pages --minify",
49
- "build:11ty": "eleventy",
50
- "build": "npm run clean && npm run build:css && npm run build:js && npm run build:11ty",
51
- "serve:css": "sass --watch src/frontend/scss:out/css --no-source-map --quiet",
52
- "serve:js": "esbuild \"src/frontend/js/pages/*.js\" --bundle --outdir=out/js/pages --watch",
53
- "serve:11ty": "eleventy --serve --quiet",
54
- "clean": "node _tools/cleanOutput.js",
55
- "serve": "npm run clean && concurrently \"npm run serve:11ty\" \"npm run serve:css\" \"npm run serve:js\"",
56
- "assistant": "node _tools/assistant.js",
57
- "postinstall": "cd src/backend/_core && composer install --quiet"
58
- }
1
+ {
2
+ "name": "create-berna-stencil",
3
+ "version": "1.0.54",
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": "MIT",
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
+ ".gitignore"
27
+ ],
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "dependencies": {
32
+ "@11ty/eleventy": "^3.1.2",
33
+ "@11ty/eleventy-img": "^6.0.4",
34
+ "bootstrap": "^5.3.8",
35
+ "bootstrap-icons": "^1.13.1",
36
+ "bulma": "^1.0.4",
37
+ "foundation-sites": "^6.9.0",
38
+ "glob": "^13.0.6",
39
+ "uikit": "^3.25.13"
40
+ },
41
+ "devDependencies": {
42
+ "concurrently": "^9.2.1",
43
+ "esbuild": "^0.27.3",
44
+ "sass": "^1.77.0"
45
+ },
46
+ "scripts": {
47
+ "build:css": "sass src/frontend/scss:c:/laragon/www/Berna-Stencil-out/css --no-source-map --style=compressed --quiet",
48
+ "build:js": "esbuild \"src/frontend/js/pages/*.js\" --bundle --outdir=c:/laragon/www/Berna-Stencil-out/js/pages --minify",
49
+ "build:11ty": "eleventy",
50
+ "build": "npm run clean && npm run build:css && npm run build:js && npm run build:11ty",
51
+ "serve:css": "sass --watch src/frontend/scss:c:/laragon/www/Berna-Stencil-out/css --no-source-map --quiet",
52
+ "serve:js": "esbuild \"src/frontend/js/pages/*.js\" --bundle --outdir=c:/laragon/www/Berna-Stencil-out/js/pages --watch",
53
+ "serve:11ty": "eleventy --serve --quiet",
54
+ "clean": "node _tools/cleanOutput.js",
55
+ "serve": "npm run clean && concurrently \"npm run serve:11ty\" \"npm run serve:css\" \"npm run serve:js\"",
56
+ "assistant": "node _tools/assistant.js",
57
+ "postinstall": "cd src/backend/_core && composer install --quiet"
58
+ }
59
59
  }
@@ -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
  ),