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}})

私はこれについて1時間以上考えてきましたが、それでもこれを行うためのより良い方法を見つけることができません。 あなたがいくつかの代替方法などを提供することができれば本当にありがたいです。

最も参考になるコメント

トップレベルを取得するための簡単なソリューション:

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がテンプレートからすべての変数名を返したと仮定しています。 それが必要な場合は、口ひげライターで公開されている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(function(v){return v [1];});

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

kuldeepdhaka picture kuldeepdhaka  ·  9コメント

barbalex picture barbalex  ·  5コメント

ForbesLindesay picture ForbesLindesay  ·  14コメント

amper5and picture amper5and  ·  5コメント

SmasherHell picture SmasherHell  ·  18コメント