Search code examples
freemarkerjbake

Freemarker templates double inheritence (child extends parent extends grandparent)


In Freemarker, how can I create a template that inherits from a template that itself inherits?

Single inheritance works fine with the <#nested> tag:

File base.ftl:

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

File normalBase.ftl:

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

How do I turn this into double inheritance where useCaseBase.ftl extends normalBase.ftl which extends base.ftl?


Solution

  • This works like a charm:

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

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

    File useCaseBase.ftl:

    <#import "normalBase.ftl" as parent>
    
    <@parent.layout>
        ${content.body}
        ... // Shared content between all use case pages
    </@parent.layout>
    

    Now I can create *.adoc pages with jbake-type set to either base, normalBase or useCaseBase and it works.