Mustache.js: Возврат имен переменных шаблона

Созданный на 31 дек. 2015  ·  12Комментарии  ·  Источник: janl/mustache.js

Привет! Это довольно странный запрос, но можно ли вернуть список входных переменных в виде массива строк или в виде объекта? Для функции генерации кода в моем коде мне нужно отобразить ряд входных данных в
строка с шаблоном усов. Входные переменные называются точно так же, как и переменные шаблона, и будут идеально отображать/отображать их, и потому что это нужно делать автоматически, отсюда и странный запрос. Вот пример того, что я имею в виду:

Предполагая функцию Mustache.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}})

Я думал об этом больше часа, и я до сих пор не могу найти лучший способ сделать это. Был бы очень признателен, если бы вы могли предложить какие-то альтернативные методы и т.д.

Самый полезный комментарий

Простое решение для получения только верхнего уровня:

Mustache.parse(template).filter(function(v) { return v[0] === 'name' || v[0] === '#' || v[0] === '&' } ).map (функция (v) { return v [1]; });

Все 12 Комментарий

Если я правильно вас понимаю, вы хотите что-то вроде этого

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

Это предполагает, что VariableNames пошла и вернула все имена переменных из шаблона. Если это то, что вы хотите, то вы, вероятно, могли бы взломать реализацию, используя открытую функцию parse в писателе усов.

Вот некоторый код, чтобы вы начали:

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"]

Обратите внимание, что, хотя можно реализовать наивную версию этого, нет способа однозначно извлечь все имена тегов, потому что такие вещи, как это:

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

… может означать либо {foo: {bar: 'baz'}} _или_ {foo: true, bar: 'baz'}} .

@bobthecow совершенно прав в данном случае. В примере, который я привел, будут только извлечены все узлы идентификатора, а также удалена вся структура, эффективно сглаживающая дерево.

@Romanx @bobthecow спасибо за помощь!

Без проблем. Удачи :)

У меня был аналогичный запрос, но мне нужно было пройтись по дереву, чтобы найти все имена переменных. Думал, что поделюсь решением, которое я использовал, если кому-то нужна ссылка.

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 это тоже страдает от проблемы двусмысленности?

Ага. Это заложено в спецификации языка.

Проблема двусмысленности интересна, в документах упоминается, что он попытается найти значение в этом контексте, а затем искать контекст родителя, если значения не найдены. Небольшое расследование привело меня к следующему:

{{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

Пример очень надуманный, и для краткости используется множество уловок, но он должен показать, насколько сложно заново изобретать велосипед. Ваше здоровье

@Immortalin Можете ли вы уточнить / дать лучшее определение проблемы? Что происходит со свойствами, вложенными в объекты? Можете ли вы предоставить более полный ввод и вывод?

@dasilvacontin проект, которому требуется эта функция, в настоящее время находится в паузе, поэтому я собираюсь закрыть его на данный момент.

Простое решение для получения только верхнего уровня:

Mustache.parse(template).filter(function(v) { return v[0] === 'name' || v[0] === '#' || v[0] === '&' } ).map (функция (v) { return v [1]; });

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

amper5and picture amper5and  ·  5Комментарии

ForbesLindesay picture ForbesLindesay  ·  14Комментарии

MatthijsZw picture MatthijsZw  ·  18Комментарии

chlab picture chlab  ·  11Комментарии

SmasherHell picture SmasherHell  ·  18Комментарии