包含一个twig模板作为要传递到另一个模板的对象?

时间:2016-04-18 14:30:33

标签: gulp twig

我正在使用gulp-twig:https://github.com/zimmen/gulp-twig

我的容器组件有一个twig文件:

{# container.twig #}
<div class="container">
  {% for item in items %}
    <div class="container__item">

      {{ item }}

    </div>
  {% endfor %}
</div>

我还有一个代码段文件:

{# snippet.twig #}
<div class="snippet">
  <h2>{{ title }}</h2>
</div>

我在page.twig中演示这些。我需要将代码段渲染为容器中的{{item}}。因此,在查看page.twig时,这应该是输出:

<div class="container">
    <div class="container__item">

      <div class="snippet">
        <h2>title</h2>
      </div>

   </div>
   <div class="container__item">

     <div class="snippet">
       <h2>title</h2>
     </div>

   </div>
   <div class="container__item">

     <div class="snippet">
       <h2>title</h2>
     </div>

   </div>
</div>

现在这里变得棘手。 container.twig和snippet.twig正被拉入另一个应用程序。因此,container.twig中的{{item}}不能更改为{{itemRenderer(item)}}。

然而,page.twig没有被其他地方使用,所以我可以编辑它,但我喜欢。在page.twig中是否有一种方法可以使用snippet.twig作为项目来呈现container.twig,而无需修改container.twig或snippet.twig?

这是我的一项任务:

var gulp    = require('gulp'),
  config    = require('../config'),
  utilities     = require('../build-utilities'),
  src       = config.path.src,
  dest      = config.path.dest,
  opts      = config.pluginOptions,
  env       = utils.getEnv(),
  plugins   = require('gulp-load-plugins')(opts.load);

var compile = function() {
  var notProdOrTest = env.deploy && !env.prod && !env.test,
    deployPath    = env.deployPath,
    sources = (env.deploy) ? ((env.styleguide) ? src.twig.styleguide: src.twig.testing): src.twig.all;
  return gulp.src(sources, {base: 'src/'})
    .pipe(plugins.twig({
      data: {
        component: utils.getDirectories('src/component/'),
        deploy    : env.deploy,
        test      : env.test,
        prod      : env.prod
      }
    }))
    .pipe(plugins.htmlmin(opts.htmlmin))
    .pipe(plugins.tap(function(file){
      file.path = file.path.replace('testing/', '');
    }))
    .pipe((notProdOrTest) ? plugins.replace(/src="\//g, 'src="/' + deployPath.root + '/'): plugins.gutil.noop())
    .pipe((notProdOrTest) ? plugins.replace(/href="\//g, 'href="/' + deployPath.root + '/'): plugins.gutil.noop())
    .pipe((notProdOrTest) ? plugins.replace(/srcset="\//g, 'srcset="/' + deployPath.root + '/'): plugins.gutil.noop())
    .pipe((notProdOrTest) ? plugins.replace(/url\('\//g, 'url(\'/' + deployPath.root + '/'): plugins.gutil.noop())
    .pipe(gulp.dest((env.deploy) ? deployPath.markup: dest.markup));
},
  watch = function() {
    gulp.watch(src.twig.watch, ['twig:compile']);
  };

module.exports = {
  compile: compile,
  watch  : watch
};

2 个答案:

答案 0 :(得分:5)

这可以完成with macros

{# macros.html.twig #}
{% macro thisItem(item) %}
    <div class="this-snippet">
        <h2>{{ item.title }}</h2>
    </div>
{% endmacro %}

{% macro thatItem(item) %}
    <div class="other-snippet">
        <h2>{{ item.title }}</h2>
    </div>
{% endmacro %}

{% macro container(itemRenderer, items) %}
    <div class="container">
        {% for item in items %}
            <div class="container__item">
                {{ itemRenderer(item) }}
            </div>
        {% endfor %}
    </div>
{% endmacro %}

然后在模板中:

{# template.html.twig #}
{% from "macros.html.twig" import thisItem as itemRenderer, container %}

{% container(itemRenderer, items) %}

在另一个模板中:

{# template2.html.twig #}
{% from "macros.html.twig" import thatItem as itemRenderer, container %}

{% container(itemRenderer, items) %}

使用常规包含可以实现同样的目的,虽然两者都提供相同的可能性,但我认为宏观解决方案更清晰。

{# snippet.html.twig #}
<div class="this-snippet">
    <h2>{{ item.title }}</h2>
</div>

{# container.html.twig #}
<div class="container">
    {% for item in items %}
        <div class="container__item">
            {% include snippetTmpl with { 'item': item } only %}
        </div>
    {% endfor %}
</div>

{# page.html.twig #}
{% include "container.html.twig" with { 'snippetTmpl': 'snippet.html.twig', 'items': items } only %}

答案 1 :(得分:0)

我没有看到如何在不修改container.html.twig的情况下实现这一目标,因为您尝试在没有{{ item }}的情况下呈现raw,这是一个HTML。过滤器,必须将{{ item }}的内容标记为HTML安全。

如果您是container.html.twig文件来源的所有者(不确定您的意思是

  

container.twig和snippet.twig被拉入另一个   应用

),也许您可​​以将{{ item }}更改为{{ item|raw }}。然后,您只需要确保传递给items的{​​{1}}参数包含由container.html.twig renderView生成的HTML。然后小心snippet.html.twig不会在其他地方使用HTML-unsafe container.html.twig

如果您真的没有动手,也可以尝试使用a Twig environment that has autoescape disabled渲染模板。

希望这有帮助!

编辑:由于您必须使用gulp-twig执行此操作,请执行以下操作:

items