Reputation: 28386
Given Ansible Jinja2 template:
{% macro directive(name, value) %}
{% if value is defined %}
{{ name }}={{ value }}
{% endif %}
{% endmacro -%}
# {{ ansible_managed }}
[Unit]
{{ directive('Description', service.description) }}
{{ directive('Documentation', service.documentation) }}
{{ directive('Requires', service.requires) }}
with service
variable definition:
service:
description: Test Template
requires: multi-user.target
how can I change the template to eliminate extra newlines in resulting output:
# Ansible managed
[Unit]
Description=Test Template
Requires=multi-user.target
so that it instead looks like:
# Ansible managed
[Unit]
Description=Test Template
Requires=multi-user.target
?
Upvotes: 1
Views: 1714
Reputation: 68589
Consider the following:
{% macro directive(name, value) %}
{% if value is defined %}
{{ name }}={{ value }} # a newline hardcoded in macro follows
{% endif %}
{% endmacro -%}
# {{ ansible_managed }}
[Unit 1]
{{ directive('Description', service.description) }}# 1st hardcoded newline follows
{{ directive('Documentation', service.documentation) }}# 2nd hardcoded newline follows
{{ directive('Requires', service.requires) }}# 3rd hardcoded newline follows
It produces:
# Ansible managed
[Unit 1]
Description=Test Template # a newline hardcoded in macro follows
# 1st hardcoded newline follows
# 2nd hardcoded newline follows
Requires=multi-user.target # a newline hardcoded in macro follows
# 3rd hardcoded newline follows
Even though documentation on whitespace control states "a single trailing newline is stripped if present", it does not apply to variable substitution, so even though the result of the macro contains a newline character at the end, this particular newline will not be stripped.
Just like it's not stripped if you define:
variable_with_newline: "value\n"
and run a template:
start-{{ variable_with_newline }}-end
it produces:
start-value
-end
To fix to the template either remove the hardcoded newlines:
[Unit]
{{ directive('Description', service.description) }}{{ directive('Documentation', service.documentation) }}{{ directive('Requires', service.requires) }}
or add explicit whitespace stripping:
[Unit]
{{ directive('Description', service.description) }}
{{- directive('Documentation', service.documentation) }}
{{- directive('Requires', service.requires) }}
or
[Unit]
{{ directive('Description', service.description) -}}
{{ directive('Documentation', service.documentation) -}}
{{ directive('Requires', service.requires) }}
Upvotes: 1