Is there a native templating system for plain text files in Python?

Question:

I am looking for either technique or templating system for Python for formatting output to simple text. What I require is that it will be able to iterate through multiple lists or dicts. It would be nice if I would be able to define template into separate file (like output.templ) instead of hardcoding it into source code.

As simple example what I want to achieve, we have variables title, subtitle and list

title = 'foo'
subtitle = 'bar'
list = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

And running throught a template, output would look like this:

Foo
Bar

Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

How to do this? Thank you.

Asked By: Gargauth

||

Answers:

There are quite a number of template engines for python: Jinja, Cheetah, Genshi etc. You won’t make a mistake with any of them.

Answered By: jammon

If your prefer to use something shipped with the standard library, take a look at the format string syntax. By default it is not able to format lists like in your output example, but you can handle this with a custom Formatter which overrides the convert_field method.

Supposed your custom formatter cf uses the conversion code l to format lists, this should produce your given example output:

cf.format("{title}n{subtitle}nn{list!l}", title=title, subtitle=sibtitle, list=list)

Alternatively you could preformat your list using "n".join(list) and then pass this to your normal template string.

Answered By: Oben Sonne

You can use the standard library string an its Template class.

Having a file foo.txt:

$title
$subtitle
$list

And the processing of the file (example.py):

from string import Template

d = {
    'title': 'This is the title',
    'subtitle': 'And this is the subtitle',
    'list': 'n'.join(['first', 'second', 'third'])
}

with open('foo.txt', 'r') as f:
    src = Template(f.read())
    result = src.substitute(d)
    print(result)

Then run it:

$ python example.py
This is the title
And this is the subtitle
first
second
third
Answered By: ThibThib

if you want arbitrary prefixes/suffixes to identify your variables, you can simply use re.sub with a lambda expression:

from pathlib import Path
import re

def tpl(fn:Path, v:dict[str,str]) -> str:
    text = fn.with_suffix('.html').read_text()
    return re.sub("(<!-- (.+?) -->)", lambda m: v[m[2].lower()], text)

html = tpl(Path(__file__), {
    'title' : 't',
    'body' : 'b'
})
Answered By: user1050755
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.