sphinxcontrib.datatemplates — Render Your Data Readable¶
sphinxcontrib.datatemplates
helps you use static data in machine
readable format in your documentation by letting you define Jinja2
templates to turn JSON, YAML, XML, or CSV data into reStructuredText
for Sphinx to render as part of its output.
- Repo: https://github.com/sphinxcontrib/sphinxcontrib.datatemplates
- Docs: http://sphinxcontribdatatemplates.readthedocs.io/
Using datatemplate¶
The datatemplate
directive is the interface between the data
source and the rendering template.
-
.. datatemplate:json::
source-path
¶ Load file at
source-path
(relative to the documentation build directory) viajson.load()
and render usingtemplate
given in directive body.
-
.. datatemplate:yaml::
source-path
¶ Load file at
source-path
(relative to the documentation build directory) via PyYAML (yaml.safe_load
) and render usingtemplate
given in directive body.
-
.. datatemplate:xml::
source-path
¶ Load file at
source-path
(relative to the documentation build directory) viaxml.etree.ElementTree.parse()
(actually usingdefusedxml
) and render usingtemplate
given in directive body.
-
.. datatemplate:import-module::
module-name
¶ Load module
module-name
(must be importable inconf.py
) viaimportlib.import_module()
and render usingtemplate
given in directive body.
-
.. datatemplate:csv::
source-path
¶ Load file at
source-path
(relative to the documentation build directory) viacsv.reader()
orcsv.DictReader
depending onheader
and render usingtemplate
given in directive body.
-
.. datatemplate:dbm:: source-path::
¶ Load DB at
source-path
(relative to the documentation build directory) viadbm.open()
and render usingtemplate
given in directive body.
Template Context¶
When a datatemplate
directive is processed, the data is passed to
the template through its context so that the symbol data
is
available as a global variable.
Important
The data is loaded from the source and passed directly to the
template. No pre-processing is done on the data, so the template needs
to handle aspects like None
values and fields that have values
that may interfere with parsing reStructuredText.
Template Helpers¶
These helper functions are exposed using their short name (without the module prefix) in the template context.
-
sphinxcontrib.datatemplates.helpers.
make_list_table
(headers, data, title='', columns=None)¶ Build a list-table directive.
Parameters: - headers – List of header values.
- data – Iterable of row data, yielding lists or tuples with rows.
- title – Optional text to show as the table title.
- columns – Optional widths for the columns.
-
sphinxcontrib.datatemplates.helpers.
make_list_table_from_mappings
(headers, data, title, columns=None)¶ Build a list-table directive.
Parameters: - headers – List of tuples containing header title and key value.
- data – Iterable of row data, yielding mappings with rows.
- title – Optional text to show as the table title.
- columns – Optional widths for the columns.
JSON Samples¶
Data File¶
{
"key1": "value1",
"key2": [
"list item 1",
"list item 2",
"list item 3"
],
"nested-list": [
["a", "b", "c"],
["A", "B", "C"]
],
"mapping-series": [
{"cola": "a", "colb": "b", "colc": "c"},
{"cola": "A", "colb": "B", "colc": "C"}
]
}
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
{{ data['key1'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data['key2'] %}
- {{item}}
{% endfor %}
Nested List Table
~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested sequences using hard-coded
headers.
{{ make_list_table(
['One', 'Two', 'Three'],
data['nested-list'],
title='Table from nested lists',
) }}
Mapping Series Table
~~~~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested dictionaries using dynamic
headers.
{{ make_list_table_from_mappings(
[('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
data['mapping-series'],
title='Table from series of mappings',
) }}
Loading the Template¶
.. datatemplate:json:: sample.json
:template: sample.tmpl
YAML Samples¶
Single Document¶
Data File¶
---
key1: value1
key2:
- list item 1
- list item 2
- list item 3
nested-list:
- ['a', 'b', 'c']
- ['A', 'B', 'C']
mapping-series:
- cola: a
colb: b
colc: c
- cola: A
colb: B
colc: C
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
{{ data['key1'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data['key2'] %}
- {{item}}
{% endfor %}
Nested List Table
~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested sequences using hard-coded
headers.
{{ make_list_table(
['One', 'Two', 'Three'],
data['nested-list'],
title='Table from nested lists',
) }}
Mapping Series Table
~~~~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested dictionaries using dynamic
headers.
{{ make_list_table_from_mappings(
[('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
data['mapping-series'],
title='Table from series of mappings',
) }}
Loading the Template¶
.. datatemplate:yaml:: sample.yaml
:template: sample.tmpl
Multiple Documents¶
Data File¶
key1: value1
---
key: value
key1: different value
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
{{ data[0]|tojson }}
List of Items
~~~~~~~~~~~~~
{% for item in data %}
- {{item|tojson}}
- {{item.key}}
- {{item.key1}}
{% endfor %}
Mapping Series Table
~~~~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested dictionaries using dynamic
headers.
{{ make_list_table_from_mappings(
[('Key', 'key'), ('Key One', 'key1')],
data,
title='Table from series of mappings',
) }}
Loading the Template¶
.. datatemplate:yaml:: sample-multiple.yaml
:template: sample-multiple.tmpl
:multiple-documents:
XML Samples¶
Data File¶
<sample>
<key1>value1</key1>
<key2>
<item>list item 1</item>
<item>list item 2</item>
<item special='yes'>list item 3</item>
</key2>
<mappingseries>
<mapping>
<cola special='yes'>a</cola>
<colb>b</colb>
<colc>c</colc>
</mapping>
<mapping>
<cola>A</cola>
<colb special='yes'>B</colb>
<colc>C</colc>
</mapping>
</mappingseries>
</sample>
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
{{ data.find('key1').text }}
List of Items
~~~~~~~~~~~~~
{% for item in data.find('key2') %}
- {{item.text}}
{% endfor %}
XPath for Items
~~~~~~~~~~~~~~~
See `XPath support <https://docs.python.org/3/library/xml.etree.elementtree.html#xpath-support>`_
{% for item in data.findall(".//*[@special='yes']") %}
- {{item.text}}
{% endfor %}
Loading the Template¶
.. datatemplate:xml:: sample.xml
:template: xml-sample.tmpl
Import-Module Samples¶
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
List of Directory Entries
~~~~~~~~~~~~~~~~~~~~~~~~~~
{% for item in data.scandir() %}
- {{item.name}}'s size is {{item.stat().st_size}} Bytes
{% endfor %}
File Path of the Null Device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``{{data.devnull}}``
Loading the Template¶
.. datatemplate:import-module:: os
:template: import-module-sample.tmpl
Rendered Output¶
Static Heading¶
List of Directory Entries¶
- dbm.rst’s size is 433 Bytes
- sample.xml’s size is 483 Bytes
- inline.rst’s size is 928 Bytes
- legacy.rst’s size is 411 Bytes
- index.rst’s size is 765 Bytes
- using.rst’s size is 4476 Bytes
- sampledbm.dat’s size is 519 Bytes
- yaml.rst’s size is 954 Bytes
- csv.rst’s size is 532 Bytes
- conf.py’s size is 15468 Bytes
- make_dbm.py’s size is 114 Bytes
- sample.csv’s size is 36 Bytes
- _templates’s size is 4096 Bytes
- sampledbm.dir’s size is 29 Bytes
- sample-multiple.yaml’s size is 53 Bytes
- json.rst’s size is 410 Bytes
- _build’s size is 4096 Bytes
- sample.yaml’s size is 212 Bytes
- import-module.rst’s size is 419 Bytes
- xml.rst’s size is 416 Bytes
- _static’s size is 4096 Bytes
- sample.json’s size is 319 Bytes
File Path of the Null Device¶
/dev/null
CSV Samples¶
Data File¶
a b c
Eins Zwei Drei
1 2 3
I II III
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Cell in Row
~~~~~~~~~~~~~~~~~~~~~~
{{ data[0].a }}
List of Cells in Row
~~~~~~~~~~~~~~~~~~~~
{% for item in data[0].items() %}
- {{item[0]}}: {{item[1]}}
{% endfor %}
Mapping Series Table
~~~~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested dictionaries using dynamic
headers.
{{ make_list_table_from_mappings(
[('One', 'a'), ('Two', 'b'), ('Three', 'c')],
data,
title='Table from series of mappings',
) }}
Loading the Template¶
.. datatemplate:csv:: sample.csv
:template: csv-sample.tmpl
:headers:
:dialect: excel-tab
DBM Samples¶
Creating Data File¶
import dbm.dumb
with dbm.dumb.open("sampledbm", "c") as db:
db[b"Hi"] = b"Hello"
db[b"Bye"] = b"Goodbye"
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
- With decoding {{ data['Hi'].decode('ascii') }}
- Without decoding {{ data['Hi'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data.items() %}
- {{item[0]}} -> {{item[1]}}
{% endfor %}
Loading the Template¶
.. datatemplate:dbm:: sampledbm
:template: dbm-sample.tmpl
Inline Sample (JSON)¶
Data File¶
{
"key1": "value1",
"key2": [
"list item 1",
"list item 2",
"list item 3"
],
"nested-list": [
["a", "b", "c"],
["A", "B", "C"]
],
"mapping-series": [
{"cola": "a", "colb": "b", "colc": "c"},
{"cola": "A", "colb": "B", "colc": "C"}
]
}
Template File¶
Individual Item
~~~~~~~~~~~~~~~
{{ data['key1'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data['key2'] %}
- {{item}}
{% endfor %}
Loading the Template¶
.. datatemplate:json::
:source: sample.json
Individual Item
~~~~~~~~~~~~~~~
{{ data['key1'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data['key2'] %}
- {{item}}
{% endfor %}
Legacy Samples¶
The datatemplate
directive is should no longer be used. It is
deprecated, and will be removed in the next release.
Data File¶
---
key1: value1
key2:
- list item 1
- list item 2
- list item 3
nested-list:
- ['a', 'b', 'c']
- ['A', 'B', 'C']
mapping-series:
- cola: a
colb: b
colc: c
- cola: A
colb: B
colc: C
Template File¶
.. -*- mode: rst -*-
Static Heading
--------------
Individual Item
~~~~~~~~~~~~~~~
{{ data['key1'] }}
List of Items
~~~~~~~~~~~~~
{% for item in data['key2'] %}
- {{item}}
{% endfor %}
Nested List Table
~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested sequences using hard-coded
headers.
{{ make_list_table(
['One', 'Two', 'Three'],
data['nested-list'],
title='Table from nested lists',
) }}
Mapping Series Table
~~~~~~~~~~~~~~~~~~~~
Rendering a table from a list of nested dictionaries using dynamic
headers.
{{ make_list_table_from_mappings(
[('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
data['mapping-series'],
title='Table from series of mappings',
) }}