Mustache.js: 返回模板变量名

创建于 2015-12-31  ·  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(function(v) { return v[1]; });

所有12条评论

如果我对你的理解正确,你想要这样的东西

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

假设VariableNames从模板返回所有变量名。 如果这就是你想要的,那么你可能会使用 mustache writer 上暴露的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'}} _or_ {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(function(v) { return v[1]; });

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

zekth picture zekth  ·  18评论

connor11528 picture connor11528  ·  3评论

barbalex picture barbalex  ·  5评论

ForbesLindesay picture ForbesLindesay  ·  14评论

MatthijsZw picture MatthijsZw  ·  18评论