<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->

<document>

<properties>
    <title>Context Howto</title>
</properties>

<body>

<section name="Using the Turbine Context">
<p>
The Turbine Templating Services attach references to default Objects in the
Turbine Context as part of their initialization. In the case of the
TurbineVelocityService these references point to RunData, TemplateLink and
TemplatePageAttributes. These three are put into the Context in the
TurbineVelocityService class. The Context stores the Objects in a Hashtable
with a key and the Object.
</p>
</section>

<section name="Using the RunData Object">
<p>
The RunData Object is referenced by the "data" keyword, which when using this
in the templating system is referenced by $data. As the Context contains a link
to the RunData object all the public methods in the RunData Object are made
available to the template. For example, typing $data.getMessage() will access
the message String being stored in the RunData Object and print that as part
of the templates output.
</p>

<p>
RunData exposes an extremely rich series of methods and fields, for a full list
of these methods refer to the Javadocs for RunData. Some of the useful methods
exposed in RunData include;
</p>

<p>
<ul>
    addMessage(String msg) <br />
    getMessage() <br />
    getParameters() <br />
    getServerName() <br />
    getTitle() <br />
    getUser() <br />
    removeUserFromSession() <br />
    setMessage(String message) <br />
    setRedirectUri(String ruri) <br />
    setTitle(String title) <br />
</ul>
</p>

<p>
The RunData also allows for access to the TemplateInfo Object via
getTemplateInfo() and several convenience methods. This allows for properties
of the Templates to be modified for a Request when using templating systems like
Velocity, WebMacro or Freemarker.
</p>

<p>
As an example assume we want a printable page that contains only the Templating
Screen and not all the navigational components. To achieve this we can strip
out all the non screen templating components by describing a new Layout Template
called PrintableLayout.vm in the templates/layouts directory. All the
PrintableLayout needs contain is;
</p>

<source test=""><![CDATA[
    $screen_placeholder
]]></source>

<p>
Without the references to the $navigation.setTemplate() methods in the template
no navigational screen will be called. In the Screen Template that wants to take
advantage of the PrintableLayout Template add to the Template;
</p>

<source test=""><![CDATA[
    $data.setLayoutTemplate("/PrintableLayout.vm")
]]></source>

<p>
This will strip the Screen Template of its Navigational components. These
convenience methods can also be used to expose and to set the Layout when the
Template is processed. Through this a User can potentially choose how they would
like their webpage to appear by choosing one of many differant Layouts or
choices you, the webdesigner provide.
</p>

<p>
Currently the setLayoutTemplate(), getLayoutTemplate(), setScreenTemplate() and
getScreenTemplate() methods arent available in TDKa9. Until the next build of
the TDK contains RunData with those methods, the setLayoutTemplate method can
still be accessed through the TemplateInfo Object that RunData exposes.
For example;
</p>

<source test=""><![CDATA[
    $data.getTemplateInfo().setLayoutTemplate("/PrintableLayout.vm")

    or

    #set $template = $data.getTemplateInfo()<br />
    $template.setLayoutTemplate("/PrintableLayout.vm")

    or

    #set $template = $data.getTemplateInfo()<br />
    $!template.setLayoutTemplate("/PrintableLayout.vm")

]]></source>

<p>
In the third example, the ! stops the echo of the Velocty Directive echoing to
screen.
</p>
</section>

<section name="Using the TemplateLink Object">
<p>
The TemplateLink is an extended version of DynamicURI customised to be used in
the templates. The TemplateLink is referenced in the templates via $link and
exposes convenience methods for building URI's on the fly. For example in a
template to build the URI to another template, TemplateLink would be referenced
via;
</p>

<source test=""><![CDATA[
    $link.setPage("newpage.vm")
]]></source>

<p>
which when added to a Velocity template in the TDK that is running as localhost,
would return;
</p>

<p>
<blockquote>
    http://127.0.0.1:8080/newapp/servlet/newapp/template/index.vm
</blockquote>
</p>

<p>
where "newapp" is the chosen webapp deployment name.
</p>

<p>
This same mechanism can also be used to link to static html;
</p>

<source>
    $link.setPage("/path/to/static.html")
</source>

<p>
However the HTML page will load itself into a screen and not be embedded withint the Layouts and Navigations. If you still wish static content to be embedded within the specified layouts and navigations it is easier to add the static content as a velocity template and not take advantage of any of the dynamic content addition the Velocity Context allows.
</p>


<p>
TemplateLink and DynamicURI again expose a rich set of methods and fields to
the link reference, for a full list of fields and methods please refer to
TemplateLink and DynamicURI in the javadocs. Some of the useful methods
exposed are;
</p>

<p>
<ul>
    setPage(String templatename) <br />
    addPathInfo(ParameterParser pp) <br />
    addPathInfo(String name, String value) <br />
    addQueryData(ParameterParser pp) <br />
    addQueryData(String name, String value) <br />
    getScriptName() <br />
    getServerData() <br />
    getServerPort() <br />
    setAction(String action) <br />
    setScreen(String screen) <br />
    setSecure() <br />
</ul>
</p>
</section>

<section name="Using the TemplatePageAttributes Object">
<p>
The TemplatePageAttributes is accessed from within the context by the keyword
"page" and provides methods to modify the various HTML attributes of the
templating system. The Template context can be used to dictate the style of
the HTML page in the navigation and layout templates as well as modify these
attributes from within a screen.
</p>

<p>
As an example in the default.vm the page can be set to a maroon background with;
</p>

<source test=""><![CDATA[
    $page.setBgColor("#800000")
]]></source>

<p>
the screen template may need to set a new title to the page being displayed in
the browser, this can be done in the screen template via;
</p>

<source test=""><![CDATA[
    $page.setTitle("New Title to Page")
]]></source>

<p>
Non standard attributes can be added to the Body tag, for instance the
leftmargin or topmargin attributes via;
</p>

<source test=""><![CDATA[
    $page.addAttribute("topmargin", 0)
]]></source>

<p>
Note though that the addAttribute method only adds attributes to the Body tag.
For a full list of methods exposed to the page reference view the Javadocs for
TemplatePageAttributes. Other methods exposed to the page reference are;
</p>

<p>
<ul>
    addAttribute(String name, String value) <br />
    getTitle() <br />
    setBackground(String url) <br />
    setBgColor(String color) <br />
    setDescription(String description) <br />
    setKeywords(String description) <br />
    setLinkColor(String color) <br />
    setStyleSheet(String url) <br />
    setTextColor(String color) <br />
    setTitle(String title) <br />
    setVLinkColor(String color) <br />
</ul>
</p>
</section>

<section name="Adding your own Objects to the Context">
<p>
As the Context is stored as a Hashtable any Object can be placed inside
it and be accessed from a template. For instance, in a Velocity Screen
in the doBuildTemplate() method, a String could be added to the Context.
Please refer to the <a href="../getting-started.html">Getting
Started</a> documentation for more examples of using the Velocity
Context with screens and events.
</p>

<source test=""><![CDATA[
    context.put("hello",new String("testing"));
]]></source>

<p>
This can be referenced from within the template via;
</p>

<source test=""><![CDATA[
    $hello the hello reference
]]></source>

<p>
which would be output as;
</p>

<source test=""><![CDATA[
    testing the hello reference
]]></source>
</section>

<section name="Using an Image Object in the Context">
<p>
Creating an HTML link to an image from a template could be done by;
</p>

<source test=""><![CDATA[
   $link.getServerScheme()
   ://
   $link.getServerName()
   :
   $link.getServerPort()
   /context/imagename.jpg
]]></source>

<p>
This has been split up into multiple lines for clarity. Doing this once is a
pain, doing it twice stinks, if the screen requires several images .... and
there are many screens .... it is a productivity killer. The Velocity Context
can be used to store this information and expose it to all the Screens
requiring it. To do this we can create an Image Object which extends the Turbine
DynamicURI Object. The following class is Jakarta Tomcat specific;
</p>


<source test=""><![CDATA[
//Turbine
import org.apache.turbine.util.DynamicURI;
import org.apache.turbine.util.RunData;


public class Image extends DynamicURI
{

    /** The images directory */
    public static final String DIR = "images";

    /** tomcat specific - tomcat context */
    private String contextpath;

    /** Constructor */
    public Image (RunData data)
    {
        super(data);

        //the Tomcat context
        contextpath = data.getRequest().getContextPath();
    }

    /** set the image and URI */
    public String setImage(String imagename)
    {
        return (
        getServerScheme() + //http
        "://" +
        getServerName()  + //www.foo.com
        ":" +
        getServerPort() + //port webserver running on (8080 for TDK)

        //the context for tomcat adds a / so no need to add another

        contextpath  +  //the tomcat context
        "/" +
        Images.DIR +
        "/" +
        imagename);
    }
}
]]></source>

<p>
This can be instantiated from within the doBuildTemplate method in a Velocity
Screen and added to the context from there;
</p>

<source test=""><![CDATA[
    public void doBuildTemplate(RunData data, Context context) throws Exception
    {
        Image image = new Image(data);
        context.put("image",image);
    }
]]></source>

<p>
from this the Image Object is accessible from within the corresponding screen
template and can be accessed by;
</p>

<source test=""><![CDATA[
    $image.setImage("imagename.jpg");
]]></source>

<p>
Which is much simpler than the original attempt at dynamically creating an image
URL. To make this Image object accessible across all Screens, sublass the
VelocityScreen Object with one that overrides the doBuildTemplate() method by
adding the Image object to the Velocity Context. Then use this class as the
parent class for the Screens that need access to the Image Object. For more
detail on taking advantage and extending the VelocityScreen Object, please view
the <a href="../getting-started.html">Getting Started</a> Document.
</p>

<p>
The above Image Object can also be modified to include any static data required
by the templates. For instance CSS files, JavaScript files etc. Instead of an
Image Object, it can be rewritten as a StaticLink Object;
</p>

<source test=""><![CDATA[
//Turbine
import org.apache.turbine.util.DynamicURI;
import org.apache.turbine.util.RunData;


public class StaticLink extends DynamicURI
{

    /** the images directory */
    public static final String IMAGES = "images";

    /** the css directory */
    public static final String CSS = "css";

    // etc

    /** tomcat specific - tomcat context */
    private String contextpath;

    /** Constructor */
    public Image (RunData data)
    {
        super(data);

        //the Tomcat context
        contextpath = data.getRequest().getContextPath();
    }

    /** set the image and URI */
    public String setImage(String imagename)
    {
        //URI Logic
    }

    /** set the CSS style and URI*/
    public String setCss(String stylesheet)
    {
        //URI Logic
    }

    /** general set method, input as string
     *  ie can be set as $staticlink.setStaticLink("images/imagename")
     */
    public String setStaticLink(String staticlink)
    {
        //URI Logic
    }

}

]]></source>
</section>

<section name="Using the Context Object with the Base/Peer OM">
<p>
As a more complex example, assume we are building a book archive system,
where users can search for books by author and title. If we search on author
"Greg Egan" and title "Permutation City", we can query the database through the
base\peer system and return a Book Object that contains the information on the
book "Permutation City". The Book Object would be placed in the context via;
</p>

<source test=""><![CDATA[
    Book book = new Book();

    //add the data to the Book Object
    //from the Base/Peer Objects for Book

    context.put("book", book);

]]></source>

<p>
and then accessed in the velocity template by;
</p>

<source test=""><![CDATA[
    $book.getAuthor()
    $book.getTitle()
]]></source>

<p>
where the two methods are public methods in the Book Object, in this case built
by the <a href="torque.html">Torque Tool</a>. These methods would return;
</p>

<source test=""><![CDATA[
    Greg Egan
    Permutation City
]]></source>

<p>
It is important not to try and put Objects with value null into the Context.
A NullPointerException will be returned. This above example is intended to get
across how the Velocity Context can be used to store data from the Base/Peer
system that can be accessed from the Templates.
</p>
</section>

</body>
</document>
