
XHTML Templates Reference
=========================

NOTE: For almost every element, the opening and closing tags
    are required to be in a single line and alone, in order to
    be processed correctly, like this:
        <Element>
            Element content here.
        </Element>
    This restriction is imposed by the current implementation 
    and will be removed later when the templates will be 
    processed using an XML parser.
    
    Also, the names of the elements and the attributes are
    case sensitive and they must be used the same as they are
    in the documentation. E.g. if you use <recordset> instead
    if <Recordset> it will not work.
    

* Comments
==========
    <!--# Comments are denoted like this #-->
    <!--# diesis at the beginning, diesis at the end #-->
    <!--#
        Such comments are not included
        in the XHTML file that is generated 
        and sent to the browser.
    #-->
    <!--
        Usual XHTML comments (like this one) are passed to
        the XHTML file that is generated from the template.
    -->
    
    Note: For the time being, the beginning of the comment
        requires an empty space after it "<!--# " in order to be
        recognized as a comment, and everything in the line
        of the closing comment "#-->", even after it, is treated
        as a comment and is discarded. This restrictions come from
        the current implementation and later they will be removed.


* Include elements
==================
    <Include SRC="templates/header.html"/>
    <Include SRC="{{#content_file}}"/>

    <!--#
        The <Include> element is used to include a template
        inside another template. This provides to the application
        modularity and more flexibility.
        
        The modularity consists in breaking a large page into
        smaller templates, and in using the same template in 
        several pages.
        
        The flexibility consists in this: the file that will be 
        included may be a variable (or may contain variables), so
        different files may be included in the same place of the page,
        according to the logic of the application.
    #-->


* Repeat elements
=================

    <Repeat rs="rsID">
        <IfEmpty>
            <!--# <IfEmpty> is included in the page in case 
                that recordset specified has no records #-->
            <tr>
                <td>No articles found!</td>
            </tr>
        </IfEmpty>
        <Header>
            <!--# <Header> is processed before 
                the repeated part (only once) #-->
        </Header>
        <RepeatBody>
            <!--# 
                Here comes the part that is repeated
                for each record in the recordset. The tag 
                <RepeatBody> is optional and may be omitted
            #-->
            <tr>
                <td> {{#TI}} </td>
                <td> {{#AU}} </td>
                . . .
            </tr>
        </RepeatBody>
        <Separator>
            <!--# <Separator> is processed between 
                two repetitions of the <RepeatBody> #-->
            <tr><td colspan="3"> <hr width="90%"> </td></tr>
        </Separator>
        <Footer>
            <!--# <Footer> is processed after 
                the repeated part (only once) #-->
        </Footer>
    </Repeat>
    
    <!--#
        The <Repeat> element is connected with a recordset by the attribute
        "rs". Its body is processed for each row of the recordset. Before
        processing the content for a certain row, all the fields of the recordset
        are declared as variables with values taken from the current record.

        In case that the recordset is empty, then the element <IfEmpty> is
        processed instead. It is optional.
        
        The elements <Header> and <Footer> are processed before the
        repetition starts and after the repetition is done. They are
        optional.
        
        The <Separator> element is processed between two repetitions
        of the body of the <Repeat>. It is optional.
        
        Everything inside the <Repeat> element and outside the
        elements <IfEmpty>, <Header>, <Footer> and <Separator> is
        considered as body of the <Repeat> and is processed for
        each record of the recordset. To make it more readable, the
        tags <RepeatBody> and </RepeatBody> may be used, but they
        are just "syntactic sugar" and don't influence anything;
        they are optional and may be omitted.
    #-->


* <If> element
===============
    <If condition="!{{#logged}}">
        <!--# login template comes here #-->
        <!--# . . . . . . . . . . . . . #-->
    </If>

    <!--#
        The content of the <If> element is processed conditionally:
        if the value of the attribute "condition" is true, then it
        is processed, otherwise it is not processed.

        The value of the condition is calculated as a PHP expression
        (after the template variables have been replaced).
    #-->


* <Recordset> elements
=======================
    <Recordset ID="rsID">
        <Query> select {{#R_NAME}} from table </Query>
    </Recordset>

    <!--#
        Each recordset has a unique ID. Later, when we use
        this recordset (e.g. in a <Repeat> element) we refer
        to it by this ID. It also has a <Query> element, which
        is executed using the default database connection.
        
        The query may contain variables, which are replaced at 
        the time that the query is executed.
    #-->
    
    <Recordset ID="doc">
        <Query>
            Select NAME_D, 
                   SURNAME_D 
            From DOCTOR
            Where condition
            Group By field
        </Query>
    </Recordset>

    <--#
        If the query is a big one, then it can be declared in several 
        lines (in order to be more readable and editable).
    #-->

* Recordsets that are displayed over several pages
===================================================
    <Recordset ID="art" recs_per_page="10">
        <Query>{{#ART_QUERY}}</Query>
    </Recordset>
    
    <!--#
        Recordsets that have a "recs_per_page" attribute are
        recordsets that are displayed over several pages.
        It retrievs from the database only one page at a time,
        out of all the results that the query may return.
        A page is a group of consecutive records, all the pages 
        have the same number of records and they form a partition 
        of all the records of the query.
        
        In this case some additional variables are declared
        which show which records are being displayed, how many
        pages are there, and at which page we are currently.
        These variables are declared during the processing of the
        <Repeat> elements, and are usually used in <Header> and <Footer>.

        These variables are:
        {{#FirstRec}}   --  the number of the first record of the page
        {{#LastRec}}        --  the number of the last record of the page
        {{#AllRecs}}        --  the number of all records that can be retrieved by the query
        {{#CurrPage}}   --  current page of records that is retrieved
        {{#NextPage}}   --  the number of the next page
        {{#PrevPage}}   --  the number of the previous page
        {{#LastPage}}   --  the number of the last page
        
        Also, the following variables are declared each time 
        that the body of the <Repeat> element is processed:
        {{#CurrentRecNr}}   --  the number of the current record
        {{#CurrentRowNr}}   --  the number of the current row

        (These can be used to define other variables, like this:
        <Var name="bgColor">({{#CurrentRowNr}}==5 ? "red" : "grey")</Var>
        and then use {{#bgColor}} )
    #-->


* <Var> elements
=================
    <Var name="SUM">{{#field1}} + {{#field2}} + {{#field3}}</Var>
    <Var name="ROW_COLOR">({{#CurrentRowNr}}%2 ? "tabgrey" : "tabwhite")</Var>
    <tr class="{{#ROW_COLOR}}"> . . . </tr>
    
    <!--#
        <Var> elements declare variables that can be used anywhere in the
        template in the current scope and in the scopes inside it. They
        are identified by their name, and their value is calculated using
        their content. The value of a variable is calculated in this way:
        first, any template variable inside them is found and replaced,
        then the resulting string is evaluated as a PHP expression.

        A variable defined by <Var> is evaluated at the time that 
        it is processed, so that if a variable is inside a <Repeat> 
        element, then it may have different values for different 
        iterations.
        
        Note: All the <Var> element must be declared in a single line,
            in order to be processed correctly. This restriction is
            imposed by the current implementation and it will be 
            removed later.
    #-->


* Template {{#variables}}
=========================
    <!--#
        Anywhere in XML where we can put character data,
        we can also put {{#variables}}, which are replaced
        by their string values at the time of template
        processing and conversion to XHTML.
        
        For more details see the file: 'variables.txt' .
        
        Note: The current implementation actually is not based on
            XML parsing, and the variables are recognized and
            replaced only in certain attributes (which are indicated
            in the documentation) and in every line that is not
            part of a framework tag (is not inside the <tag denoters>).
    #-->
    
    
* WebBox-es
============

    <WebBox ID="boxID">
        <!-- content of WebBox -->
    </WebBox>
        
<!--#
    A WebBox is a template which has also its own PHP code, which
    handles its server-side logic. It is an almost self-contained
    and independent template which can be easily included in other
    pages or in other projects.
    
    For more details see the file: 'webox.txt' .
#-->


* - Variables can also be used in the 'rs' attribute of a <Repeat> tag,
    e.g.   <Repeat rs="{{rs_id}}"> . . . </Repeat> .
    This allows a repeat block to use different queries in different
    cases (according to the logic of the program). These variables
    are evaluated at the parse time, at the time that the repeat
    element is parsed. So, if you give value to this variable inside
    the function onRender(), it will not get it; instead it should be
    given value in the function onParse(), or it should be a state 
    variable or global variable.

* - The syntax of tag Recordset now is:
    <Recordset ID="rsID" type="rsType">
    where 'rsType' can be one of the values: "StaticRS", "DynamicRS",
    "EditableRS", "PagedRS", "TableRS". The attibute type can be
    omitted; in this case the default value is "StaticRS".

    A 'static' recordset is the recordset described above, a RS that
    cannot be opened more than once per page. A 'dynamic' RS is a
    recordset that evaluates its query (replaces its {{variables}}),
    executes it and refreshes the content each time that its
    method Open() is called. Notice that before a recordset was
    'dynamic' by default and 'static' only if specified, but now a
    RS is 'static' by default (if no type is given). This is
    because 'static' recordsets are more common in web applications
    and 'dynamic' recordsets are useful only in special cases, 
    e.g. when we have two nested recordsets (associated with two
    nested <Repeat>s) and the inner RS uses a {{variable}} provided
    by the outer RS.

    A 'PagedRS' is a recordset that divides  the results of the
    query into pages of certain size, and retrives from DB only
    one page of them. It requires the attribute 'recs_per_page',
    which specifies the size of the page. It is used to display
    big recordsets, when they cannot fit in a single HTML page.

    An 'EditableRS' is a RS that can be modified from the PHP code.
    The programer can retrive the results of a query from DB and
    then modify them, or start with an empty RS and fill it 
    programatically. It makes possible to use templates for results
    that don't come from DB (e.g. when you want to display a folder
    listing and you get the files and folders using some PHP functions).

    This feature can be used in the "folderListing" webbox, for
    example. Instead of generating all the html code of the 
    folder listing programatically, a <Repeat> template, associated
    with a <Recordset> could be used, and this recordset could be
    filled from an array or from php code (instead of being filled
    from database).
    The benefit of this aproach (vs. generatin all the html code
    in php) would be that we are able to change the layout of the
    'folderListing' webbox more easily, because instead of changing
    the php code, we change only a template.

--------------------------------------------------------------
* - <Repeat rs="{{tpl_var}}">
    The attribute rs of the <Repeat> tag can contain variables
    (so that the same repeat can use different recordsets, 
    according to the logic of the program). These variables
    are evaluated now in render time (before they were evaluated
    in parse time) because this is more convenient.

--------------------------------------------------------------------
* - The tag <WebObject> can be written in several lines (for making it
    more readable, in case that it has many attributes) and the parser
    can handle it. E.g.
        <WebObject Class = "listbox" Name  = "country" 
                   rs    = "rs_id" 
                   width = "---------------" />

--------------------------------------------------------------------
* - The recordsets declared by the <Recordset> tag were by default
    of type "StaticRS". Now the default type is "EditableRS",
    because this is more useful (and anyway EditableRS extends StaticRS).
    It can be declared explicitly as "StaticRS" only when the programer 
    has strong reasons to disallow the modification of this recordset
    from the PHP code.

TODO: Add a separate section for Recordsets and the <Repeat> tag.

* - The expression of the <Var> tag can now be declared in several 
    lines, like this:
    <Var name="class">
      ( 
        "{{item}}"=="{{{{obj_id}}->selected_item}}" ? 
            "leftMenu-item-selected" 
            :"leftMenu-item"
      )
    </Var>
