using template engine to generate code (text)

1k Views Asked by At

I have bunch of YAML files in a config folder and bunch of templates in a template folder. The use case I have is to generate text file based on the yaml config and templates. I want to see if python tempting engines can be used to solve this problem.

I see that template engines are used in a web development context. The use case I have is very similar (but not same). I want to generate some text. It need not be displayed on a web page. Instead it should generate just a text file.

Example Inputs: config folder: config/yaml1, config/yaml2, config/yaml3.. template: template/template1, template/template2, template3.

Output

scripts/script1, script2, script3

The number of scripts = number of templates

There are 2 types of templates

One that is straightforward/direct substitution Example

YAML1:
    Titles:4
    SubTitles:10
Template1:
Number of Titles {Titles} where as Number of Subtitles is {SubTitles}

Other Template is a nested one. Basically the template needs to be looped based on YAML Example:

    YAML2:
        Book: "The Choice of using Choice"
            Author: "Unknown1"
        Book: "Chasing Choices"
            Author:"Known2"

Template2
Here are all the Books with Author Info
The author of the {Book} is {Author}

Expected output is a single text file that has

Number of Titles 4 where as Number of Subtitles is 10 The author of the The Choice of using Choice is Unknown1 The author of the Chasing Choices is known2

Can someone post me in the right direction?

1

There are 1 best solutions below

4
Dietrich Epp On

You can do this with regular expressions and search/replace. You can pass a function instead of a string to the re.sub function. Of course, it relies on having valid YAML:

YAML1:
    Titles: 4
    #      ^ need space here
    SubTitles: 10
Template1:
    Number of Titles {Titles} where as Number of Subtitles is {SubTitles}
    # Need indentation here

The python code would look like this:

import re
import yaml

# Match either {var}, {{, or }}
TEMPLATE_CODE = re.compile(r'\{(\w+)\}|\{\{|\}\}')

def expand(tmpl, namespace):
    print(namespace)
    def repl(m):
        name = m.group(1)
        if name:
            # Matched {var}
            return str(namespace[name])
        # matched {{ or }}
        return m.group(0)[0]
    return TEMPLATE_CODE.sub(repl, tmpl)

def expand_file(path):
    with open(path) as fp:
        data = yaml.safe_load(fp)
    print(expand(data['Template1'], data['YAML1']))

And here's the output:

Number of Titles 4 where as Number of Subtitles is 10

There are, of course, a lot of ways to make this more complicated, like using a proper templating engine.