Desde a versão 2.3.1, os delimitadores personalizados aparentemente não funcionam mais para Mustache.parse()
. Veja os seguintes exemplos:
Isso provavelmente está relacionado ao #663 e sua correção. Observe que posso restaurar isso usando o Mustache.tags = [...]
mais recente: https://codepen.io/mbrodala/pen/QBJoOx
Por favor, você pode dar uma olhada nisso?
Muito obrigado pelo relato @mbrodala , esses codepens são muito apreciados!
@mbrodala Obrigado pelos codepens.
Eu me pergunto se houve um mal-entendido aqui.
describe('when parsing a template with tags specified followed by the same template with different tags specified', function() {
it('returns different tokens for the latter parse', function() {
var template = "(foo)[bar]";
var parsedWithParens = Mustache.parse(template, ['(', ')']);
var parsedWithBrackets = Mustache.parse(template, ['[', ']']);
assert.notDeepEqual(parsedWithBrackets, parsedWithParens);
});
});
A função parse
estava armazenando em cache usando apenas template
como chave de cache, de modo que da próxima vez que parse
fosse usado para analisar esse modelo, ele retornaria exatamente os mesmos tokens, mesmo se os tags
especificados forem diferentes.
tags
é um parâmetro opcional e, quando omitido, volta para mustache.tags
, que por padrão é ['{{', '}}']
. O fallback mustache.tags
é usado como parte da chave de cache.
Acho que sei o que está acontecendo com relação à correção do bug e às expectativas, e tentarei orientá-lo e usarei o codepen como exemplo.
Mustache.parse(template, ['[[', ']]']);
Na versão 2.3.0, isso instrui o Mustache a analisar template
, usando ['[[', ']]']
como tags. Mustache faz isso e retorna o resultado correto, mas armazena em cache a chamada usando apenas template
. Veja as linhas 447-450 de [email protected]
:
if (tokens == null)
tokens = cache[template] = parseTemplate(template, tags);
A próxima chamada no codepen é:
var output = Mustache.render(
template,
...
render
não recebe um parâmetro tags
, então não passa um para parse
, então quando render
é chamado, parse
usa mustache.tags
como suas tags. Então, quando essa chamada render
é feita, é efetivamente um parse
, "Por favor, analise template
e implicitamente use ['{{', '}}']
como tags
." parse
realmente faz a coisa errada e faz uma pesquisa de cache ignorando completamente tags
e mustache.tags
. Acontece de retornar o resultado do template analisado com [['[', ']']]
, mas apenas porque a primeira chamada para parse
em todo o programa para aquele template
foi feita com ['[[', ']']]
como tags
.
Mustache.parse(template, ['[[', ']]']);
O resultado da análise é armazenado em cache usando template
e tags
, que é ['[[', ']]']
como cacheKey.
A próxima chamada:
var output = Mustache.render(
template,
...
render
chama parse
, passando template
mas omitindo tags
. parse
, portanto, tem tags
de volta para mustache.tags
, que continua sendo o padrão ['{{', '}}']
. parse
faz uma pesquisa de cache na chave de cache de template
e ['{{', '}}']
, e incorre em uma falha de cache, como esperado, pois parse
ainda não foi chamado com essa combinação de template
e tags. Portanto, ele analisa template
usando ['{{', '}}']
.
Eu acredito que v2.3.1 exibe o comportamento correto. Se tivéssemos que alterar o codepen em https://codepen.io/mbrodala/pen/QBJoOx ligeiramente e executá-lo na v2.3.0:
var template = "[[item.title]] [[item.value]]";
Mustache.parse(template, ['[[', ']]']);
var output = Mustache.render(
template,
{
item: {
title: "TEST",
value: 1
}
}
);
alert(output);
A saída é [[item.title]] [[item.value]]
, o que não é esperado.
Eu posso ver como o comportamento em https://codepen.io/mbrodala/pen/NBEJjX pode ser surpreendente, já que as chamadas Mustache.parse
e Mustache.render
estão uma ao lado da outra e uma pode não até perceber que Mustache.parse
até leva um argumento tags
. (Por que Mustache.parse
aceita um argumento tags
? Nunca é usado em nenhum lugar em mustache.js
-- parse
simplesmente padroniza internamente para mustache.tags
. ..)
Se a mudança de comportamento realmente desafia as expectativas de um lançamento de correção de bugs, então não sei exatamente o que fazer. Uma possibilidade é lançar outra versão de correção de bug com o #664 revertido, o que na verdade remove todo o comportamento de cache (dado que no #643, todas as pesquisas de cache serão perdidas). Poderíamos então colocar o #664 de volta na próxima grande revisão. Outra possibilidade é remover todo o cache em uma versão de correção de bug (em vez de liberar um mustache.js
com cache não funcional) e, em seguida, colocar todo o cache de volta na próxima revisão principal. A primeira opção provavelmente tem menos risco (menor quantidade de mudança de código), mas a última opção é provavelmente mais "correta". @phillipj pensamentos?
Muito obrigado pela pesquisa detalhada que faz todo o sentido do meu ponto de vista.
Eu não me importaria com a mudança, mas dado que é impossível passar tags
para Mustache.render()
para garantir um acerto de cache e que Mustache.parse()
é anunciado para armazenar em cache o template
(sem menção de tags
aqui) Gostaria de saber se isso realmente deveria ser revertido.
Se assumirmos que alguém chama Mustache.parse
com um conjunto personalizado de tags
, também podemos assumir que template
usa esses delimitadores (BTW, "tags" vs "delimiters" devem ser clareou também). Em seguida, podemos supor que uma chamada para Mustache.render
deve funcionar, não importa como e se o template
dado já está armazenado em cache e como foi compilado, se for o caso. No momento, isso não é garantido caso tags
personalizados sejam usados.
@mbrodala Sim, isso faz sentido, embora Mustache.parse(template, ['[[', ']]']);
seguido por Mustache.parse(template, ['((', '))']);
dando exatamente o mesmo resultado ainda seria inesperado.
Aqui está uma solução/compromisso de homem de palha ("homem de palha" porque eu não gosto, mas vale a pena fazer um brainstorming). Poderíamos ter parse
cache contra template
sozinho e template
com tags. Quando parse
é chamado com tags
especificado, ele faz uma pesquisa contra template
e tags
. Quando chamamos render
, que chama parse
sem tags
, fazemos uma pesquisa apenas contra template
. Pensamentos?
Parece estranho e basicamente é, mas corrigirá esse problema, mantendo a correção intacta. OK do meu ponto de vista.
@mbrodala é a questão central que você não pode passar tags
para render
? Também poderíamos adicionar um parâmetro tags
a render
.
@petrkoutnysw Esse é aproximadamente o problema que você também está enfrentando?
É pelo menos uma inconsistência entre parse()
e render()
. Nós nem usaríamos parse()
se pudéssemos passar tags personalizadas para render()
. E agora, com o cache adequado, isso se torna mais óbvio.
+1 para adicionar um parâmetro de tags a render() para eliminar muita confusão - também fomos afetados por essa mudança e o link b/w parse e render sempre pareceu um pouco mais mágico do que o necessário.
Ok, então que tal desabilitarmos o cache em uma versão de correção de bug, para corrigir o problema imediato e cumprir o versionamento semântico, e reintroduzi-lo e tags
no método render
na próxima versão principal? (Mais uma vez, não sou um grande fã da solução do espantalho que propus.)
Muito obrigado por esse passo a passo completo @raymond-lam!
Estou inclinado para o lançamento de correção de bug sugerido, principalmente por causa de preocupações e projetos em que essa mudança de comportamento é inesperada e, portanto, pode causar estragos em projetos em estado selvagem.
Reintroduzindo o comportamento de armazenamento em cache novamente na próxima versão principal planejada, podemos incluir instruções de migração nas notas da versão.
@phillipj Emiti o pull request #670 que reverte #643 e #664. Em vez de desabilitar o cache todos juntos, por uma questão de mitigação de risco, simplesmente voltar ao comportamento v2.3.0 (em uma versão de correção de bugs) parece mais seguro para dependentes do Mustache v2.xx Vou emitir outra solicitação de pull para reintroduzir em uma versão principal.
@phillipj #671 reintroduz correções de cache, para aguardar um grande lançamento.
Criou o problema #672 para abordar a adição de tags
ao `render.
Muito obrigado por investigar e consertar isso, vocês são demais. 👍
Tiramos o chapéu para @raymond-lam por este! Graças a você também, é crucial para nós sabermos quando mudanças inesperadas acontecem na natureza.
v2.3.2 foi publicado 🚀