0

ChromeアプリでjQuery.Templateを使用していますが、数日前にChromeがChromeブラウザとChromeウェブストアを更新manifest_version:1したため、拡張機能をウェブストアで公開したい場合は使用できません。デスクトップからのインストールアプリも無効になっています。だから私は使用しなければなりませんが、jQuery.Templatesで使用されたmanifest_version:2いくつかの問題があります。script-src 'unsafe-eval'

したがって、ディレクティブunsafe-evalは許可されていません。script-src

どのJavaScriptテンプレートエンジンを使用できるかについての提案はありますか?

テンプレートエンジンから必要なもの:

  • 使用法はありませnew Function()eval()
  • jQuery.Templatesのような単純なデータアクセス:${my_variable}
  • インラインロジック:{{if a==b}} ... {{else b == c}} ... {{/if}}
  • 変数に値を設定している可能性がありますが、必ずしもそうとは限りません。${my_variable = 123, ''}
  • プラグインのようなものでなければなりません(フレームワークではなく、アプリを書き直しません)。

注:いいえ、サンドボックス化されたページは使用しません。非常に醜い解決策だと思います。

Upd:回答ありがとうございます。メインのテンプレートエンジンとしてHandlebars.jsを選択しました

4

3 に答える 3

0

テンプレートシステムが必要で、マニフェストバージョン2で動作するものを探して、これを見つけました...
http://code.google.com/p/json-template/wiki/Reference
...どこにもありませんコードはevalを使用しますか。残念ながら、私はそれを完全に使用する方法を理解するのが少し難しいと感じており、それを自分で見始めたばかりなので、私の次のコメントは完全に真実ではないかもしれません。
私はJQueryを使用していないので、実際に比較することはできませんが、ほとんどの場合、JQueryは必要なことを実行できると思います。
jqueryのようなスクリプトタグを使用したインラインコードは実行しませんが、実行は非常に簡単です。インラインテンプレートを使用できるように、これをかなりすばやく作成しました。

jsontemplate.inlineSCRIPT = function(source,templateoptions) {
    var templates = source.querySelectorAll('script[type="text/json-template"]');
    for (var i = 0; i < templates.length; i++) {

        var template = templates[i];

        var options = JSON.parse(template.getAttribute('options'));

        if (!options.object) continue;

        var sourceObjectBits = options.object.split('.');

        var sourceObject = window[sourceObjectBits[0]];

        for (var i = 1; i < sourceObjectBits.length; i++) {
            if (!sourceObject[sourceObjectBits[i]]) break;
            sourceObject = sourceObject[sourceObjectBits[i]];
        }

        if (i != sourceObjectBits.length) continue;

        var target;
        if (options.target) {
            options.target == 'self' ? target = template : target = document.querySelector(options.target);
        } else {
            target = template;
        }

        if (!target) continue;

        if (options.innerOuter) {
            options.innerOuter == 'inner' ? target.innerHTML = jsontemplate.expand(template.innerHTML, sourceObject,templateoptions) : target.outerHTML = jsontemplate.expand(template.innerHTML, sourceObject,templateoptions);
        } else {
            target.outerHTML = jsontemplate.expand(template.innerHTML, sourceObject,templateoptions);
        }
    }
}

....そして私のhtmlで私は持つことができます...

<script type='text/json-template' options='{"object":"a.b.details"}'>
    {# This is a comment and will be removed from the output.}
    {.section songs}
      {.repeated section @}
        {.if equals test title}
          test equaled title
        {.end}
      {.end}
    {.or}
    <p><em>(No page content matches)</em></p>
    {.end}
</script>

テンプレートにはいくつかの条件がありますが、変数= trueの場合のように、かなり基本的なものです。しかし、変数が変数と等しい場合、これを行うための何も見つかりませんでした。カスタム述語を使用してそれらを追加することもできますが、jsontemplateのソースを変更せずに、引数を使用して述語を追加する方法を理解していません。述語を追加すると、必要な条件に対応できるはずですが、テンプレートの構文は見栄えがよくありません。if equalsを追加すると、テンプレートのソースは次のようになります。

{.if equals test title}
  test equaled title
{.end}

...つまり、変数testの値がtitleの値と等しい場合は、このブロックを実行し、orブロックとelseのifをさらに使用できます。jsontemplateのソースを変更せずに追加する方法はわかりませんが、その方法は次のとおりです
。関数function _Pluralize(value, unused_context, args) {行76の後に、次のような別の関数を追加します。

// Are two variables equal, gotta add the error checking
function _Mine(value, context, args) {
  var s, p;
  switch (args.length) {
    case 0:
      s = value;
      break;
    case 1:
       s = context.get(args[0]);
      break;
    case 2:
      s = context.get(args[0])==context.get(args[1]);
      break;
    default:
      // Should have been checked at compile time
      throw {
        name: 'EvaluationError', message: 'pluralize got too many args'
      };
  }
  return s;
}

..次に、コンパイル関数function _Compile(template_str, options) {でその行(関数宣言のすぐ下)を探し、次のvar default_predicates = PrefixRegistry([ように追加します。

  // default predicates with arguments
  var default_predicates = PrefixRegistry([
    {name: 'equals', func: _Mine},
    {name: 'test', func: _TestAttribute}
      ]);

...述語を使用して変数を設定することもできると確信していますが、それは試していません。とにかく、間違いなく一見の価値があります。

于 2012-08-02T17:39:27.397 に答える
0

詳細な回答に感謝しますが、Handlebars.jsというよりエレガントな解決策を見つけました。

テンプレート用のプリコンパイルエンジンがあり、プリコンパイルされたテンプレートを使用する場合は使用しませんeval()。非常に単純なインラインロジック(変数のtrueまたはfalseを確認できます)がありますが、非常に高速です。=)比較のために試してみてください。一瞬:プリコンパイルにNodeJSを使用します。必要ない場合は、を使用してHandlebars.compile()ください。

注:manifest_version: 2事前コンパイルを使用する必要があります。使用しようとするとHandlebars.compile()、CSP違反に関するエラーが発生します。

NodeJSをインストールしている場合は、を使用してそのプリコンパイルエンジンを試すことができますnpm install handlebars -g。FSの任意のプロジェクトで-g使用できます。handlebarsこのコマンドをsudoする必要があるかもしれません。次に、端末をリロードし、テンプレートファイルで構成されるフォルダにCDを挿入します。

.handlebarsそれらをHandlebars.js構文に移行し、各ファイルに拡張子を追加する必要があります。次に実行しますhandlebars path/to/templates/*.handlebars -f js/templates.js

Handlebars.jsの後にこのjsファイルをロードすると、コンパイルされたテンプレートがここにあります。

Handlebars.templates[your_template_file_name]

例えば:

my_template.handlebars

<div>{{testing_template}}</div>

main.js

// example with RequreJS
require(["handlebars", "templates"], function(){
    var template = Handlebars.templates.my_template,
        rendered = template({
            "testing_template" : "some text right here"
        });

    console.log(rendered);
});

コンソールでは、次のように表示されます。

> "<div>some text right here</div>"

Handlebars.jsは、ループとカスタムヘルパーだけでなく、単純{{#if}}{{#unless}}ブロックもサポートします。{{#each}}私が思うに非常に強力です。

于 2012-08-03T03:31:26.700 に答える
0

私はこれについていくつかの調査を行いました。私にとって最も簡単な方法は、jQueryテンプレートの機能を置き換えるいくつかのカスタム関数を作成することでした。

于 2012-08-09T08:42:46.060 に答える