Non-HTML use-cases ------------------ Mustache templates are, by spec, expected to autoescape especial HTML characters from variables, unless a raw variable is used. From the `official manual`_: All variables are HTML escaped by default. If you want to return raw contents without escaping, use the triple mustache: {{{name}}}. You can also use & to return its raw contents: {{& name}}. .. _official manual: https://mustache.github.io/mustache.5.html#Variables **mstache** is highly customizable and can be adapted for non-HTML use-cases not covered by the reference specs and, so, rarely supported by any other implementation. This page explains a few use-case scenarios. JSON Template ============= The following is an example on how integrate Mustache templating in a JSON context, the customizations made are: 1. ``escape`` customized to disable HTML-escaping. 2. ``stringify`` replaces for JSON encoding. 3. ``tags`` customized to include quotes, replacing whole strings with JSON. .. code:: python import json import textwrap import mstache print(mstache.render( textwrap.dedent(''' { "number": "{{int_value}}", "string": "{{str_value}}", "object": "{{dict_value}}" } '''), { 'int_value': 1, 'str_value': 'string', 'dict_value': {}, }, stringify=lambda data, text: ( # JSONify values json.dumps(data).encode() ), escape=lambda x: x, # omit any escaping tags=('"{{', '}}"'), # mstache tags to replace entire strings )) # { # "number": 1, # "string": "string", # "object": {} # } Binary template =============== **mstache** is one of the few Mustache implementations supporting binary templates, if any at all, where every byte is representative. This is thanks to both its support for :class:`bytes` templates and high customizability. For binary templates you will need to care of the following: 1. Your template would need to be of type :class:`bytes` for the rendering output to be also in :class:`bytes`. 2. Ensure your string variables are either :class:`bytes` or expected to be encoded as ``utf-8``. 3. ``virtuals`` can be used as encoding and utility helpers. 4. ``stringify`` can be used to customize how objects are turned into bytes. Binary template example: .. code:: python import functools import json import mstache output = mstache.render( ( # bytes template b'{{data.length_uint32}}{{data}}' b'{{integer.as_uint32}}' ), { 'data': 'hello world!\nsome bytes', # to be utf8-encoded 'integer': 5, # to be encoded as 4-byte big-endian uint }, getter=functools.partial( mstache.default_getter, virtuals=mstache.default_virtuals | { # virtual byte helpers 'length_uint32': lambda x: ( # byte-length as 4-byte big-endian uint len(x.encode() if isinstance(x, str) else x) .to_bytes(4) ), 'as_uint32': lambda x: ( # value as 4-byte big-endian uint int(x).to_bytes(4) ), }, ), escape=lambda x: x, # omit any escaping keep_lines=True, # do not collapse block lines ) print(output) # b'\x00\x00\x00\x17hello world!\nsome bytes\x00\x00\x00\x05' # addendum: extraction size = int.from_bytes(output[:4]) print((size, output[4:4 + size], int.from_bytes(output[-4:]))) # (23, b'hello world!\nsome bytes', 5)