Mustache.js: Renvoi des noms de variable de modèle

Créé le 31 déc. 2015  ·  12Commentaires  ·  Source: janl/mustache.js

Salut! C'est une requête plutôt bizarre mais y a-t-il de toute façon pour retourner la liste des variables d'entrée sous forme de tableau de chaîne ou d'objet ? Pour une fonction de génération de code dans mon code, j'ai besoin de mapper une série d'entrées dans
une ficelle en forme de moustache. Les variables d'entrée sont nommées exactement de la même manière que les variables de modèle et leur seront parfaitement ombrées/mappées et parce que cela doit être fait automatiquement, d'où l'étrange requête. Voici un exemple de ce que je veux dire :

Assumer une fonction Moustache.getTemplateVariablesListAsObject

var pycode = <see below>
Blockly.JavaScript['math_foo'] = function(block) {
  var value_name = Blockly.JavaScript.valueToCode(block, 'NAME', Blockly.JavaScript.ORDER_ATOMIC);
// result would be something like: {value_name: value_name}
var inputList =  Mustache.getTemplateVariablesListAsObject(pycode)

  var code = Mustache.render(pycode,  inputList)
  return code;
};
def hello(foo):
  print foo
hello({{value_name}})

J'y ai réfléchi pendant plus d'une heure et je ne trouve toujours pas de meilleure façon de le faire. Je serais vraiment reconnaissant si vous pouviez proposer des méthodes alternatives, etc.

Commentaire le plus utile

Solution simple pour obtenir uniquement le niveau supérieur :

Moustache.parse(template).filter(function(v) { return v[0] === 'nom' || v[0] === '#' || v[0] === '&' } ).map(fonction(v) { retourner v[1]; });

Tous les 12 commentaires

Si je vous comprends bien, vous voulez quelque chose comme ça

var myTemplate = "{{foo}} is {{bar}}";
var variableNames = Mustache.VariableNames(myTemplate) // ['foo', 'bar']

Cela suppose que VariableNames est allé et a renvoyé tous les noms de variables du modèle. Si c'est ce que vous voulez, vous pourriez probablement pirater une implémentation en utilisant la fonction exposée parse sur l'écrivain moustache.

Voici un code pour vous aider à démarrer :

var results = Mustache.parse('{{foo}} is {{bar}}')
                       .filter(function(v) { return v[0] === 'name' })
                       .map(function(v) { return v[1]; });

console.log(results) // ["foo", "bar"]

Notez que bien qu'il soit possible d'implémenter une version naïve de ceci, il n'y a aucun moyen d'extraire sans ambiguïté tous les noms de balises, car des choses comme ceci :

{{# foo }}
  * {{ bar }}
{{/ foo }}

… pourrait signifier soit {foo: {bar: 'baz'}} _ou_ {foo: true, bar: 'baz'}} .

@bobthecow a entièrement raison dans cette circonstance. L'exemple que j'ai donné ne ferait que retirer tous les nœuds d'identification, il supprimerait également toute structure aplatissant efficacement l'arbre.

@Romanx @bobthecow merci pour votre aide !

Aucun problème. Bonne chance :)

J'ai eu une demande similaire, mais j'avais besoin de parcourir l'arborescence pour trouver tous les noms de variables. Je pensais partager la solution que j'ai utilisée si quelqu'un avait besoin d'une référence.

var parseTree = Mustache.parse('{{#foo}}{{bar}}{{/foo}} {{baz}}');
var variableList = parseTree.reduce(function flattenVariablesFromParseTree(acc, v){
                    if(v[0] === 'name'){
                      return acc.concat([v]);
                    } else if (v[0] === '#') {
                      return acc.concat(v[4].reduce(flattenVariablesFromParseTree, []));
                    } else {
                      return acc;
                    }
                  }, [])
                  .map(function(v){ return v[1]; });
//variableList: ["bar", "baz"]

@nicluo souffre -t-il également du problème d'ambiguïté ?

Ouais. C'est inhérent à la spécification du langage.

Le problème d'ambiguïté est intéressant, la documentation mentionne qu'il essaierait de trouver la valeur dans ce contexte, puis rechercherait le contexte du parent si aucune valeur n'est trouvée. Une petite enquête m'a amené à ça :

{{bar}} 
{{#foo}}
  {{bar}} 
  {{#foo}}
    {{bar}} 
    {{#baz}}
      {{no}} 
      {{yes}}
    {{/baz}}
  {{/foo}}
{{/foo}}

var renderString = '{{bar}} {{#foo}}{{bar}} {{#foo}}{{bar}} {{#baz}}{{no}} {{yes}}{{/baz}}{{/foo}}{{/foo}}';
var renderContext = new Mustache.Context({
  bar: 'bar',
  baz: {
    no: 'no'
  },
  foo: {
    bar: 'y',
    foo: {
      bar: 'z',
      yes: 'yes'
    }
  }});

var parseTree = Mustache.parse(renderString);
var variableRefList = [];
var variableNameList = parseTree.reduce(function flattenVariablesFromParseTree(acc, v){
                    // Skip non-name or non-# tags
                    if(v[0] !== 'name' && v[0] !== '#'){
                      return acc;
                    }

                    var paths = [v[1]].concat(this.parents.slice(0).map(function(e){
                      return [e, v[1]].join('.');
                    }));

                    // Pops available context until a value is found
                    var path;
                    while(path = paths.pop()){
                      if(renderContext.lookup(path)){
                        //push to advanced list
                        variableRefList.push(path);
                        contextFound = true;
                        break;
                      }
                    }

                    if(v[0] === 'name'){
                      return acc.concat([v]);
                    } else if (v[0] === '#')  {
                      if(typeof renderContext.lookup(path) === 'object'){
                        this.parents = this.parents.concat([path]);
                      }

                      return acc.concat(v[4].reduce(
                        flattenVariablesFromParseTree.bind({
                          parents: this.parents
                        }), []));
                    }
                  }.bind({parents: []}), [])
                  .map(function(v){ return v[1]; });

//variableNameList: ["bar", "bar", "bar", "no", "yes"]
//variableRefList: ["bar", "foo", "foo.bar", "foo.foo", "foo.foo.bar", "baz", "baz.no", "foo.foo.yes"]
//Mustache.render(renderString, renderContext): bar y z no yes

L'exemple est très artificiel et il existe de nombreuses astuces pour rester concis, mais il devrait montrer à quel point je trouve difficile de réinventer la roue. Acclamations

@Immortalin Pouvez-vous élaborer / fournir une meilleure définition du problème ? Que se passe-t-il avec les propriétés imbriquées dans des objets ? Pouvez-vous fournir une entrée et une sortie plus complètes ?

@dasilvacontin le projet qui nécessite cette fonctionnalité est actuellement en pause donc je vais le fermer pour le moment

Solution simple pour obtenir uniquement le niveau supérieur :

Moustache.parse(template).filter(function(v) { return v[0] === 'nom' || v[0] === '#' || v[0] === '&' } ).map(fonction(v) { retourner v[1]; });

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

zekth picture zekth  ·  18Commentaires

funston picture funston  ·  7Commentaires

barbalex picture barbalex  ·  5Commentaires

connor11528 picture connor11528  ·  3Commentaires

MatthijsZw picture MatthijsZw  ·  18Commentaires