1 | # blað
|
2 |
|
3 | A minimalist flat-file CMS with dynamic content.
|
4 |
|
5 | [![Build Status](https://img.shields.io/travis/radekstepan/blad/master.svg?style=flat)](https://travis-ci.org/radekstepan/blad)
|
6 | [![Dependencies](http://img.shields.io/david/radekstepan/blad.svg?style=flat)](https://david-dm.org/radekstepan/blad)
|
7 | [![License](http://img.shields.io/badge/license-AGPL--3.0-red.svg?style=flat)](LICENSE)
|
8 |
|
9 | ## Features
|
10 |
|
11 | 1. Reads content from Markdown files and YAML front-matter.
|
12 | 1. No database or write access to disk needed.
|
13 | 1. In-memory cache maintains dynamic content defined in helper functions.
|
14 | 1. Powerful [Swig](http://paularmstrong.github.io/swig/) templating.
|
15 |
|
16 | ## Quickstart
|
17 |
|
18 | ```bash
|
19 | $ npm install blad -g
|
20 | $ blad --port 8080
|
21 | # blad/4.0.0-alpha started on port 8080
|
22 | ```
|
23 |
|
24 | ## Configuration
|
25 |
|
26 | The following command will launch a blad server on port `5050`, sourcing files from the `example/` directory and keep all cached content for a period of `1` day.
|
27 |
|
28 | ```bash
|
29 | $ ./bin/blad.js --port 5050 --source example/ --cache 1440
|
30 | ```
|
31 |
|
32 | ### Content
|
33 |
|
34 | The site pages are maintained as sets of Markdown files with YAML front-matter. The name corresponds to the url of the page so, for example, `/content/people/radek.md` will get mapped to the `/people/radek` URL.
|
35 |
|
36 | Among the fields one can set in the front-matter, `template` is the most important one. It sets a Swig HTML file that will be used to render the page. Not specifying this property will make the page serve `204 No Content` when accessed.
|
37 |
|
38 | Fields are represented as key-value pairs of arbitrary depth.
|
39 |
|
40 | ### Layouts
|
41 |
|
42 | Is a place where [Swig](http://paularmstrong.github.io/swig/) templates live. They can be extended and macros work too.
|
43 |
|
44 | If a `404.html` template is provided together with a document entitled `404.md`, these will be rendered when a user tries to visit a page that does not exist.
|
45 |
|
46 | You can access the URL of a page you are on by using the `url` key.
|
47 |
|
48 | #### Relations
|
49 |
|
50 | You can access content in other documents by using the relations helper object.
|
51 |
|
52 | To get a list of top-level pages in the CMS use:
|
53 |
|
54 | ```
|
55 | {% for page in rel.menu() %}
|
56 | {{ page.url }}
|
57 | {% endfor %}
|
58 | ```
|
59 |
|
60 | To get a list of sibling documents:
|
61 |
|
62 | ```
|
63 | {% for page in rel.siblings(url) %}
|
64 | {{ page.url }}
|
65 | {% endfor %}
|
66 | ```
|
67 |
|
68 | You can get a list of children of depth `n`:
|
69 |
|
70 | ```
|
71 | {% for page in rel.children(url, n) %}
|
72 | {{ page.url }}
|
73 | {% endfor %}
|
74 | ```
|
75 |
|
76 | Access the first existing parent document:
|
77 |
|
78 | ```
|
79 | {% set parent = rel.parent(url) %}
|
80 | ```
|
81 |
|
82 | Check if one document is the same as another or one of its descendants:
|
83 |
|
84 | ```
|
85 | {% set isFamily = rel.isFamily('/people', '/people') %}
|
86 | ```
|
87 |
|
88 | Or just check if one document is a child of another:
|
89 |
|
90 | ```
|
91 | {% set isChild = rel.isChild('/people', '/people/radek') %}
|
92 | ```
|
93 |
|
94 | ### Helpers
|
95 |
|
96 | Are modules (in JS or CoffeeScript) that can be accessed at page render stage. Typically they will be used to access remote data to then be rendered in a page. In a YAML front-matter we would request a helper like so:
|
97 |
|
98 | ```
|
99 | ---
|
100 | helpers:
|
101 | people: my_helper.js
|
102 | ---
|
103 | ```
|
104 |
|
105 | The first time a page is rendered, the helper in `my_helper.js` is called. It is expected to be a function with two parameters, `data` and `cb`. The former is a map of key-value fields from the front-matter, the latter a callback for when the helper has done its job. As an example:
|
106 |
|
107 | ```js
|
108 | module.exports = (data, cb) => {
|
109 | // Do some work...
|
110 |
|
111 | // Call back.
|
112 | cb(null, result);
|
113 | };
|
114 | ```
|
115 |
|
116 | You can access 3rd party libraries here by defining them in `package.json` of the site.
|
117 |
|
118 | The data is then accessible under the key `people` (in the example above) in the page layout and saved for `--cache` amount of time. This is a startup parameter and saves having us make potentially expensive operations every time a page is requested.
|
119 |
|
120 | ### Public
|
121 |
|
122 | All static content, like CSS and JS files, can be accessed here. Use `/public/path` in layouts when accessing these files.
|