2016-02-03 14 views
9

play_hosts è un elenco di tutte le macchine per un gioco. Voglio prenderle e usare qualcosa come format() per riscriverle come [email protected]%s e poi unirle insieme a qualcosa come join(). Quindi:Jinja2: format + unire gli elementi di un elenco

Tutti gli esempi di formato utilizzano piping in cui l'input è la stringa di formato e non un elenco. C'è un modo per usare questi (o qualcos'altro) per realizzare ciò che voglio? L'output dovrebbe simile a:

['[email protected]', '[email protected]', [email protected]', ...] 

Il doc Jinja2 descrive formato come questo:

format(value, *args, **kwargs) 

Applicare stringa Python formattazione su un oggetto:

{{ "%s - %s"|format("Hello?", "Foo!") }} 
-> Hello? - Foo! 

Così dà tre tipi di input ma non descrive quegli input nell'esempio, che ne mostra uno nella pipe e gli altri due passati via args. Esiste una parola chiave arg per specificare la stringa che viene convogliata? Per favore aiuto, monaci pitone!

+0

sarebbe questo lavoro? (Non ho mai usato jinja) '{% per host in play_host%}' '{{" rabbitmq @% s "| format (host)}}' '{% endfor%}' – Pynchia

+0

Sembra una comprensione di lista è tutto hai bisogno. – Barmar

risposta

5

In ansible è possibile utilizzare il filtro regex_replace:

{{ play_hosts | map('regex_replace', '^(.*)$', '[email protected]\\1') | list} 
6

È possibile creare filtri personalizzati

# /usr/share/ansible/plugins/filter/format_list.py (check filter_plugins path in ansible.cfg) 

def format_list(list_, pattern): 
    return [pattern % s for s in list_] 


class FilterModule(object): 
    def filters(self): 
     return { 
      'format_list': format_list, 
     } 

e usarlo

{{ play_hosts | format_list('[email protected]%s') }} 
+0

Penso che questa sia la soluzione migliore. Il tuo codice Jinja2 diventerà rapidamente ingombrante se proverai a fare tutto nel tuo playbook. – rumdrums

+0

Tale 'format_list' dovrebbe essere davvero parte di Jinja2! – geekQ

4

si potrebbe semplicemente join non solo da , ma anche aggiungere il prefisso insieme ad esso. Ora che non è molto divinatorio o sofisticati, ma una molto semplice soluzione di lavoro:

[[email protected]{{ play_hosts | join(', [email protected]') }}] 
+0

La ripetizione non è carina, ma sembra più pulita di 'regex_replace'. Manca davvero un filtro pulito in jinja2. +1 per la soluzione alternativa – geekQ

+0

Ciò tuttavia lascerà un "conigliomq @" penzolante in caso di una lista vuota. – lmNt

2

Credo che un altro modo sarebbe utilizzando la funzione globale joiner, come si in grado di leggere in http://jinja.pocoo.org/docs/2.9/templates/#list-of-global-functions:

un falegname viene passata una stringa e tornerà quella stringa ogni volta che viene chiamato, tranne la prima volta (nel qual caso si r crea una stringa vuota). È possibile utilizzare questo per unire le cose

Così il vostro codice sarebbe qualcosa di simile:

[ 
{% set comma = joiner(",") %}  
{% for host in play_hosts %} 
    {{ comma() }} 
    {{ "[email protected]%s"|format(host) }} 
{% endfor %} 
] 
Problemi correlati