Moban
General purpose static text generator using Jinja2 and other python template engines
Install / Use
/learn @moremoban/MobanREADME
================================================================================ mó bǎn - 模板 General purpose static text generator
.. image:: https://raw.githubusercontent.com/pyexcel/pyexcel.github.io/master/images/patreon.png :target: https://www.patreon.com/chfw
.. image:: https://codecov.io/gh/moremoban/moban/branch/master/graph/badge.svg :target: https://codecov.io/gh/moremoban/moban
.. image:: https://badge.fury.io/py/moban.svg :target: https://pypi.org/project/moban
.. image:: https://pepy.tech/badge/moban :target: https://pepy.tech/project/moban
.. image:: https://readthedocs.org/projects/moban/badge/?version=latest :target: http://moban.readthedocs.org/en/latest/
.. image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg :target: https://gitter.im/chfw_moban/Lobby
:Author: C.W. and its contributors (See contributors.rst) :Issues: http://github.com/moremoban/moban/issues :License: MIT
Announcement
In version 0.8.0, moban.plugins.jinja2.tests.files is moved to moban-ansible
package. moban.plugins.jinja2.filters.github is moved to moban-jinja2-github
package Please install them for backward compatibility.
Quick start
.. code-block:: bash
$ export HELLO="world"
$ moban "{{HELLO}}"
world
Or
.. code-block:: bash
$ export HELLO="world"
$ echo "{{HELLO}}" | moban
Or simply
.. code-block:: bash
$ HELLO="world" moban "{{HELLO}}"
A bit formal example:
.. code-block:: bash
$ moban -c data.yml -t my.template
world
Given data.yml as:
.. code-block:: bash
hello: world
and my.template as:
.. code-block:: bash
{{hello}}
Please note that data.yml will take precedence over environment variables.
Template inheritance and custom template directories
Suppose there exists shared/base.jj2, and two templates child1.jj2 and
child2.jj2 derives from it. You can do:
.. code-block:: bash
$ moban -t child1.jj2 -td shared -o child1
$ moban -t child2.jj2 -td shared -o child2
Data overload and custom data directories
Effectively each data file you give to moban, it overrides environment variables.
Still you can have different layers of data. For example, you can have
shared/company_info.yml, use project1.yml for project 1 and
project2.yml for project 2. In each of the derived data file, simply mention:
.. code-block:: bash
overrides: company_info.yml ...
Here is the command line to use your data:
.. code-block:: bash
$ moban -cd shared -c project1.yaml -t README.jj2
Custom jinja2 extension
moban allows the injection of user preferred jinja2 extensions:
.. code-block:: bash
$ moban -e jj2=jinja2_time.TimeExtension ...
Well, can I nick some existing functions as filters, tests? Or create a global from another library?
Sure, you can use the same '-e' syntax:
.. code-block:: bash
$ moban -e jinja2=filter:module.path.filter_function
jinja2=test:module.path.test_function
jinja2=global:identifier=module.path.variable
In this case, you would have to include the external library in your own requirements.txt
Here is an example:
.. code-block:: bash
$ moban -e jinja2=filter:moban.externals.file_system.url_join
jinja2=test:moban.externals.file_system.exists
jinja2=global:description=moban.constants.PROGRAM_DESCRIPTION
-t "{{ 'a'|url_join('b')}} {{'b' is exists}}"
Can I write my own jinja2 test, filter and/or globals?
moban allows the freedom of craftsmanship. Please refer to the docs for more details. Here is an example:
.. code-block:: python
import sys import base64
from moban.plugins.jinja2.extensions import JinjaFilter
@JinjaFilter() def base64encode(string): if sys.version_info[0] > 2: content = base64.b64encode(string.encode("utf-8")) content = content.decode("utf-8") else: content = base64.b64encode(string) return content
And you can use it within your jinja2 template, mytest.jj2:
.. code-block:: python
{{ 'abc' | base64encode }}
Assume that the custom example was saved in custom-jj2-plugin
.. code-block:: bash
$ moban -pd custom-jj2-plugin -t mytest.jj2 ...
Moban will then load your custom jinja2 functions
Slim template syntax for jinja2
with moban-slim <https://github.com/moremoban/moban-slim>_ installed,
Given a data.json file with the following content
.. code-block::
{
"person": {
"firstname": "Smith",
"lastname": "Jones",
},
}
.. code-block:: bash
$ moban --template-type slim -c data.json "{{person.firstname}} {{person.lastname}}" Smith Jones
Handlebars.js template
With moban-handlebars <https://github.com/moremoban/moban-handlebars>_
installed,
Given a data.json file with the following content
.. code-block::
{
"person": {
"firstname": "Yehuda",
"lastname": "Katz",
},
}
.. code-block:: bash
$ moban --template-type handlebars -c data.json "{{person.firstname}} {{person.lastname}}" Yehuda Katz
For handlebars.js users, yes, the example was copied from handlebarjs.com. The
aim is to show off what we can do.
Let's continue with a bit more fancy feature:
.. code-block:: bash
$ moban --template-type handlebars -c data.json "{{#with person}}{{firstname}} {{lastname}} {{/with}}"
Moban's way of pybar3 usage <https://github.com/wbond/pybars3#usage>_:
Let's save the following file a script.py under helper_and_partial folder:
.. code-block:: python
from moban_handlebars.api import Helper, register_partial
register_partial('header', '<h1>People</h1>')
@Helper('list') def _list(this, options, items): result = [u'<ul>'] for thing in items: result.append(u'<li>') result.extend(options'fn') result.append(u'</li>') result.append(u'</ul>') return result
And given data.json reads as the following:
.. code-block::
{ "people":[ {"name": "Bill", "age": 100}, {"name": "Bob", "age": 90}, {"name": "Mark", "age": 25} ] }
Let's invoke handlebar template:
.. code-block:: bash
$ moban --template-type hbs -pd helper_and_partial -c data.json "{{>header}}{{#list people}}{{name}} {{age}}{{/list}}" Handlebars-ing {{>header}... to moban.output Handlebarsed 1 file. $ cat moban.output
<h1>People</h1><ul><li>Bill 100</li><li>Bob 90</li><li>Mark 25</li></ul>Velocity template
With moban-velocity <https://github.com/moremoban/moban-velocity>_
installed,
Given the following data.json:
.. code-block::
{"people": [ {"name": "Bill", "age": 100}, {"name": "Bob", "age": 90}, {"name": "Mark", "age": 25} ] }
And given the following velocity.template:
.. code-block::
Old people: #foreach ($person in $people) #if($person.age > 70) $person.name #end #end
Third person is $people[2].name
moban can do the template:
.. code-block:: bash
$ moban --template-type velocity -c data.json -t velocity.template Old people:
Bill
Bob
Third person is Mark
Can I write my own template engine?
Yes and please check for more details <https://github.com/moremoban/moban/tree/dev/tests/regression_tests/level-7-b-template-engine-plugin>_.
Given the following template type function, and saved in custom-plugin dir:
.. code-block:: python
from moban.core.content_processor import ContentProcessor
@ContentProcessor("de-duplicate", "De-duplicating", "De-duplicated") def de_duplicate(content: str, options: dict) -> str: lines = content.split(b'\n') new_lines = [] for line in lines: if line not in new_lines: new_lines.append(line) return b'\n'.join(new_lines)
You can start using it like this:
.. code-block:: bash
$ moban --template-type de-duplicate -pd custom-plugin -t duplicated_content.txt
TOML data format
moban-anyconfig <https://github.com/moremoban/moban-anyconfig>_ should be installed first.
Given the following toml file, sample.toml:
.. code-block::
title = "TOML Example" [owner] name = "Tom Preston-Werner"
You can do:
.. code-block:: bash
$ moban -c sample.toml "{{owner.name}} made {{title}}" Tom Preston-Werner made TOML Example
Not limited to toml, you can supply moban with the following data formats:
.. csv-table:: Always supported formats, quoting from python-anyconfig :header: "Format", "Type", "Requirement" :widths: 15, 10, 40
JSON, json, json (standard lib) or simplejson
Ini-like, ini, configparser (standard lib)
Pickle, pickle, pickle (standard lib)
XML, xml, ElementTree (standard lib)
Java properties, properties, None (native implementation with standard lib)
B-sh, shellvars, None (native implementation with standard lib)
For any of the following data formats, you elect to install by yourself.
.. csv-table:: Supported formats by pluggable backend modules :header: "Format", "Type", "Required backend" :widths: 15, 10, 40
Amazon Ion, ion, anyconfig-ion-backend
BSON, bson, anyconfig-bson-backend
CBOR, cbor, ``
