Jinja: Suporta variáveis ​​aninhadas

Criado em 7 dez. 2016  ·  7Comentários  ·  Fonte: pallets/jinja

Estive pesquisando documentação e vários artigos online e não consegui encontrar qualquer menção de ter variáveis ​​aninhadas, então estou abrindo uma solicitação de recurso. Isso poderia ajudar a beneficiar muitos projetos, permitindo chamadas de variáveis ​​mais complexas e automáticas.

Uma variável normal pode ser definida assim:

{{ variable }}

Seria útil permitir que informações dinâmicas de outra variável fossem usadas para preencher outro nome de variável.

{{ variable{{ generated_var }} }}

Meu caso de uso exato é com Ansible. Estou pegando uma lista de dispositivos de interface de rede de uma variável (ansible_interfaces). Então, posso usar isso para fazer referência às informações de outra variável (ansible_eth0, por exemplo). Aqui está uma estrutura básica do que está tentando realizar.

{% for interface in ansible_interfaces %}
IPADDR{{ loop.index }}={{ ansible_{{ interface }}.ipv4.address }}
NETMASK{{ loop.index }}={{ ansible_{{ interface }}.ipv4.netmask }}
{% endfor %}

Jinja2 não gosta quando renderiza, pois reclama dos colchetes extras existentes. Para saber como implementar isso, pensei em uma dessas duas ideias diferentes.

(1) Permitir expansão variável. Isso é exatamente o que eu estava mostrando antes; permitindo que as variáveis ​​sejam analisadas de dentro para fora.

(2) Adicione um filtro para converter uma string em um nome de variável.

{% for interface in ansible_interfaces %}
{% set interface_string="ansible_%s.ipv4.address"|format(interface) %}
IPADDR{{ loop.index }}={{ interface_string|variable }}
NETMASK{{ loop.index }}={{ interface_string|variable }}
{% endfor %}

Aqui está um código aproximado (não funcional) que mostra a segunda ideia.

# vim jinja2/jinja2/filters.py
<strong i="21">@environmentfilter</strong>
def do_variable(environment, s):
    string_to_variable = "{{ %s }}" % s
    return environment.from_string(string_to_variable).render()

Idealmente, a opção 1 seria menos complexa em termos de uso do usuário final. Deixe-me saber sua opinião sobre o assunto. Esta é a primeira vez que examino o código do Jinja2, mas adoraria contribuir se precisar de ajuda com o código.

Comentários muito úteis

http://serverfault.com/questions/762079/how-to-loop-through-interface-facts

Parece que você pode fazer isso:

{{ hostvars[inventory_hostname]['ansible_%s' | format(interface)].ipv4.address }}

Sou muito forte: -1: em nomes de variáveis ​​variáveis. Geralmente é um sinal de arquitetura ruim se um aplicativo não fornece um dicionário / lista de dados adequado se você precisar acessá-lo por chave dinâmica ou iterar sobre ele. FWIW, acho que este hostvars dict é um tanto feio comparado a um dict apropriado que mapeia nomes de interface para dados de interface. Eu abriria um problema com o Ansible, sugerindo mudar essa lista para um dict. Uma vez que iterar sobre um dicionário fornece suas chaves, ele pode nem ser incompatível com versões anteriores se eles o alterassem para um dicionário.

Todos 7 comentários

http://serverfault.com/questions/762079/how-to-loop-through-interface-facts

Parece que você pode fazer isso:

{{ hostvars[inventory_hostname]['ansible_%s' | format(interface)].ipv4.address }}

Sou muito forte: -1: em nomes de variáveis ​​variáveis. Geralmente é um sinal de arquitetura ruim se um aplicativo não fornece um dicionário / lista de dados adequado se você precisar acessá-lo por chave dinâmica ou iterar sobre ele. FWIW, acho que este hostvars dict é um tanto feio comparado a um dict apropriado que mapeia nomes de interface para dados de interface. Eu abriria um problema com o Ansible, sugerindo mudar essa lista para um dict. Uma vez que iterar sobre um dicionário fornece suas chaves, ele pode nem ser incompatível com versões anteriores se eles o alterassem para um dicionário.

Estou 100% de acordo que a renderização de dentro para fora para obter nomes de variáveis ​​* N variáveis ​​é uma ideia RUIM .

No entanto, cheguei aqui procurando uma solução para aninhamento de renderização de fora para dentro e acabei explorando a solução sozinho. Existe suporte para tal coisa? A adição de um filtro nested_render seria benéfica ou prejudicial, pois provavelmente confundiria as pessoas?

Variáveis ​​aninhadas resolveriam um problema com WTForms, em que uma construção como
{{ form.playername(value="{{ currentname }}") }}
seria muito mais claro do que qualquer outra solução que encontrei.

{{ form.playername(value=currentname) }} faz isso. mas fyi, você deve passar os dados atuais para o construtor do formulário e não se preocupar com eles nos modelos

Ah, é simples assim! Acabei usando Javascript para definir o valor da variável currentname. Quando defino o valor padrão no objeto de formulário no código Python, ele não é atualizado.

Passe por #pocoo no IRC e me pingue lá (é muito offtopic aqui) e eu posso te dizer como fazer isso corretamente.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

delroth picture delroth  ·  4Comentários

htgoebel picture htgoebel  ·  4Comentários

DriverX picture DriverX  ·  4Comentários

priestc picture priestc  ·  5Comentários

mtrstudio picture mtrstudio  ·  5Comentários