Двойное наследование шаблонов Freemarker (потомок расширяет родительский, расширяет дедушку и бабушку)

Как в Freemarker создать шаблон, унаследованный от шаблона, который наследует сам?

Одиночное наследование отлично работает с <#nested> тег:

Файл :

      <#macro layout>
<html lang="en">
  <head>...</head>
  <body>
    <div>... (navigation bar)</div>
    <div class="container">
      <#nested>
    </div>
  </body>
</html>
</#macro>

Файл :

      <#import "base.ftl" as base>

<@base.layout>
  <div class="row">
    <div class="col-md-9">
      ${content.body}
    </div>
    <div class="col-md-3">
       <p>Latest releases</p>
       <ul>....</ul>
    </div>
  </div>
</@base.layout>

Как превратить это в двойное наследование, когда useCaseBase.ftl расширяет normalBase.ftl который расширяет base.ftl?

2 ответа

я пытался реализоватьextendsиblockкак Джинджа2.

extends.ftlдля определения макросов.

      <#if !blocks??>
    <#assign blocks = {} />
</#if>

<#macro extends ftl>
    <#nested />
    <#include ftl />
</#macro>

<#macro replace name>
    <#local value>
        <#nested />
    </#local>
    <#assign blocks += {name: value} />
</#macro>

<#macro block name>
    <#if blocks[name]??>
        <!-- replaced ${name} -->
        ${blocks[name]}
    <#else>
        <!-- default ${name} -->
        <#nested />
    </#if>
</#macro>

base.ftlдля макета

      <#import "extends.ftl" as layout />

<!DOCTYPE html>
<html>
<head>
    <title>A demo of FreeMarker extends directive</title>
</head>
<body>
<@layout.block "message">
    This is default message in base.ftl
</@layout.block>
</body>
</html>

окончательно,index.ftlтак:

      <#import "extends.ftl" as layout />

<@layout.extends "base.ftl">
    <@layout.replace "message">
        This is the message from index.ftl
    </@layout.replace>
</@layout.extends>

Взгляните на https://github.com/emesday/freemarker-extends .

Это работает как шарм:

Файл base.ftl:

      <#macro layout>
<html lang="en">
  <head>...</head>
  <body>
    ... // Shared navigation bar
    <div class="container">
      <#nested>
    </div>
    ... // Shared footer
  </body>
</html>
</#macro>

<@layout>
  ${content.body}
</@layout>

Файл normalBase.ftl:

      <#import "base.ftl" as parent>

<#macro layout>
    <@parent.layout>
        <div class="row">
            <div class="col-md-9">
                <#nested>
            </div>
            <div class="col-md-3">
                ... // Shared sidebar
            </div>
        </div>
    </@parent.layout>
</#macro>

<@layout>
    ${content.body}
</@layout>

Файл useCaseBase.ftl:

      <#import "normalBase.ftl" as parent>

<@parent.layout>
    ${content.body}
    ... // Shared content between all use case pages
</@parent.layout>

Теперь я могу творить *.adoc страницы с jbake-type установить либо base, normalBase или же useCaseBase и это работает.

Другие вопросы по тегам