个性化阅读
专注于IT技术分析

如何在没有双花括号冲突的情况下使用Angular.js和Twig

点击下载

本文概述

Twig和Angular.js使用相同的符号来控制其呈现结构:{{和}}, 对于使用Twig作为默认后端模板引擎的代码来说, 这是不好的。

虽然, 也许有些开发人员没有这个问题, 他们会考虑:如果你应该使用后端渲染模板, 为什么要使用angular进行渲染, 为什么会出现此问题呢?

问题本身在于, 将始终处理要打印的Twig变量或指令, 并且未经Twig处理就没有{{或}}, 这基本上是由于角度引起的错误。如果你开始只在Twig文件中写入angular:

<body ng-app="myApp" ng-controller="myCtrl">
{#
Note that {{x}} is not Twig but AngularJS
#}
<h1>{{label}}</h1>

<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
    $scope.label = "Hello world";
});
</script>
</body>

Twig将解析这些符号的方式不是Tangle(纯HTML), 而是Twig, 因此错误消息是label变量不存在。

幸运的是, 有很多方法可以解决此问题。

Twig可能的解决方案

解决此问题的最可靠方法是使用”树枝方式”进行制作, 因为可以使用许多选项。

更改渲染符号

Twig允许对块定界符进行一些语法自定义。不建议使用此功能, 因为模板将与你的自定义语法绑定在一起。但是对于特定项目, 可以更改默认值。要更改块定界符, 你需要创建自己的词法分析器对象:

<?php

$twig = new Twig_Environment();

$lexer = new Twig_Lexer($twig, array(
    'tag_comment'   => array('[#', '#]'), 'tag_block'     => array('[%', '%]'), 'tag_variable'  => array('[[', ']]'), 'interpolation' => array('#[', ']'), ));
$twig->setLexer($lexer);

但是, 如果更改词法定界符({{和}}), 则不建议这样做, 因为更改它们会禁止你使用共享捆绑软件提供的任何模板(包括TwigBundle本身提供的异常模板)和第三方Twig库。在此处阅读有关Lexer的更多信息。

防止树枝处理块

逐字标记将部分标记为不应解析的原始文本。该标签非常方便, 因为你无需修改​​角度工作样式, 即:

<body ng-app="myApp" ng-controller="myCtrl">

{#
  If you don't use verbatim in the following line
  Twig will crash as "x" doesn't exists.
  To solve it wrap in a verbatim tag.
#}

{% verbatim %}
<h1 ng-repeat="x in records">{{x}}</h1>
{% endverbatim %}

<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
    $scope.records = [
        "Alfreds Futterkiste", "Berglunds snabbköp", "Centro comercial Moctezuma", "Ernst Handel", ]
});
</script>

</body>

注意:在较早版本的twig中, 此标签命名为raw, 但已重命名以避免与raw过滤器混淆。

你可以在下面的树枝小提琴中看到逐字标记工作:

将你的角度模板写为字符串

只需将Angular模板包含在Twig字符串中即可。

<h1 ng-repeat="x in records">{{'{{x}}'}}</h1>
{#
    The output will be :
    <h1 ng-repeat="x in records">{{x}}</h1>
#}

{# Or mix with twig variables #}

{%set aTwigVariable = "x" %}
<h1 ng-repeat="x in records">{{'{{' ~ aTwigVariable ~ '}}'}}</h1>
{#
    The output will be :
    <h1 ng-repeat="x in records">{{x}}</h1>
#}

尽管它修改了你的编码方式, 但此解决方案非常简单, 但是功能强大。

警告:你应该使用单引号而不是双引号。双引号启用Twig的字符串插值, 因此你必须更加小心内容, 尤其是在使用表达式时。

创建一个自动添加符号的Twig函数

不必自己编写花括号, 而是创建一个为你执行的Twig函数, 这样就不会为Twig处理花括号。

根据你使用Twig的方式, 你可能需要阅读Symfony文档或Twig官方文档。

基本上, 函数看起来像:

<?php 
public function angularParse($string = ""){
    return "{{".$string."}}";
}

并将其注册到你的扩展类中:

<?php 
public function getFunctions()
{
    return array(
        new \Twig_SimpleFunction('angularParse', array($this, 'angularParse')), );
}

注意:显然再简单不过了。你可以添加更多东西来替换符号(如果已附加符号)。

最后在树枝上使用它:

<h1 ng-repeat="x in records">{{angularParse('x')}}</h1>
{#
    The output will be :
    <h1 ng-repeat="x in records">{{x}}</h1>
#}

Angular的可能解决方案

与树枝相反, Angular没有太多选择来解决你的问题。

更改渲染符号

Angular允许你更改视图中渲染插值提供程序的方式来渲染角度变量。

尽管有时会使用此功能来混合不同的标记语言, 例如将Angular模板包装在Python Jinja模板(或任何其他模板语言, 如Twig)中。混合模板语言非常危险。嵌入模板语言将无法安全地转出Angular表达式, 因此模板中任何用户控制的值都将导致跨站点脚本(XSS)安全错误。

要更改插值提供程序, 请使用以下代码段:

angular.module('myApp', []).config(function($interpolateProvider){
    $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});

在此处阅读有关Angular文档的更多关于interpolateProvider的信息。

如果你知道一次使用Angular和Twig的另一种方法, 请在评论框中与社区共享。

玩得开心

赞(0)
未经允许不得转载:srcmini » 如何在没有双花括号冲突的情况下使用Angular.js和Twig

评论 抢沙发

评论前必须登录!