Reputation: 330
Using Python’s Jinja, I’m concerned with both code readability and correct output. Here is my Jinja template:
M3U_TEMPLATE = jinja2.Template(
textwrap.dedent("""\
#EXTM3U
{% for item in playlist %}
#EXTALB:{{ item.strAlbum }} ({{ item.release }})
#EXTART:{{ item.strAlbumArtists }}
#EXTINF:{{ item.iDuration }},{{ item.strArtists }} - {{ item.strTitle }}
{{ item.path }}
{% endfor %}
""")
)
Python’s textwrap.dedent()
takes care of removing most of indent from the text. But I want to remove also the indents from the block of text inside the {% for %}
loop. I want this kind of result:
#EXTM3U
#EXTALB:Offramp (1982)
#EXTART:Pat Metheny Group
#EXTINF:408,Pat Metheny Group - James
/media/Jazz, Fusion etc/Pat Metheny Group/1982 • Offramp/06 James.m4a
#EXTALB:Blue Moon (1961)
#EXTART:The Marcels
#EXTINF:133,The Marcels - Blue Moon
/media/Pop/The Marcels/1961 • Blue Moon/01 Blue Moon.m4a
But I’m getting this:
#EXTM3U
#EXTALB:Offramp (1982)
#EXTART:Pat Metheny Group
#EXTINF:408,Pat Metheny Group - James
/media/Jazz, Fusion etc/Pat Metheny Group/1982 • Offramp/06 James.m4a
#EXTALB:Blue Moon (1961)
#EXTART:The Marcels
#EXTINF:133,The Marcels - Blue Moon
/media/Pop/The Marcels/1961 • Blue Moon/01 Blue Moon.m4a
I want the item’s block indentation in code, but not in final result. So how to get rid of this? Can’t find a Jinja example that covers my case.
Upvotes: 0
Views: 82
Reputation: 160043
Fortunately, Jinja already supports this quite handily in several different ways:
By adding a trailing -
to the directive - "You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed"
{% for item in playlist -%}
In your case, since you have multiple lines within the block that are prefixed with "raw" characters, this option will not work (subsequent lines in the loop will still have the wrong indentation).
Use the keyword arguments to jinja2.Template
that control this behavior for the entire template / Environment
, namely trim_blocks
and lstrip_blocks
:
M3U_TEMPLATE = jinja2.Template(
textwrap.dedent("""
{% for item in playlist %}
#EXTALB:{{ item.strAlbum }} ({{ item.release }})
#EXTART:{{ item.strAlbumArtists }}
#EXTINF:{{ item.iDuration }},{{ item.strArtists }} - {{ item.strTitle }}
{{ item.path }}
{% endfor %}
"""),
trim_blocks=True,
lstrip_blocks=True
)
Upvotes: 0
Reputation: 141698
You can just preprocess the template to remove leading spaces from each line.
template = textwrap.dedent("""\
#EXTM3U
{% for item in playlist %}
#EXTALB:{{ item.strAlbum }} ({{ item.release }})
#EXTART:{{ item.strAlbumArtists }}
#EXTINF:{{ item.iDuration }},{{ item.strArtists }} - {{ item.strTitle }}
{{ item.path }}
{% endfor %}
""")
template_no_leading_spaces = "\n".join(line.lstrip() for line in template.splitlines())
M3U_TEMPLATE = jinja2.Template(template_no_leading_spaces)
Upvotes: 0
Reputation: 13397
You can just dedent post-rendering. The thing is also - you don't want to dedent template, because template should remain readable - that's why indents on loops, assignment clauses etc. Also - one of the variables coming from rendering might include any spacing character that will break your assumptions.
M3U_TEMPLATE = jinja2.Template(
"""
{% for item in playlist %}
#EXTALB:{{ item.strAlbum }} ({{ item.release }})
#EXTART:{{ item.strAlbumArtists }}
#EXTINF:{{ item.iDuration }},{{ item.strArtists }} - {{ item.strTitle }}
{{ item.path }}
{% endfor %}
"""
)
print(
textwrap.dedent(
M3U_TEMPLATE.render(
playlist=[
{"strAlbum": "album", "release": "v1.0", "strAlbumArtists": "artist", "iDuration": "tooLong", "strArtists": "AnotherArtist", "strTitle": "title", "path": "path"},
{"strAlbum": "album1", "release": "v2.0", "strAlbumArtists": "artist1", "iDuration": "tooLong1", "strArtists": "AnotherArtist1", "strTitle": "title1", "path": "path1"}
]
)
)
)
Upvotes: 0
Reputation: 328
Can you please try this code:
I just introduced an hypen at the end of for loop item object.
M3U_TEMPLATE = jinja2.Template(
textwrap.dedent("""\
#EXTM3U
{% for item in playlist -%}
#EXTALB:{{ item.strAlbum }} ({{ item.release }})
#EXTART:{{ item.strAlbumArtists }}
#EXTINF:{{ item.iDuration }},{{ item.strArtists }} - {{ item.strTitle }}
{{ item.path }}
{% endfor %}
""")
)
Upvotes: -1