<chapter id="templates">
  <title>Templates</title>

  <section>
    <title>Introduction</title>
    <para>
      Phorum uses a template system for separating application code
      from presentation code. Application code contains all the
      logic that is needed for running Phorum. This is PHP code which
      is maintained by programmers. Presentation code is used to
      translate the data that is generated by the application code into
      a HTML page that can be viewed by the end user. This Presentation
      code can be maintained by HTML designers.
    </para>
    <para>
      The big advantages of this type of system are that HTML designers
      will not be bothered with complicated PHP code and that it is easy
      to create multiple presentation styles for Phorum.
    </para>
    <para>
      Although there is no application logic in the templates, it is
      still possible to put presentation logic in there. Presentation
      logic is only used for things like making decisions on what
      to show and how to show it and for processing data that
      has been generated by the application code. For writing
      presentation logic, a very simple custom programming language
      is available (more on that will follow when we talk about the
      <xref linkend="templates.templatelang"/>).
    </para>
  </section>

  <section>
    <title>Template structure</title>
    <para>
      A template set is a collection of files that together form a
      single template. All template sets are stored in their own
      subdirectory under the directory
      <filename>{phorum dir}/templates</filename>. If we asume
      that we have three templates <literal>default</literal>,
      <literal>template1</literal> and <literal>template2</literal>,
      then the directory structure for storing these templates
      would look like this:
      <literallayout><literal>
{phorum dir}
 |
 +-- templates
    |
    +-- default
    |
    +-- template1
    |
    +-- template2 </literal></literallayout>
    </para>
    <para>
      Inside these template subdirectories, the files for the templates
      are stored. There, the the following files can be found:
      <variablelist>
        <varlistentry>
          <term>info.php</term>
          <listitem><para>
            This is a PHP file that is used for describing some
            properties of the template. This file can define the
            following variables:
            <itemizedlist>
              <listitem>
                <literal>$name</literal><sbr/>
                Mandatory variable. This variable hold the name that
                you want to give to the template. This is the name
                that will be displayed in template selection boxes.
                The name of the directory for the template will only
                be used by Phorum internally.
              </listitem>
              <listitem>
                <literal>$version</literal><sbr/>
                Mandatory variable. This variable holds the version number
                for your template. It's used so you can track what version
                of the template is installed for Phorum. You can use any
                type of version numbering you like. If you do not know
                what to use, then simply give your first version of the
                template version 1, the second number 2, and so on.
              </listitem>
              <listitem>
                <literal>$template_hide</literal><sbr/>
                Optional variable. If set to a true value, the template
                will be hidden from user select boxes where the end user
                can choose the template that he wants to use.
              </listitem>
            </itemizedlist>
            <example><title>Template information file: $info.php</title><programlisting><![CDATA[
<?php
// Prevent loading from outside the Phorum application.
if (!defined("PHORUM")) return;

// Template information.
$name = "A brilliant template";
$version = "1.2-beta";
$template_hide = 1;
?> ]]></programlisting></example>
          </para></listitem>
        </varlistentry>
        <varlistentry>
          <term>.tpl and .php files</term>
          <listitem>
            <para>
              These are the files that hold the actual template code.
              When the Phorum application wants to display a template,
              it is always referenced by its basename (i.e. without any
              file extension like <filename>.php</filename> or
              <filename>.tpl</filename> after it). If the file
              <filename>&lt;template basename&gt;.php</filename> exists
              in the template directory, then Phorum will use that file
              as the template input.
              Else, <filename>&lt;template basename&gt;.tpl</filename> will
              be used.
            </para>
            <para>
              An example: if Phorum wants to display the "header" template,
              it will first search for <filename>header.php</filename> in
              the template directory. If that file does not exist, it will
              use <filename>header.tpl</filename> instead.
            </para>
            <para>
              PHP files (<filename>*.php</filename>) contain pure
              PHP/HTML code. In Phorum template files
              (<filename>.tpl</filename>) you can additionally
              make use of the <xref linkend="templates.templatelang"/>.
            </para>
            <para>
              Using this system, template authors can completely
              revert to using pure PHP-code for templates, without using
              the template language at all. The Phorum development team
              does not recommend doing this. To keep templates simple,
              always try to stick to the combination of HTML code and the
              template language.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>Other files and subdirectories</term>
          <listitem>
            <para>
              In most cases these will be image files which are stored
              in a subdirectory <filename>images</filename> of the
              template. But template authors are free to add
              whatever subdirectories and files they like to the
              template directory (e.g. Flash based page components,
              CSS stylesheets, audio files, JavaScript libraries, etc.).
            </para>
          </listitem>
        </varlistentry>
      </variablelist>
    </para>
    <para>
      Combining all this, the full tree for a typical template would
      look like this:
      <literallayout><literal>
{phorum dir}
 |
 +-- templates
    |
    +-- templatename
         |
         +-- info.php
         |
         +-- *.tpl
         |
         +-- images
              |
              +-- *.gif, *.jpg, *.png
      </literal></literallayout>
    </para>
  </section>

  <section>
    <title>How to start your own template</title>

    <para>
      Although you can start writing a new template totally from scratch,
      it is of course much easier to take an existing template and modify
      that one for your needs. Here are the steps that you have to take
      for accomplishing this:
    </para>

    <itemizedlist>

      <listitem>
        <para>
          <emphasis role="bold">Copy the default template</emphasis><sbr/>
          Take the default template directory from
          <filename>{phorum dir}/templates/default</filename> and
          copy it over to another directory, for example
          <filename>{phorum dir}/templates/mytpl</filename>.
        </para>
      </listitem>

      <listitem>
        <para>
          <emphasis role="bold">Edit info.php for your template</emphasis><sbr/>
          Edit
          <filename>{phorum dir}/templates/mytpl/info.php</filename>.
          In this file you have to edit at least the <literal>$name</literal>
          variable, e.g. to <literal>$name = "My very own template";</literal>
        </para>
        <para>
          You can hide the template from the user template selection
          boxes by setting <literal>$template_hide = 1</literal>.
          If you do this, you can only select this template through
          the admin interface.
        </para>
      </listitem>

      <listitem>
        <para>
          <emphasis role="bold">Configure Phorum to use your template</emphasis><sbr/>
          Open Phorum's admin page
          <filename>{phorum url}/admin.php</filename> and go to
          "Default Settings". There you will find the "Template" option.
          Set that option to your own template. All forums that
          inherit their settings from the default settings will use the
          template automatically. For other folders and forums, you will
          have to go to their settings pages to set their template to
          the default template as well.
        </para>
      </listitem>

    </itemizedlist>

    <para>
      That is it! You are now using your own template. From here on,
      you can start tweaking the template files in your
      <filename>{phorum dir}/templates/mytpl</filename> directory.
    </para>
    <para>
      Phorum uses its own template language to allow for dynamic templates
      without using PHP. More information on this can be found in
      the section about the <xref linkend="templates.templatelang"
      xrefstyle="template:Phorum template language"/>.
    </para>
  </section>

  <section id="templates.templatelang">
    <title>The Phorum template language</title>

    <section>
      <title>Introduction</title>
      <para>
        The largest part of the code that can be found in Phorum template
        files (<filename>*.tpl</filename>) is plain HTML. To be able to use
        and display the dynamic data that has been generated by Phorum
        (like message information, lists of private messages and search
        results), Phorum uses a custom template language which can be used
        to mix the HTML code with dynamic data. The template language is a
        very simple programming language with only a few statements to use.
        This section will describe the template language in detail.
      </para>
    </section>

    <section>
      <title>General syntax</title>
      <para>
        Templates are built using HTML code. Embedded in
        this HTML code, there can be template language statements. All
        template statements in the templates are surrounded by "{" and "}"
        characters. Here's a simple example of what a template could look
        like:

        <example><title>Template example</title><programlisting><![CDATA[
<html>
 <head>
<title>{HTML_TITLE}</title>
 </head>
 <body>
Your username is: {USER->username}

{IF USER->username "george"}
  <b>Hello, George!</b>
{/IF}
 </body>
</html> ]]></programlisting></example>

        Because curly braces have a special meaning in the templates, you have
        to take care when using them for other things than Phorum template
        code. This applies to plain PHP code, JavaScript code and CSS code
        that you use in your templates. To prevent the template engine from
        getting confused, you can add a space after "{" and before "}".
        Examples:
        <programlisting><![CDATA[
Code that will cause problems if used in a template file:

PHP: if ($a == $b) {print "They are the same!\n";}
JavaScript: if (a == b) {alert("They are the same!\n");}
CSS: #phorum .thing {font-size: 110%;}

What it should be written like:

PHP: if ($a == $b) { print "They are the same!\n"; }
JavaScript: if (a == b) { alert("They are the same!\n"); }
CSS: #phorum .thing { font-size: 110%; }<sbr/> ]]></programlisting>
      </para>
    </section>

    <section id="templates.datatypes">
      <title>Data types</title>

      <para>
        The template language supports four data types to use in statements:
        <itemizedlist>
          <listitem><xref linkend="templates.integers"
                          xrefstyle="template:Integers"/></listitem>
          <listitem><xref linkend="templates.strings"
                          xrefstyle="template:Strings"/></listitem>
          <listitem><xref linkend="templates.phpconstants"
                          xrefstyle="template:PHP Constants"/></listitem>
          <listitem><xref linkend="templates.templatevars"
                          xrefstyle="template:Template variables"/></listitem>
        </itemizedlist>
      </para>

      <section id="templates.integers">
        <title>Integers</title>
        <para>
          Integers are formatted as a sequence of numbers.
          <example><title>Integer values</title><programlisting>
403
90
4231 </programlisting></example>
          Here is an example of template code in which integers are used:
          <example><title>Code using integer values</title><programlisting><![CDATA[
{VAR INTEGERVAR 1000}
The variable INTEGERVAR is {INTEGERVAR}.

{IF INTEGERVAR 333}
  The INTEGERVAR has the value 333.
{/IF} ]]></programlisting></example>
        </para>
      </section>

      <section id="templates.strings">
        <title>Strings</title>
        <para>
          Strings are sequences of characters within quotes (both double and
          single quotes can be used).
          <example><title>String values</title><programlisting>
"this is a string value"
"My 1st string!"
'Single quoted string is possible too' </programlisting></example>
          Now if you need the quote which you used to surround the string
          with inside the string itself, you must escape it using \" or \'.
          This is consistent with the way that PHP strings are escaped.
          <example><title>Escaped quotes in string values</title><programlisting>
"this is a \"string\" value"
'Single quoted \'string\' value'
"You can use both \" and ' for strings!"</programlisting></example>
          Here are some examples of template code in which strings are used:
          <example><title>Code using string values</title><programlisting><![CDATA[
{VAR QUESTION "Do you know what \"fubar\" means?"}
{VAR CORRECT "That was the right answer!"}
{VAR INCORRECT "No.. you were wrong!"}

{IF ANSWER 'Fucked Up Beyond All Recognition'}
  {CORRECT}
{ELSE}
  {INCORRECT}
{/IF} ]]></programlisting></example>
        </para>
      </section>

      <section id="templates.phpconstants">
        <title>PHP constants</title>

        <para>
          It is possible to define constants within PHP. This is done using
          the define() PHP statement. Here's an example:
          <programlisting>
&lt;?php define("MY_CONSTANT", "The constant value") ?&gt;</programlisting>
          You can reference PHP constants from the template language by
          using its name, without any quotes. So the constant that was
          defined in the code above, can be used like this in a template:
          <example><title>Code using a PHP constant definition</title><programlisting>The value of my PHP constant is {MY_CONSTANT}</programlisting></example>
          Apart from defining your own PHP constants, you can also use
          constants that are already defined by PHP. Two useful constants to
          use are <literal>true</literal> (value = 1) and
          <literal>false</literal> (value = 0). Using these, you can
          write template code like this:
          <example><title>Code using built-in PHP constants</title><programlisting><![CDATA[
{VAR SOME_OPTION true}

{IF SOME_OPTION true}
  The option SOME_OPTION is true.
{/IF} ]]></programlisting></example>
        </para>
      </section>

      <section id="templates.templatevars">
        <title>Template variables</title>

        <para>
          About the most important data type for the template language is
          the template variable. Template variables are used by Phorum to
          store dynamic data, which can be used by your templates.
          You can also use the variables for storing dynamic data of
          your own from the templates. Template variables can contain both
          simple values and complex arrays of data.
        </para>
        <para>
          You can reference a template variable by using the variable's name,
          without any quotes.
          <note>
            This is the same type of notation as the one that is used for
            referencing PHP constants
            (see <xref linkend="templates.phpconstants"/>).
            If there are both
            a constant and a variable with the same name, the value of the
            contstant will take precedence over the template variable.
          </note>
          <example><title>Template variables</title><programlisting>
NAME
HTML_TITLE
MESSAGES</programlisting></example>
          In case the variable represents an array, you can reference
          the array elements by using the following pointer notation:
          <example><title>Referencing elements in a template variable array</title><programlisting>
ARRAYVARIABLE-&gt;SIMPLE_ELEMENT
ARRAYVARIABLE-&gt;ARRAY_ELEMENT-&gt;SIMPLE_ELEMENT</programlisting></example>
          Within a template, variables are used like this:
          <example><title>Code using template variables</title><programlisting><![CDATA[
{VAR MY_VAR "Assign a value to a variable from the template"}

You username is: {USER->username}<br/>
The current forum's name is: {NAME}<br/>

{LOOP MESSAGES}
  Subject: {MESSAGES->subject}<br/>
{/LOOP MESSAGES} ]]></programlisting></example>
          What variables are available for what template pages is fully
          determined by Phorum.
        </para>
      </section>
    </section>

    <section>
      <title>Statements</title>

      <para>
        The template language has a number of statements that can be
        used for executing templating actions and decisions.
        <itemizedlist>
          <listitem><xref linkend="templates.display"
                          xrefstyle="template:Display a variable"/></listitem>
          <listitem><xref linkend="templates.comments"
                          xrefstyle="template:In line comments"/></listitem>
          <listitem><xref linkend="templates.define"
                          xrefstyle="template:DEFINE"/></listitem>
          <listitem><xref linkend="templates.var"
                          xrefstyle="template:VAR"/></listitem>
          <listitem><xref linkend="templates.if"
                          xrefstyle="template:IF .. ELSEIF .. ELSE .."/></listitem>
          <listitem><xref linkend="templates.loop"
                          xrefstyle="template:LOOP"/></listitem>
          <listitem><xref linkend="templates.include"
                          xrefstyle="template:INCLUDE"/></listitem>
          <listitem><xref linkend="templates.hook"
                          xrefstyle="template:HOOK"/></listitem>
        </itemizedlist>

      </para>

      <section id="templates.display">
        <title>Display a variable</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem><para>
                This is both the most simple and the most important template
                statement there is. Using this statement, you can display
                the contents of a value.
              </para></listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[{<VALUE>}]]></literal>
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>Display a variable</title><programlisting><![CDATA[
The name of the current forum is: {NAME} ]]></programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.comments">
        <title>In line comments</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem><para>
                Sometimes, it's useful to explain what you are doing when
                writing complicated templating code. In that case you can
                use comments to document what you are doing.
                You can also use comments to add general info to the
                template (like in the example below).
              </para></listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[{! <COMMENT TEXT>}]]></literal>
                </para>
                <para>
                  The <literal>&lt;COMMENT TEXT&gt;</literal> can contain
                  any characters you like, except for "}".
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>Add in line comments</title><programlisting>
{! This template was created by John Doe and his lovely wife Jane } </programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.define">
        <title>DEFINE</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  Using this statement, you can set definitions that
                  can be used by the Phorum software. These are mainly used
                  for doing settings from the template file "settings.tpl"
                  to tweak Phorum's internal behaviour.
                </para>
                <para>
                  Definitions that have been set using this statement are
                  not available from other template statements.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[{DEFINE <PHORUM DEFINITION> <VALUE>}]]></literal>
                </para>
                <para>
                  What you can use for
                  <literal>&lt;PHORUM DEFINITION&gt;</literal> is fully
                  determined by the Phorum software (and possibly modules).
                  The <literal>&lt;VALUE&gt;</literal> can be any of
                  the data types that are supported by the template
                  language (see <xref linkend="templates.datatypes"/>).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>DEFINE statement usage</title><programlisting>
{DEFINE list_pages_shown 5}</programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.var">
        <title>VAR</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  Using this statement, you can set variable definitions
                  that can be used by the Phorum template language.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[{VAR <TEMPLATE VARIABLE> <VALUE>}]]></literal>
                </para>
                <para>
                  <literal>&lt;TEMPLATE VARIABLE&gt;</literal> can be an
                  existing or a new variable name
                  (see <xref linkend="templates.templatevars"/>).
                  The <literal>&lt;VALUE&gt;</literal> can be any of
                  the data types that are supported by the template
                  language (see <xref linkend="templates.datatypes"/>).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>VAR statement usage</title><programlisting>
{VAR MY_VAR "This is my first variable!"}
{VAR MY_VAR OTHER_VAR}
{VAR MY_VAR 1234}

{VAR IS_COOL true}
{IF IS_COOL}
  Yes, this is cool
{/IF} </programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.if">
        <title>IF .. ELSEIF .. ELSE ..</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  Using these statements, you can control if certain blocks
                  of code in your template are processed or not, based on
                  a given <literal>&lt;CONDITION&gt;</literal>.
                  This can for example be useful if you want certain
                  parts of the page to be only visible for registered users.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literallayout><literal><![CDATA[
{IF <CONDITION>}
  .. conditional code ..
[{ELSEIF <CONDITION>}
  .. conditional code ..]
[{ELSE}
  .. conditional code ..]
{/IF}

<CONDITION> Syntax: [NOT] <TEMPLATE VARIABLE> [<VALUE>]
                  ]]></literal></literallayout>
                </para>
                <para>
                  The <literal>&lt;TEMPLATE VARIABLE&gt;</literal> in a
                  <literal>&lt;CONDITION&gt;</literal> has to be an
                  existing variable name.
                  The <literal>&lt;VALUE&gt;</literal> can be any of
                  the data types that are supported by the template
                  language (see <xref linkend="templates.datatypes"/>).
                </para>
                <para>
                  If a <literal>&lt;VALUE&gt;</literal> is used, the
                  <literal>&lt;TEMPLATE VARIABLE&gt;</literal> will be
                  compared to the <literal>&lt;VALUE&gt;</literal>.
                  If the <literal>&lt;VALUE&gt;</literal> is omitted,
                  then the condition will check whether the
                  <literal>&lt;TEMPLATE VARIABLE&gt;</literal> is set
                  and not empty.
                </para>
                <para>
                  A condition can be negated by prepending the keyword
                  <literal>NOT</literal> to it.
                </para>
                <para>
                  Multiple conditions can be chained using the keywords
                  <literal>AND</literal> or <literal>OR</literal>.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>IF .. ELSEIF .. ELSE .. statement usage</title><programlisting><![CDATA[
{IF NOT LOGGEDIN}
   You are currently not logged in.
{ELSEIF USER->username "John"}
   Hey, it's good to see you again, mr. John!
{ELSE}
   Welcome, {USER->username}!
{/IF}

{IF ADMINISTRATOR true OR USER->username "John"}
   You are either an administrator or John.
{/IF}

{IF VARIABLE1 VARIABLE2}
   Variable 1 and 2 have the same value.
{/IF} ]]></programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.loop">
        <title>LOOP</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  The LOOP statement is used for looping through the
                  elements of array based template variables (for example
                  arrays of forums, messages and users).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literallayout><literal><![CDATA[
{LOOP <ARRAY VARIABLE>}
  {<ARRAY VARIABLE>}
{/LOOP <ARRAY VARIABLE>}
                  ]]></literal></literallayout>
                </para>
                <para>
                  The <literal>&lt;ARRAY VARIABLE&gt;</literal> has to
                  be the name of an existing template variable containing
                  an array.
                </para>
                <para>
                  Within the LOOP, the active array element is assigned to a
                  variable that has the same name as the
                  <literal>&lt;ARRAY VARIABLE&gt;</literal> that you are
                  looping over. In our example below, we are looping over
                  <literal>USERS</literal>, which is an array of user
                  data records. Within the loop, <literal>USERS</literal>
                  is no long the array of users itself, but the user data
                  record for a single user instead.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>LOOP statement usage</title><programlisting><![CDATA[
<ul>
{LOOP USERS}
  <li>{USERS->username}</li>
{/LOOP USERS}
</ul> ]]></programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.include">
        <title>INCLUDE</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  Include another template in the template.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[
{INCLUDE [ONCE] <INCLUDE PAGE>}
                  ]]></literal>
                </para>
                <para>
                  The <literal>&lt;INCLUDE PAGE&gt;</literal> can be any of
                  the data types that are supported by the template
                  language (see <xref linkend="templates.datatypes"/>).
                </para>
                <para>
                  By specifiying the keyword <literal>ONCE</literal> before
                  the name of template to include, you can make sure that
                  that template is only included once per page.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>INCLUDE statement usage</title><programlisting><![CDATA[
{INCLUDE "paging"}

{VAR include_page "cool_include_page"}
{INCLUDE include_page}

{INCLUDE ONCE "css"} ]]></programlisting></example>
              </para></listitem>
            </varlistentry>
            <varlistentry>
              <term>Limitiation</term>
              <listitem>
                <para>
                  It is not possible to use a dynamic INCLUDE statement
                  (one where the <literal>&lt;INCLUDE PAGE&gt;</literal>
                  is set through a template variable) within a LOOP
                  statement, in case the included template needs to have
                  access to the active LOOP element. There is no problem if
                  you use a static INCLUDE statement (one where the
                  <literal>&lt;INCLUDE PAGE&gt;</literal> is set through
                  a string value).
                </para>
                <para>
                  If you really need this kind of functionality though, you
                  can work around this limitation by assigning the active
                  LOOP element to a new template variable, prior to
                  including the dynamic
                  <literal>&lt;INCLUDE PAGE&gt;</literal>. Example:
                  <programlisting><![CDATA[
{! include_page holds the dynamic page to include }
{VAR include_page "some_page"}

{LOOP loop_variable}
  {! Makes loop_variable available as temp_variable in the include }
  {VAR temp_variable loop_variable}
  {INCLUDE include_page}
{/LOOP loop_variable} ]]></programlisting>
                  This way you can access the active LOOP element from the
                  included template through <literal>temp_variable</literal>.
                  If you would access <literal>loop_variable</literal>
                  from there, you'd see that it does not contain the
                  active LOOP element, but the full array that you are
                  looping over instead.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

      <section id="templates.hook">
        <title>HOOK</title>
        <para>
          <variablelist>
            <varlistentry>
              <term>Function</term>
              <listitem>
                <para>
                  The HOOK statement can be used to run a module hook
                  from a template. By using hooks in the templates,
                  you have an easy way for modules to add data to a page,
                  without having to change the templates too much.
                  Because these hooks need an activated module that
                  acts upon them, creating HOOK statements is certainly
                  for advanced users only.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Syntax</term>
              <listitem>
                <para>
                  <literal><![CDATA[
{HOOK <HOOK NAME> [<ARG1> <ARG2> .. <ARGn>]}
                  ]]></literal>
                </para>
                <para>
                  Both the <literal>&lt;HOOK NAME&gt;</literal> and the
                  arguments that are used in the HOOK statement can be any
                  of the data types that are supported by the template
                  language (see <xref linkend="templates.datatypes"/>).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>How hook functions are called</term>
              <listitem>
                <para>
                  Depending on the number or arguments that are used in the
                  HOOK statement, different type of calls are made to the
                  hook function for the given
                  <literal>&lt;HOOK NAME&gt;</literal>.
                  <itemizedlist>
                    <listitem>
                      <emphasis>No arguments:</emphasis><sbr/>
                      the hook function is called without any
                      arguments at all:<sbr/>
                      <literal>hook_function()</literal>
                    </listitem>
                    <listitem>
                      <emphasis>One argument:</emphasis><sbr/>
                      The single argument is used directly for calling
                      the hook function:<sbr/>
                      <literal>hook_function($ARG1)</literal>
                    </listitem>
                    <listitem>
                      <emphasis>Multiple arguments:</emphasis><sbr/>
                      The arguments are wrapped in an array, which is then
                      used for calling the hook function:<sbr/>
                      <literal>hook_function(array($ARG1,$ARG2,..$ARGn))</literal>
                    </listitem>
                  </itemizedlist>
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>Example code</term>
              <listitem><para>
                <example><title>HOOK statement usage</title><programlisting><![CDATA[
{HOOK "template_hook"}

{LOOP MESSAGES}
  {HOOK "show_message" MESSAGES}
{/LOOP MESSAGES}

{VAR HOOKNAME "my_magic_hook"}
{HOOK HOOKNAME "my argument"} ]]></programlisting></example>
              </para></listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>

    </section>

    <section>
      <title>Need the power of PHP?</title>

      <para>
        Template writers for whom the template language is too limited
        can break into PHP at any point in the templates, using the
        regular <literal>&lt;?php ... ?&gt;</literal> syntax. It is not
        mandatory at all to use the Phorum template language for your
        templates.
      </para>

      <para>
        The biggest drawback here, is that knowledge of the Phorum
        internals is required if you want to work with the data that
        has been generated by Phorum.
      </para>

      <para>
        Most template writers will normally only be using HTML and the
        Phorum template language.
      </para>

      <important>
        <para>
          To prevent confusion between PHP code blocks and template
          statements (which are both surrounded by "{" and "}" characters),
          always use a whitespace after an opening "{" character in your PHP
          code. So instead of writing:
          <programlisting><![CDATA[
<?php if ($this = true) {print "It's true";} ?> ]]></programlisting>
          you now have to write:
          <programlisting><![CDATA[
<?php if ($this = true) { print "It's true"; } ?>]]></programlisting>
          This way you can mix PHP code with template code without running
          into problems.
        </para>
      </important>

    </section>


  </section>

</chapter>
