Mustache.js: Adicionar opção: Aviso sobre variáveis ​​desconhecidas

Criado em 14 set. 2016  ·  18Comentários  ·  Fonte: janl/mustache.js

Às vezes cometemos erros de digitação em nomes de variáveis ​​(mesmo com autosuggest).
Seria ótimo se houvesse uma configuração para que o bigode-js gerasse um aviso sobre variáveis ​​'desconhecidas', em vez de devolver uma string vazia (mesmo que seja compatível com as especificações).

A página de manual do Mustache diz:
By default a variable "miss" returns an empty string. This can usually be configured in your Mustache library. The Ruby version of Mustache supports raising an exception in this situation, for instance.

Comentários muito úteis

Eu prefiro um erro grave, de modo que, por exemplo, ao usar com Express, torne-se uma resposta 500 e não apenas um registro em algum lugar enquanto o usuário final está vendo uma página renderizada incorretamente (potencialmente renderizada de forma incorreta, dependendo de como o a variável deveria ser usada); isso pode ser ainda mais útil na produção do que no desenvolvimento local, dependendo de quão boa é sua página 500 vs. quão ruim as páginas renderizadas incorretamente seriam para a funcionalidade de seu aplicativo. O uso de seções ainda pode permitir que os modelos ignorem as variáveis ​​ausentes, mesmo com erros graves para uso direto. E qualquer uso de nível superior que precise registrar o problema estaria no controle do sistema de registro, então não teríamos que nos preocupar, digamos, com o mecanismo de aviso interno do Mustache prejudicando a saída de executores de teste ou coisas assim.

Eu tenho um protótipo funcionando em https://github.com/ScottFreeCode/mustache.js , embora eu pudesse usar um pouco de ajuda para descobrir como escrever um teste para ele.

Todos 18 comentários

Adoro este recurso de outros frameworks durante o desenvolvimento local, então + 1 de mim! Acho que é importante que tenha mínimo ou nenhum impacto no desempenho, embora. Talvez até factível, mantendo o núcleo como está? Por exemplo, substituindo alguns métodos internos para permitir esse tipo de comportamento durante o desenvolvimento.

Talvez um mustache.dev.js que é construído usando mustache.js e as substituições de função contendo a lógica de verificação?

Eu prefiro um erro grave, de modo que, por exemplo, ao usar com Express, torne-se uma resposta 500 e não apenas um registro em algum lugar enquanto o usuário final está vendo uma página renderizada incorretamente (potencialmente renderizada de forma incorreta, dependendo de como o a variável deveria ser usada); isso pode ser ainda mais útil na produção do que no desenvolvimento local, dependendo de quão boa é sua página 500 vs. quão ruim as páginas renderizadas incorretamente seriam para a funcionalidade de seu aplicativo. O uso de seções ainda pode permitir que os modelos ignorem as variáveis ​​ausentes, mesmo com erros graves para uso direto. E qualquer uso de nível superior que precise registrar o problema estaria no controle do sistema de registro, então não teríamos que nos preocupar, digamos, com o mecanismo de aviso interno do Mustache prejudicando a saída de executores de teste ou coisas assim.

Eu tenho um protótipo funcionando em https://github.com/ScottFreeCode/mustache.js , embora eu pudesse usar um pouco de ajuda para descobrir como escrever um teste para ele.

Hmm, então usar a existência de um objeto como if ( {{#thing}} ) geraria um erro? (Acho que isso é bastante comum)

Ou apenas a renderização real das variáveis ​​( {{ id }} ) geraria um erro? O que você estava pensando?

Editar: recurso muito legal que eu adicionaria +1 para habilitar por padrão em um major, caso isso não acabe sendo um incômodo.

Na minha opinião, o primeiro deve ser um erro, o segundo um 'aviso'.
Para ambos, gostaria de saber que está faltando um valor.

Mesmo que, no segundo caso, possa não quebrar tecnicamente, pode ter um grande impacto na página.

Além disso, o contrário seria bom: variáveis ​​não utilizadas ... Mas isso é muito mais impacto para causar, eu acho! : D

Em 8 de novembro de 2016, às 14:19, David da Silva [email protected] escreveu:

Hmm, então usar a existência de um objeto como se ({{#thing}}) geraria um erro? (Acho que isso é bastante comum)

Ou apenas a renderização real de variáveis ​​({{id}}) geraria um erro? O que você estava pensando?

-
Você está recebendo isso porque é o autor do tópico.
Responda a este e-mail diretamente, visualize-o no GitHub https://github.com/janl/mustache.js/issues/599#issuecomment -259133973 ou ignore o tópico https://github.com/notifications/unsubscribe-auth/ AJ8FmSptdhysYrQpg1ODkIrm12A_TXcYks5q8HbbgaJpZM4J8lKe.

Na minha opinião, o primeiro deve ser um erro, o segundo um 'aviso'.
Para ambos, gostaria de saber que está faltando um valor.

@MatthijsZw entendo. Acabei de lembrar que você poderia armazenar um null para a propriedade, o que seria uma boa coisa a se fazer e, portanto, nenhuma exceção ocorreria. (mencionando isso especialmente para o caso if )

Edit: Minha posição atual é que eu prefiro Errar em ambos. Eu prefiro comportamentos consistentes, e você forçaria o uso de null para valores ausentes vazios, o que eu acho preferível.

Além disso, o contrário seria bom: variáveis ​​não utilizadas ... Mas isso é muito mais impacto para causar, eu acho! : D

Estou pensando que seria legal obter de alguma forma o esquema para os dados que um modelo está esperando e usá-lo para gerar uma consulta GraphQL ... ou algo semelhante.

Refletindo mais, acho que parte do problema aqui é que os dados ausentes são inválidos _por_ - e, portanto, _apenas se_ - o modelo está _esperando_ esses dados. Portanto, dados ausentes que o modelo simplesmente exibiria são sempre inválidos por essa lógica, mas é concebível que um modelo possa em um lugar esperar que certos dados estejam disponíveis e ramificar nele como algum tipo de sinalizador verdadeiro / falso (por isso é inválido se não for tanto falso quanto ausente e, portanto, não atender a essa expectativa), mas em outro pode esperar que os dados possam ou não estar disponíveis e ramificar se estão (nesse caso, nunca é inválido).

Nessa perspectiva, usar null para controlar isso não faz muito sentido para mim:

  • Se os dados estiverem errados - não atendendo às expectativas - como podemos esperar que os dados errados controlem o comportamento do modelo sobre como lidar com dados errados?
  • A expectativa está realmente no modelo de qualquer maneira.
  • null poderia ser um valor falsey para branches na verdade que esperam dados e os consideram inválidos para os dados estarem ausentes, mas isso ainda nos deixa com a necessidade de ramificar precisamente se os dados foram fornecidos porque nós espere que os dados não sejam preenchidos (nem mesmo com null , a menos que sejam provenientes de uma fonte que usa null para dados ausentes, por exemplo, SQL - e na verdade, isso sugere que tratar null como ausente ou não deve ser configurável com base na fonte de dados).

O que precisamos é de dois tipos de ramos, para as diferentes expectativas por parte do modelo. O que, até onde sei, é lamentável porque a especificação Mustache independente de linguagem, embora permita (mas não obriga) a configuração de se os dados ausentes são um erro, até onde eu sei não tem nada para um tipo diferente de ramo que seria diferente neste ponto. Hmm...


Por outro lado, estou pensando que dados estranhos / excedentes / não usados ​​não são realmente uma questão de os dados serem inválidos, é uma questão de o modelo ser inválido se não usar esses dados quando o aplicativo / dados / modelo espera que seja usado. Ou seja, se alguma coisa é potencialmente utilizável, mas o modelo pode decidir se é relevante, então não importa se o modelo imprime essas coisas, mas se alguma coisa realmente _precisa_ ser exibida ao usuário, então se o modelo não para mostrar que é um erro. Como uma espécie de reversão, a expectativa está fora do modelo (no modelo?) E a invalidade de não atender a essa expectativa está no modelo. Provavelmente é melhor lidar com isso separadamente, eu acho.


Os itens acima são, suponho, opiniões fortes fracamente defendidas.

IMO interpretar null valores como valores não existentes está errado.

{ name: null }

esse objeto tem uma propriedade name com um valor falso e, portanto, nunca deve ser visto como inválido e, portanto, não é um motivo para ser descartado.

Uma verificação mais apropriada seria verificar se uma propriedade solicitada foi definida como fazemos em mustache.hasProperty () .

mas em outro pode esperar que os dados possam ou não estar disponíveis e ramificar se estão (neste caso, nunca é inválido).

O que eu estava tentando transmitir é que, se você ramificar dependendo da chave X (por exemplo, {{#X}} , os dados fornecidos devem ter um valor para a chave X , seja um verdadeiro ou valor falso, mas definitivamente não undefined .

  • null implica "sim, eu sei que não há valor. Estou marcando explicitamente que não há valor".
  • undefined implica principalmente que a chave X nem mesmo está definida (se você definir uma chave com um valor de undefined seria melhor usar null ) . E se a chave não for definida, é por ser 'preguiçoso' ao declarar os dados (por exemplo, não usar null quando um objeto ref está faltando) ou por causa de erro humano (erro de digitação, lapso, confusão)

Portanto, neste caso, eu veria benefícios em lançar um erro. (tentando ramificar em uma chave que tem um valor de undefined )

No outro caso, tentando renderizar undefined ou null , não tenho certeza se há algum caso de uso para isso. Talvez errar nisso também.

a menos que esteja vindo de uma fonte que usa nulo para dados ausentes, por exemplo, SQL

Afaik, a filosofia do Mustache não é usar os modelos como estão, mas gerar uma 'visão' deles. Você poderia adicionar null s caso seu provedor não o faça.

Atualmente estou pensando que dados estranhos / excedentes / não utilizados não são realmente uma questão de os dados serem inválidos, é uma questão de o modelo ser inválido se não usar esses dados quando o aplicativo / dados / modelo espera que ser usado

Hmm, acho que é muito comum não usar todos os dados fornecidos. Eu lancei a ideia principalmente para as sutilezas das ferramentas, como a geração de consulta GraphQL que sugeri.

se alguma coisa realmente precisa ser exibida para o usuário, então, se o modelo não exibir, isso é um erro

Mas quem / o que decide quais "coisas realmente precisam ser exibidas para o usuário"? O escritor de modelos que estou supondo? Se você forçar as pessoas a usarem todos os dados da visualização, estará obrigando-as a gerar uma visualização personalizada para cada modelo que pretendem renderizar.

Como uma observação: meu caso de uso foi uma configuração manual sem ramificação.

Eu pedi a "outras pessoas" que criassem os dados (eventos) manualmente e, nesse caso, não tive como verificar se eles preencheram todos os campos ou cometeram erros de digitação nos nomes das variáveis.

Meu modelo diria “{{event.name}} em {{event.date}}”. Nesse caso, um valor ausente criaria uma página horrível.
Todos os campos eram obrigatórios, portanto, adicionar lógica para não exibir {{event.date}} não faria sentido.

Nesse caso, as variáveis ​​'não usadas' também seriam úteis para verificar se há erros de digitação ou itens que eles adicionaram pensando que apareceriam 'magicamente' na página :)

Tenho certeza de que esse caso de uso viola a ideologia do Bigode de alguma forma, mas é um cenário real.
E seria ótimo para ambas as situações (valores ausentes + valores não usados) gerar um aviso.

Em 9 de novembro de 2016, às 10:53, David da Silva [email protected] escreveu:

mas em outro pode esperar que os dados possam ou não estar disponíveis e ramificar se estão (neste caso, nunca é inválido).

O que eu estava tentando transmitir é que, se você ramificar dependendo da chave X (por exemplo, {{#X}}, os dados fornecidos devem ter um valor para a chave X, um valor verdadeiro ou falso, mas definitivamente não indefinido.

null significa "sim, eu sei que não há valor. Estou marcando explicitamente que não há valor".
undefined geralmente implica que a chave X nem mesmo está definida (se você definir uma chave com um valor de undefined, seria melhor usar null). E se a chave não for definida, é por ser 'preguiçoso' ao declarar os dados (por exemplo, não usar nulo quando um objeto ref está faltando) ou por causa de erro humano (erro de digitação, deslize, confusão)
Portanto, neste caso, eu veria benefícios em lançar um erro. (tentando ramificar em uma chave que tem um valor indefinido)

Por outro lado, tentando renderizar indefinido ou nulo, não tenho certeza se há algum caso de uso para isso. Talvez errar nisso também.

a menos que esteja vindo de uma fonte que usa nulo para dados ausentes, por exemplo, SQL

Afaik, a filosofia do Mustache não é usar os modelos como estão, mas gerar uma 'visão' deles. Você pode adicionar valores nulos caso seu provedor não o faça.

Atualmente estou pensando que dados estranhos / excedentes / não utilizados não são realmente uma questão de os dados serem inválidos, é uma questão de o modelo ser inválido se não usar esses dados quando o aplicativo / dados / modelo espera que ser usado

Hmm, acho que é muito comum não usar todos os dados fornecidos. Eu lancei a ideia principalmente para as sutilezas das ferramentas, como a geração de consulta GraphQL que sugeri.

se alguma coisa realmente precisa ser exibida para o usuário, então, se o modelo não exibir, isso é um erro

Mas quem / o que decide quais "coisas realmente precisam ser exibidas para o usuário"? O escritor de modelos que estou supondo? Se você forçar as pessoas a usarem todos os dados da visualização, estará obrigando-as a gerar uma visualização personalizada para cada modelo que pretendem renderizar.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub https://github.com/janl/mustache.js/issues/599#issuecomment -259374603 ou silencie o tópico https://github.com/notifications/unsubscribe-auth/ AJ8FmcFicDWYjSqibyWac-Sqjg-iFetnks5q8ZgqgaJpZM4J8lKe.

Tenho certeza de que esse caso de uso viola a ideologia do Bigode de alguma forma, mas é um cenário real. E seria ótimo para ambas as situações (valores ausentes + valores não usados) gerar um aviso.

Ambos parecem viáveis. Pode ser útil para o IC.

Eu prefiro ver o parâmetro diretamente na visualização para depuração.

Meu caso de uso é um pouco diferente: eu uso o Mustache para transformar os modelos do Terraform usando o Gulp. Uma variável ausente pode fazer com que as instâncias não inicializem corretamente, especialmente ao substituir em strings de formato livre. Eu vim com um patch de macaco rápido para obter essa funcionalidade, mas dificilmente é ideal:

var mustache = require("mustache");

var errors = [];
var lookup = mustache.Context.prototype.lookup;

mustache.Context.prototype.lookup = function(name) {
    var value = lookup.bind(this)(name);

    if (value === undefined) {
        console.error("Unknown symbol", name);
        errors.push(name);
    }

    return value;
}

var render = mustache.render;

mustache.render = function(template, view, partials) {
    var result = render.bind(this)(template, view, partials);

    if (errors.length > 0) {
        throw {message: "Unknown symbols: " + errors.join(", ")};
    }

    return result;
}

Notas:

  • Ele não fornece números de linha ou nomes de símbolos totalmente qualificados
  • Provavelmente é totalmente inseguro se você estiver trabalhando em um ambiente multithread

No entanto, funcionou bem para os meus propósitos e tenho certeza de que alguém pode adaptá-lo, se necessário.

Usar o bigode como um mecanismo de modelagem em qualquer tipo de ambiente de gerenciamento de configuração requer erros graves nas variáveis ​​ausentes. Eu tenho um caso de uso semelhante a @steverukuts , transformando documentos de implantação do kubernetes. Variáveis ​​ausentes são sempre erros neste caso de uso.

@stefaneg alguns meses depois de escrever que, na verdade, descobri que o Terraform suporta configuração escrita no formato JSON, então agora eu uso isso em vez de usar o Mustache. Isso é muito melhor e mais programável. Agora, suspendemos o uso do Mustache para isso e ele será removido na próxima revisão de nosso pipeline de implantação.

Tendo olhado a documentação de implantação do Kubernetes, vejo que esses são arquivos YAML. A maioria das linguagens de programação tem bibliotecas que podem ler e escrever YAML, então sugiro que você faça isso. Com meu experimento, aprendi que, quando você tenta manipular um formato legível por máquina, quase sempre tem uma opção melhor do que Mustache.

Observação: embora eu não use mais o Mustache para nada mais, ainda sinto que esta é uma solicitação de recurso válida.

A solução é utilizar um guiador , que suporta a mesma sintaxe, e também possui uma opção estrita que é exatamente o que é necessário neste caso de uso.

@steverukuts Você está certo sobre o formato legível por máquina de manipulação, se você tem uma manipulação predeterminada que precisa de suporte, e especialmente se você precisa ter alguma inteligência embutida nela. Para uma ferramenta de configuração aberta, isso se torna muito inflexível muito rápido, daí a necessidade de modelagem. Tente escrever uma ferramenta que suporte a inserção de valores arbitrários em lugares arbitrários e ... você terá um mecanismo de modelagem muito em breve.

No trabalho, temos usado o kontemplate para configurar os recursos do Kubernetes nos últimos anos. É basicamente o motor de templates go, com algumas funções úteis de sprig e customizadas nesse projeto. Foi feito como uma abordagem mais leve do que o leme, por exemplo.

Em relação à discussão acima; ele também explodirá em variáveis ​​desconhecidas.

A solução é utilizar um guiador , que suporta a mesma sintaxe, e também possui uma opção estrita que é exatamente o que é necessário neste caso de uso.

Esse problema me forçou a usar o guidão também. É uma pena que isso não seja compatível com bigode.

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

Questões relacionadas

rlightner picture rlightner  ·  7Comentários

kuldeepdhaka picture kuldeepdhaka  ·  9Comentários

mbrodala picture mbrodala  ·  16Comentários

Immortalin picture Immortalin  ·  12Comentários

ForbesLindesay picture ForbesLindesay  ·  14Comentários