nibula 2.4.3 → 2.4.4

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.
@@ -1,236 +0,0 @@
1
- # Nunjucks (HTML) Components
2
-
3
- ## What is Nunjucks
4
-
5
- Nunjucks (`.njk`) is an HTML file that supports logic like variables, `if` statements, and `for` loops. It can extend a base layout and include other `.njk` components
6
-
7
- ## Create a component
8
-
9
- Create a new `.njk` file anywhere inside `src/frontend/components/`. You can organize them into subfolders freely
10
-
11
- ```
12
- src/frontend/components/
13
- ├── global/
14
- │ ├── header.njk
15
- │ └── footer.njk
16
- ├── not-found.njk
17
- ├── welcome.njk
18
- ```
19
-
20
- ## Include a component
21
-
22
- Components are included in the page that renders them. Open the page's file in `src/frontend/routes/` and write the includes in its body
23
-
24
- ### example-page.njk <small>(`src/frontend/routes/`)</small>
25
-
26
- ```js
27
- ---
28
- title: "examplePage"
29
- permalink: "/example-page/"
30
- layout: base.njk
31
- ---
32
-
33
- {% include "example-component-1.njk" %}
34
- {% include "subfolder/example-component-2.njk" %}
35
- ```
36
-
37
- Components render in the order you list them. If a component lives in a subfolder, specify the relative path accordingly
38
-
39
- Paths are resolved from `src/frontend/components/`, so you never write that part — `"welcome.njk"`, not `"components/welcome.njk"`
40
-
41
- > ⚠️ If you move or delete a component, update every route that includes it or the build will fail
42
-
43
- Writing HTML directly in the route works too, and is perfectly fine for a short page. Components are the recommendation when there is something to reuse or when a page grows past a screenful — not a rule
44
-
45
- ## Nest components
46
-
47
- A component can include other components. This is useful for breaking complex sections into smaller, reusable pieces.
48
-
49
- ### exampleComponent.njk
50
- ```html
51
- <section class="hero">
52
- {% include "hero/hero-title.njk" %}
53
- {% include "hero/hero-button.njk" %}
54
- </section>
55
- ```
56
-
57
- > The same path rules apply: if the included component is in a subfolder, specify the full relative path.
58
-
59
- ## Markdown files
60
-
61
- ### What is Markdown
62
-
63
- Markdown (`.md`) is a way to write formatted text without HTML tags. You write
64
- `**bold**` instead of `<strong>bold</strong>`, and a line starting with `-`
65
- becomes a list item. For a page that is mostly text — an article, a privacy
66
- policy, a changelog — it is much faster than writing the markup by hand.
67
-
68
- ### Write the file
69
-
70
- Create a `.md` file in `src/frontend/components/`, next to your `.njk` ones.
71
-
72
- #### article.md <small>(`src/frontend/components/`)</small>
73
-
74
- ```markdown
75
- ## Section title
76
-
77
- Regular paragraph text. **Bold** and *italic* work as usual.
78
-
79
- - First item
80
- - Second item
81
- ```
82
-
83
- ### Show it in a page
84
-
85
- Open the page's file in `src/frontend/routes/` and add this line to its body:
86
-
87
- ```html
88
- <article class="markdown-body">
89
- {% renderFile "article.md" | markdownPath, { site: site }, "md" %}
90
- </article>
91
- ```
92
-
93
- Four parts to it:
94
-
95
- | Part | What it does |
96
- |---|---|
97
- | `class="markdown-body"` | the wrapper that applies the Markdown styling — without it your content renders unstyled |
98
- | `renderFile` | turns the Markdown into HTML and puts it in the page |
99
- | `markdownPath` | fills in the `src/frontend/components/` part of the path for you |
100
- | `{ site: site }` | hands the file your site settings — see below |
101
- | `"md"` | specifies that the rendering should be done as Markdown, ignoring the njk engine associated by default with the file extension |
102
-
103
- Subfolders work the same way as with components:
104
- `"legal/privacy.md" | markdownPath`
105
-
106
- ### Why `{ site: site }`
107
-
108
- A `.md` file can use site values, exactly like a component:
109
-
110
- ```markdown
111
- Welcome to {{ site.title }}
112
- ```
113
-
114
- But a Markdown file does not automatically see them. Anything the file needs has
115
- to be listed in the curly braces:
116
-
117
- ```js
118
- {% renderFile "article.md" | markdownPath, { site: site, pages: pages } %}
119
- ```
120
-
121
- If you forget, nothing breaks — the value simply comes out empty. So if a
122
- `{{ site.something }}` disappears from your page, this is why.
123
-
124
- ### Extras you get for free
125
-
126
- **Links to a section.** Every `##` and `###` heading gets an anchor, so you can
127
- link straight to it: `yoursite.com/my-page/#section-title`.
128
-
129
- **CSS classes.** Markdown produces plain HTML with no classes, so your framework's
130
- styling doesn't reach it. Add a class in curly braces after the element:
131
-
132
- ```markdown
133
- ## Section title {.text-center}
134
- ```
135
-
136
- > ⚠️ If the `.md` file is missing or the name is misspelled, the build stops with
137
- > an error. That is on purpose: silently skipping content you asked for is worse.
138
-
139
- ## Global components
140
-
141
- Header and footer live in `src/frontend/components/global/` and are automatically included in every page via `base.njk`. Edit them to change the site-wide layout
142
-
143
- ## Custom layouts
144
-
145
- `base.njk` is the default layout, but it isn't the only one you can have. Any
146
- `.njk` file in `src/frontend/layouts/` is a layout, and each route picks its own.
147
-
148
- The usual reason is a page that doesn't fit the standard shell: a landing page
149
- with no header or footer, a full-screen login, a "coming soon" holding page.
150
-
151
- Copy `base.njk`, rename it, and change only what you need — that way you keep the
152
- head, the SEO tags and the CSS/JS wiring, which is the part you don't want to
153
- rewrite:
154
-
155
- ```
156
- src/frontend/layouts/
157
- ├── base.njk
158
- └── custom.njk
159
- ```
160
-
161
- ### custom.njk <small>(`src/frontend/layouts/`)</small>
162
-
163
- Same as `base.njk`, without the two global includes:
164
-
165
- ```html
166
- <body>
167
- <main>
168
- {{ content | safe }}
169
- </main>
170
- </body>
171
- ```
172
-
173
- Then point the route at it:
174
-
175
- ### landing.njk <small>(`src/frontend/routes/`)</small>
176
-
177
- ```js
178
- ---
179
- title: "landing"
180
- permalink: "/landing/"
181
- layout: custom.njk
182
- ---
183
- ```
184
-
185
- Paths are resolved from `src/frontend/layouts/`, so you write `"custom.njk"`, not
186
- `"layouts/custom.njk"` — the same rule as components.
187
-
188
- > ⚠️ A layout you copy is a copy: a later fix to `base.njk` won't reach it. Keep
189
- > the differences to the minimum, and check your custom layouts when you change
190
- > something in the head.
191
-
192
- ## Site data in components
193
-
194
- All values defined in `src/frontend/data/site.json` are globally available in every component via `{{ site.* }}`
195
-
196
- ### site.json <small>(`src/frontend/data/`)</small>
197
- ```json
198
- {
199
- "site_name": "Site name",
200
- "title": "Site title",
201
- "description": "Site description",
202
- "keywords": "keyword1, keyword2, keyword3",
203
- "domain": "yoursite.com",
204
- "url": "https://yoursite.com",
205
- "lang": "en",
206
- "author": "Name and surname",
207
- "logo": "/assets/brand/logo.svg",
208
- "legal": {
209
- "privacy": "",
210
- "cookie": "",
211
- "terms": "",
212
- "copyright": {
213
- "year": "2026",
214
- "text": "All rights reserved."
215
- }
216
- }
217
- }
218
- ```
219
-
220
- `legal.privacy`, `legal.cookie` and `legal.terms` hold the URLs of your legal pages — the footer links to them. See **Head & SEO** DOC file for what every field does
221
-
222
- ### Usage in any `.njk` file
223
- ```html
224
- <p>{{ site.title }}</p>
225
- <a href="{{ site.legal.privacy }}">Privacy Policy</a>
226
- <img src="{{ site.logo }}" alt="{{ site.title }}">
227
- ```
228
-
229
- > In a `.md` file rendered with `renderFile`, these values only work if you passed
230
- > `site` in the curly braces — see *Why `{ site: site }`* above.
231
-
232
- ## Your own data files
233
-
234
- `site.json` isn't special: **any** `.json` file you drop in `src/frontend/data/` becomes a global variable, and the variable takes the name of the file.
235
-
236
- Create `test.json`, put anything you want inside it, and every key is reachable as `test.yourKey` — no import, no configuration, no restart.
@@ -1,52 +0,0 @@
1
- # Creating Pages
2
-
3
- > Examples use JavaScript, but everything applies equally to TypeScript. The only difference is the file extension (`.ts` instead of `.js`), that imports do **not** include the extension, and that paths use `src/frontend/ts/` instead of `src/frontend/js/`.
4
-
5
- The recommended way is via the **Assistant CLI**
6
-
7
- ## What gets created
8
- For a page named `my-page`:
9
-
10
- | File | Purpose |
11
- |---|---|
12
- | `src/frontend/routes/my-page.njk` | Template with front matter |
13
- | `src/frontend/scss/pages/myPage.scss` | Imports framework + modules |
14
- | `src/frontend/js/pages/myPage.js` | Imports JS/TS modules |
15
-
16
- It also adds a stub entry in `src/frontend/data/pages.json` for the page's SEO and CDN links — fill it in as described in the **Head & SEO** DOC file.
17
-
18
- ## Adding content
19
-
20
- The route is created empty, with two commented examples: one for including a
21
- `.njk` component, one for rendering a `.md` file. Uncomment the one you need or
22
- write your HTML directly in the body — see the **Components** DOC file.
23
-
24
- ## URL and title
25
-
26
- The URL is the kebab-case name (`/my-page/`). The `title` in the front matter is camelCase (`myPage`) and is used internally to load the correct CSS and JS files, and to look up the page's record in `pages.json` — do not change it.
27
-
28
- ## Layout
29
-
30
- `layout` decides the HTML skeleton the page is rendered into. New pages get `base.njk`, which brings the head, the SEO tags, the header and the footer.
31
-
32
- A page that needs a different shell — a landing page with no header, for instance — points at a layout of its own. See **Components** DOC file, *Custom layouts*.
33
-
34
- ## Subpages (nested URLs)
35
-
36
- To create a URL like `domain.it/about/team`, edit the `permalink` in `src/frontend/routes/team.njk` and add the parent segment before the final slash:
37
-
38
- ```js
39
- ---
40
- title: "team"
41
- permalink: "/about/team/"
42
- layout: base.njk
43
- ---
44
- ```
45
-
46
- The parent path (`about`) does **not** need to exist as a real page — it's just a URL prefix. Only the last segment (`team`) must match the filename and the `title` in the front matter.
47
-
48
- | Goal URL | permalink value | File |
49
- |---|---|---|
50
- | `/team/` | `/team/` | `routes/team.njk` |
51
- | `/about/team/` | `/about/team/` | `routes/team.njk` |
52
- | `/company/about/team/` | `/company/about/team/` | `routes/team.njk` |
package/docs/Deploy.md DELETED
@@ -1,279 +0,0 @@
1
- # Deploy
2
-
3
- Nibula builds your finished site into a folder called `out`. Publishing means
4
- copying that folder onto a web server so people can reach it.
5
-
6
- How you do that depends on two things: **where** you are publishing, and **which
7
- backend** you picked when you created the project (see `docs/Backend.md`).
8
-
9
- ## Start here
10
-
11
- If you don't know which case you are in, answer this first:
12
-
13
- **Did you choose the PHP backend or the Node backend?**
14
-
15
- - **PHP** → almost anywhere works, including cheap hosting plans. Jump to
16
- *Shared hosting* or *Windows hosting*.
17
- - **Node** → you need a server you control. Jump to *Your own server*.
18
- - **No `/api` endpoints at all?** Your site is fully static. Anything works,
19
- including free hosting like Netlify or GitHub Pages.
20
-
21
- ## Why the backend decides everything
22
-
23
- The two backends run in completely different ways, and this is the one thing
24
- worth understanding before you pick a host.
25
-
26
- **PHP** runs **once per visit**. A request arrives, the web server starts PHP,
27
- PHP answers, PHP exits. Nothing stays running, so there is nothing to look after.
28
-
29
- **Node is itself a server**. It is a program that must stay running all the time,
30
- listening in the background, while the web server forwards `/api` requests to it.
31
- Somebody has to start that program and restart it if the machine reboots or the
32
- program crashes.
33
-
34
- That is why **cheap shared hosting cannot run the Node backend**. On plans like
35
- Aruba or cPanel you upload files into a folder and that's all you can do — there
36
- is no way to start a program and keep it alive. If that's your host, choose PHP.
37
- It isn't a limitation of Nibula.
38
-
39
- > **Shared hosting** means a plan where you share a server with other customers
40
- > and only get a folder to upload into. **A VPS** is a whole machine that is
41
- > yours, where you can install and run whatever you want.
42
-
43
- ## Where you can publish
44
-
45
- | Target | Frontend | PHP backend | Node backend |
46
- |---|---|---|---|
47
- | Shared hosting (Apache — Aruba, cPanel) | ✅ | ✅ | ❌ no program can stay running |
48
- | Windows hosting (IIS) | ✅ | ✅ | ⚠️ only with the ARR module |
49
- | Your own VPS (Nginx on Ubuntu) | ✅ | ✅ | ✅ |
50
- | Static hosting (Netlify, Vercel, GitHub Pages) | ✅ | ❌ | ❌ |
51
-
52
- Static hosting serves files and nothing else. Perfect if your site has no `/api`
53
- endpoints, unusable if it does.
54
-
55
- ## What you need
56
-
57
- **PHP backend:** a host with PHP support, and Composer to install the backend's
58
- dependencies.
59
-
60
- **Node backend:** Node.js 18 or newer, and command-line access to the server so
61
- you can start the backend program.
62
-
63
- ## Editing the server config
64
-
65
- Every server needs a configuration file telling it how to behave — which page to
66
- show on a 404, which files to keep private, where to send `/api` requests. Nibula
67
- writes these for you.
68
-
69
- `.htaccess` (Apache) and `web.config` (IIS) are already inside `out`, ready to
70
- upload. To change a rule, edit the original in `src/frontend/hosting/` — anything
71
- you change directly inside `out` is erased the next time you build.
72
-
73
- `nginx.conf` is different. It sits in your project root and is **not** copied into
74
- `out`, because Nginx does not read config files from the site folder. You install
75
- it on the server yourself, as described below.
76
-
77
- ---
78
-
79
- ## Shared hosting (Apache)
80
-
81
- Upload **the contents of `out`** — not the folder itself — into your web root.
82
- Depending on the host it is called `htdocs`, `public_html` or `www`.
83
-
84
- That's it. `.htaccess` is already in there and Apache reads it automatically:
85
- folder listings are off, errors show your `/404.html`, sensitive files are
86
- blocked, the backend source is sealed off, and `/api/*` is routed.
87
-
88
- **How `/api` gets routed:** if the server has a module called `mod_proxy`, `/api`
89
- is forwarded to Node. If it doesn't — the usual case on shared hosting — `/api`
90
- goes to PHP instead. To force PHP on a server that does have `mod_proxy`, comment
91
- out the `mod_proxy` block in `.htaccess`.
92
-
93
- ## Windows hosting (IIS)
94
-
95
- Same as above: upload the contents of `out`. `web.config` is already there and
96
- read automatically.
97
-
98
- **How `/api` gets routed:** to PHP, by default. To use Node instead, uncomment
99
- the `ApiToNode` rule in `web.config` and delete `ApiToPhp`. This only works if
100
- the server has the ARR and URL Rewrite modules with proxying turned on — which
101
- means a server you control, not shared hosting.
102
-
103
- > ⚠️ **If you chose Node and your host has no ARR** (Aruba and most Windows
104
- > shared hosting), do **not** upload the `backend` folder. Without it the static
105
- > site works fine and `/api/*` simply shows your `404.html`. Upload it and every
106
- > `/api` request returns an empty 404 instead, because IIS sends the request to
107
- > the PHP front controller — a file a Node project doesn't have.
108
-
109
- ---
110
-
111
- ## Your own server (Nginx on a VPS)
112
-
113
- Nginx doesn't read config files from the site folder: the whole site is described
114
- in one file kept elsewhere on the machine. Nibula ships that file, ready to use,
115
- as `nginx.conf` in your project root.
116
-
117
- It **handles both backends with no edits**: `/api` goes to Node, and if Node
118
- isn't running the request falls through to PHP automatically.
119
-
120
- Upload the contents of `out` to `/var/www/SITE_FOLDER`, then work through the
121
- steps below.
122
-
123
- ### 1. Fill in the placeholders
124
-
125
- Open `nginx.conf` on your computer and replace these four words with your own
126
- values:
127
-
128
- | Placeholder | What to put there |
129
- |---|---|
130
- | `YOUR_DOMAIN` | your domain — appears twice, once for port 80 and once for 443 |
131
- | `SITE_FOLDER` | the folder name you used under `/var/www/` |
132
- | `YOUR_CERTIFICATE` | the folder name under `/etc/letsencrypt/live/` |
133
- | `SITE_NAME` | the file name you'll use in the commands below — pick anything |
134
-
135
- ### 2. Install what's missing
136
-
137
- Skip anything already installed.
138
-
139
- ```bash
140
- sudo apt update
141
- sudo apt install -y nginx certbot python3-certbot-nginx
142
- ```
143
-
144
- With the PHP backend, also:
145
-
146
- ```bash
147
- sudo apt install -y php-fpm
148
- ```
149
-
150
- ### 3. Get an HTTPS certificate
151
-
152
- This is what makes your site load over `https://` instead of `http://`.
153
- Certificates are free and last 90 days; the second command renews them
154
- automatically.
155
-
156
- ```bash
157
- sudo certbot certonly --nginx --cert-name SITE_NAME -d YOUR_DOMAIN
158
- sudo systemctl enable --now certbot.timer
159
- ```
160
-
161
- ### 4. Install the site file
162
-
163
- ```bash
164
- # Go to the folder where Nginx keeps site files
165
- cd /etc/nginx/sites-available
166
-
167
- # Create the file and paste in the contents of your edited nginx.conf
168
- sudo nano SITE_NAME
169
- # Paste, then: CTRL + O, ENTER, CTRL + X
170
-
171
- # Switch the site on by copying it into sites-enabled
172
- sudo cp SITE_NAME ../sites-enabled/
173
-
174
- # Check the config for mistakes, then apply it
175
- sudo nginx -t && sudo systemctl reload nginx
176
- ```
177
-
178
- If `nginx -t` reports an error, fix it before reloading — Nginx keeps running on
179
- the old config until the reload succeeds, so your site stays up.
180
-
181
- ### If something goes wrong
182
-
183
- | What you see | What it usually means |
184
- |---|---|
185
- | `cannot load certificate ... Permission denied` | you ran `nginx -t` without `sudo` |
186
- | `cannot load certificate ... No such file` | wrong certificate name |
187
- | `no alternative certificate subject name` | the certificate doesn't cover this domain |
188
- | `unknown directive "http2"` | Nginx older than 1.25 — check with `nginx -v` |
189
- | NXDOMAIN or a timeout during certbot | your domain's DNS isn't pointing at this server yet |
190
- | A blank 500 instead of your 404 page | `404.html` is missing from the upload |
191
- | 502 on `/api`, Node backend | the Node program isn't running |
192
- | 502 on `/api`, PHP backend | wrong php-fpm socket path in the config |
193
-
194
- ---
195
-
196
- ## Starting the Node backend on the server
197
-
198
- Only for the Node backend. After uploading `out`:
199
-
200
- **1. Install its dependencies**
201
-
202
- ```bash
203
- cd /var/www/SITE_FOLDER/backend
204
- npm install
205
- ```
206
-
207
- **2. Create its config file**
208
-
209
- Make sure `config.js` exists in `out/backend/`. If it doesn't, copy
210
- `example.config.js` to `config.js` and fill in your values.
211
-
212
- **3. Try it out first**
213
-
214
- `screen` lets you start a program, walk away, and come back to it later. Use it
215
- to check the backend actually works before setting it up properly.
216
-
217
- ```bash
218
- screen -S node-backend
219
- # Inside the new screen:
220
- sudo node /var/www/SITE_FOLDER/backend/_core/index.js
221
- curl http://127.0.0.1:3000/api/example-public
222
- ```
223
-
224
- If `curl` prints a JSON response, the backend is alive. Press `CTRL + A` then `D`
225
- to leave the screen without stopping the program; `screen -r node-backend` brings
226
- you back.
227
-
228
- **4. Then set it up for real**
229
-
230
- `screen` is for testing — the program dies if the server reboots. For a live site
231
- use **systemd**, the part of Linux that manages background programs. It starts
232
- your backend at boot and restarts it if it crashes.
233
-
234
- Create `/etc/systemd/system/backend-node.service`:
235
-
236
- ```ini
237
- [Unit]
238
- Description=Nibula Node backend
239
- After=network.target
240
-
241
- [Service]
242
- Type=simple
243
- User=www-data
244
- WorkingDirectory=/var/www/SITE_FOLDER/backend
245
- ExecStart=/usr/bin/node /var/www/SITE_FOLDER/backend/_core/index.js
246
- Restart=always
247
- RestartSec=5
248
-
249
- [Install]
250
- WantedBy=multi-user.target
251
- ```
252
-
253
- Adjust `WorkingDirectory`, and check the path to `node` with `which node`. Then:
254
-
255
- ```bash
256
- sudo systemctl daemon-reload
257
- sudo systemctl enable --now backend-node
258
- sudo systemctl status backend-node
259
- ```
260
-
261
- The last command should say `active (running)`.
262
-
263
- (If you already use `pm2`, that works too:
264
- `pm2 start _core/index.js --name backend-node`.)
265
-
266
- ### Settings the Node backend reads at startup
267
-
268
- These are set in the systemd file, on their own lines, as
269
- `Environment=KEY=value`. All three have sensible defaults — you usually don't
270
- need to touch them.
271
-
272
- | Setting | Default | What it does |
273
- |---|---|---|
274
- | `PORT` | `3000` | the port Node listens on — must match the one in `nginx.conf` |
275
- | `HOST` | `127.0.0.1` | keep this as-is: it means "local only", so Node is reachable through the web server and not directly from the internet |
276
- | `DOCUMENT_ROOT` | detected automatically | where `404.html` lives — the folder above `backend/` |
277
-
278
- > Error detail is **not** set here. That's the `APP_ENV` key inside `config.js` /
279
- > `config.php` — see `docs/Backend.md`.