Question

Normally, when a template uses inheritance, it's possible to render the contents of parent template. For example, in Twig:

{% extends "base.html" %}

{% block sidebar %}
    {{ parent() }}
    ...
{% endblock %}

It means that if I sometimes don't need the contents of parent template, I just simply remove the parent() function. How can I achieve this in Scala template?

Was it helpful?

Solution

You can create a HTML block in child view first and then pass it to parent (layout):

@sidebar = {
    <div>MySidebar</div>
}

@parent(sidebar){
    <div>Main content of the child view</div>
}

So in parent.scala.html layout you will use it just like

@(sidebar: Html = null)(content: Html)

<div id="parent-wrap">
    @sidebar
    @content
</div>

Of course if you gonna to use the same HTML code for many subpages you'll do better if you use a tag instead of declaring @sidebar block in each view. Remember that tag is nothing more then just a scala view (template) and you can include it as any other view. Just create a normal view in app/views/tags i.e.: sidebar.scala.html with required HTML block, so you can later use it somewhere like:

<div class="span3">@tags.sidebar("content to pass")</div>

or as a block passed to higher level layout, etc :

@parent(tags.sidebar(additionalContent)){
    <div>Main content of the child view</div>
}

TBH I never knew what's the difference between including views and tags ;)

OTHER TIPS

Well, views are just functions in play. You cannot inherit them, but you can easily define reusable blocks:

@parent() = {
    ...
}

And then reuse it anywhere:

<div ....sidebar>
  @parent()
</div>

The working example would look like this:

base.scala.html

@(title: String)(content: Html)
<html>
    <head><title>@title</title></head>
    <body>
        <div class=...>@content</div>
    </body>
</html>

index.scala.html

@(someParam: String)

@base("index") {
    <h1>@someParam</h1>
}

If you don't need your index page to share the base's behaviour - just don't use @base:

index.scala.html

@(someParam: String)

...some other content
@someParam
...more content

Like this:

parent.scala.html

@(title: String)(content: (() => Html) => Html) {
<div class="parent">
  <h2>@title</h2>
  @content { () =>
    <p>This is the parents optional contribution to the sidebar.</p>
  }
</div>

child.scala.html

@parent("Some title") { parentSidebar =>
  <p>Blah blah blah.</p>
  <div class="sidebar">
    ...
    @parentSidebar()
  </div>
}

So the parent takes a function that takes a function that returns HTML.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top