Joel Regen wrote:

> David,
> Wouldn't it make sense to introduce a few attributes to the template tags
> that allow specification of values using references to beans?  This idea is
> used extensively in the other struts tags.  Look at the html:link tag, for
> example.  It allows you to specify a bean that contains a property that can
> be used as the value for a named request parameter.  This kind of
> parameterization is fairly powerful.

Indeed.

> With these attributes in place you can leverage the use of the controller
> actions (in an MVC architecture) to setup one or more 'template specifiers'
> in session or request context and redirect to the JSP that contains the
> template tags.  It alleviates the need for extensive use of logic: tags.
> yes?

Absolutely. Thanks to Joel for pointing this out! I found his email so
inspiring that I took a crack at this in my local build. Here's how it works:

Currently, you use templates like this: (this is from the struts-template
example)

<%@ taglib uri='/WEB-INF/tlds/struts-template.tld' prefix='template' %>

<template:insert template='/chapterTemplate.jsp'>
  <template:put name='title' content='Templates' direct='true'/>
  <template:put name='header' content='/header.html' />
  <template:put name='sidebar' content='/sidebar.jsp' />
  <template:put name='content' content='/introduction.html'/>
  <template:put name='footer' content='/footer.html' />
</template:insert>

Collectively, template:put tags within a template:insert tag define a screen,
which is equivalent to a single Web page. Each screen contains regions; for
example, there are five regions in the code fragment above: title, header,
sidebar, content, and footer. Those regions, identified by the name attribute,
either include content or print it directly, depending upon the direct
attribute.

The template:put tag stores its three attributes--name, content, and direct--in
an instance of ScreenDefinition. That class is a simple façade for a hash
table. (See org.apache.struts.taglib.template.util.ScreenDefinition).

I've added a new template tag** that lets you specify that screen definition
directly. Here's how you use it:

<%@ page import='org.apache.struts.taglib.template.util.Content'    %>
<%@ page import='org.apache.struts.taglib.template.util.ScreenDefinition' %>

<% ScreenDefinition screenDefinition = new ScreenDefinition();
     screenDefinition.put("title",   new Content("Struts Templates Example",
"true"));
     screenDefinition.put("header",  new Content("/header.html", "false"));
     screenDefinition.put("sidebar", new Content("/sidebar.jsp", "false"));
     screenDefinition.put("content", new Content("/introduction.html",
"false"));
     screenDefinition.put("footer",  new Content("/footer.html", "false"));
%>

<template:screen template='/chapterTemplate.jsp'
                              screen='<%= introductionScreen %>'/>

The template:screen tag effectively lets you move the template:put tags into a
bean (a ScreenDefinition). But creating that bean is too painful because the
author must know about the Content and ScreenDefinition classes (I can hardly
remember where they are or what they're called). We can fix the problem with
another tag that creates a screen definition, like this:

<template:screenDefinition id='introductionScreen' scope='request'
        regions='<%= new String[] {
                "title", "header", "sidebar", "content", "footer" } %>'

       content='<%= new String[][] {
            { "Struts Template Example", "true"  }, // title
            { "/header.html",            "false" }, // header
            { "/sidebar.jsp",            "false" }, // sidebar
            { "/introduction.html",      "false" }, // content
            { "/footer.html",            "false" }  // footer
       }%>'
/>

The template:screenDefinition tag creates a screen definition and stores it in
the specified scope, with the specified id. For the code listed above, that
screen definition is named introductionScreen and it's placed in request scope.
You can specify any of the four scopes (page/request/session/application).

With the screenDefinition tag, the author only deals with String arrays,
instead of Content and ScreenDefinitions.

Templates are powerful because they centralize page layout, which simplifies
page maintenance, and allows global changes. The tags proposed here let you
define numerous screen definitions in a single JSP file, which centralizes your
screen definitions.

Like templates themselves, which simplify page layout and enable global layout
changes, screens simplify screen creation and maintenance, and allow global
screen changes.


david

* The ContentMap class has been renamed to ScreenDefinition.

** I wanted to take Joel's advice and add some attributes to the existing
template:insert tag, but this new tag doesn't have a body, so they must be
separate tags.

>
> Joel
>
> -----Original Message-----
> From: David Geary [mailto:[EMAIL PROTECTED]]
> Sent: Wednesday, February 21, 2001 2:52 PM
> To: Joel Regen
> Subject: Re: switchable layout
>
> Joel Regen wrote:
>
> > David,
> >
> > you wrote:
> > ...
> > >       chapter = content.substring(0,content.lastIndexOf("/"));
> > ******* Do you mean ...lastIndexOf("."));... here ^^^^?
> > I'm a bit confused here ;-)
>
> No, it's "/". That line of code is parsing a request parameter that
> indicates
> the content's directory. So, for the following URI ...
>
> book.jsp?content=/chapters/templates/introduction.html
>
> ... the chapter variable would be /chapters/templates. That variable's
> used
> to include other content, such as a footer, like this:
>
>   <template:put name='footer'
>                   content='<%= chapter + "/footer.html" %>' />
>
> In that case, the footer content would be
> /chapters/templates/footer.html.
>
> david

Reply via email to