2016-04-18 14 views
13

Im usando gulp-ramoscello: https://github.com/zimmen/gulp-twigIncludere un modello di ramoscello come oggetto da passare in un altro modello?

Ho un file ramoscello per la mia componente contenitore:

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

     {{ item }} 

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

Ho anche un file di frammento:

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

Im provare le canzoni di questi in pagina. ramoscello. Devo rendere lo snippet come {{item}} all'interno del contenitore. Così, durante la visualizzazione page.twig questo dovrebbe essere l'output:

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

Ora qui è dove ottiene ingannevole. container.twig e snippet.twig vengono estratti in un'altra applicazione. Pertanto {{item}} all'interno di container.twig non può essere cambiato in qualcosa come {{itemRenderer (item)}}.

Tuttavia, page.twig non viene utilizzato da nessun'altra parte, quindi posso modificarlo come preferisco. C'è un modo in page.twig per rendere container.twig con snippet.twig come se fosse un elemento, senza modificare container.twig o snippet.twig?

Questo è il mio compito sorso:

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 
}; 
+0

caso in cui il frammento di essere reso per tutte le voci o solo prima/dopo l'elenco degli articoli? – xabbuh

+0

Dovrebbe essere visualizzato per gli articoli, ho aggiornato la mia domanda per renderlo più chiaro. – Evans

+0

Non sono sicuro di capire il tuo problema. Hai scritto * come molti componenti diversi possono essere l'elemento all'interno del contenitore *, non puoi aggiungere un test per utilizzare questo codice solo quando necessario? –

risposta

0

non vedo come potrebbe essere possibile senza modificare container.html.twig, dal momento che si sta cercando di rendere {{ item }}, che è destinato ad essere HTML, senza il filtro raw, che è obbligatorio per segnare il contenuto di {{ item }} come HTML-safe.

Se sei il proprietario di origine container.html.twig di file (non so cosa si intende per

container.twig e snippet.twig vengono tirati in un'altra applicazione

), forse è possibile modificare {{ item }} a {{ item|raw }}. Quindi devi solo assicurarti che il parametro items passato a container.html.twig contenga HTML generato da un renderView di snippet.html.twig. Quindi fai solo attenzione. container.html.twig non viene utilizzato da qualche altra parte con HTML non sicuro items.

Se davvero non hai le mani sopra, puoi anche provare a rendere il tuo modello con a Twig environment that has autoescape disabled.

Spero che questo aiuti!

EDIT: Dal momento che si deve fare questo usando gulp-ramoscello, che dire qualcosa di simile:

var titles = ['First snippet', 'second snippet']; 
var i, items; 
for (i = 0; i < titles.length; i++) { 
    gulp.src('/path/to/snippet.html.twig') 
     .pipe(plugins.twig({ 
      data: { 
       title: titles[i] 
      } 
     })) 
     .pipe(plugins.intercept(function(file){ 
       items[i] = file.contents.toString(); 
       return file; 
     })); 
} 

gulp.src('/path/to/container.html.twig') 
    .pipe(plugins.twig({ 
      data: { 
       items: items 
      } 
     })) 
    .dest('/path/to/dest.html'); 
+0

Sto usando gulp-twig. L'altra applicazione (che usa symphony) userà i componenti in un modo diverso, quindi il suo synatax non può variare molto da quello che ho già per container.twig e snippet.twig. – Evans

+0

Puoi incollarci il tuo script gulp? – Terenoth

+0

Ive ha aggiornato la mia domanda. – Evans

5

Ciò potrebbe essere fatto 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 %} 

E poi nel modello:

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

{% container(itemRenderer, items) %} 

E in un altro modello:

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

{% container(itemRenderer, items) %} 

La stessa cosa può essere ottenuta con gli inclusi regolari, anche se entrambi offrono le stesse possibilità, penso che la soluzione macro sia più pulita.

{# 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 %} 
+0

Im paura che ho bisogno di usare include come alcuni file includeranno altri file. Ho semplificato il codice per il mio esempio ma immagino un frammento di codice necessario per includere altri componenti più piccoli. Ma forse questo non può essere fatto e la tua è la risposta più vicina. – Evans

+0

beh, i nomi dei modelli possono anche essere variabili, quindi questo può anche essere fatto con include, proverò ad aggiungere un esempio alla mia risposta. – NDM

+0

Non ho idea di cosa si voglia fare con include che non è possibile fare con la soluzione macro, si riducono alla stessa cosa, ma le macro sono più pulite. – NDM

Problemi correlati