docs/content/templates/data.md (4266B)
1 +++
2 title = "Template data"
3 description = "Everything a template can read"
4 weight = 20
5 toc = true
6 +++
7
8 Two objects are in scope on every page: `site` and `page`.
9
10 ## site
11
12 | | |
13 |---|---|
14 | `site.title` | From `sqzass.toml`. |
15 | `site.description` | From `sqzass.toml`. |
16 | `site.origin` | Scheme and host only. `{{ site.origin }}{{ page.url }}` is an absolute URL — page URLs already carry the subpath. |
17 | `site.base_path` | The path prefix when the site lives under one, else empty. Only for URLs a template writes by hand. |
18 | `site.language` | The language of the page being rendered. |
19 | `site.sections` | Top-level sections **in this language**. |
20 | `site.highlight_css` | URL of the generated highlight stylesheet, or nothing if highlighting is off. |
21 | `site.search` | URL of this language's search index, or nothing with `[search] enabled = false`. |
22 | `site.feed` | URL of this language's Atom feed, or nothing when no page in it carries a date. See [Feeds](@/features/feeds.md). |
23
24 `site.sections` contains only the current language's tree, which is what makes
25 navigation safe: an untranslated page is not in it, so a link to it cannot be
26 drawn. Each section carries `title`, `description`, `url`, `weight`, `pages`
27 and `subsections`, and each entry in `pages` has `title`, `description`, `url`
28 and `weight`.
29
30 ## page
31
32 | | |
33 |---|---|
34 | `page.title` | |
35 | `page.description` | |
36 | `page.url` | `/ko/start/installation/` |
37 | `page.permalink` | The absolute URL — `origin` + `url`. |
38 | `page.content` | Rendered HTML. **Needs `\| safe`.** |
39 | `page.weight`, `page.draft`, `page.language` | Front matter, as given. |
40 | `page.toc` | Whether the author asked for a contents list. |
41 | `page.toc_entries` | The contents themselves — `{level, id, title, children}`, nested. |
42 | `page.translations` | Only languages this page exists in. Empty means no switcher. |
43 | `page.section` | The section this page belongs to. Nothing at the top level, and nothing on a section index — a section is not inside itself. |
44 | `page.prev`, `page.next` | The neighbouring pages **within this section**. Nothing on a section index, for the same reason. |
45 | `page.children` | A section's own pages. Empty on ordinary pages. |
46 | `page.is_section` | |
47 | `page.date` | The publication date in parts — `year`, `month`, `day`, `date`, `iso` — or nothing. See [Feeds](@/features/feeds.md). |
48 | `page.extra` | Your `[extra]` table. |
49
50 ## page.children is two things
51
52 On the root `_index.md` it holds the top-level sections. On any other section it
53 holds that section's own pages, followed by its subsections. Both are what a
54 listing template needs, and neither is obvious from the name.
55
56 ```html
57 {% for child in page.children %}
58 <a href="{{ child.url }}">{{ child.title }}</a>
59 {%- if child.description %}<p>{{ child.description }}</p>{% endif %}
60 {% endfor %}
61 ```
62
63 Ordinary pages have an empty list.
64
65 ## page.toc_entries
66
67 `{level, id, title, children}`, nested by relative depth — an h2 followed by an
68 h4 nests, without assuming the levels are consecutive. It is collected for every
69 page, whether or not `toc = true`; the front matter field is the author's
70 intent, and the data is there either way so a template can decide.
71
72 Rendering it needs a recursive macro:
73
74 ```html
75 {% macro toc_list(entries) %}
76 <ul>
77 {%- for e in entries %}
78 <li><a href="#{{ e.id }}">{{ e.title }}</a>
79 {%- if e.children %}{{ toc_list(e.children) }}{% endif %}
80 </li>
81 {%- endfor %}
82 </ul>
83 {% endmacro %}
84
85 {% if page.toc and page.toc_entries %}{{ toc_list(page.toc_entries) }}{% endif %}
86 ```
87
88 ## asset()
89
90 `asset("css/main.css")` returns the hashed URL that file was written to:
91
92 ```html
93 <link rel="stylesheet" href="{{ asset("css/main.css") }}">
94 ```
95
96 Asking for a file that was not collected is an error, so a renamed stylesheet
97 fails the build instead of silently 404ing for every visitor.
98
99 ## Slashes are not escaped
100
101 Jinja2 escapes five characters. Some ports escape `/` as well, which turns
102 every URL on every page into `href="https://…"`. sqzass restores
103 Jinja2's own behaviour, so URLs come out as URLs.
104
105 ## Missing keys stop the build
106
107 ```
108 undefined value: page.descriptoin
109 ```
110
111 Rather than an empty string where your description was. See
112 [Templates](@/templates/_index.md).