33

Coming from a background in Django, I often use "template inheritance", where multiple templates inherit from a common base. Is there an easy way to do this in JSP? If not, is there an alternative to JSP that does this (besides Django on Jython that is :)

base template

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

basic content

{% extends "base template" %}
{% block content %}
<h1>{{ content.title }} <-- Fills in a variable</h1>
{{ content.body }} <-- Fills in another variable
{% endblock %}

Will render as follows (assuming that conten.title is "Insert Title Here", and content.body is "Insert Body Here")

<html>
  <body>
    <h1>Insert title Here <-- Fills in a variable</h1>
    Insert Body Here <-- Fills in another variable
  </body>
<html>
Ryan
  • 15,016
  • 6
  • 48
  • 50

6 Answers6

21

You can do similar things using JSP tag files. Create your own page.tag that contains the page structure. Then use a <jsp:body/> tag to insert the contents.

Ben Lings
  • 28,823
  • 13
  • 72
  • 81
  • 12
    related: [JSP tricks to make templating easier?](http://stackoverflow.com/questions/1296235/jsp-tricks-to-make-templating-easier) (tag files short tutorial) – f4lco Feb 23 '11 at 13:41
13

You can use rapid-framework for JSP template inheritance

base.jsp

%@ taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
<html>  
    <head>
        <rapid:block name="head">
            base_head_content
        </rapid:block>
    </head>  
    <body>  
        <br />  
        <rapid:block name="content">
            base_body_content
        </rapid:block>  
    </body>  
</html>

child.jsp

<%@ taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
<rapid:override name="content">  
     <div>
        <h2>Entry one</h2>
        <p>This is my first entry.</p>
    </div>
</rapid:override>  

<!-- extends from base.jsp or <jsp:include page="base.jsp"> -->  
<%@ include file="base.jsp" %> 

output

<html>
<head>  
 base_head_content
</head>  
<body>  
    <br />  
    <div>
        <h2>Entry one</h2>
        <p>This is my first entry.</p>
    </div>
</body>  
</html>

source code

http://rapid-framework.googlecode.com/svn/trunk/rapid-framework/src/rapid_framework_common/cn/org/rapid_framework/web/tags/

Tmh
  • 1,321
  • 14
  • 27
badqiu
  • 131
  • 1
  • 2
10

You'll probably want to look into Tiles.

EDIT: On a related note to tiles, you might want to look into Struts. It's not what you're looking for (that's tiles), but it is useful for someone coming from Django.

geowa4
  • 40,390
  • 17
  • 88
  • 107
  • 6
    I've never tried tiles and just skimmed the documentation, but I'm curious whether my perception is correct: it seems there's a lot of setup (config files + need to write java classes)? The great thing about Django templates is that they pretty much just work, inheritance and such are super-easy to do with just the parent template file and the child template file, no need for additional configuration. – Roy Tang Sep 09 '10 at 06:40
  • You should really try Rythm (http://rythmengine.com), it's just simple to use and has powerful features. Check my answer below or go to the website to have a taste – Gelin Luo Dec 14 '12 at 06:50
  • 1
    I am having the same problem, ie to find a suitable template framework that allows template inheritance like you describe it. Tiles does indeed have this functionality, but the "file" you call basic content above is defined in an xml file, which is a lot of hassle in my opinion. I would much rather have a separate file basiccontent.jsp rather than an "view definition" in an xml file. – Emil G Mar 13 '13 at 13:51
4

Other options worth exploring include Sitemesh, which is built on the idea of page decorators, and Java Server Faces (JSF), which employs web-based UI components. And while we're talking about rapid development with web frameworks on the Java platform, I encourage you to check out Grails. It has the same mission has Django; namely, rapid web app development based on convention over configuration.

Hope that's not too many suggestion for one post. :o)

yawmark
  • 1,934
  • 14
  • 16
3

My favorite Java web front-end tech is Facelets. It supports the most Django-like templating I've seen. It's not quite as clean as Django's, but you get the same inheritance benefits.

Instead of Django's:

Super:

{% block content %}{% endblock %}

Sub:

{% block content %}inheriting template's content here{% endblock %}

Facelet's syntax is like this:

Super:

<ui:insert name="content"></ui:insert>

Sub:

<ui:define name="content">inheriting template's content here</ui:define>
jaketrent
  • 1,173
  • 11
  • 25
1

Rythm Template engine has implemented an elegant approach for template inheritance.

So suppose your layout template (parent template) called main.html:

<h1>@get("title", "default main page")</h1>
<div id="left-panel">@render("leftPanel")<div>
<div id="right-panel">@render("rightPanel")</div>
<div id="main-content">@render()</div>
<div id="footer">
@render("footer"){
   @**
    * the content here is supplied if the child template failed 
    * to provide it's own footer implementation
    *@
   <div class="footer">copyright 2012 ...</div>
}
</div>

And here is your target template:

@extends(main)
@set(title: "My Cool Page")
@section("leftPanel") {
<ul class="menu">
...
</ul>
}

@section("rightPanel") {
<div class="news">
...
</div>
}

@*** note no "footer" section supplied so the default content will be used **@

@*** the rest is for the main content **@
...

Check the real demo at http://rythmengine.com/demo/testdefaultlayoutcontent

A comprehensive document could be found at http://www.playframework.org/modules/rythm. Though it's targeted to Play!Framework, most of the content also apply to pure rythm engine without Play!Framework.

Gelin Luo
  • 14,035
  • 27
  • 86
  • 139