Двойное наследование шаблонов 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
и это работает.