如何在Jinja2中为数组中的每个元素添加前缀和后缀?

huangapple go评论62阅读模式
英文:

How to add prefix and suffix to every element in array in Jinja2?

问题

{{ ['host1', 'host2', 'host3'] | map('string') | map('join', 'https://', ':1234') | join(',') }}

英文:

I need a one-liner Jinja2 template for the following task which will used in Ansible.

I have a list of hostnames and want to add protocol and port to every one of them, then join the new string together.
From list ['host1', 'host2', 'host3'] and prefix 'https://' and suffix ':1234' i need the following string created: 'https://host1:1234,https://host2:1234',https://host3:1234'.

What i put together from here and there is something like this:
{{ ['host1', 'host2'] | map('string') | **** | join(',') }} where **** is probably a map or a format filter, i just couldn't figure it out.

答案1

得分: 3

使用严格的Jinja 模板来完成这个任务并不是一个可行的方式。

如果你是在Python中使用Jinja,最简单的解决方案可能是定义一个自定义过滤器:

import jinja2

def strformat(v, fmt):
    return fmt % v

env = jinja2.Environment()
env.filters['strformat'] = strformat

hosts = ['host1', 'host2', 'host3']
t = env.from_string('{{ hosts | map("strformat", "https://%s:1234") | join(",") }}')
print(t.render(hosts=hosts))

运行上面的代码会产生以下输出:

https://host1:1234,https://host2:1234,https://host3:1234

或者,您可以在将列表传递给模板之前对其进行转换:

import jinja2

hosts = ['host1', 'host2', 'host3']
formatted_hosts = [ 'https://%s:1234' % host for host in hosts]
t = jinja2.Template('{{ formatted_hosts | join(",") }}')
print(t.render(hosts=hosts, formatted_hosts=formatted_hosts))

这产生相同的输出。


如果您正在使用Ansible中的Jinja,您可以使用regex_replace过滤器来实现相同的效果:

- hosts: localhost
  gather_facts: false
  vars:
    hosts: ['host1','host2','host3']
  tasks:
    - debug:
        msg: '{{ hosts | map("regex_replace", "^(.*)$", "https://\:1234") | join(",") }}'

这是另一种方法来实现相同的结果。

英文:

There isn't any way to do this using strict Jinja.

If you're using Jinja from Python, the easiest solution is probably to define a custom filter:

import jinja2

def strformat(v, fmt):
    return fmt % v

env = jinja2.Environment()
env.filters['strformat'] = strformat

hosts = ['host1', 'host2', 'host3']
t = env.from_string('{{ hosts | map("strformat", "https://%s:1234") | join(",") }}')
print(t.render(hosts=hosts))

Running the above code produces:

https://host1:1234,https://host2:1234,https://host3:1234

Alternatively, just transform the list before you pass it in to your template:

import jinja2

hosts = ['host1', 'host2', 'host3']
formatted_hosts = [ 'https://%s:1234' % host for host in hosts]
t = jinja2.Template('{{ formatted_hosts | join(",") }}')
print(t.render(hosts=hosts, formatted_hosts=formatted_hosts))

This produces the same output.


If you happen to be using Jinja in Ansible, you can accomplish the same thing with the regex_replace filter:

- hosts: localhost
  gather_facts: false
  vars:
    hosts: ['host1','host2','host3']
  tasks:
    - debug:
        msg: '{{ hosts | map("regex_replace", "^(.*)$", "https://:1234") | join(",") }}'

huangapple
  • 本文由 发表于 2023年3月4日 09:28:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75633128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定