Wysiwyg Template Guide

Last Updated: 2002/Jan/21

Introduction to Wysiwyg Templates

Templates are the request driven display engine for cofax. Templates save you time, resources, and leverage what you already know. They are built using HTML files marked up with special comment tags. Wysiwyg Template is the default templating system used in Cofax. Due to Cofax's design, it's possible to implement other templating systems in short order, but for the purposes of this document, we are going to cover Wysiwyg Templates, hereafter simply called templates.

Using a template, a designer can "view source" a live page, static or dynamic, make changes, and after ensuring that the comment tags are in place the template is immediately usable. The templating system works with a hierarchical structure. For example, a master template is applied to all Inquirer stories if no section-specific templates are found. If a story-specific template is found, then it overrides the section template. This makes the system very flexible. A designer can either apply one template for everything, or use specific templates for section (i.e. sports) and even individual items. In addition different hierarchies of templates can be applied to the same content set for different sites!

Where to develop your templates

Templates are developed on the publishing server. Each publication get's it's own area to save and publish templates. Use standard HTML and text editors to create your templates and FTP them to the publishing server. After posting new templates, go to your preview web address to view the results. When satisfied, use the "publish" program to post new templates to the outside world. The publish command removes templates from production server's caches. Ask your administrator for access to the publishing server and for the location of the publish command.

Creating your default templates

A publication must have at least two templates to be functional - the listTemplate.htm and articleTemplate.htm files. Put these in the root folder of your publication. These will be the default templates used for any mapping section. listTemplates are used for index pages, articleTemplates are used when a particular file is requested.

You can override, for any particular mapping section, by creating a subfolder named after the "Section URL Folder" field in the Editor's Tools, and putting new a new listTemplate, articleTemplate, or both in this new folder.

How templates are picked

Internally, when Cofax recieves a request, an internal glossary (table of keys and values) is initialized (technically this is not true, but it is practically so) and data about the request occuring is inserted into it. These values are available to you in the template to print out and use as parameters for package tags. It's this functionality that allows you to drive a site from as little as two templates. Cofax will use these values to pick a template by walking your template folder's sub-directories.

There are three methods Cofax uses to find a template. Each is driven by the request. One for indexes, one for files, and one for overrides. What follows is examples of the three methods.

  • Example 1: http://web.philly.com/content/inquirer/2000/06/07/front_page/

    The glossary has been initialized and it contains the following values:

    NameValue
    request:publicationinquirer
    request:sectionfront_page
    request:namefront_page
    request:fileName 
    request:fileNameWithExtention 
    request:date2000/06/07
    request:hostweb.philly.com
    request:path_info/inquirer/2000/06/07/front_page
    request:query_string 
    request:template 
    request:urlhttp://web.philly.com/content/inquirer/2000/06/07/front_page/07gop.htm
    request:date_format_1Wednesday, June 7, 2000
    request:day_of_weekWed
    Any HTTP_HEADERS and any values passed in PUTs and GETS are inserted and have names prefixed with "request:"

    listTemplates are used by index requests such as this. Cofax first looks for the existance of "listTemplate.htm" in the "inquirer/front_page" folder (notice that dates are virtual and ignored in template searches), and if failing that, climbs up the template path to the "inquirer/" folder to use it's "listTemplate.htm", which, you remember, must exist.

  • Example 2: http://web.philly.com/content/inquirer/2000/06/07/front_page/07microsoft.htm

    The glossary has been initialized and it contains the following values:

    NameValue
    request:publicationinquirer
    request:sectionfront_page
    request:namefront_page
    request:fileName07microsoft
    request:fileNameWithExtention07microsoft.htm
    request:date2000/06/07
    request:hostweb.philly.com
    request:path_info/inquirer/2000/06/07/front_page
    request:query_string 
    request:template 
    request:urlhttp://web.philly.com/content/inquirer/2000/06/07/front_page/07gop.htm
    request:date_format_1Wednesday, June 7, 2000
    request:day_of_weekWed
    Any HTTP_HEADERS and any values passed in PUTs and GETS are inserted and have names prefixed with "request:"

    articleTemplates are used by file requests such as this. But first, Cofax will assume you are looking for an actual file called "07microsoft.htm" to use as a template. Cofax will first look for the existance of a "07microsoft.htm" in the "inquirer/front_page" folder, and if failing that, climbs up the template path to the "inquirer/" folder to look for "07microsoft.htm" there. Failing this search, Cofax will proceed to look for an "articleTemplate.htm" in the "inquirer/front_page" folder, and if failing that, climbs up the path to "inquirer/" to look for "articleTemplate.htm" there, which must exist.

  • Example 3: http://web.philly.com/content/inquirer/2000/06/07/front_page/07microsoft.htm?template=aprint.htm

    The glossary has been initialized and it contains the following values:

    NameValue
    request:publicationinquirer
    request:sectionfront_page
    request:namefront_page
    request:fileName07microsoft
    request:fileNameWithExtention07microsoft.htm
    request:date2000/06/07
    request:hostweb.philly.com
    request:path_info/inquirer/2000/06/07/front_page
    request:query_string 
    request:templateaprint.htm
    request:urlhttp://web.philly.com/content/inquirer/2000/06/07/front_page/07gop.htm
    request:date_format_1Wednesday, June 7, 2000
    request:day_of_weekWed
    Any HTTP_HEADERS and any values passed in PUTs and GETS are inserted and have names prefixed with "request:"

    When request:template has a value, as is the case here, Cofax will look for the existance of the exact template specified to use. In this example, Cofax will look for a file called "aprint.htm". Cofax will first look for the existance of a "aprint.htm" in the "inquirer/front_page" folder, and if failing that, climbs up the template path to the "inquirer/" folder to look for "aprint.htm". If Cofax does not find this template, it will result in a 404 returned to the user.

    What goes in a template

    Templates are plain text files that you insert a text based formatting language, for example HTML for the web, and use packageTags to call the content you need and templateTags to use the content returned.

  • packageTag Syntax:

    packageTags collect data from the datastore and, upon command, insert data into the glossary. They have fascilities to repeat a section of formatting for each row returned from the datastore, to display a header and footer if rows are returned, to return a 404 if no rows are returned, and to display a formatting block of text if no rows are returned. Line feeds are recognized in the syntax and must be followed.

    Use the templateTags within headerFormat, displayFormat, footerFormat, and noArticles to use data in the glossary or returned from the packageTag itself. Data returned from the datastore is not available in headerFormat, footerFormat and noArticles sections.

    
    <!-- packageTag action="package tag name" -->
    
    
    
    Available to all packageTags:
    
    (<!--param name="ADDTOGLOSSARY" value="true" -->)
    
    (<!--param name="RETURN404" value="true" -->)
    
    (<!--param name="STARTROW" value="true" -->)
    
    (<!--param name="NUMROWS" value="true" -->)
    
    (<!--param name="SHOWGLOSSARY" value="true" -->)
    
    (<!--param name="SHOWPACKAGETAG" value="true" -->)
    
    
    
    Most packageTags take additional parameters that, if values are set 
    
    in the glossary already, do not need to be specified.
    
    (<!--param name="a param name" value="a param value" -->)
    
    
    
    (<!-- headerFormat -->
    
      HTML or other text to display as a header for rows returned.  Prints just once.
    
    <!-- /headerFormat -->)
    
    
    
    (<!-- displayFormat -->
    
      HTML or other text to display for each row returned.
    
    <!-- /displayFormat -->)
    
    
    
    (<!-- footerFormat -->
    
      HTML or other text to display as a footer for rows returned.
    
    <!-- /footerFormat -->)
    
    
    
    (<!-- noArticles -->
    
      HTML or other text to display if no rows returned.
    
    <!-- /noArticles -->)
    
    
    
    <!-- /packageTag -->
    
    
  • templateTag Syntax:

    templateTags are used to display data returned by a packageTag or collected in the glossary.

    • <h2><!-- request:mynameis -->name will print here<!-- /request:mynameis --></h2>

      This syntax leaves behind the comment tags in the source, replacing everything inbetween with the value of the tag.

    • faq

      This syntax replaces the tag with the value. This syntax, and it's stripline equivalent, are necessary when used as attributes in HTML. For example, within an <img> field.

    • <h2><!-- request:mynameis stripline="true" -->name will print here<!-- /request:mynameis --></h2>

      This syntax leaves behind the comment tags in the source, only if a value is returned. Otherwise, it strips the comment tags, the filler, and any surrounding text on that line.

    • `request:section stripline=true`

      This syntax replaces the tag with the value. This syntax, and it's non-stripline equivalent, are necessary when used as attributes in HTML. For example, within an <img> field. This syntax, like it's comments equivalent, will erase all surrounding text on the line if no value is returned.

  • Example 1: A listTemplate.htm that can serve every section on your site
  • This template would be called from any index url mentioning a mapping section's URL folder (specified in the Editor's tools). For example, "/inquirer/2000/08/15/front_page", "/inquirer/2000/09/04/sports", and "/inquirer/2000/02/01/magazine" all could share this template from the root folder.

    
    -- begin listTemplate.htm -- 
    
    <html>
    
    <head>
    
    
    
    <!-- packageTag action="PublicationGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="SectionGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <title>
    
    `PublicationGlossary:pubDesc` -> `SectionGlossary:sectionDesc` 
    
    </title>
    
    
    
    </head>
    
    
    
    <body>
    
    
    
    <img src="`SectionGlossary:image`">
    
    
    
    <!-- SectionGlossary:include -->include section specific html<!-- /SectionGlossary:include -->
    
    
    
    <!-- packageTag action="getSection" -->
    
    
    
      <!-- headerFormat -->
    
    <table>  
    
      <!-- /headerFormat -->
    
    
    
      <!-- displayFormat -->
    
    <tr>    
    
    
    
    <td>
    
    <img src="/objects/`getSection:pubName`/images/`getSection:dateFolder`/`getSection:listImage stripLine=true`" align="left">
    
    </td>
    
    
    
    <td>
    
        <a href="`getSection:fileName`.htm">
    
        <h2><!-- getSection:headline -->Insert the headline<!-- /getSection:headline --></h2>
    
        <h4><!-- getSection:headline2 stripLine="true" -->I'm a headline2<!-- /getSection:headline2 --></h4>
    
        </a>
    
    
    
        <!-- getSection:lead -->Insert the Lead<!-- /getSection:lead --><br clear="all"><p>
    
    </td>    
    
    </tr>
    
    
    
      <!-- /displayFormat -->
    
    
    
        <!-- footerFormat -->
    
    </table>  
    
      <!-- /footerFormat -->
    
    
    
      <!-- noArticles -->
    
            <h4>Either there has been a technical problem, or there are no stories for this section today.
    
    	</h4>
    
      <!-- /noArticles -->
    
    
    
    <!-- /packageTag -->
    
    
    
    </body>
    
    </html>
    
    
    
    -- end  listTemplate.htm --
    
    

    How does this template know what content to use?

    First, remember when a request comes to Cofax, a glossary is initialized and the values are used to pick a template. They are also available for you to print out inside of the template. Notice the calls to "request:" prefixed parameters above. They are from the request itself. Also notice values mentioned like "SectionGlossary:image". If you send the "ADDTOGLOSSARY" parameter to a packageTag, then that tag inserts the values into the glossary, prefixed with the tag name, and you can use these througout the template and not just within a displayFormat.

    Now when a particular packageTag is called, it used the values in the current glossary to complete the action. For example, "PublicationGlossary" uses "request:publication" as a parameter. This template used three packageTags, "PublicationGlossary", "SectionGlossary", and "getSection".

    Remember our example above for an index template? "request:publication" got the value "inquirer" from the request and, and the packageTag "PublicationGlossary" recieved this as a parameter to return it's data.

  • Example 2: An articleTemplate.htm that can serve any article on your site
  • This template would be called from any file url. For example, "/inquirer/2000/08/15/front_page/george.htm", "/inquirer/2000/09/04/sports/kick.htm", and "/inquirer/2000/02/01/magazine/life.htm" all could share this template from the root folder.

    
    -- begin articleTemplate.htm -- 
    
    <html>
    
    <head>
    
    
    
    <!-- packageTag action="PublicationGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="SectionGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="getArticle" -->
    
         <!-- param name="ADDTOGLOSSARY" value="true" -->
    
         <!-- param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <title>`PublicationGlossary:pubDesc` - Introduction to templates</title>
    
    <meta name="publication" content="cofax">
    
    <meta name="headline" content="Introduction to templates ">
    
    <meta name="author" content="`getArticle:byline`">
    
    <meta name="byline" content="`getArticle:byline`">
    
    <meta name="description" content="">
    
    <meta name="keywords" content="`request:name`">
    
    <meta name="section" content="`request:name`">
    
    <meta name="dateline" content="`getArticle:dateline`">
    
    <meta name="publicationdate" content="`getArticle:pubDate`">
    
    
    
    </head>
    
    <body>
    
    
    
    <img src="`SectionGlossary:image`">
    
    
    
    <!-- SectionGlossary:include -->include section specific html<!-- /SectionGlossary:include -->
    
    
    
    <h2>
    
    <!-- getArticle:headline -->Insert the headline<!-- /getArticle:headline -->
    
    </h2>
    
    
    
    <h4>
    
    <!-- getArticle:headline2 stripLine="true" -->a headline 2<!-- /getArticle:headline2 -->
    
    </h4>
    
    
    
    <!-- packageTag action="getRelatedLinks" -->
    
      <!-- headerFormat -->
    
      <img width=161 height=13 src=http://objects.philly.com/wordtease/wt_related.gif><br>
    
      <hr size=1 noshade>
    
      <!-- /headerFormat -->
    
    
    
      <!-- displayFormat -->
    
        <li><a href="`getRelatedLinks:link`">`getRelatedLinks:text`</a>
    
      <!-- /displayFormat -->
    
      <!-- noArticles -->
    
      <!-- /noArticles -->
    
    
    
      <!-- footerFormat -->
    
      <hr size=1 noshade>
    
      <!-- /footerFormat -->
    
    <!-- /packageTag -->
    
    
    
    
    
    <b><center>
    
    <!-- getArticle:byline stripLine="true" -->I'm a byline<!-- /getArticle:byline --><br>
    
    <!-- getArticle:bycredit stripLine="true" -->a bycredit<!-- /getArticle:bycredit -->
    
    </center></b>
    
    
    
    <br>
    
    <!-- getArticle:body -->Insert the body<!-- /getArticle:body -->
    
    
    
    </body>
    
    </html>
    
    -- end  articleTemplate.htm --
    
    
  • Example 3: Overriding packageTag params approaches to do some cool stuff
  • First, here goes a template to display the top 5 articles in 3 specific sections.

    
    -- begin listTemplate.htm -- 
    
    <html>
    
    <head>
    
    
    
    <!-- packageTag action="PublicationGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="SectionGlossary" -->
    
    <!--param name="ADDTOGLOSSARY" value="true" -->
    
    <!--param name="RETURN404" value="true" -->
    
    <!-- /packageTag -->
    
    
    
    <title>
    
    `PublicationGlossary:pubDesc` -> `SectionGlossary:sectionDesc` 
    
    </title>
    
    
    
    </head>
    
    
    
    <body>
    
    
    
    <img src="`SectionGlossary:image`">
    
    
    
    <!-- SectionGlossary:include -->include section specific html<!-- /SectionGlossary:include -->
    
    
    
    <!-- packageTag action="getSection" -->
    
    
    
    <!-- param name="NUMROWS" value="5" -->
    
    <!-- param name="request:name" value="front_page" -->
    
    
    
      <!-- headerFormat -->
    
    <ul>  
    
      <!-- /headerFormat -->
    
    
    
      <!-- displayFormat -->
    
    <li>    
    
    
    
    <img src="/objects/`getSection:pubName`/images/`getSection:dateFolder`/`getSection:listImage stripLine=true`" align="left">
    
    
    
        <a href="`getSection:fileName`.htm">
    
        <h2><!-- getSection:headline -->Insert the headline<!-- /getSection:headline --></h2>
    
        <h4><!-- getSection:headline2 stripLine="true" -->I'm a headline2<!-- /getSection:headline2 --></h4>
    
        </a>
    
    
    
    </li>    
    
    
    
      <!-- /displayFormat -->
    
    
    
        <!-- footerFormat -->
    
    </ul>  
    
      <!-- /footerFormat -->
    
    
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="getSection" -->
    
    
    
    <!-- param name="NUMROWS" value="5" -->
    
    <!-- param name="request:name" value="business" -->
    
    
    
      <!-- headerFormat -->
    
    <ul>  
    
      <!-- /headerFormat -->
    
    
    
      <!-- displayFormat -->
    
    <li>    
    
    
    
    <img src="/objects/`getSection:pubName`/images/`getSection:dateFolder`/`getSection:listImage stripLine=true`" align="left">
    
    
    
        <a href="`getSection:fileName`.htm">
    
        <h2><!-- getSection:headline -->Insert the headline<!-- /getSection:headline --></h2>
    
        <h4><!-- getSection:headline2 stripLine="true" -->I'm a headline2<!-- /getSection:headline2 --></h4>
    
        </a>
    
    
    
    </li>    
    
    
    
      <!-- /displayFormat -->
    
    
    
        <!-- footerFormat -->
    
    </ul>  
    
      <!-- /footerFormat -->
    
    
    
    <!-- /packageTag -->
    
    
    
    <!-- packageTag action="getSection" -->
    
    
    
    <!-- param name="NUMROWS" value="5" -->
    
    <!-- param name="request:name" value="sports" -->
    
    
    
      <!-- headerFormat -->
    
    <ul>  
    
      <!-- /headerFormat -->
    
    
    
      <!-- displayFormat -->
    
    <li>    
    
    
    
    <img src="/objects/`getSection:pubName`/images/`getSection:dateFolder`/`getSection:listImage stripLine=true`" align="left">
    
    
    
        <a href="`getSection:fileName`.htm">
    
        <h2><!-- getSection:headline -->Insert the headline<!-- /getSection:headline --></h2>
    
        <h4><!-- getSection:headline2 stripLine="true" -->I'm a headline2<!-- /getSection:headline2 --></h4>
    
        </a>
    
    
    
    </li>    
    
    
    
      <!-- /displayFormat -->
    
    
    
        <!-- footerFormat -->
    
    </ul>  
    
      <!-- /footerFormat -->
    
    
    
    <!-- /packageTag -->
    
    
    
    
    
    
    
    </body>
    
    </html>
    
    
    
    -- end  listTemplate.htm --
    
    

    We are specifing how many rows we want returned with "NUMROWS" and overriding the "request:name" parameter, that usually get's it's value from the request, in each packageTag call.

  • Example 4: Exporting to the XML RSS syndication format
  • Data always needs to usable in other formats. Templates can be used to produce them. What follows in "rss.htm" is a template that exports an index to XML RSS format. RSS is a popular format used in content syndication (insert link---Karl). This template would be called from any section like a file name. For example, if "rss.htm" was saved at the publication root, "/2000/08/02/front_page/rss.htm", "/2000/08/02/sports/rss.htm", "/2000/08/02/magazine/rss.htm", etc, would all use the same template. You can use this as an example to produce almost any kind of specialized template.

    
    -- begin rss.htm --
    
    
    
    <?xml version="1.0"?>
    
    
    
    <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
    
                "http://my.netscape.com/publish/formats/rss-0.91.dtd">
    
    
    
    <rss version="0.91">
    
    <!-- packageTag action="PublicationGlossary" -->
    
    <!-- param name="ADDTOGLOSSARY" value="true" -->
    
    <!-- /packageTag -->
    
      <channel>
    
        <title>`PublicationGlossary:pubDesc`</title>
    
        <link>`PublicationGlossary:homePage`</link>
    
        <description>`PublicationGlossary:tagLine`</description>
    
        <language>en-us</language>
    
    <!-- packageTag action="getSection" -->
    
      <!-- param name="NUMROWS" value="10" -->
    
      <!-- displayFormat -->
    
        <item>
    
        <title>`getSection:headline`</title>
    
        <link>http://web.philly.com/content/`getSection:virtualFolder`/`getSection:fileName`.htm</link>
    
        <description>`getSection:lead`</description>
    
        </item>
    
      <!-- /displayFormat -->
    
    <!-- /packageTag -->
    
      </channel>
    
    
    
    </rss>
    
    
    
    -- end rss.htm --