Кузнечный шаблон шаблона

Можно ли использовать шаблоны, которые расширяют друг друга?

Скажем, у меня есть эти файлы:

base.html:

<html><head>...<head><body>{{{ contents }}}</body></html>

threeColumns.html:

---
layout: base.html
---
<div class="three-cols-row">
   <div class="first col">
      {{> nav}}
   </div>
   <div class="second col">
       {{{ contents }}}
   </div>
   <div class="third col">
      {{> aside}}
   </div>
</div>

somePost.html:

---
layout: threeColumns.html
---

My awesome blogbost

Желаемый результат:

<html><head>...<head>
    <body>
        <div class="three-cols-row">
           <div class="first col">
              NAV CONTENT
           </div>
            <div class="second col">
               My awesome blogbost
           </div>
           <div class="third col">
              ASIDE CONTENT
           </div>
        </div>
    </body>
</html>

Я использую макеты Metalsmith.


person Ali Ok    schedule 09.03.2016    source источник


Ответы (2)


Это так, но не совсем так, как вы хотите.

Metalsmith-layouts предназначен для использования в качестве прокладки для наследования шаблонов для языков, которые не изначально поддерживают его, как руль. Чтобы сделать это возможным, он анализирует файлы, которые вы ему передаете, в данном случае somePost.html, и ищет ключ layout во вступительной части. После этого он обрабатывает выбранный макет threeColumns.html, передавая somePost.html в threeColumns.html в качестве переменной contents.

В этот момент файл обрабатывается выбранным вами движком посредством консолидации. Таким образом, ключ layout, характерный для metalsmith-layouts, больше не работает в threeColumns.html, потому что не обрабатывается metalsmith-layouts. На данный момент файл обрабатывается с помощью консолидации.

Что вы можете сделать, так это использовать язык, изначально поддерживающий наследование шаблонов, например swig. Тогда вы можете сделать:

build.js

/**
 * Dependencies
 */
var filenames = require('metalsmith-filenames');
var layouts = require('metalsmith-layouts');
var metalsmith = require('metalsmith');

/**
 * Build
 */
metalsmith(__dirname)
  .use(filenames()) // Necessary for extends and includes
  .use(layouts('swig'))

  .build(function(err){
    if (err) throw err;
  });

src/somePost.swig

---
layout: threeColumns.swig
---
<p>My awesome blogpost</p>

layouts/threeColumns.swig

{% extends "base.swig" %}

{% block body %}
<div class="three-cols-row">
   <div class="first col">
      {% include "nav.swig" %}
   </div>
   <div class="second col">
       {{ contents | safe }}
   </div>
   <div class="third col">
      {% include "aside.swig" %}
   </div>
</div>
{% endblock %}

layouts/base.swig

<html>
  <head><head>
  <body>
    {% block body %}{% endblock %}
  </body>
</html>

layouts/nav.swig

<nav>Navigation</nav>

layouts/aside.swig

<aside>Aside content</aside>

Если вы затем запустите node build.js из командной строки, он превратит его в одну страницу.

person Community    schedule 10.03.2016
comment
Что ж, я отказался от SWIG, но приму этот ответ в качестве справочного материала для других людей. - person Ali Ok; 16.03.2016
comment
@AliOk Я понимаю. Кстати, вам не обязательно использовать swig, подойдет любой язык, изначально поддерживающий наследование шаблонов. - person ; 17.03.2016

Похоже, вы используете Handlebars в качестве механизма шаблонов для работы с металлами. Это означает, что вам нужно будет зарегистрировать свои части.

Что-то вроде:

var contents = fs.readFileSync(__dirname + "/templates/partials/" + fileName).toString();
Handlebars.registerPartial(partialTemplateName, contents);

Вероятно, у вас будет несколько частичных файлов, поэтому вы можете использовать fs.readdirSync('templates/partials'); для получения всех файлов, а затем заключить это в цикл для каждого файла.

person James Khoury    schedule 10.03.2016