22Templating
33==========
44
5- ``sphinxnotes.render `` uses Jinja2 _ to turn structured context data into markup
6- text, usually reStructuredText. The rendered text is then parsed again by
7- Sphinx/docutils and inserted into the document.
8-
95This page focuses on the context made available to templates, when that context
106is available, and how extension authors can add more of it. You should already
117be comfortable with basic Jinja2 syntax before reading this page.
128
139.. _Jinja2 : https://jinja.palletsprojects.com/en/stable/templates/
1410
15- Directive Data Context
16- ======================
11+ Jinja Environment
12+ =================
13+
14+ Templates are rendered in a sandboxed Jinja2 environment.
15+
16+ - Undefined variables raise errors by default (``undefined=DebugUndefined ``)
17+ - Extension ``jinja2.ext.loopcontrols ``, ``jinja2.ext.do `` are enabled by default.
18+ - Output is plain markup text, so you can generate lists, directives, roles,
19+ and other reStructuredText constructs.
20+
21+ Built-in filters
22+ ----------------
23+
24+ ``role ``
25+ We provides a ``roles `` filter for producing role markup from a sequence of
26+ strings.
27+
28+ .. example ::
29+ :style: grid
30+
31+ .. data.render::
32+
33+ {%
34+ set text = ['index', 'usage']
35+ | roles('doc')
36+ | join(', ')
37+ %}
38+
39+ :Text: ``{{ text }}``
40+ :Rendered: {{ text }}
41+
42+ Extending filters
43+ -----------------
44+
45+ To be done.
46+
47+ Context
48+ =======
49+
50+ Directive and Role Context
51+ --------------------------
1752
1853When a directive or role provides data through
1954:py:class: `~sphinxnotes.render.BaseDataDefineDirective ` or
@@ -43,43 +78,43 @@ The following `template variables`_ are available in the main context:
4378
4479 {{ name }}
4580
46- .. data.define:: foo
81+ .. data.define:: This is the argument
4782
4883 For role, this is not available for now.
4984
5085 ``{{ attrs.xxx }} ``
5186 For directive, this refer to the directive options.
5287 It is a mapping of option's field to its value, so
53- ``{{ attrs.color }} `` and ``{{ attrs['color '] }} `` are equivalent.
88+ ``{{ attrs.label }} `` and ``{{ attrs['label '] }} `` are equivalent.
5489
5590 .. example ::
5691 :style: grid
5792
5893 .. data.template::
5994
60- Color is {{ attrs.color }}.
95+ Label is {{ attrs.label }}.
6196
62- .. data ::
63- :color: red
97+ .. data.define ::
98+ :label: Important
6499
65100 For role, this is not available for now.
66101
67102 .. note ::
68103
69104 Attribute values are also lifted to the top-level template context when
70- there is no name conflict. For example, ``{{ color }} `` can be used
71- instead of ``{{ attrs.color }} ``, but ``{{ name }} `` still refers to
105+ there is no name conflict. For example, ``{{ label }} `` can be used
106+ instead of ``{{ attrs.label }} ``, but ``{{ name }} `` still refers to
72107 the data object's own ``name `` field.
73108
74109 .. example ::
75110 :style: grid
76111
77112 .. data.template::
78113
79- {{ color }} and {{ attrs.color }} are same.
114+ {{ label }} and {{ attrs.label }} are same.
80115
81- .. data ::
82- :color: red
116+ .. data.define ::
117+ :label: Important
83118
84119 ``{{ content }} ``
85120 For directive, this refer to the directive body.
@@ -91,9 +126,9 @@ The following `template variables`_ are available in the main context:
91126
92127 {{ content }}
93128
94- .. data ::
95-
96- Color is red .
129+ .. data.define ::
130+
131+ This is the body content .
97132
98133 For role, this refer to the interpreted text.
99134
@@ -104,7 +139,7 @@ The following `template variables`_ are available in the main context:
104139
105140 {{ content }}
106141
107- :data: `Color is red `
142+ :data:`This is the interpreted text `
108143
109144 The type of each variable depends on the corresponding :py:class: `~sphinxnote.render.Schema `.
110145For developers, the schema is provided by the
@@ -114,15 +149,13 @@ For example, for the `sphinxnotes.data` extension, the schema is defined through
114149the :rst:dir: `data.schema ` directive.
115150
116151Extra Context
117- =============
118-
119- TODO: Refactor
152+ -------------
120153
121154Templates may also receive extra context entries in addition to the main data
122155context. These entries are stored under names prefixed with ``_ ``.
123156
124157Built-in extra context
125- ----------------------
158+ ......................
126159
127160.. list-table ::
128161 :header-rows: 1
@@ -156,83 +189,30 @@ arbitrary Python object behavior.
156189
157190 .. data.render::
158191
159- Current document title is {{ _doc.title }}.
192+ Current document title is
193+ "{{ _doc.title }}".
160194
161195 Extending extra context
162- -----------------------
196+ .......................
163197
164198Extension authors can register more context generators through
165199:py:data: `sphinxnotes.render.REGISTRY `.
166200
167- .. code-block :: python
168-
169- from sphinxnotes.render import REGISTRY , ParsePhaseExtraContext
170-
171- class ProjectContext (ParsePhaseExtraContext ):
172- def generate (self , host ):
173- return {' lineno' : host.lineno}
174-
175-
176- REGISTRY .extra_context.add_parsing_phase_context(' project' , ProjectContext())
177-
178- The registered context becomes available in templates as ``_project ``.
179-
180- Depending on when the value can be computed, implement one of these base
181- classes:
182-
183- - :py:class: `~sphinxnotes.render.GlobalExtraContxt ` for context available in
184- every phase.
185- - :py:class: `~sphinxnotes.render.ParsePhaseExtraContext ` for context generated
186- during :py:data: `~sphinxnotes.render.Phase.Parsing `.
187- - :py:class: `~sphinxnotes.render.ResolvePhaseExtraContext ` for context generated
188- during :py:data: `~sphinxnotes.render.Phase.Parsed ` or
189- :py:data: `~sphinxnotes.render.Phase.Resolving `.
190-
191- Jinja Environment
192- =================
193-
194- Templates are rendered in a sandboxed Jinja2 environment.
195-
196- - Undefined variables raise errors by default (``undefined=DebugUndefined ``)
197- - Extension ``jinja2.ext.loopcontrols ``, ``jinja2.ext.do `` are enabled by default.
198- - Output is plain markup text, so you can generate lists, directives, roles,
199- and other reStructuredText constructs.
200-
201- Built-in filters
202- ----------------
203-
204- ``role ``
205- We provides a ``roles `` filter for producing role markup from a sequence of
206- strings.
207-
208- .. example ::
209- :style: grid
210-
211- .. data.render::
212-
213- {%
214- set text = ['index', 'usage']
215- | roles('doc')
216- | join(', ')
217- %}
218-
219- :Text: ``{{ text }}``
220- :Rendered: {{ text }}
201+ TODO.
221202
222- Extending filters
223- -----------------
203+ Template
204+ ========
224205
225- To be done.
226- Phases
227- ======
206+ Render Phases
207+ -------------
228208
229209Each :py:class: `~sphinxnotes.render.Template ` has a render phase controlled by
230210:py:class: `~sphinxnotes.render.Phase `.
231211
232212``parsing `` (:py:data: `sphinxnotes.render.Phase.Parsing `)
233213 Render immediately while the directive or role is running.
234214
235- This is the default render pahse .
215+ This is the default render phase .
236216 Choose this when the template only needs local information and does not rely
237217 on the final doctree or cross-document state.
238218
@@ -243,9 +223,11 @@ Each :py:class:`~sphinxnotes.render.Template` has a render phase controlled by
243223 :on: parsing
244224
245225 - The current document has
246- {{ _doc.sections | length }} section(s).
226+ {{ _doc.sections | length }}
227+ section(s).
247228 - The current project has
248- {{ _sphinx.env.all_docs | length }} document(s).
229+ {{ _sphinx.env.all_docs | length }}
230+ document(s).
249231
250232 ``parsed `` (:py:data: `sphinxnotes.render.Phase.Parsed `)
251233 Render after the current document has been parsed.
@@ -260,9 +242,11 @@ Each :py:class:`~sphinxnotes.render.Template` has a render phase controlled by
260242 :on: parsed
261243
262244 - The current document has
263- {{ _doc.sections | length }} section(s).
245+ {{ _doc.sections | length }}
246+ section(s).
264247 - The current project has
265- {{ _sphinx.env.all_docs | length }} document(s).
248+ {{ _sphinx.env.all_docs | length }}
249+ document(s).
266250
267251 ``resolving `` (:py:data: `sphinxnotes.render.Phase.Resolving `)
268252 Render late in the build, after references and other transforms are being
@@ -278,9 +262,22 @@ Each :py:class:`~sphinxnotes.render.Template` has a render phase controlled by
278262 :on: resolving
279263
280264 - The current document has
281- {{ _doc.sections | length }} section(s).
265+ {{ _doc.sections | length }}
266+ section(s).
282267 - The current project has
283- {{ _sphinx.env.all_docs | length }} document(s).
268+ {{ _sphinx.env.all_docs | length }}
269+ document(s).
270+
271+ Debugging
272+ ---------
273+
274+ Set :py:attr: `sphinxnotes.render.Template.debug ` to ``True `` to append a debug
275+ report to the rendered document. The report includes the resolved context,
276+ available extra-context keys, the template source, the rendered markup text,
277+ and the final nodes produced from that markup.
278+
279+ This is especially useful when a template fails because of an undefined
280+ variable, unexpected data shape, or invalid generated markup.
284281
285282End-to-End Example
286283==================
@@ -316,14 +313,3 @@ This pattern is often the most convenient way to build small, declarative
316313directives. For more control, subclass
317314:py:class: `~sphinxnotes.render.BaseDataDefineDirective ` directly and implement
318315``current_schema() `` and ``current_template() `` yourself.
319-
320- Debugging
321- =========
322-
323- Set :py:attr: `sphinxnotes.render.Template.debug ` to ``True `` to append a debug
324- report to the rendered document. The report includes the resolved context,
325- available extra-context keys, the template source, the rendered markup text,
326- and the final nodes produced from that markup.
327-
328- This is especially useful when a template fails because of an undefined
329- variable, unexpected data shape, or invalid generated markup.
0 commit comments