Create different documents from the same sources via Jinja (object method)
With Jinja, you can define objects (audience, platform, version, etc.) and include or exclude text blocks according to their attributes.
-
Create the following
conditional-text.rstfile:Using conditional text================================={% if public.elec %}.. admonition:: Danger for electriciansRisk of electrocutionDo not touch electrical wires.{% else %}.. admonition:: Danger for plumbersRisk of drowningDo not dive into the pool.{% endif %} -
Define an Audience class with two attributes for plumbers and electricians:
class Audience:def __init__(self,electrician,plumber):self.elec=electricianself.plum=plumber -
Create an instance of the Audience class whose value is true for electricians and false for plumbers:
user=Audience(True,False) -
Create and run the following script:
#!/usr/bin/pythonclass Audience:def __init__(self,electrician,plumber):self.elec=electricianself.plum=plumberimport jinja2import sysreload(sys)sys.setdefaultencoding('utf8')user=Audience(True,False)env = jinja2.Environment(loader=jinja2.FileSystemLoader('./'))template = env.get_template('texte-conditionnel.rst')string=template.render(public=user)print(string) -
The contents of the
conditional-text.rstfile are overwritten and contain only the information intended for electricians. -
Create a condition for audiences other than electricians or plumbers:
Using conditional text================================={% if public.elec %}.. admonition:: Danger for electriciansRisk of electrocutionDo not touch electrical wires.{% elif public.plum %}.. admonition:: Danger for plumbersRisk of drowningDo not dive into the pool.{% else %}.. admonition:: No dangerIf you're not a plumber or an electrician, you're not in anyno danger.{% endif %} -
Create a new class for seasons:
class Season:def __init__(self,winter,spring,summer,autumn):self.win=winterself.spr=springself.sum=summerself.aut=autumn -
Create more complex conditions:
Using conditional text================================={% if public.elec %}.. admonition:: Danger for electriciansRisk of electrocutionDo not touch electrical wires.{% elif public.plum and seas.wint %}.. admonition:: Danger for plumbersRisk of fractureDo not dive into the frozen pool.{% elif public.plum and seas.summ %}.. admonition:: Danger for plumbersRisk of hydrocutionDo not dive into cold water when it is hot.{% elif public.plum and seas.spri or seas.autu %}.. admonition:: Danger for plumbersRisk of somethingDon't dive into the pool, you never know.{% else %}.. admonition:: No dangerIf you're not a plumber or an electrician, you're not in anyno danger.{% endif %} -
Vary the values of the Audience and Season class instances to filter the content of the
conditional-text.rstfile.#!/usr/bin/pythonclass Audience:def __init__(self,electrician,plumber):self.elec=electricianself.plum=plumberclass Season:def __init__(self,winter,spring,summer,autumn):self.wint=winterself.spri=springself.summ=summerself.autu=autumnimport jinja2import sysreload(sys)sys.setdefaultencoding('utf8')user=Audience(False,True)when=Season(False,False,False,True)env = jinja2.Environment(loader=jinja2.FileSystemLoader('./'))template = env.get_template('conditional-text.rst')string=template.render(public=user,seas=when)print(string) -
Use a more readable variant in the content file:
It may be more intuitive to specify a user-friendly string value in the content file, especially if editors are unfamiliar with object-oriented programming, as the
==equality test is more meaningful to most people.Using conditional text================================={% if public.personae == "electrician" %}.. admonition:: Danger for electriciansRisk of electrocutionDo not touch electrical wires.{% elif public.personae == "plumber" and public.season == "winter" %}.. admonition:: Danger for plumbersRisk of fractureDo not dive into the frozen pool.{% elif public.personae == "plumber" and public.season == "summer" %}.. admonition:: Danger for plumbersRisk of hydrocutionDo not dive into cold water when it is hot.{% elif public.personae == "plumber" and public.season == "spring" or public.season == "autumn" %}.. admonition:: Danger for plumbersRisk of somethingDon't dive into the pool, you never know.{% else %}.. admonition:: No dangerIf you're not a plumber or an electrician, you're not in anyno danger.{% endif %}It’s more economical to use a single object class, even if it does mix cabbages and carrots (as much in this far-fetched example as in real life, where you’d mix audiences, versions, platforms, etc.).
#!/usr/bin/pythonclass Audience:def __init__(self,pers,seas):self.personae=persself.season=seasimport jinja2import sysreload(sys)sys.setdefaultencoding('utf8')user=Audience("plumber", "winter")env = jinja2.Environment(loader=jinja2.FileSystemLoader('./'))template = env.get_template('conditional-text.rst')string=template.render(public=user)print(string) -
Modify your script to indicate the public and the season as parameters:
code/profiling.py Usage:
Terminal window ./profiling.py plumber autumnIf you’ve been paying close attention, you’ll have noticed that this script renders the else condition in the content file useless, since the parameter values are tested before execution.
To allow the passage of unexpected values and display the contents of the else block, the code must be modified as follows:
#!/usr/bin/python# coding: utf8class Audience:def __init__(self,pers,seas):self.personae=persself.season=seasimport jinja2import sysreload(sys)sys.setdefaultencoding('utf8')if len(sys.argv) == 3:pubparam=str(sys.argv[1])seasparam=str(sys.argv[2])user=Audience(pubparam,seasparam)env = jinja2.Environment(loader=jinja2.FileSystemLoader('./'))template = env.get_template('texte-conditionnel.rst')string=template.render(public=user)print(string)else:print('Please indicate public and season')