Template Tag

TTP templates support <template> tag to define several templates within single file. Each template processed separately, no data shared between templates, but results of one template can be used by lookup functions in another template.

Only two levels of hierarchy supported - top template tag and a number of child template tags within it, further template tags nested within children are ignored.

First use case for this functionality stems from the fact that templates executed in sequence, meaning it is possible to use results produced by one template in next template(s), for instance first template can produce lookup table text file and other template will rely on.

Another use case is templates grouping under single definition to simplify loading - instead of adding each template to TTP object, all of them can be loaded in one go.

For instance:

from ttp import ttp

template1="""
<group>
interface {{ interface }}
 ip address {{ ip }}/{{ mask }}
</group>
"""

template2="""
<group name="vrfs">
VRF {{ vrf }}; default RD {{ rd }}
<group name="interfaces">
  Interfaces: {{ _start_ }}
    {{ intf_list | ROW }}
</group>
</group>
"""

parser = ttp()
parser.add_data(some_data)
parser.add_template(template1)
parser.add_template(template2)
parser.parse()

Above code will produce same results as this code:

from ttp import ttp

template="""
<template>
<group>
interface {{ interface }}
 ip address {{ ip }}/{{ mask }}
</group>
</template>

<template>
<group name="vrfs">
VRF {{ vrf }}; default RD {{ rd }}
<group name="interfaces">
  Interfaces: {{ _start_ }}
    {{ intf_list | ROW }}
</group>
</group>
</template>
"""

parser = ttp()
parser.add_data(some_data)
parser.add_template(template)
parser.parse()

Template tag attributes

There are a number of attributes supported by template tag. These attributes help to define template processing behavior.

Attribute

Description

name

Unique template identifier

base_path

Fully qualified OS path to data

results

Identifies the way results grouping method

pathchar

Character to use for group name-path processing

name

name="template_name"

Template name attribute is a string that indicates the unique name of the template. This attribute required if final results structure should be dictionary and not list (default behavior) as can be indicated in ttp.result method using structure argument, e.g.

Example

In below example results produced by TTP will be formed into dictionary structure using template names attributes as top level keys.

Consider this code:

from ttp import ttp
import json

template="""
<template name="template-1">
<input load="text">
interface Vlan778
 ip address 2002:fd37::91/124
</input>
<group name="interfaces-1">
interface {{ interface }}
 ip address {{ ip }}
</group>
</template>

<template name="template-2">
<input load="text">
interface Vlan778
 description V6 Management vlan
</input>
<group name="interfaces-2">
interface {{ interface }}
 description {{ description | ORPHRASE }}
</group>
</template>
"""

parser=ttp(template=template)
parser.parse()
results = parser.result(structure="dictionary")
print(json.dumps(results, sort_keys=True, indent=4, separators=(',', ': ')))

Results would be:

{
    "template-1": [
        {
            "interfaces-1": {
                "interface": "Vlan778",
                "ip": "2002:fd37::91/124"
            }
        }
    ],
    "template-2": [
        {
            "interfaces-2": {
                "description": "V6 Management vlan",
                "interface": "Vlan778"
            }
        }
    ]
}

base_path

base_path="/os/base/path/to/data/"

This attributes allows to specify base OS file system path to the location of data folders, folders with actual data can be detailed further using relative path in inputs’ url attribute.

Example

In below template base_path attribute set to /path/to/Data/, as a result all urls for all inputs within this template will be extended to absolute path in such a way that:

  • Input dataset-1 url /data-1/ will become /path/to/Data/data-1/

  • Input dataset-2 url /data-2/ will become /path/to/Data/data-2/

Absolute path will be used to load data for each input.

Template:

<template base_path="/path/to/Data/">

<input name="dataset-1">
url = "/data-1/"
</input>

<input name="dataset-2">
url = "/data-2/"
</input>

<group name="interfaces1" input="dataset-1">
interface {{ interface }}
 switchport access vlan {{ access_vlan }}
</group>

<group name="interfaces2" input="dataset-2">
interface {{ interface }}
  ip address {{ ip  }}/{{ mask }}
</group>

</template>

results

results="per_template|per_input"

Template results attribute allows to influence the logic used to combine template results, options are:

  • per_input - default, allows to combine results on a per input basis. For instance, if we have two text files with data that needs to be parsed, first file will be parsed by a set of groups associated with this template, combining results in a structure, that will be appended to the list of overall template results. Same will happen with next file. As a result, for this particular template two result items will be produced, one for each file.

  • per_template - allows to combine results on a per template basis. For instance, if we have two text files with data that needs to be parsed, first file will be parsed by a set of groups associated with this template, combining results in a structure, that structure will be used by TTP to merge with results produced by next file. As a result, for this particular template single results item will be produced, that item will contain merged results for all inputs’ files/datum.

Main use case for per_template behavior is to combine results across all the inputs and produce structure that will be more flat and might be easier to work with in certain situations.

Example

In this template we have two templates defined, with same set of inputs/data and groups, but first template has per_input (default) logic, while second template was configured to use per_template behavior.

Template:

<template>
<input load="text">
interface Vlan778
 ip address 2002:fd37::91/124
interface Vlan800
 ip address 172.16.10.1/24
</input>

<input load="text">
interface Vlan779
 ip address 192.168.1.1/24
interface Vlan90
 ip address 192.168.90.1/24
</input>

<group name="interfaces">
interface {{ interface }}
 ip address {{ ip }}
</group>
</template>


<template results="per_template">
<input load="text">
interface Vlan778
 ip address 2002:fd37::91/124
interface Vlan800
 ip address 172.16.10.1/24
</input>

<input load="text">
interface Vlan779
 ip address 192.168.1.1/24
interface Vlan90
 ip address 192.168.90.1/24
</input>

<group name="interfaces">
interface {{ interface }}
 ip address {{ ip }}
</group>
</template>

Results:

[
    [ <-----------------------------------------------first template results:
        {
            "interfaces": [
                {
                    "interface": "Vlan778",
                    "ip": "2002:fd37::91/124"
                },
                {
                    "interface": "Vlan800",
                    "ip": "172.16.10.1/24"
                }
            ]
        },
        {
            "interfaces": [
                {
                    "interface": "Vlan779",
                    "ip": "192.168.1.1/24"
                },
                {
                    "interface": "Vlan90",
                    "ip": "192.168.90.1/24"
                }
            ]
        }
    ],
    [ <-----------------------------------------------second template results:
        {
            "interfaces": [
                {
                    "interface": "Vlan778",
                    "ip": "2002:fd37::91/124"
                },
                {
                    "interface": "Vlan800",
                    "ip": "172.16.10.1/24"
                },
                {
                    "interface": "Vlan779",
                    "ip": "192.168.1.1/24"
                },
                {
                    "interface": "Vlan90",
                    "ip": "192.168.90.1/24"
                }
            ]
        }
    ]
]

pathchar

pathchar="."

At the moment this argument behavior is not fully implemented/tested, hence refrain from using it.

pathchar allows to specify character to use to separate path items for groups name attribute, by default it is dot character.