# https://rutube.ru/video/95fc76d7920b390aafc7e45653359d88/

pip install jinja2

#!/usr/bin/env python3
from jinja2 import Template

name = "Федор"

tm = Template("Привет {{ name }}")
msg = tm.render(name=name)

print(msg)

{%  %} - спецификатор шаблона;
{{  }} - вырожение для вставки кострукций Python в шаблон;
{#  #} - блок комментариев
#  ##  - строковый комментарий

#!/usr/bin/env python3
from jinja2 import Template

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age


per = Person("Федор", 33)

tm = Template("Мне {{ p.age }} лет и зовут {{ p.name }}")
msg = tm.render(p = per)

print(msg)

Экранирование
{% raw %} {% endraw %}

#!/usr/bin/env python3
from jinja2 import Template

name = "Федор"

link = """В HTML-доументе ссылки опредеяются так:
<a href="#">Ссылка</a>
"""

tm = Template("{{link | e}}")
msg = tm.render(link=link)

print(msg)
 

{% for <выражение>-%}
  <повторяемый фрагмент>
{%endfor-%}

{%if <выражение>-%}
{%if else-%}
{%endif-%}

sum - вычесление сумм
    sum(iterable, attribute=None, start=0)
max (attribute='price')
random
replace("o", "O")

 

#!/usr/bin/env python3
from jinja2 import Template

cars = [
  {'model':'audi', 'price': 23000},
  {'model':'shkoda', 'price': 17000},

]

tpl = "Сумма цены автомобилей {{ cs | sum(attribute='price')}}"

tm = Template(tpl)
msg = tm.render(cs=cars)

print(msg)

{% filter <название фильтра> %}
<фрагмент для применения фильтра>
{% endfilter %}


#!/usr/bin/env python3
from jinja2 import Template

html = '''
{% macro input(name='', value='', type='text', size=20) -%}
  <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}">
{%- endmacro %}

<p>{{ input('username') }}
<p>{{ input('email') }}
<p>{{ input('passwrd') }}
'''

tm = Template(html)
msg = tm.render()

print(msg)
 

Работа с шаблонами(мой пример):

mkdir  templates

шаблон для пользователей templates/user.ldif:

cat > templates/user.ldif  << EOF
# user.ldif
dn: uid={{user.login}},ou=People,{{data.suffix}}
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: {{user.login}}
sn: {{user.login}}
userPassword: {{user.hash}}
loginShell: {{user.shell}}
uidNumber: {{user.uid}}
gidNumber: {{user.gid}}
homeDirectory: {{user.home}}
shadowLastChange: 0
shadowMax: 0
shadowWarning: 0
{%- if user.mail %}
mail: {{user.mail}}
{%- endif %}

dn: cn={{user.group}},ou=Groups,{{data.suffix}}
objectClass: posixGroup
cn: {{user.group}}
gidNumber: {{user.gid}}
memberUid: {{user.uid}}



EOF

шаблон для базовой структуры templates/base.ldif:

cat > templates/base.ldif  << EOF
# base.ldif
dn: ou=People,{{data.suffix}}
objectClass: organizationalUnit
ou: people

dn: ou=Groups,{{data.suffix}}
objectClass: organizationalUnit
ou: groups





EOF

главный файл:

#!/usr/bin/env python3
from jinja2 import Environment, FileSystemLoader
import crypt

def ldif_write(file_name, data):
    with open(file_name, 'w') as file:
        file.write(data)


data = {"suffix": "dc=dotty,dc=su"}
user = {
    "login":"test1"
    ,"group":"test1"
    ,"hash": "hash"
    ,"uid": 2002
    ,"gid": 2002
    ,"shell": "/bin/bash"
    ,"home": "/home/test1"
    ,"mail": "test1@mail.ru"
    }

file_loader = FileSystemLoader("templates")
env = Environment(loader=file_loader)

tm = env.get_template('base.ldif')
msg = tm.render(data=data)
ldif_write('base.ldif', msg)
print(msg)

tm = env.get_template('user.ldif')
msg = tm.render(data=data,user=user)
ldif_write(f'{user['login']}.ldif', msg)

ресурсы:

Настройка OpenLDAP

jinja2