matrix-doc/scripts/templating
Travis Ralston 9aa47b86c4 Introduce a concept of a room version specification
The "Room Specification" (or "Room Version Specification") is the specification that defines which room versions do what and are intended to be documents which speak the truth about how rooms operate under the hood.

The approach taken here is a bit different than other specifications. For starters, the specification is versioned in this project instead of relying on the matrix.org repository to track compiled HTML. This is done for a couple reasons, the first being we're still developing the v1 specification while concurrently making a v2 spec and the second being trying to reduce the reliance on matrix.org's repository for specifications.

Because the room spec is built into versions, some changes needed to be made. The `targets.yaml` now has a special syntax for indicating what version something is at, and the changelog generator can handle rendering different versions of the same changelog (as parsed from the RST). Some additional work has been put in to the changelog parsing to allow us to reference the v1 room spec as "v1" without having to sacrifice clarity in the changelog headings.

Finally, this moves the identifier grammar as it stands into the v1 room spec. This is in anticipation of the v2 room spec having a different set of grammar. Event schemas haven't been migrated here while the MSC to change them is in-flight.

There are a few open questions at this point:
* Do we move state resolution into here?
* Do we move the auth rules into here?

Note: this does not introduce the concept of versioned schemas (tabs) that I was previously working with. There's currently no use for them, so they are shelved elsewhere.
2018-09-10 16:34:42 -06:00
..
batesian Remove extraneous list casting 2018-07-10 16:52:17 -06:00
matrix_templates Introduce a concept of a room version specification 2018-09-10 16:34:42 -06:00
README.md Move templating into scripts dir 2017-11-08 08:37:56 +00:00
build.py Remove extraneous list casting 2018-07-10 16:52:17 -06:00

README.md

This folder contains the templates and a home-brewed templating system called Batesian for creating the spec. Batesian uses the templating system Jinja2 in Python.

Installation

 $ pip install Jinja2

Running

To pass arbitrary files (not limited to RST) through the templating system:

 $ python build.py -i matrix_templates /random/file/path/here.rst

The template output can be found at out/here.rst. For a full list of options, type python build.py --help.

Developing

Sections and Units

Batesian is built around the concept of Sections and Units. Sections are strings which will be inserted into the provided document. Every section has a unique key name which is the template variable that it represents. Units are arbitrary python data. They are also represented by unique key names.

Adding template variables

If you want to add a new template variable e.g. {{foo_bar}} which is replaced with the text foobar, you need to add a new Section:

  • Open matrix_templates/sections.py.

  • Add a new function to MatrixSections called render_foo_bar. The function name after render_ determines the template variable name, and the return value of this function determines what will be inserted.

    def render_foo_bar(self):
        return "foobar"
    
  • Run build.py with a file which has {{foo_bar}} in it, and it will be replaced with foobar.

Adding data for template variables

If you want to expose arbitrary data which can be used by MatrixSections, you need to add a new Unit:

  • Open matrix_templates/units.py.

  • Add a new function to MatrixUnits called load_some_data. Similar to sections, the function name after load_ determines the unit name, and the return value of this function determines the value of the unit.

    def load_some_data(self):
        return {
           "data": "this could be JSON from file from json.loads()",
           "processed_data": "this data may have helper keys added",
           "types": "it doesn't even need to be a dict. Whatever you want!"
        }
    
  • In MatrixSections, you can now call self.units.get("some_data") to retrieve the value you returned.

Using Jinja templates

Sections can use Jinja templates to return text. Batesian will attempt to load all templates from matrix_templates/templates/. These can be accessed in Section code via template = self.env.get_template("name_of_template.tmpl"). At this point, the template is just a standard jinja2.Template. In fact, self.env is just a jinja2.Environment.

Debugging

If you don't know why your template isn't behaving as you'd expect, or you just want to add some informative logging, use self.log in either the Sections class or Units class. You'll need to add -v to build.py for these lines to show.

About

Batesian was designed to be extremely simple and just use Python as its language rather than another intermediary language like some other templating systems. This provides a lot of flexibility since you aren't contrained by a templating language. Batesian provides a thin abstraction over Jinja which is very useful when you want to do random bits of processing then dump the output into a Jinja template. Its name is derived from Batesian mimicry due to how the templating system uses Python as its language, but in a harmless way.