-6

Trying to build a JSON file from a template. It works ok as such, but for some reason newlines within loop constructs go missing, which I find rather irksome; the file "works" (is machine readable just fine), but for human consumption it's pretty ill-suited.

Here's my template:

{
        "Users": 
        [
{% for username,user in _vpn_user_accounts.items() %}
              {
              "Name" : "{{ user.name }}",
              "Hash" : "{{ user.hash }}",
              "Cns" : [
{% for cn in user.cns.get(server_name, []) %}
                      "{{ cn }}"{% if not loop.last -%},{% endif %}
{% endfor %}
              ],
              "key_ids" : [
{% for key in user.get( 'keys' , []) %}
{% if key.public is defined %}
                      "{{ key.public }}"{% if not loop.last %},{% endif %}
{% endif %}
{% endfor %}
              ],
              "comment" : "{{ user.get( 'comment', '' ) }}"
              } {% if not loop.last %},{% endif %}
{% endfor %}
        ]
}

Here's some sample data:

  - andrej:
      name: "andrej"
      hash: "$2b$10$8EF3H.../Wj0RchEqU6"
      cns:
        h:
          - "andrej_linux_h_201808171440"
          - "andrej_linuxvm_h_201809131031"
          - "andrej_mac_h_201808171441"
          - "andrej_phone_h_201808171441"
        w:
          - "andrej_linux_w_201808171439"
          - "andrej_linuxvm_w_201809131031"
          - "andrej_mac_w_201808171441"
          - "andrej_phone_w_201808171441"
      keys:
        - name: "andrej"
          public: "kbjrvtni"
        - name: "andrej2"
          public: "ijrltifu"
        - name: "andrej3"
          public: "rbcvncbt"
      comment: "systems"

This is my desired outcome (running against server "w"):

{
    "Users": 
    [
            {
                    "Name" : "andrej",
                    "Hash" : "$2b$10$8EF3H.../Wj0RchEqU6",
                    "Cns"  : [ 
                            "andrej_linux_w_201808171439",
                            "andrej_linuxvm_w_201809131031",
                            "andrej_mac_w_201808171441",
                            "andrej_phone_w_201808171441"
                    ],
                    "key_ids" : [ 
                            "kbjrvtni",
                            "ijrltifu",
                            "rbcvncbt" 
                    ],
                    "comment" : "systems guy"
            }
     ]
}

This is what I get:

{
    "Users": 
    [
            {
                    "Name" : "andrej",
                    "Hash" : "$2b$10$8EF3H.../Wj0RchEqU6",
                    "Cns"  : [ 
                            "andrej_linux_w_201808171439",                                "andrej_linuxvm_w_201809131031",                                "andrej_mac_w_201808171441",                                "andrej_phone_w_201808171441"                        ],
                    "key_ids" : [ 
                            "kbjrvtni",                                "ijrltifu",                                "rbcvncbt"                         ],
                    "comment" : "systems guy"
            }
     ]
}

I have experimented with #Jinja2: trim_blocks and #Jinja2: keep_newline, neither of which showed the desired result. Well, trim_blocks kind of did, but it also gave me a bunch of empty lines where the jinja conditionals were ... unsatisfactory.

Any hints on how to resolve this? As I said, it works, but it irks me immensely that I can't get human readable, nice output.

tink
  • 14,342
  • 4
  • 46
  • 50
  • @techraf - elaborate? And how does that explain the newline issue? – tink Oct 02 '18 at 19:00
  • gotcha. my sanitisation of my data was overzealous, it stripped the hypens from the lists under w: and h: respectively. Will amend post data now. – tink Oct 02 '18 at 19:14
  • And for the record: none of the answers in the thread which you tagged mine to be a duplicate of fixed the issue in and by themselves. I had found that one yesterday. @techraf – tink Oct 02 '18 at 19:33
  • I don't think writing `{% endif %}{% endfor %}` in a single line instead of two makes this any different or unique question. You had newlines in your template and you got them in the output. That's how templating works. Do you want the question to be closed as typo instead? – techraf Oct 02 '18 at 19:41

1 Answers1

3

And this little change actually made the problem go away in the end.

#jinja2: trim_blocks:False
{
        "Users": 
        [
{% for username,user in _vpn_user_accounts.items() %}
              {
              "Name" : "{{ user.name }}",
              "Hash" : "{{ user.hash }}",
              "Cns" : [
{%- for cn in user.cns.get(server_name, []) %}
                      "{{ cn }}"{% if not loop.last -%},{% endif %}
{%- endfor %}
              ],
              "key_ids" : [
{%- for key in user.get( 'keys' , []) %}
{% if key.public is defined %}
                      "{{ key.public }}"{% if not loop.last %},{% endif %}
{% endif %}
{%- endfor %}
              ],
              "comment" : "{{ user.get( 'comment', '' ) }}"
              } {% if not loop.last %},{% endif %}
{% endfor %}
        ]
}
tink
  • 14,342
  • 4
  • 46
  • 50
  • 4
    For those missing what the 'little chagne' is, the head of the file adds `#jinja2: trim_blocks:False` imho this should be the accepted answer for the question posed. – Oneiroi Oct 26 '18 at 12:57