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.
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.
Comentários muito úteis
http://serverfault.com/questions/762079/how-to-loop-through-interface-facts
Parece que você pode fazer isso:
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.