Skip to content

Commit a3de9fe

Browse files
committed
chore: add documentation
1 parent 45b79a6 commit a3de9fe

File tree

3 files changed

+389
-31
lines changed

3 files changed

+389
-31
lines changed

docs/configuration.md

Lines changed: 167 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,180 @@
11
---
2-
title: Welcome to Sissi
2+
title: Configuration
33
layout: base.html
44
---
55
# {{ title }}
66

7-
Right now there's not too much to configure. Specify an input dir, specify an output dir:
7+
## Config file
8+
9+
Sissi looks for a config file named `.sissi.js` or `.sissi.config.js` in the project root. The file must have a default export that is a function:
10+
11+
```js
12+
// .sissi.config.js
13+
export default function(config) {
14+
// register plugins and filters here
15+
return {
16+
dir: { input: 'src', output: 'dist' }
17+
};
18+
}
19+
```
20+
21+
The function receives a `SissiConfig` instance and may return an object with a `dir` key to override directories.
22+
23+
## Directory options
24+
25+
All paths are relative to the project root. These are the defaults:
26+
27+
| Key | Default | Description |
28+
|------------|--------------|--------------------------------------------------|
29+
| `input` | `.` | Source directory |
30+
| `output` | `public` | Build output directory |
31+
| `includes` | `_includes` | Partials for `<html-include src="..."/>` |
32+
| `layouts` | `_layouts` | Layout templates (referenced via frontmatter) |
33+
| `data` | `_data` | Global data files (`.js`, `.json`, `.yaml`) |
834

935
```js
1036
export default function(config) {
11-
// You can add plugins via config.addPlugin here
12-
// config.addPlugin(html);
1337
return {
1438
dir: {
15-
input: 'demo',
16-
output: 'dist'
39+
input: 'src',
40+
output: 'dist',
41+
includes: 'src/_includes',
42+
layouts: 'src/_layouts',
43+
data: 'src/_data',
1744
}
18-
}
45+
};
46+
}
47+
```
48+
49+
## Output naming
50+
51+
By default Sissi preserves the input path and swaps the file extension (`defaultNaming`). You can switch to directory-based URLs with `directoryNaming`, which turns `about.html` into `about/index.html`:
52+
53+
```js
54+
import { directoryNaming } from 'sissi/naming';
55+
56+
export default function(config) {
57+
config.naming = directoryNaming;
58+
}
59+
```
60+
61+
## config API
62+
63+
### `config.addPlugin(fn)`
64+
65+
Registers a plugin. Plugins follow the same signature as the config function — they receive the `SissiConfig` instance and may return a `dir` override.
66+
67+
```js
68+
import myPlugin from './my-plugin.js';
69+
70+
export default function(config) {
71+
config.addPlugin(myPlugin);
72+
}
73+
```
74+
75+
### `config.addFilter(name, fn)`
76+
77+
Registers a template filter. Filters are called via the pipe syntax in templates.
78+
79+
```js
80+
config.addFilter('shout', (str) => str.toUpperCase());
81+
config.addFilter('prefix', (str, pre) => `${pre}${str}`);
82+
```
83+
84+
```html
85+
{\{ title | shout }\}
86+
{\{ title | prefix: 'Hello, ' }\}
87+
```
88+
89+
### `config.addExtension(ext, processingFunction)`
90+
91+
Registers a compiler for a file extension. Also implicitly adds the extension to the set of template formats so those files are compiled rather than passthrough-copied.
92+
93+
### `config.addCollection(name, fn)`
94+
95+
Registers a named collection. The callback receives a `CollectionsAPI` and must return an array. See the [Collections](/collections) page for details.
96+
97+
```js
98+
config.addCollection('recentPosts', (api) =>
99+
api.getFilteredByTag('post').slice(0, 5)
100+
);
101+
```
102+
103+
### `config.addTemplateFormats(formats)`
104+
105+
Marks additional file extensions as template formats. Accepts a comma-separated string or an array.
106+
107+
```js
108+
config.addTemplateFormats('njk,liquid');
109+
config.addTemplateFormats(['njk', 'liquid']);
110+
```
111+
112+
### `config.setTemplateFormats(formats)`
113+
114+
Replaces the full set of template formats. Same argument shape as `addTemplateFormats`.
115+
116+
### `config.addPassthroughCopy(paths)`
117+
118+
No-op for Eleventy compatibility. In Sissi, every file whose extension is not in `templateFormats` is passthrough-copied automatically — you never need to opt in explicitly.
119+
120+
## Writing a plugin
121+
122+
A plugin is just a function with the same shape as the config function — it receives the `SissiConfig` instance, calls any config methods it needs, and optionally returns a `dir` override.
123+
124+
### Adding a new template format
125+
126+
The most common use case is registering a compiler for a new file extension via `config.addExtension`. The compiler object must have:
127+
128+
- **`outputFileExtension`** — the extension of the output file (e.g. `'html'`)
129+
- **`compile(inputContent, inputPath)`** — an async function that receives the raw file content and path, and returns another async function that receives the template data and returns the final string
130+
131+
```js
132+
// my-plugin.js
133+
export default function myPlugin(config) {
134+
config.addExtension('txt', {
135+
outputFileExtension: 'html',
136+
compile: async (inputContent, inputPath) => {
137+
return async (data) => {
138+
// transform inputContent into HTML here
139+
return `<pre>${inputContent}</pre>`;
140+
};
141+
},
142+
});
143+
}
144+
```
145+
146+
### Adding filters inside a plugin
147+
148+
Plugins can also bundle filters so related functionality ships together:
149+
150+
```js
151+
// my-plugin.js
152+
export default function myPlugin(config) {
153+
config.addFilter('shout', (str) => str.toUpperCase());
154+
155+
config.addExtension('txt', {
156+
outputFileExtension: 'html',
157+
compile: async (inputContent) => async () => `<pre>${inputContent}</pre>`,
158+
});
19159
}
20160
```
161+
162+
### Using the plugin
163+
164+
```js
165+
// .sissi.config.js
166+
import myPlugin from './my-plugin.js';
167+
168+
export default function(config) {
169+
config.addPlugin(myPlugin);
170+
}
171+
```
172+
173+
## CLI flags
174+
175+
| Command | Description |
176+
|------------------|-------------------------------------------------------|
177+
| `sissi build` | One-time build to the output directory |
178+
| `sissi watch` | Watch mode — rebuilds on file changes |
179+
| `sissi dev` | Dev server with watch mode and hot reload |
180+
| `--dry` | Skip writing files (useful for debugging the build) |

docs/data.md

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,118 @@
22
title: All about Data
33
layout: base.html
44
---
5+
## Data Cascade
56

6-
# All about Data
7+
When Sissi processes a template it merges data from three sources, in order of increasing precedence:
78

8-
## Data Cascade
9+
1. **Sissi built-ins** — the `page` object, `collections`, and anything provided by plugins
10+
2. **`_data/` files** — global data loaded from your data directory
11+
3. **Frontmatter** — per-file data declared at the top of each source file
912

10-
### Data provided by Sissi
13+
Later sources win, so frontmatter values override global data, and global data overrides Sissi defaults.
1114

12-
### The `_data` subdirectory
15+
## Data provided by Sissi
1316

14-
### The Frontmatter
17+
Every template receives a `page` object describing the current file:
1518

16-
## Using data inside templates
19+
| Field | Example | Description |
20+
|-------------------------------|----------------------------------|-----------------------------------------------|
21+
| `page.url` | `/posts/hello/` | Output URL path |
22+
| `page.inputPath` | `posts/hello.md` | Source file path (relative to input dir) |
23+
| `page.outputPath` | `public/posts/hello/index.html` | Absolute output file path |
24+
| `page.fileSlug` | `hello` | Filename without extension |
25+
| `page.filePathStem` | `/posts/hello` | Path without extension |
26+
| `page.outputFileExtension` | `html` | Extension of the output file |
27+
| `page.date` | `Date` object | Date from frontmatter, or epoch if absent |
1728

18-
Sissi supports a "poor girl's handlebars". It looks for expressions wrapped in double curly braces and replaces them with the data accordingly. If the data is resolved as a function, a parameterless function call will be invoked. If the data results a Promise, it is automatically resolved.
29+
```html
30+
<a href="{\{ page.url }\}">Permalink</a>
31+
```
1932

20-
If you place a javascript file named `meta.js` in your _data directory which provides a default export, you can access the object like this:
33+
## The `_data` subdirectory
34+
35+
Any `.js`, `.json`, or `.yaml` file in `_data/` is loaded as global data. The filename (without extension) becomes the key:
36+
37+
**JavaScript** — the default export is the value; it can be a plain object, an array, or an async function:
2138

2239
```js
40+
// _data/meta.js
2341
export default {
24-
author: 'Lea'
42+
author: 'Lea Rosema',
43+
siteTitle: 'My Site',
2544
};
2645
```
2746

47+
**JSON:**
48+
49+
```json
50+
// _data/links.json
51+
[
52+
{ "label": "GitHub", "url": "https://github.com" }
53+
]
54+
```
55+
56+
**YAML:**
57+
58+
```yaml
59+
# _data/nav.yaml
60+
- label: Home
61+
url: /
62+
- label: About
63+
url: /about/
64+
```
65+
66+
All three are accessed in templates by their filename stem:
67+
2868
```html
2969
{\{ meta.author }\}
70+
{\{ meta.siteTitle }\}
3071
```
3172

32-
Alternatively, you can put json or yaml into the data directory.
73+
Changes to any file in `_data/` trigger a full site rebuild in watch mode.
74+
75+
## The Frontmatter
76+
77+
Frontmatter is declared at the very top of a source file between `---` delimiters. **YAML** is the default format:
78+
79+
```yaml
80+
---
81+
title: Hello World
82+
date: 2024-06-01
83+
tags: [post, featured]
84+
layout: base.html
85+
---
86+
```
87+
88+
You can also use **JSON** by writing `---json` as the opening delimiter:
89+
90+
```json
91+
---json
92+
{
93+
"title": "Hello World",
94+
"tags": ["post", "featured"],
95+
"layout": "base.html"
96+
}
97+
---
98+
```
99+
100+
### Reserved frontmatter keys
101+
102+
| Key | Effect |
103+
| --- | --- |
104+
| `layout` | Wraps the page in a layout from `_layouts/` |
105+
| `tags` | Adds the page to one or more [collections](/collections) |
106+
| `date` | Sets the page date used for sorting |
107+
| `eleventyExcludeFromCollections` | `true` to exclude from all collections, or a list of tag names to exclude from specific ones |
108+
109+
## Using data inside templates
110+
111+
See the [Templating](/templating) page for the full template syntax. A quick example:
112+
113+
If `_data/meta.js` exports `{ author: 'Lea' }`, you can reference it as:
114+
115+
```html
116+
{\{ meta.author }\}
117+
```
33118

119+
If the value resolves to a function it is called with no arguments. If it returns a `Promise` it is awaited automatically.

0 commit comments

Comments
 (0)