<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You 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.
-->
<!DOCTYPE howto PUBLIC "-//APACHE//DTD How-to V2.0//EN" "http://forrest.apache.org/dtd/howto-v20.dtd">
<howto>
  <header>
    <title>How to write a forrest:contract?</title>
    <abstract>
      This How-To will explain how we wrote the contracts for views and hope
      afterwards you will be able to do the same.
    </abstract>
    <last-modified-content-date date="2005-06-06"/>
  </header>
  <audience title="Intended Audience">
    <warning>
      "Views" are new functionality which is still in development phase. That is
      why it is in the "whiteboard" section of the Forrest distribution. This
      HowTo is a good start but still needs proof-reading.
    </warning>
    <p>
      Devs and skin developer that wants to get started with forrest:contract
      development. To really understand this how-to you need basic and sometimes
      advanced understanding of the "old fashion" skin development process.
    </p>
  </audience>
  <purpose title="Purpose">
    <p>
      This setup guide will explain how to create a forrest:contract from
      scratch and how this forrest:contract work with the core parts of forrest.
    </p>
  </purpose>
  <prerequisites title="Prerequisites">
    <ul>
      <li>
        You have a ready-to-go new seed (newSeed) based on views like described in <a href="site:howto/view/install">Install views</a>.
      </li>
      <li>
      	This includes as well all additional plugins that are mentioned in <a href="site:howto/view/install">Install views</a>.
      </li>
      <li>
        Reading that how-to is as well a good idea to understand the used dir-structure in this how-to.
      </li>
    </ul>
  </prerequisites>
  <steps title="Steps">
    <note>
      The following content is from many mails around the topic, this how-to
      tries to be the consolidation of this thread. It is mainly based on the
      [RT] Why using views - in comparison with "old fashion" skins - usecase
      i18n
    </note>
    <p>
      By working on the i18n integration for "pelt" we crossed again the whys
      for using views. ;-) The maintainment problem was to change the captions
      of the skin features (contracts) to enable support for i18n. The case is
      that the <code>site2xhtml.xsl</code> has a lot of repeating code.
    </p>
    <p>
      For example the "last-publish"-contract could be found 2 times in the
      code. This is not the only contract that was (is) double in the code. The
      problem with that is that we needed to search the code for each caption
      and senseless repeat the following maintainment step of adding the
<![CDATA[<i18n:text/>]]>
      -tags.
    </p>
    <source>
<![CDATA[
- <script language="JavaScript"
- type="text/javascript">document.write("Published: " + document.lastModified);</script>

+ <script type="text/javascript">document.write("<i18n:text >Last
+ Published:</i18n:text>&#160;" + document.lastModified);
]]>
    </source>
    <section id="enhanceMaintainment">
      <title>Enhance the maintainment</title>
      <p>
        Now we can enhance the maintainment for the future and we give this code
        snippets contracts names (based on their functionality). This naming
        enables us to keep the contract separate from the position code itself.
        In xsl you would simply do:
      </p>
      <ol>
        <li>replace the script by <![CDATA[<xsl:call-template name="siteinfo-last-published"/>]]></li>
        <li>and add:</li>
      </ol>
      <source>
<![CDATA[<xsl:template name="siteinfo-last-published">
 <script type="text/javascript">
  document.write("<i18n:text >Last Published:</i18n:text>&#160;" + document.lastModified);
 </script>
</xsl:template>]]>
      </source>
      <p>
        This allows us in a next maintainment just change the code of
<![CDATA[<xsl:template name="siteinfo-last-published"/>]]>
        and apply it in any position where it is placed.
      </p>
      <note>
        Now this refactoring of the site2xhtml.xsl is exactly what we doing in
        creating contracts for views.
      </note>
    </section>
    <section id="blankContract">
      <title>Explaining the blank forrest:contract</title>
      <p>
        To start a new forrest:contract you can copy the 'blank.ft' from
        <code>org.apache.forrest.plugin.output.viewHelper.xhtml/resources/templates</code>.
        The exact file system path can be looked up at
        <code>http://localhost:8888/ls.contracts.html</code>.
      </p>
      <p>
        The 'blank.ft' is a simple xml file with the following code which you
        can use to base new contracts on:
      </p>
      <source>
<![CDATA[<forrest:contract 
  xmlns:forrest="http://apache.org/forrest/templates/1.0"
  name="blank" type="nugget">
  
  <!--NOTE: 
    When using the blank template as c'n p master just search and replace 'blank' by the {contract-name}!-->
  
  <description>
    {contract-name} will output {contract-funtion}. This is just a blank contract, it will output *nothing*.
  </description>
  <usage>]]>&lt;![CDATA[<![CDATA[<forrest:contract name="blank"/>]]>]]&gt;<![CDATA[</usage>
  <forrest:template xmlns:forrest="http://apache.org/forrest/templates/1.0"
    format="xhtml" name="blank" inputFormat="xsl" body="false" head="false">
    <xsl:stylesheet version="1.1" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <!--Add here the needed templates-->
    </xsl:stylesheet>
  </forrest:template>
</forrest:contract>
]]>
      </source>
      <p>
        The most important is the name of the contract <code>
<![CDATA[<forrest:contract name="blank"/>]]>
        </code>. This name is the same as the file name of the contract (without
        file extension) <code>blank.ft</code>.
      </p>
      <note>
        This is a <strong>naming convention</strong> that you have to always
        met. All @name has to be file name of the contract without file
        extension!
      </note>
      <p>
        The <code>
<![CDATA[<description/>]]>
        </code> tag needs to be filled in with some information that is
        explaining the contract to the webdesigner. The better explained the
        more efficient for the webdesigner to pick the right contract.
      </p>
      <source>
<![CDATA[<description>
  siteinfo-last-published-howto will output the last published date of the site with the help of jscript.
</description>]]>
      </source>
      <p>
        In the <code>
<![CDATA[<usage/>]]>
        </code> tag we have to explain how the designer can use the contract in
        his view.
      </p>
      <source>
<![CDATA[<usage>]]>&lt;![CDATA[<![CDATA[<forrest:contract name="siteinfo-last-published-howto"/>]]>]]&gt;<![CDATA[</usage>]]>
      </source>
      <p>
        <code>
<![CDATA[<forrest:template name="blank" body="false" head="false">]]>
        </code> That leads to the template attribute @body="true" and
        @head="false". In xhtml a contract can add content to the
<![CDATA[<body/>]]>
        or/and
<![CDATA[<head/>]]>
        part of
<![CDATA[<html/>]]>
        . This values have to be change when adding an actual template. Besides
        this a xsl-template has to indicate this in the naming. A template that
        add content to the html body has to end with "<code>-body</code>"!!!
      </p>
      <note>
        It is possible to use contracts in different in/output-formats. We are
        focusing for now on format="xhtml" as ouput and the inputFormat="xsl".
      </note>
      <p>
        A
<![CDATA[<forrest:template />]]>
        has the son
<![CDATA[<xsl:stylesheet/>]]>
        where we can create templates for the html-head and html-body. For
        adding content into the body of the final document change @body="true"
        and add:
      </p>
      <source>
<![CDATA[<xsl:stylesheet version="1.1" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <!--Add here the needed templates-->
 <xsl:template name="blank-body"/>
</xsl:stylesheet>]]>
      </source>
    </section>
    <section id="newContract">
      <title>Create a new contract</title>
      <fixme author="thorsten">
        We need to explain basic naming convention for contracts. Like "naming
        do not say about layout position but functionality of the contract.".
      </fixme>
      <p>
        Now lets pick up the example we started with and create a
        "siteinfo-last-published-howto" contract. Save the blank.ft to
        <code>{project.home}/src/documentation/resources/templates/siteinfo-last-published-howto.ft</code>.
      </p>
      <p>
        Now the maintainment optimized code (xpath="/html/body/*") was:
      </p>
      <source>
<![CDATA[<xsl:template name="siteinfo-last-published">
 <script type="text/javascript">
  document.write("<i18n:text >Last Published:</i18n:text>&#160;" + document.lastModified);
 </script>
</xsl:template>]]>
      </source>
      <p>
        In this code we have to do the following steps to use it in our
        contract:
      </p>
      <ul>
        <li>Search and replace "siteinfo-last-published" with "siteinfo-last-publish-howto-body"</li>
        <li>Add a "debug string - " to the template</li>
      </ul>
      <p>
        The contract after this steps should look like:
      </p>
      <source>
<![CDATA[<xsl:template name="siteinfo-last-publish-howto-body">
debug string - 
 <script type="text/javascript">
  document.write("<i18n:text >Last Published:</i18n:text>&#160;" + document.lastModified);
 </script>
</xsl:template>]]>
      </source>
      <p>
        Now we have to do some last steps in the siteinfo-last-publish-howto.ft
      </p>
      <ul>
        <li>Search and replace "blank" with "siteinfo-last-publish-howto"</li>
        <li>Add description and usage of the contract</li>
        <li>Set @body="true"</li>
        <li>Copy the maintainment optimized code to the contract.</li>
      </ul>
      <p>
        As the result your code should look like this:
      </p>
      <source>
<![CDATA[<forrest:contract xmlns:forrest="http://apache.org/forrest/templates/1.0"
  name="siteinfo-last-published-howto" type="nugget">
  <description>
    siteinfo-last-published-howto will output the last published date of the site with the help of jscript.
  </description>
  <usage>]]>&lt;![CDATA[<![CDATA[<forrest:contract name="siteinfo-last-published-howto"/>]]>]]&gt;<![CDATA[</usage>
  <forrest:template 
    xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
    xmlns:forrest="http://apache.org/forrest/templates/1.0"
    format="xhtml" name="siteinfo-last-published-howto" inputFormat="xsl" body="true" head="false">
    <xsl:stylesheet version="1.1" 
        xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template name="siteinfo-last-published-howto-body">
          debug string - 
          <script type="text/javascript">document.write("<i18n:text >Last Published:</i18n:text>&#160;" + document.lastModified);</script>
        </xsl:template>
    </xsl:stylesheet>
  </forrest:template>
</forrest:contract>]]>
      </source>
    </section>
    <section id="viewContract">
      <title>Activating the contract</title>
      <p>
        To see whether the new contract works we need to add it to our view. The
        contract usage contains the contract-tag <code>
<![CDATA[<forrest:contract name="siteinfo-last-published-howto"/>]]>
        </code> Please see <a href="site:howto/view/DSL">Getting started with
        forrest:view DSL</a> for more details.
      </p>
      <fixme author="thorsten">
        Let us now look into advanced features of views. I will write a how-to
        for advanced contracts soon. :)
      </fixme>
    </section>
  </steps>
  <extension title="Further Reading">
    <p>
      Congratulations you are now able to work with view contracts. From here we
      recommend to read the following How-To's:
    </p>
    <ul>
      <li><a href="site:howto/view/DSL">Getting started with forrest:view DSL</a></li>
    </ul>
  </extension>
  <feedback title="Feedback">
    <p>
      Please provide feedback about this document via the
      <a href="site:mail-lists">mailing lists</a>.
    </p>
  </feedback>
</howto>
