diff --git a/doc/README.md b/doc/README.md
index e4b748a56..a9e5253a0 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -34,4 +34,5 @@ Rougail est un bibliothèque python3 qui permet de charger des dictionnaires (fi
## Les templates
- Type creole
+ - Type jinja2
FIXME ^^
diff --git a/doc/dev/config.md b/doc/dev/config.md
index d53529660..7c804f888 100644
--- a/doc/dev/config.md
+++ b/doc/dev/config.md
@@ -54,7 +54,7 @@ Le répertoire des templates est géré dans la clef "templates_dir" et a comme
## Le moteur de templates par défaut
-Le moteur de template est géré dans la clef "default_engine" et a comme valeur par défaut : "creole". Les valeurs possible sont "none" ou "creole".
+Le moteur de template est géré dans la clef "default_engine" et a comme valeur par défaut : "creole". Les valeurs possible sont "none", "creole" ou "jinja2".
## Le répertoire des patchs
diff --git a/doc/service/file.md b/doc/service/file.md
index f2f1de03d..19bbd770a 100644
--- a/doc/service/file.md
+++ b/doc/service/file.md
@@ -138,8 +138,14 @@ Il est possible de redéfinir les éléments d'un fichier dans un dictionnaire d
Par défaut, le moteur de templating est le moteur de templating compatible avec "creole".
-Aujourd'hui il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) :
+Il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) :
```
/etc/squid/squid.conf
```
+
+Ou d'utiliser le moteur "jinja2" :
+
+```
+/etc/squid/squid.conf
+```
diff --git a/doc/service/override.md b/doc/service/override.md
index e1edd2b90..8f0365752 100644
--- a/doc/service/override.md
+++ b/doc/service/override.md
@@ -30,8 +30,14 @@ Dans ce cas le fichier de destination aura le même nom.
Par défaut, le moteur de templating est le moteur de templating compatible avec "creole".
-Aujourd'hui il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) :
+Il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) :
```
```
+
+Ou d'utiliser le moteur "jinja2" :
+
+```
+
+```
diff --git a/src/rougail/data/rougail.dtd b/src/rougail/data/rougail.dtd
index cb8f1bf03..396a8a71c 100644
--- a/src/rougail/data/rougail.dtd
+++ b/src/rougail/data/rougail.dtd
@@ -66,11 +66,11 @@
-
+
-
+
diff --git a/src/rougail/template/engine/__init__.py b/src/rougail/template/engine/__init__.py
index 35f66f16e..26989911d 100644
--- a/src/rougail/template/engine/__init__.py
+++ b/src/rougail/template/engine/__init__.py
@@ -1,4 +1,4 @@
-from . import none, creole
+from . import none, creole, jinja2
-__all__ = ('none', 'creole')
+__all__ = ('none', 'creole', 'jinja2')
diff --git a/src/rougail/template/engine/jinja2.py b/src/rougail/template/engine/jinja2.py
new file mode 100644
index 000000000..a447dfefb
--- /dev/null
+++ b/src/rougail/template/engine/jinja2.py
@@ -0,0 +1,69 @@
+"""Jinja2 engine
+
+Created by:
+EOLE (http://eole.orion.education.fr)
+Copyright (C) 2005-2018
+
+Forked by:
+Cadoles (http://www.cadoles.com)
+Copyright (C) 2021
+
+distribued with GPL-2 or later license
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+from typing import Any, Dict
+from jinja2 import Environment, FileSystemLoader
+from jinja2.exceptions import UndefinedError
+
+from ...i18n import _
+from ...utils import normalize_family
+from ...error import TemplateError
+
+
+def process(filename: str,
+ source: str,
+ true_destfilename: str,
+ destfilename: str,
+ variable: Any,
+ rougail_variables_dict: Dict,
+ eosfunc: Dict,
+ ):
+ """Process a cheetah template
+ """
+ # full path of the destination file
+ dir_name, template_name = filename.rsplit('/', 1)
+ if source is not None: # pragma: no cover
+ raise TemplateError(_('source is not supported for jinja2'))
+ rougail_variables_dict['rougail_variable'] = variable
+ if variable is not None:
+ var = {'rougail_variable': variable}
+ else:
+ var = {}
+ try:
+ # extra_context = {'normalize_family': normalize_family,
+ # eosfunc
+ env = Environment(loader=FileSystemLoader(dir_name))
+ template = env.get_template(template_name)
+ data = template.render(**rougail_variables_dict, rougail_filename=true_destfilename, **var)
+ except UndefinedError as err: # pragma: no cover
+ varname = err
+ msg = f"Error: unknown variable used in template {filename} to {destfilename}: {varname}"
+ raise TemplateError(_(msg)) from err
+
+ if not data.endswith('\n'):
+ data = data + '\n'
+ with open(destfilename, 'w') as file_h:
+ file_h.write(data)
diff --git a/tests/dictionaries/01base_file/00-base.xml b/tests/dictionaries/01base_file/00-base.xml
index c5d313376..5e1ac5f7c 100644
--- a/tests/dictionaries/01base_file/00-base.xml
+++ b/tests/dictionaries/01base_file/00-base.xml
@@ -4,6 +4,7 @@
/etc/file
+ /etc/file2
diff --git a/tests/dictionaries/01base_file/makedict/base.json b/tests/dictionaries/01base_file/makedict/base.json
index 2b24b0b16..fe375f632 100644
--- a/tests/dictionaries/01base_file/makedict/base.json
+++ b/tests/dictionaries/01base_file/makedict/base.json
@@ -1 +1 @@
-{"rougail.general.mode_conteneur_actif": "non", "services.test.files.file.engine": "creole", "services.test.files.file.group": "root", "services.test.files.file.mode": "0644", "services.test.files.file.name": "/etc/file", "services.test.files.file.owner": "root", "services.test.files.file.source": "file", "services.test.files.file.activate": true}
+{"rougail.general.mode_conteneur_actif": "non", "services.test.files.file.engine": "creole", "services.test.files.file.group": "root", "services.test.files.file.mode": "0644", "services.test.files.file.name": "/etc/file", "services.test.files.file.owner": "root", "services.test.files.file.source": "file", "services.test.files.file.activate": true, "services.test.files.file2.engine": "jinja2", "services.test.files.file2.group": "root", "services.test.files.file2.mode": "0644", "services.test.files.file2.name": "/etc/file2", "services.test.files.file2.owner": "root", "services.test.files.file2.source": "file2", "services.test.files.file2.activate": true}
diff --git a/tests/dictionaries/01base_file/result/etc/file2 b/tests/dictionaries/01base_file/result/etc/file2
new file mode 100644
index 000000000..4089fbcce
--- /dev/null
+++ b/tests/dictionaries/01base_file/result/etc/file2
@@ -0,0 +1,2 @@
+non
+non
diff --git a/tests/dictionaries/01base_file/result/tmpfiles.d/rougail.conf b/tests/dictionaries/01base_file/result/tmpfiles.d/rougail.conf
index 574c7b823..2dab2179e 100644
--- a/tests/dictionaries/01base_file/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/01base_file/result/tmpfiles.d/rougail.conf
@@ -1,2 +1,4 @@
C /etc/file 0644 root root - /usr/local/lib/etc/file
z /etc/file - - - - -
+C /etc/file2 0644 root root - /usr/local/lib/etc/file2
+z /etc/file2 - - - - -
diff --git a/tests/dictionaries/01base_file/tiramisu/base.py b/tests/dictionaries/01base_file/tiramisu/base.py
index 0bdb05a1c..a66324825 100644
--- a/tests/dictionaries/01base_file/tiramisu/base.py
+++ b/tests/dictionaries/01base_file/tiramisu/base.py
@@ -22,7 +22,15 @@ option_12 = StrOption(name="owner", doc="owner", default="root")
option_13 = StrOption(name="source", doc="source", default="file")
option_14 = BoolOption(name="activate", doc="activate", default=True)
option_7 = OptionDescription(name="file", doc="file", children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
-option_6 = OptionDescription(name="files", doc="files", children=[option_7])
+option_16 = StrOption(name="engine", doc="engine", default="jinja2")
+option_17 = StrOption(name="group", doc="group", default="root")
+option_18 = StrOption(name="mode", doc="mode", default="0644")
+option_19 = FilenameOption(name="name", doc="name", default="/etc/file2")
+option_20 = StrOption(name="owner", doc="owner", default="root")
+option_21 = StrOption(name="source", doc="source", default="file2")
+option_22 = BoolOption(name="activate", doc="activate", default=True)
+option_15 = OptionDescription(name="file2", doc="file2", children=[option_16, option_17, option_18, option_19, option_20, option_21, option_22])
+option_6 = OptionDescription(name="files", doc="files", children=[option_7, option_15])
option_5 = OptionDescription(name="test", doc="test", children=[option_6])
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
diff --git a/tests/dictionaries/01base_file/tmpl/file2 b/tests/dictionaries/01base_file/tmpl/file2
new file mode 100644
index 000000000..6d214113d
--- /dev/null
+++ b/tests/dictionaries/01base_file/tmpl/file2
@@ -0,0 +1,2 @@
+{{ mode_conteneur_actif }}
+{{ rougail.general.mode_conteneur_actif }}
diff --git a/tests/dictionaries/01base_file_utfchar/00-base.xml b/tests/dictionaries/01base_file_utfchar/00-base.xml
index 8cfac211f..63bce8959 100644
--- a/tests/dictionaries/01base_file_utfchar/00-base.xml
+++ b/tests/dictionaries/01base_file_utfchar/00-base.xml
@@ -4,6 +4,7 @@
/etc/systemd-makefs@dev-disk-by\x2dpartlabel
+ /etc/systemd-makefs@dev-disk-by\x2dpartlabel2
diff --git a/tests/dictionaries/01base_file_utfchar/makedict/base.json b/tests/dictionaries/01base_file_utfchar/makedict/base.json
index 9ccbba635..ccb3f1edc 100644
--- a/tests/dictionaries/01base_file_utfchar/makedict/base.json
+++ b/tests/dictionaries/01base_file_utfchar/makedict/base.json
@@ -1 +1 @@
-{"rougail.general.mode_conteneur_actif": "non", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.engine": "creole", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.group": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.mode": "0644", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.name": "/etc/systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.owner": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.source": "systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.activate": true}
+{"rougail.general.mode_conteneur_actif": "non", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.engine": "creole", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.group": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.mode": "0644", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.name": "/etc/systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.owner": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.source": "systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.activate": true, "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.engine": "jinja2", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.group": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.mode": "0644", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.name": "/etc/systemd-makefs@dev-disk-by\\x2dpartlabel2", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.owner": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.source": "systemd-makefs@dev-disk-by\\x2dpartlabel2", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel2.activate": true}
diff --git "a/tests/dictionaries/01base_file_utfchar/result/etc/systemd-makefs@dev-disk-by\\x2dpartlabel2" "b/tests/dictionaries/01base_file_utfchar/result/etc/systemd-makefs@dev-disk-by\\x2dpartlabel2"
new file mode 100644
index 000000000..d907505b5
--- /dev/null
+++ "b/tests/dictionaries/01base_file_utfchar/result/etc/systemd-makefs@dev-disk-by\\x2dpartlabel2"
@@ -0,0 +1 @@
+non
diff --git a/tests/dictionaries/01base_file_utfchar/result/tmpfiles.d/rougail.conf b/tests/dictionaries/01base_file_utfchar/result/tmpfiles.d/rougail.conf
index 2904be176..23f97d816 100644
--- a/tests/dictionaries/01base_file_utfchar/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/01base_file_utfchar/result/tmpfiles.d/rougail.conf
@@ -1,2 +1,4 @@
C /etc/systemd-makefs@dev-disk-by\x2dpartlabel 0644 root root - /usr/local/lib/etc/systemd-makefs@dev-disk-by\x2dpartlabel
z /etc/systemd-makefs@dev-disk-by\x2dpartlabel - - - - -
+C /etc/systemd-makefs@dev-disk-by\x2dpartlabel2 0644 root root - /usr/local/lib/etc/systemd-makefs@dev-disk-by\x2dpartlabel2
+z /etc/systemd-makefs@dev-disk-by\x2dpartlabel2 - - - - -
diff --git a/tests/dictionaries/01base_file_utfchar/tiramisu/base.py b/tests/dictionaries/01base_file_utfchar/tiramisu/base.py
index 15fd72dad..85b887edc 100644
--- a/tests/dictionaries/01base_file_utfchar/tiramisu/base.py
+++ b/tests/dictionaries/01base_file_utfchar/tiramisu/base.py
@@ -22,7 +22,15 @@ option_12 = StrOption(name="owner", doc="owner", default="root")
option_13 = StrOption(name="source", doc="source", default="systemd-makefs@dev-disk-by\\x2dpartlabel")
option_14 = BoolOption(name="activate", doc="activate", default=True)
option_7 = OptionDescription(name="systemd_makefs@dev_disk_by\\x2dpartlabel", doc="systemd-makefs@dev-disk-by\\x2dpartlabel", children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
-option_6 = OptionDescription(name="files", doc="files", children=[option_7])
+option_16 = StrOption(name="engine", doc="engine", default="jinja2")
+option_17 = StrOption(name="group", doc="group", default="root")
+option_18 = StrOption(name="mode", doc="mode", default="0644")
+option_19 = FilenameOption(name="name", doc="name", default="/etc/systemd-makefs@dev-disk-by\\x2dpartlabel2")
+option_20 = StrOption(name="owner", doc="owner", default="root")
+option_21 = StrOption(name="source", doc="source", default="systemd-makefs@dev-disk-by\\x2dpartlabel2")
+option_22 = BoolOption(name="activate", doc="activate", default=True)
+option_15 = OptionDescription(name="systemd_makefs@dev_disk_by\\x2dpartlabel2", doc="systemd-makefs@dev-disk-by\\x2dpartlabel2", children=[option_16, option_17, option_18, option_19, option_20, option_21, option_22])
+option_6 = OptionDescription(name="files", doc="files", children=[option_7, option_15])
option_5 = OptionDescription(name="test", doc="test", children=[option_6])
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
diff --git "a/tests/dictionaries/01base_file_utfchar/tmpl/systemd-makefs@dev-disk-by\\x2dpartlabel2" "b/tests/dictionaries/01base_file_utfchar/tmpl/systemd-makefs@dev-disk-by\\x2dpartlabel2"
new file mode 100644
index 000000000..db665a0e7
--- /dev/null
+++ "b/tests/dictionaries/01base_file_utfchar/tmpl/systemd-makefs@dev-disk-by\\x2dpartlabel2"
@@ -0,0 +1 @@
+{{ mode_conteneur_actif }}
diff --git a/tests/dictionaries/20override/00-base.xml b/tests/dictionaries/20override/00-base.xml
index 959ba53c5..010e20219 100644
--- a/tests/dictionaries/20override/00-base.xml
+++ b/tests/dictionaries/20override/00-base.xml
@@ -5,6 +5,9 @@
+
+
+
diff --git a/tests/dictionaries/20override/makedict/base.json b/tests/dictionaries/20override/makedict/base.json
index 074f8f468..f919d6256 100644
--- a/tests/dictionaries/20override/makedict/base.json
+++ b/tests/dictionaries/20override/makedict/base.json
@@ -1 +1 @@
-{"rougail.general.mode_conteneur_actif": "non", "services.test.overrides.test_service.engine": "creole", "services.test.overrides.test_service.name": "test", "services.test.overrides.test_service.source": "test.service", "services.test.overrides.test_service.activate": true}
+{"rougail.general.mode_conteneur_actif": "non", "services.test.overrides.test_service.engine": "creole", "services.test.overrides.test_service.name": "test", "services.test.overrides.test_service.source": "test.service", "services.test.overrides.test_service.activate": true, "services.test2.overrides.test2_service.engine": "jinja2", "services.test2.overrides.test2_service.name": "test2", "services.test2.overrides.test2_service.source": "test2.service", "services.test2.overrides.test2_service.activate": true}
diff --git a/tests/dictionaries/20override/result/systemd/system/test2.service.d/rougail.conf b/tests/dictionaries/20override/result/systemd/system/test2.service.d/rougail.conf
new file mode 100644
index 000000000..d907505b5
--- /dev/null
+++ b/tests/dictionaries/20override/result/systemd/system/test2.service.d/rougail.conf
@@ -0,0 +1 @@
+non
diff --git a/tests/dictionaries/20override/tiramisu/base.py b/tests/dictionaries/20override/tiramisu/base.py
index 59a598b8b..cc6b9910d 100644
--- a/tests/dictionaries/20override/tiramisu/base.py
+++ b/tests/dictionaries/20override/tiramisu/base.py
@@ -21,5 +21,12 @@ option_11 = BoolOption(name="activate", doc="activate", default=True)
option_7 = OptionDescription(name="test_service", doc="test.service", children=[option_8, option_9, option_10, option_11])
option_6 = OptionDescription(name="overrides", doc="overrides", children=[option_7])
option_5 = OptionDescription(name="test", doc="test", children=[option_6])
-option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
+option_15 = StrOption(name="engine", doc="engine", default="jinja2")
+option_16 = StrOption(name="name", doc="name", default="test2")
+option_17 = StrOption(name="source", doc="source", default="test2.service")
+option_18 = BoolOption(name="activate", doc="activate", default=True)
+option_14 = OptionDescription(name="test2_service", doc="test2.service", children=[option_15, option_16, option_17, option_18])
+option_13 = OptionDescription(name="overrides", doc="overrides", children=[option_14])
+option_12 = OptionDescription(name="test2", doc="test2", children=[option_13])
+option_4 = OptionDescription(name="services", doc="services", children=[option_5, option_12], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
diff --git a/tests/dictionaries/20override/tmpl/test2.service b/tests/dictionaries/20override/tmpl/test2.service
new file mode 100644
index 000000000..db665a0e7
--- /dev/null
+++ b/tests/dictionaries/20override/tmpl/test2.service
@@ -0,0 +1 @@
+{{ mode_conteneur_actif }}
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/00-base.xml b/tests/dictionaries/40ifin_leadershipauto_follower/00-base.xml
index 89472aa2b..b7db45905 100644
--- a/tests/dictionaries/40ifin_leadershipauto_follower/00-base.xml
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/00-base.xml
@@ -3,6 +3,7 @@
/etc/mailname
+ /etc/mailname2
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/makedict/base.json b/tests/dictionaries/40ifin_leadershipauto_follower/makedict/base.json
index d62bf5fd5..3fa240621 100644
--- a/tests/dictionaries/40ifin_leadershipauto_follower/makedict/base.json
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/makedict/base.json
@@ -1 +1 @@
-{"rougail.general.mode_conteneur_actif": "non", "rougail.general.condition": "oui", "rougail.general.leader.leader": [{"rougail.general.leader.leader": "a", "rougail.general.leader.follower2": null}, {"rougail.general.leader.leader": "b", "rougail.general.leader.follower1": null, "rougail.general.leader.follower2": null}], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": "/etc/mailname", "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true}
+{"rougail.general.mode_conteneur_actif": "non", "rougail.general.condition": "oui", "rougail.general.leader.leader": [{"rougail.general.leader.leader": "a", "rougail.general.leader.follower2": null}, {"rougail.general.leader.leader": "b", "rougail.general.leader.follower1": null, "rougail.general.leader.follower2": null}], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": "/etc/mailname", "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true, "services.test.files.mailname2.engine": "jinja2", "services.test.files.mailname2.group": "root", "services.test.files.mailname2.mode": "0644", "services.test.files.mailname2.name": "/etc/mailname2", "services.test.files.mailname2.owner": "root", "services.test.files.mailname2.source": "mailname2", "services.test.files.mailname2.activate": true}
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/result/etc/mailname2 b/tests/dictionaries/40ifin_leadershipauto_follower/result/etc/mailname2
new file mode 100644
index 000000000..b7cbd32c2
--- /dev/null
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/result/etc/mailname2
@@ -0,0 +1,5 @@
+leader: a
+follower2:
+leader: b
+follower1:
+follower2:
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/result/tmpfiles.d/rougail.conf b/tests/dictionaries/40ifin_leadershipauto_follower/result/tmpfiles.d/rougail.conf
index 46697e03a..7a8d00f42 100644
--- a/tests/dictionaries/40ifin_leadershipauto_follower/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/result/tmpfiles.d/rougail.conf
@@ -1,2 +1,4 @@
C /etc/mailname 0644 root root - /usr/local/lib/etc/mailname
z /etc/mailname - - - - -
+C /etc/mailname2 0644 root root - /usr/local/lib/etc/mailname2
+z /etc/mailname2 - - - - -
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/tiramisu/base.py b/tests/dictionaries/40ifin_leadershipauto_follower/tiramisu/base.py
index f4fe7ffbb..11bdb7a27 100644
--- a/tests/dictionaries/40ifin_leadershipauto_follower/tiramisu/base.py
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/tiramisu/base.py
@@ -27,7 +27,15 @@ option_17 = StrOption(name="owner", doc="owner", default="root")
option_18 = StrOption(name="source", doc="source", default="mailname")
option_19 = BoolOption(name="activate", doc="activate", default=True)
option_12 = OptionDescription(name="mailname", doc="mailname", children=[option_13, option_14, option_15, option_16, option_17, option_18, option_19])
-option_11 = OptionDescription(name="files", doc="files", children=[option_12])
+option_21 = StrOption(name="engine", doc="engine", default="jinja2")
+option_22 = StrOption(name="group", doc="group", default="root")
+option_23 = StrOption(name="mode", doc="mode", default="0644")
+option_24 = FilenameOption(name="name", doc="name", default="/etc/mailname2")
+option_25 = StrOption(name="owner", doc="owner", default="root")
+option_26 = StrOption(name="source", doc="source", default="mailname2")
+option_27 = BoolOption(name="activate", doc="activate", default=True)
+option_20 = OptionDescription(name="mailname2", doc="mailname2", children=[option_21, option_22, option_23, option_24, option_25, option_26, option_27])
+option_11 = OptionDescription(name="files", doc="files", children=[option_12, option_20])
option_10 = OptionDescription(name="test", doc="test", children=[option_11])
option_9 = OptionDescription(name="services", doc="services", children=[option_10], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_9])
diff --git a/tests/dictionaries/40ifin_leadershipauto_follower/tmpl/mailname2 b/tests/dictionaries/40ifin_leadershipauto_follower/tmpl/mailname2
new file mode 100644
index 000000000..021f00bb4
--- /dev/null
+++ b/tests/dictionaries/40ifin_leadershipauto_follower/tmpl/mailname2
@@ -0,0 +1,9 @@
+{% for lead in leader -%}
+leader: {{ lead }}
+{% if lead.follower1 is defined -%}
+follower1: {{ lead.follower1 if lead.follower1 }}
+{% endif -%}
+{% if lead.follower2 is defined -%}
+follower2: {{ lead.follower2 if lead.follower2 }}
+{% endif -%}
+{% endfor -%}
diff --git a/tests/dictionaries/60extra_group/00-base.xml b/tests/dictionaries/60extra_group/00-base.xml
index 1fd2ac821..6d1b7533d 100644
--- a/tests/dictionaries/60extra_group/00-base.xml
+++ b/tests/dictionaries/60extra_group/00-base.xml
@@ -3,6 +3,7 @@
/etc/mailname
+ /etc/mailname2
diff --git a/tests/dictionaries/60extra_group/makedict/base.json b/tests/dictionaries/60extra_group/makedict/base.json
index b8be046fb..263c7033e 100644
--- a/tests/dictionaries/60extra_group/makedict/base.json
+++ b/tests/dictionaries/60extra_group/makedict/base.json
@@ -1 +1 @@
-{"rougail.general.mode_conteneur_actif": "non", "rougail.general.activer_ejabberd": "non", "extra.ejabberd.description.description": [{"extra.ejabberd.description.description": "test", "extra.ejabberd.description.mode": "pre"}], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": "/etc/mailname", "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true}
+{"rougail.general.mode_conteneur_actif": "non", "rougail.general.activer_ejabberd": "non", "extra.ejabberd.description.description": [{"extra.ejabberd.description.description": "test", "extra.ejabberd.description.mode": "pre"}], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": "/etc/mailname", "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true, "services.test.files.mailname2.engine": "jinja2", "services.test.files.mailname2.group": "root", "services.test.files.mailname2.mode": "0644", "services.test.files.mailname2.name": "/etc/mailname2", "services.test.files.mailname2.owner": "root", "services.test.files.mailname2.source": "mailname2", "services.test.files.mailname2.activate": true}
diff --git a/tests/dictionaries/60extra_group/result/etc/mailname2 b/tests/dictionaries/60extra_group/result/etc/mailname2
new file mode 100644
index 000000000..dc34cc5b0
--- /dev/null
+++ b/tests/dictionaries/60extra_group/result/etc/mailname2
@@ -0,0 +1,11 @@
+contain test
+1
+leader: test
+follower: pre
+supeq
+sup
+diff
+testpre
+pretest
+leader2: test
+follower2: pre
diff --git a/tests/dictionaries/60extra_group/result/tmpfiles.d/rougail.conf b/tests/dictionaries/60extra_group/result/tmpfiles.d/rougail.conf
index 46697e03a..7a8d00f42 100644
--- a/tests/dictionaries/60extra_group/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/60extra_group/result/tmpfiles.d/rougail.conf
@@ -1,2 +1,4 @@
C /etc/mailname 0644 root root - /usr/local/lib/etc/mailname
z /etc/mailname - - - - -
+C /etc/mailname2 0644 root root - /usr/local/lib/etc/mailname2
+z /etc/mailname2 - - - - -
diff --git a/tests/dictionaries/60extra_group/tiramisu/base.py b/tests/dictionaries/60extra_group/tiramisu/base.py
index 437937a91..7b63628bf 100644
--- a/tests/dictionaries/60extra_group/tiramisu/base.py
+++ b/tests/dictionaries/60extra_group/tiramisu/base.py
@@ -28,7 +28,15 @@ option_18 = StrOption(name="owner", doc="owner", default="root")
option_19 = StrOption(name="source", doc="source", default="mailname")
option_20 = BoolOption(name="activate", doc="activate", default=True)
option_13 = OptionDescription(name="mailname", doc="mailname", children=[option_14, option_15, option_16, option_17, option_18, option_19, option_20])
-option_12 = OptionDescription(name="files", doc="files", children=[option_13])
+option_22 = StrOption(name="engine", doc="engine", default="jinja2")
+option_23 = StrOption(name="group", doc="group", default="root")
+option_24 = StrOption(name="mode", doc="mode", default="0644")
+option_25 = FilenameOption(name="name", doc="name", default="/etc/mailname2")
+option_26 = StrOption(name="owner", doc="owner", default="root")
+option_27 = StrOption(name="source", doc="source", default="mailname2")
+option_28 = BoolOption(name="activate", doc="activate", default=True)
+option_21 = OptionDescription(name="mailname2", doc="mailname2", children=[option_22, option_23, option_24, option_25, option_26, option_27, option_28])
+option_12 = OptionDescription(name="files", doc="files", children=[option_13, option_21])
option_11 = OptionDescription(name="test", doc="test", children=[option_12])
option_10 = OptionDescription(name="services", doc="services", children=[option_11], properties=frozenset({"hidden"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_5, option_10])
diff --git a/tests/dictionaries/60extra_group/tmpl/mailname2 b/tests/dictionaries/60extra_group/tmpl/mailname2
new file mode 100644
index 000000000..589c548e7
--- /dev/null
+++ b/tests/dictionaries/60extra_group/tmpl/mailname2
@@ -0,0 +1,33 @@
+{% if 'test' in extra.ejabberd.description -%}
+contain test
+{% endif -%}
+{{ extra.ejabberd.description|length }}
+{% if 'a' in extra.ejabberd.description -%}
+contain a
+{% endif -%}
+{% for description in extra.ejabberd.description -%}
+leader: {{ description }}
+follower: {{ description.mode }}
+{% if description <= description.mode -%}
+infeq
+{% endif -%}
+{% if description >= description.mode -%}
+supeq
+{% endif -%}
+{% if description < description.mode -%}
+inf
+{% endif -%}
+{% if description > description.mode -%}
+sup
+{% endif -%}
+{% if description == description.mode -%}
+eq
+{% endif -%}
+{% if description != description.mode -%}
+diff
+{% endif -%}
+{{ description + description.mode }}
+{{ description.mode + description }}
+{% endfor -%}
+leader2: {{ extra.ejabberd.description[0] }}
+follower2: {{ extra.ejabberd.description[0].mode }}
diff --git a/tests/dictionaries/70container_files_symlink_multi/00-base.xml b/tests/dictionaries/70container_files_symlink_multi/00-base.xml
index 07bc97421..94c9cb9d6 100644
--- a/tests/dictionaries/70container_files_symlink_multi/00-base.xml
+++ b/tests/dictionaries/70container_files_symlink_multi/00-base.xml
@@ -3,6 +3,7 @@
file_name
+ file_name2
@@ -10,5 +11,9 @@
/etc/mailname
/etc/mailname2
+
+ /etc/mailname3
+ /etc/mailname4
+
diff --git a/tests/dictionaries/70container_files_symlink_multi/makedict/base.json b/tests/dictionaries/70container_files_symlink_multi/makedict/base.json
index 13f02e446..2b759eeb1 100644
--- a/tests/dictionaries/70container_files_symlink_multi/makedict/base.json
+++ b/tests/dictionaries/70container_files_symlink_multi/makedict/base.json
@@ -1 +1 @@
-{"rougail.file_name": ["/etc/mailname", "/etc/mailname2"], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": ["/etc/mailname", "/etc/mailname2"], "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true}
+{"rougail.file_name": ["/etc/mailname", "/etc/mailname2"], "rougail.file_name2": ["/etc/mailname3", "/etc/mailname4"], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": ["/etc/mailname", "/etc/mailname2"], "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.activate": true, "services.test.files.mailname2.engine": "jinja2", "services.test.files.mailname2.group": "root", "services.test.files.mailname2.mode": "0644", "services.test.files.mailname2.name": ["/etc/mailname3", "/etc/mailname4"], "services.test.files.mailname2.owner": "root", "services.test.files.mailname2.source": "mailname2", "services.test.files.mailname2.activate": true}
diff --git a/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname3 b/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname3
new file mode 100644
index 000000000..2585efaa0
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname3
@@ -0,0 +1 @@
+/etc/mailname3
diff --git a/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname4 b/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname4
new file mode 100644
index 000000000..d58aef4bf
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi/result/etc/mailname4
@@ -0,0 +1 @@
+/etc/mailname4
diff --git a/tests/dictionaries/70container_files_symlink_multi/result/tmpfiles.d/rougail.conf b/tests/dictionaries/70container_files_symlink_multi/result/tmpfiles.d/rougail.conf
index 7a8d00f42..95445abe3 100644
--- a/tests/dictionaries/70container_files_symlink_multi/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/70container_files_symlink_multi/result/tmpfiles.d/rougail.conf
@@ -2,3 +2,7 @@ C /etc/mailname 0644 root root - /usr/local/lib/etc/mailname
z /etc/mailname - - - - -
C /etc/mailname2 0644 root root - /usr/local/lib/etc/mailname2
z /etc/mailname2 - - - - -
+C /etc/mailname3 0644 root root - /usr/local/lib/etc/mailname3
+z /etc/mailname3 - - - - -
+C /etc/mailname4 0644 root root - /usr/local/lib/etc/mailname4
+z /etc/mailname4 - - - - -
diff --git a/tests/dictionaries/70container_files_symlink_multi/tiramisu/base.py b/tests/dictionaries/70container_files_symlink_multi/tiramisu/base.py
index fa10981de..81b7088e5 100644
--- a/tests/dictionaries/70container_files_symlink_multi/tiramisu/base.py
+++ b/tests/dictionaries/70container_files_symlink_multi/tiramisu/base.py
@@ -12,16 +12,25 @@ try:
except:
from tiramisu import *
option_2 = FilenameOption(name="file_name", doc="file_name", multi=True, default=['/etc/mailname', '/etc/mailname2'], default_multi="/etc/mailname", properties=frozenset({"mandatory", "normal"}))
-option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
-option_7 = StrOption(name="engine", doc="engine", default="creole")
-option_8 = StrOption(name="group", doc="group", default="root")
-option_9 = StrOption(name="mode", doc="mode", default="0644")
-option_10 = SymLinkOption(name="name", opt=option_2)
-option_11 = StrOption(name="owner", doc="owner", default="root")
-option_12 = StrOption(name="source", doc="source", default="mailname")
-option_13 = BoolOption(name="activate", doc="activate", default=True)
-option_6 = OptionDescription(name="mailname", doc="mailname", children=[option_7, option_8, option_9, option_10, option_11, option_12, option_13])
-option_5 = OptionDescription(name="files", doc="files", children=[option_6])
-option_4 = OptionDescription(name="test", doc="test", children=[option_5])
-option_3 = OptionDescription(name="services", doc="services", children=[option_4], properties=frozenset({"hidden"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_3])
+option_3 = FilenameOption(name="file_name2", doc="file_name2", multi=True, default=['/etc/mailname3', '/etc/mailname4'], default_multi="/etc/mailname3", properties=frozenset({"mandatory", "normal"}))
+option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3])
+option_8 = StrOption(name="engine", doc="engine", default="creole")
+option_9 = StrOption(name="group", doc="group", default="root")
+option_10 = StrOption(name="mode", doc="mode", default="0644")
+option_11 = SymLinkOption(name="name", opt=option_2)
+option_12 = StrOption(name="owner", doc="owner", default="root")
+option_13 = StrOption(name="source", doc="source", default="mailname")
+option_14 = BoolOption(name="activate", doc="activate", default=True)
+option_7 = OptionDescription(name="mailname", doc="mailname", children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
+option_16 = StrOption(name="engine", doc="engine", default="jinja2")
+option_17 = StrOption(name="group", doc="group", default="root")
+option_18 = StrOption(name="mode", doc="mode", default="0644")
+option_19 = SymLinkOption(name="name", opt=option_3)
+option_20 = StrOption(name="owner", doc="owner", default="root")
+option_21 = StrOption(name="source", doc="source", default="mailname2")
+option_22 = BoolOption(name="activate", doc="activate", default=True)
+option_15 = OptionDescription(name="mailname2", doc="mailname2", children=[option_16, option_17, option_18, option_19, option_20, option_21, option_22])
+option_6 = OptionDescription(name="files", doc="files", children=[option_7, option_15])
+option_5 = OptionDescription(name="test", doc="test", children=[option_6])
+option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
diff --git a/tests/dictionaries/70container_files_symlink_multi/tmpl/mailname2 b/tests/dictionaries/70container_files_symlink_multi/tmpl/mailname2
new file mode 100644
index 000000000..32fea5cb4
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi/tmpl/mailname2
@@ -0,0 +1 @@
+{{ rougail_filename }}
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/00-base.xml b/tests/dictionaries/70container_files_symlink_multi_variable/00-base.xml
index 9a78b764b..4e29e1bf4 100644
--- a/tests/dictionaries/70container_files_symlink_multi_variable/00-base.xml
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/00-base.xml
@@ -3,6 +3,7 @@
file_name
+ file_name2
@@ -10,6 +11,10 @@
/etc/mailname
/etc/mailname2
+
+ /etc/mailname3
+ /etc/mailname4
+
mailname
mailname2
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/makedict/base.json b/tests/dictionaries/70container_files_symlink_multi_variable/makedict/base.json
index 20ffd9cac..c16808061 100644
--- a/tests/dictionaries/70container_files_symlink_multi_variable/makedict/base.json
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/makedict/base.json
@@ -1 +1 @@
-{"rougail.file_name": ["/etc/mailname", "/etc/mailname2"], "rougail.var": ["mailname", "mailname2"], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": ["/etc/mailname", "/etc/mailname2"], "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.variable": ["mailname", "mailname2"], "services.test.files.mailname.activate": true}
+{"rougail.file_name": ["/etc/mailname", "/etc/mailname2"], "rougail.file_name2": ["/etc/mailname3", "/etc/mailname4"], "rougail.var": ["mailname", "mailname2"], "services.test.files.mailname.engine": "creole", "services.test.files.mailname.group": "root", "services.test.files.mailname.mode": "0644", "services.test.files.mailname.name": ["/etc/mailname", "/etc/mailname2"], "services.test.files.mailname.owner": "root", "services.test.files.mailname.source": "mailname", "services.test.files.mailname.variable": ["mailname", "mailname2"], "services.test.files.mailname.activate": true, "services.test.files.mailname2.engine": "jinja2", "services.test.files.mailname2.group": "root", "services.test.files.mailname2.mode": "0644", "services.test.files.mailname2.name": ["/etc/mailname3", "/etc/mailname4"], "services.test.files.mailname2.owner": "root", "services.test.files.mailname2.source": "mailname2", "services.test.files.mailname2.variable": ["mailname", "mailname2"], "services.test.files.mailname2.activate": true}
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname3 b/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname3
new file mode 100644
index 000000000..0288f489b
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname3
@@ -0,0 +1 @@
+mailname
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname4 b/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname4
new file mode 100644
index 000000000..80d43ca54
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/result/etc/mailname4
@@ -0,0 +1 @@
+mailname2
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/result/tmpfiles.d/rougail.conf b/tests/dictionaries/70container_files_symlink_multi_variable/result/tmpfiles.d/rougail.conf
index 7a8d00f42..95445abe3 100644
--- a/tests/dictionaries/70container_files_symlink_multi_variable/result/tmpfiles.d/rougail.conf
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/result/tmpfiles.d/rougail.conf
@@ -2,3 +2,7 @@ C /etc/mailname 0644 root root - /usr/local/lib/etc/mailname
z /etc/mailname - - - - -
C /etc/mailname2 0644 root root - /usr/local/lib/etc/mailname2
z /etc/mailname2 - - - - -
+C /etc/mailname3 0644 root root - /usr/local/lib/etc/mailname3
+z /etc/mailname3 - - - - -
+C /etc/mailname4 0644 root root - /usr/local/lib/etc/mailname4
+z /etc/mailname4 - - - - -
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/tiramisu/base.py b/tests/dictionaries/70container_files_symlink_multi_variable/tiramisu/base.py
index b241d49d3..53db93a43 100644
--- a/tests/dictionaries/70container_files_symlink_multi_variable/tiramisu/base.py
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/tiramisu/base.py
@@ -12,18 +12,28 @@ try:
except:
from tiramisu import *
option_2 = FilenameOption(name="file_name", doc="file_name", multi=True, default=['/etc/mailname', '/etc/mailname2'], default_multi="/etc/mailname", properties=frozenset({"mandatory", "normal"}))
-option_3 = StrOption(name="var", doc="var", multi=True, default=['mailname', 'mailname2'], default_multi="mailname", properties=frozenset({"mandatory", "normal"}))
-option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3])
-option_8 = StrOption(name="engine", doc="engine", default="creole")
-option_9 = StrOption(name="group", doc="group", default="root")
-option_10 = StrOption(name="mode", doc="mode", default="0644")
-option_11 = SymLinkOption(name="name", opt=option_2)
-option_12 = StrOption(name="owner", doc="owner", default="root")
-option_13 = StrOption(name="source", doc="source", default="mailname")
-option_14 = SymLinkOption(name="variable", opt=option_3)
-option_15 = BoolOption(name="activate", doc="activate", default=True)
-option_7 = OptionDescription(name="mailname", doc="mailname", children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14, option_15])
-option_6 = OptionDescription(name="files", doc="files", children=[option_7])
-option_5 = OptionDescription(name="test", doc="test", children=[option_6])
-option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
-option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
+option_3 = FilenameOption(name="file_name2", doc="file_name2", multi=True, default=['/etc/mailname3', '/etc/mailname4'], default_multi="/etc/mailname3", properties=frozenset({"mandatory", "normal"}))
+option_4 = StrOption(name="var", doc="var", multi=True, default=['mailname', 'mailname2'], default_multi="mailname", properties=frozenset({"mandatory", "normal"}))
+option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3, option_4])
+option_9 = StrOption(name="engine", doc="engine", default="creole")
+option_10 = StrOption(name="group", doc="group", default="root")
+option_11 = StrOption(name="mode", doc="mode", default="0644")
+option_12 = SymLinkOption(name="name", opt=option_2)
+option_13 = StrOption(name="owner", doc="owner", default="root")
+option_14 = StrOption(name="source", doc="source", default="mailname")
+option_15 = SymLinkOption(name="variable", opt=option_4)
+option_16 = BoolOption(name="activate", doc="activate", default=True)
+option_8 = OptionDescription(name="mailname", doc="mailname", children=[option_9, option_10, option_11, option_12, option_13, option_14, option_15, option_16])
+option_18 = StrOption(name="engine", doc="engine", default="jinja2")
+option_19 = StrOption(name="group", doc="group", default="root")
+option_20 = StrOption(name="mode", doc="mode", default="0644")
+option_21 = SymLinkOption(name="name", opt=option_3)
+option_22 = StrOption(name="owner", doc="owner", default="root")
+option_23 = StrOption(name="source", doc="source", default="mailname2")
+option_24 = SymLinkOption(name="variable", opt=option_4)
+option_25 = BoolOption(name="activate", doc="activate", default=True)
+option_17 = OptionDescription(name="mailname2", doc="mailname2", children=[option_18, option_19, option_20, option_21, option_22, option_23, option_24, option_25])
+option_7 = OptionDescription(name="files", doc="files", children=[option_8, option_17])
+option_6 = OptionDescription(name="test", doc="test", children=[option_7])
+option_5 = OptionDescription(name="services", doc="services", children=[option_6], properties=frozenset({"hidden"}))
+option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_5])
diff --git a/tests/dictionaries/70container_files_symlink_multi_variable/tmpl/mailname2 b/tests/dictionaries/70container_files_symlink_multi_variable/tmpl/mailname2
new file mode 100644
index 000000000..256954446
--- /dev/null
+++ b/tests/dictionaries/70container_files_symlink_multi_variable/tmpl/mailname2
@@ -0,0 +1 @@
+{{ rougail_variable }}