[phpwebapp-commits] CVS: books/content/initial_xml phpwebapp_manual_en.xml,1.2,1.3
Brought to you by:
dashohoxha
From: Dashamir H. <das...@us...> - 2005-11-12 12:15:28
|
Update of /cvsroot/phpwebapp/books/content/initial_xml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31350/content/initial_xml Modified Files: phpwebapp_manual_en.xml Log Message: Index: phpwebapp_manual_en.xml =================================================================== RCS file: /cvsroot/phpwebapp/books/content/initial_xml/phpwebapp_manual_en.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** phpwebapp_manual_en.xml 12 Nov 2005 12:12:04 -0000 1.2 --- phpwebapp_manual_en.xml 12 Nov 2005 12:15:20 -0000 1.3 *************** *** 124,233 **** <title>Templates</title> <para>Templates are XHTML files which can contain some additional tags and some variables. These tags and variables are processed by the framework and are replaced with HTML code when the web page is created. These templates allow the web page designer to work almost independently from the database designer and from the PHP programmer that implements the logic of the application. </para> ! <para>Some of the extra tags that can be used in templates are: <Include>, &amp;lt;If&amp;gt;, &amp;lt;Repeat&amp;gt;, &amp;lt;WebBox&amp;gt;, &amp;lt;Recordset&amp;gt;, etc. They can be mixed and nested without problem (except for some special cases). </para> <section id="xhtml"> <title>The XHTML Standard</title> <para>The main (root) template of the page should start like this: ! <programlisting>&lt;?xml version="1.0" encoding="iso-8859-1"?&gt; ! &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ! "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt; ! &lt;html xmlns="http://www.w3.org/1999/xhtml" lang="EN"&gt; ! </programlisting> ! because if no DOCTYPE is defined, the parser will have problems with reckognizing entities (&amp;amp;nbsp; &amp;amp;amp; etc.), and there may be any other problems as well. </para> <para>For the other templates (which are included from another one), these headers shoud not be added, because the parser will add them automatically, so that they become well-formed xml and are parsed successfully. The headers that will be added to the other templates will be a copy of the headers of the main template. </para> <para>If the included templates do have the prolog and the root element, it has no effect in the generated page, because the framework will just discard them. On the other hand, it is not practical to include the prolog and the root element in each template; some of them may be just small templates, like this one: ! <programlisting>&lt;tr&gt; ! &lt;td&gt;...&lt;/td&gt; ! &lt;/tr&gt; ! </programlisting></para> ! <para>The templates must be well-formed XML files. This is required by the framework because it uses an XML parser to parse them, and if a template is not well-formed, the parser will not be able to parse it and will display an error. E.g. <emphasis>&amp;lt;br/&amp;gt;</emphasis> must be used instead of <emphasis>&amp;lt;br&amp;gt;</emphasis> , <emphasis>&amp;lt;img ... /&amp;gt;</emphasis> instead of <emphasis>&amp;lt;img ...&amp;gt;</emphasis> , etc. (see <ulink url="http://www.w3schools.com/xhtml/xhtml_html.asp">XHTML vs HTML</ulink> for more details about these). </para> <para>Except the usual XHTML tags, the templates can also contain extra elements (tags), which are reckognized and processed by the framework. For the framework it doesn't matter the case (upper/lower) of these tags, however it is good to keep them in lowercase, since all the other XHTML tags are required to be lowercase (by the XHTML standard). </para> <para>So, the templates may not be fully compliant to the XHTML standard, due to the additional things that are supported by the framework. However, the page that the framework generates from them and which is sent to the browser, is a valid XHTML page. </para> ! <para>The framework preserves any CDATA marks that are found in the templates (this means that they still apear in the resulting page). This is important because the javascript code in an XHTML page needs to be written inside a CDATA section and, if the framework did not preserve the CDATA marks, the resulting page would not be a valid XHTML page. </para> ! <para>Another issue related to XML is this: each xml parser is required to process the entities: &amp;amp;amp; &amp;amp;lt; &amp;amp;gt; &amp;amp;quot; and &amp;amp;apos; and to return the corresponding character instead of the entity itself. For this reason, in order to include e.g. an ampersand in a page, it is not enough to write it in template as <emphasis>&amp;amp;amp;</emphasis> but it should be written as <emphasis>&amp;amp;amp;amp;</emphasis> . The same goes for &amp;amp;amp;lt;, &amp;amp;amp;quot;, etc. </para> </section> <section id="tpl-comments"> <title>Comments</title> <para>Template comments are just like usual XHTML comments, but they are discarded by the framework when the template is processed. They are denoted by adding a diesis after the opening mark: </para> ! <programlisting>&lt;!--# Such comments are not included in the XHTML file that is generated and sent to the browser. ! --&gt; ! &lt;!-- Usual XHTML comments (like this one) are passed to the XHTML file that is generated from the template. ! --&gt; ! </programlisting> </section> <section id="tpl-include"> <title>Include</title> ! <para>The <emphasis>&amp;lt;Include&amp;gt;</emphasis> element is used to include a template inside another template: ! <programlisting>&lt;include src="templates/header.html" /&gt; ! &lt;include src="{{content_file}}" /&gt; ! &lt;include src="{{./}}edit/cluster_edit.html" /&gt; ! </programlisting></para> <para>It 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. </para> <para>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. The variables used here are evaluated when the template is parsed, so they should be parse-time variables (see later about what this means). </para> <tip> ! <para>Note in the last example the variable <emphasis>{{#./}}</emphasis> . It is defined automatically by the framework and it allways keeps the path of the current directory (the directory of the template that contains the <emphasis>&amp;lt;include&amp;gt;</emphasis> ). This allows the usage of relative paths in the "src" attribute, and it makes the application more flexible. So, the directory containing the template can be renamed or moved to another location, however the paths of the included files need not to be changed since they are relative to the current directory.</para> </tip> </section> <section id="tpl-if"> <title>If</title> ! <para>The content of the element <emphasis>&amp;lt;If&amp;gt;</emphasis> is included in the resulting page conditionally. If the value of the attribute "condition" is true, then it is included, otherwise it is skiped. </para> ! <programlisting>&lt;if condition="!{{admin}}"&gt; ! &lt;a class="button" href="javascript:edit()"&gt;Edit&lt;/a&gt; ! &lt;/if&gt; ! </programlisting> <para>The value of the condition is calculated as a PHP expression (after the template variables have been replaced). The evaluation of the condition is done at the render time (when the page is generated, see later about parse and render), so they should be render-time variables. </para> <tip> ! <para>Use <emphasis>!=</emphasis> instead of <emphasis>&amp;lt;&amp;gt;</emphasis> in the expression of the condition, because the xml parser complains about the characters &amp;lt; and &amp;gt; inside the value of an attribute. ! <programlisting>This is wrong: &lt;if condition="'{CurrPage}'&lt;&gt;'{PrevPage}'"&gt;...&lt;/if&gt;</programlisting><programlisting>This is right: &lt;if condition="'{CurrPage}'!='{PrevPage}'"&gt;...&lt;/if&gt;</programlisting></para> </tip> </section> <section id="tpl-repeat"> <title>Repeat</title> ! <para>The <emphasis>&amp;lt;Repeat&amp;gt;</emphasis> element is used to repeat a part of the template several times: ! <programlisting>&lt;table&gt; ! &lt;repeat rs="rs_id"&gt; ! &lt;tr&gt;&lt;td&gt;{{field_name}}&lt;/td&gt;&lt;/tr&gt; ! &lt;/repeat&gt; ! &lt;/table&gt; ! </programlisting></para> ! <para>It is useful e.g. for constructing tables, when you want to add a row for each record in the result of a DB query. The attribute <emphasis>rs</emphasis> is the id of a recordset<footnote><para>A recordset is an object that contains the results of a DB query.</para></footnote> . The body of the &amp;lt;repeat&amp;gt; will be repeated for each record of the recordset. Each time, the fields of the record will be used as template variables for it. </para> ! <para>In case that the recordset is empty, the content of the element <emphasis>&amp;lt;IfEmpty&amp;gt;</emphasis> (if present) is displayed instead of the body. The <emphasis>&amp;lt;Separator&amp;gt;</emphasis> element is displayed between two repetitions of the body of the &amp;lt;Repeat&amp;gt;. It is optional. </para> ! <para>The elements &amp;lt;IfEmpty&amp;gt; and &amp;lt;Separator&amp;gt; can be placed anywhere inside the &amp;lt;Repeat&amp;gt;. Everything inside the &amp;lt;Repeat&amp;gt; element and outside the elements &amp;lt;IfEmpty&amp;gt; and &amp;lt;Separator&amp;gt; is considered as body of the &amp;lt;Repeat&amp;gt; and is processed for each record of the recordset. To make it more readable, the tag <emphasis>&amp;lt;RepeatBody&amp;gt;</emphasis> may be used, but it is just "syntactic sugar" and doesn't effect anything. It is optional and usually is omitted. </para> ! <programlisting>&lt;table&gt; ! &lt;repeat rs="rs_id"&gt; ! &lt;ifempty&gt; ! &lt;!--# &lt;IfEmpty&gt; is included in the page in case ! that recordset specified has no records #--&gt; ! &lt;tr&gt; ! &lt;td&gt;No articles found!&lt;/td&gt; ! &lt;/tr&gt; ! &lt;/ifempty&gt; ! &lt;repeatbody&gt; ! &lt;!--# Here comes the part that is repeated for each record in the recordset. The tag ! &lt;RepeatBody&gt; is optional and may be omitted ! #--&gt; ! &lt;tr&gt; ! &lt;td&gt; {{TI}} &lt;/td&gt; ! &lt;td&gt; {{AU}} &lt;/td&gt; . . . ! &lt;/tr&gt; ! &lt;/repeatbody&gt; ! &lt;separator&gt; ! &lt;!--# &lt;Separator&gt; is processed between ! two repetitions of the &lt;RepeatBody&gt; #--&gt; ! &lt;tr&gt;&lt;td colspan="3"&gt; &lt;hr width="90%" /&gt; &lt;/td&gt;&lt;/tr&gt; ! &lt;/separator&gt; ! &lt;/repeat&gt; ! &lt;/table&gt; ! </programlisting> <para>The value of the "rs" attribute can also contain variables, like this: ! <programlisting>&lt;repeat rs="{{rs_id}}"&gt; . . . &lt;/repeat&gt;</programlisting> This allows a repeat block to use different queries in different cases (according to the logic of the program). These variables are evaluated in render time (it should be assigned in the function onParse(), or it should be a state variable or global variable). </para> </section> --- 124,240 ---- <title>Templates</title> <para>Templates are XHTML files which can contain some additional tags and some variables. These tags and variables are processed by the framework and are replaced with HTML code when the web page is created. These templates allow the web page designer to work almost independently from the database designer and from the PHP programmer that implements the logic of the application. </para> ! <para>Some of the extra tags that can be used in templates are: <Include>, <If>, <Repeat>, <WebBox>, <Recordset>, etc. They can be mixed and nested without problem (except for some special cases). </para> <section id="xhtml"> <title>The XHTML Standard</title> <para>The main (root) template of the page should start like this: ! <programlisting><![CDATA[<?xml version="1.0" encoding="iso-8859-1"?> ! <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ! "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ! <html xmlns="http://www.w3.org/1999/xhtml" lang="EN"> ! ]]></programlisting> ! because if no DOCTYPE is defined, the parser will have problems with reckognizing entities (&nbsp; &amp; etc.), and there may be any other problems as well. </para> <para>For the other templates (which are included from another one), these headers shoud not be added, because the parser will add them automatically, so that they become well-formed xml and are parsed successfully. The headers that will be added to the other templates will be a copy of the headers of the main template. </para> <para>If the included templates do have the prolog and the root element, it has no effect in the generated page, because the framework will just discard them. On the other hand, it is not practical to include the prolog and the root element in each template; some of them may be just small templates, like this one: ! <programlisting><![CDATA[<tr> ! <td>...</td> ! </tr> ! ]]></programlisting></para> ! <para>The templates must be well-formed XML files. This is required by the framework because it uses an XML parser to parse them, and if a template is not well-formed, the parser will not be able to parse it and will display an error. E.g. <emphasis><br/></emphasis> must be used instead of <emphasis><br></emphasis> , <emphasis><img ... /></emphasis> instead of <emphasis><img ...></emphasis> , etc. (see <ulink url="http://www.w3schools.com/xhtml/xhtml_html.asp">XHTML vs HTML</ulink> for more details about these). </para> <para>Except the usual XHTML tags, the templates can also contain extra elements (tags), which are reckognized and processed by the framework. For the framework it doesn't matter the case (upper/lower) of these tags, however it is good to keep them in lowercase, since all the other XHTML tags are required to be lowercase (by the XHTML standard). </para> <para>So, the templates may not be fully compliant to the XHTML standard, due to the additional things that are supported by the framework. However, the page that the framework generates from them and which is sent to the browser, is a valid XHTML page. </para> ! <para>The framework preserves any CDATA marks that are found in the templates (this means that they still apear in the resulting page). This is important because the javascript code in an XHTML page needs to be written inside a CDATA section and, if the framework did not preserve the CDATA marks, the resulting page could not be a valid XHTML page. </para> ! <para>Another issue related to XML is this: each xml parser is required to process the entities: &amp; &lt; &gt; &quot; and &apos; and to return the corresponding character instead of the entity itself. For this reason, in order to include e.g. an ampersand in a page, it is not enough to write it in template as <emphasis>&amp;</emphasis> but it should be written as <emphasis>&amp;amp;</emphasis> . The same goes for &amp;lt;, &amp;quot;, etc. </para> </section> <section id="tpl-comments"> <title>Comments</title> <para>Template comments are just like usual XHTML comments, but they are discarded by the framework when the template is processed. They are denoted by adding a diesis after the opening mark: </para> ! <programlisting> ! <![CDATA[<!--# 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. ! --> ! ]]> ! </programlisting> </section> <section id="tpl-include"> <title>Include</title> ! <para>The <emphasis><Include></emphasis> element is used to include a template inside another template: ! <programlisting><![CDATA[<include src="templates/header.html" /> ! <include src="{{content_file}}" /> ! <include src="{{./}}edit/cluster_edit.html" /> ! ]]></programlisting></para> <para>It 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. </para> <para>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. The variables used here are evaluated when the template is parsed, so they should be parse-time variables (see later about what this means). </para> <tip> ! <para>Note in the last example the variable <emphasis>{{#./}}</emphasis> . It is defined automatically by the framework and it allways keeps the path of the current directory (the directory of the template that contains the <emphasis><include></emphasis> ). This allows the usage of relative paths in the "src" attribute, and it makes the application more flexible. So, the directory containing the template can be renamed or moved to another location, however the paths of the included files need not to be changed since they are relative to the current directory.</para> </tip> </section> <section id="tpl-if"> <title>If</title> ! <para>The content of the element <emphasis><If></emphasis> is included in the resulting page conditionally. If the value of the attribute "condition" is true, then it is included, otherwise it is skiped. </para> ! <programlisting> ! <![CDATA[<if condition="!{{admin}}"> ! <a class="button" href="javascript:edit()">Edit</a> ! </if> ! ]]> ! </programlisting> <para>The value of the condition is calculated as a PHP expression (after the template variables have been replaced). The evaluation of the condition is done at the render time (when the page is generated, see later about parse and render), so they should be render-time variables. </para> <tip> ! <para>Use <emphasis>!=</emphasis> instead of <emphasis><></emphasis> in the expression of the condition, because the xml parser complains about the characters < and > inside the value of an attribute. ! <programlisting>This is wrong: <![CDATA[<if condition="'{{CurrPage}}'<>'{{PrevPage}}'">...</if>]]></programlisting><programlisting>This is right: <![CDATA[<if condition="'{{CurrPage}}'!='{{PrevPage}}'">...</if>]]></programlisting></para> </tip> </section> <section id="tpl-repeat"> <title>Repeat</title> ! <para>The <emphasis><Repeat></emphasis> element is used to repeat a part of the template several times: ! <programlisting><![CDATA[<table> ! <repeat rs="rs_id"> ! <tr><td>{{field_name}}</td></tr> ! </repeat> ! </table> ! ]]></programlisting></para> ! <para>It is useful e.g. for constructing tables, when you want to add a row for each record in the result of a DB query. The attribute <emphasis>rs</emphasis> is the id of a recordset<footnote><para>A recordset is an object that contains the results of a DB query.</para></footnote> . The body of the <repeat> will be repeated for each record of the recordset. Each time, the fields of the record will be used as template variables for it. </para> ! <para>In case that the recordset is empty, the content of the element <emphasis><IfEmpty></emphasis> (if present) is displayed instead of the body. The <emphasis><Separator></emphasis> element is displayed between two repetitions of the body of the <Repeat>. It is optional. </para> ! <para>The elements <IfEmpty> and <Separator> can be placed anywhere inside the <Repeat>. Everything inside the <Repeat> element and outside the elements <IfEmpty> and <Separator> is considered as body of the <Repeat> and is processed for each record of the recordset. To make it more readable, the tag <emphasis><RepeatBody></emphasis> may be used, but it is just "syntactic sugar" and doesn't effect anything. It is optional and usually is omitted. </para> ! <programlisting> ! <![CDATA[<table> ! <repeat rs="rs_id"> ! <ifempty> ! <!--# <IfEmpty> is included in the page in case ! that recordset specified has no records #--> ! <tr> ! <td>No articles found!</td> ! </tr> ! </ifempty> ! <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> ! </repeat> ! </table> ! ]]> ! </programlisting> <para>The value of the "rs" attribute can also contain variables, like this: ! <programlisting><![CDATA[<repeat rs="{{rs_id}}"> . . . </repeat> ! ]]></programlisting> This allows a repeat block to use different queries in different cases (according to the logic of the program). These variables are evaluated in render time (it should be assigned in the function onParse(), or it should be a state variable or global variable). </para> </section> *************** *** 235,245 **** <title>Identation</title> <para>The framework tries to indent the generated XHTML page as well as possible. If you view the source of a page that is generated by the framework, usually you will see a well-indented XHTML code that is easy to read and to copy/paste. </para> ! <para>The framework does not modify the indentation of the HTML code inside the templates, however it tries to keep the indentation of the &amp;lt;include&amp;gt; elements. That is, all the included code is indented with the same indentation as the &amp;lt;include&amp;gt; element. </para> ! <para>Most of the time this is good, however sometimes it has undesirable effects. For example, for the XHTML elements &amp;lt;pre&amp;gt;, &amp;lt;xmp&amp;gt; and &amp;lt;textarea&amp;gt;, it would add unwanted extra spaces at the begining of each line. This would be wrong because their contents is 'preformated' and it should not be modified. The framework corrects this by reckognizing these tags and adding no extra indentation to their contents. </para> ! <para>Sometimes it may be usefull to add no indentation to a part of a template. This can be done by including it inside the &amp;lt;unindented&amp;gt; tag, like this: ! <programlisting>&lt;unindented&gt; {{file_revision}} ! &lt;/unindented&gt; ! </programlisting> It will turn off the extra indentation that is done by the framework. </para> </section> --- 242,252 ---- <title>Identation</title> <para>The framework tries to indent the generated XHTML page as well as possible. If you view the source of a page that is generated by the framework, usually you will see a well-indented XHTML code that is easy to read and to copy/paste. </para> ! <para>The framework does not modify the indentation of the HTML code inside the templates, however it tries to keep the indentation of the <include> elements. That is, all the included code is indented with the same indentation as the <include> element. </para> ! <para>Most of the time this is good, however sometimes it has undesirable effects. For example, for the XHTML elements <pre>, <xmp> and <textarea>, it would add unwanted extra spaces at the begining of each line. This would be wrong because their contents is 'preformated' and it should not be modified. The framework corrects this by reckognizing these tags and adding no extra indentation to their contents. </para> ! <para>Sometimes it may be usefull to add no indentation to a part of a template. This can be done by including it inside the <unindented> tag, like this: ! <programlisting><![CDATA[<unindented> {{file_revision}} ! </unindented> ! ]]></programlisting> It will turn off the extra indentation that is done by the framework. </para> </section> *************** *** 249,285 **** <section id="tpl-db-recordset"> <title>Recordset, Query, dbCommand</title> ! <para>The <emphasis>&amp;lt;Recordset&amp;gt;</emphasis> element can be used to define a DB query, which can be executed later by the framework and the result can be used to construct a <emphasis>Recordset</emphasis> object. It can be used like this: </para> ! <programlisting>&lt;Recordset id="rs-id"&gt; ! &lt;Query&gt; SELECT field1, {{field_name}} FROM table-name WHERE id = '{{id}}' ! &lt;/Query&gt; ! &lt;/Recordset&gt; ! </programlisting> ! <para>Each &amp;lt;recordset&amp;gt; has a unique ID. Later, when we use this recordset (e.g. in &amp;lt;repeat&amp;gt;) we refer to it by this ID. </para> ! <para>It also has a &amp;lt;Query&amp;gt; element, which contains the query to be executed. The query may contain variables, which are replaced at the time that the query is executed. </para> <tip> ! <para>If there is any <emphasis>smaller-than</emphasis> operator (&amp;lt;) in the contents of a &amp;lt;Query&amp;gt; element, then either replace ! it by &amp;amp;lt; or enclose the query in CDATA marks.</para> </tip> ! <para>There is also a <emphasis>&amp;lt;dbCommand&amp;gt;</emphasis> element, which is in fact identical to &amp;lt;recordset&amp;gt; but is usually used for insert/update/delete queries (which usually do not give a result other that successful/unsuccessful and cannot be used to construct a <emphasis>Recordset</emphasis> object). </para> </section> <section id="tpl-db-type"> <title>Types of Recordsets</title> ! <para>The &amp;lt;Recordset&amp;gt; can also have a "type" attribute: ! <programlisting>&lt;Recordset id="rs-id" type="rs-type"&gt;</programlisting></para> <para>This attribute can have one of the values: (EditableRS | StaticRS | DynamicRS | PagedRS). The default value (if the attribute is missing) is 'EditableRS'. </para> <para>An 'EditableRS' is a recordset 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 recordsets even for results that don't come from DB. </para> <para>A 'StaticRS' is a recordset that is opened only once in a page. It is more efficient for recordsets that are used many times in a page without changing (e.g. when a recordset fills a listbox and this listbox is used many times in the page). An editable RS is also static, so a recordset is by default static (if the "type" attribute is missing). This type needs to be declared explicitly only when for some reason we don't want the recordset to be editable (it just gets the results from the DB and it cannot be modified from the PHP code). </para> ! <para>A 'DynamicRS' is a recordset that executes its query each time that it is opened. Since the query can contain {{variables}} and the variables of the query are evaluated and replaced just before the execution, the result of the query can be different each time that it is executed. It is useful e.g when we have a &amp;lt;repeat&amp;gt; nested inside another &amp;lt;repeat&amp;gt;: the recordset of the inner &amp;lt;repeat&amp;gt; will be opened and refreshed for each record of the outer recordset, and since it can contain variables that are defined by the outer &amp;lt;repeat&amp;gt;, it can have different results each time that it is repeated. </para> <para>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. A page is a group of consecutive records. All the pages (except the last one) have the same number of records and they form a partition of all the records of the query. If the recordset is of type 'PagedRS' then the attribute 'recs_per_page' must be defined as well, which specifies the size of the page. This type of recordset is usually used to display queries that have many results which usually cannot fit in a single HTML page. </para> </section> <section id="tpl-db-rsnavig"> <title>rsNavig</title> ! <para>Suppose that we have a &amp;lt;repeat&amp;gt; which is connected to a paged recordset. Then just records of one page (the current page) of the recordset are displayed in the XHTML page. In order to navigate to the other pages of the recordset we need to know what is the next page, previous page, last page, etc. </para> ! <para>n this case the element <emphasis>&amp;lt;rsNavig&amp;gt;</emphasis> is useful: ! <programlisting>&lt;rsNavig rs="paged-rs-id"&gt; ... &lt;/rsNavig&gt;</programlisting></para> ! <para>The attribute "rs" of &amp;lt;rsNavig&amp;gt; contains the id of a <emphasis>PagedRS</emphasis> recordset. The framework gets from the recordset some navigation variables and makes them available in the scope of &amp;lt;rsNavig&amp;gt;. These variables are: </para> <itemizedlist> <listitem> --- 256,293 ---- <section id="tpl-db-recordset"> <title>Recordset, Query, dbCommand</title> ! <para>The <emphasis><Recordset></emphasis> element can be used to define a DB query, which can be executed later by the framework and the result can be used to construct a <emphasis>Recordset</emphasis> object. It can be used like this: </para> ! <programlisting> ! <![CDATA[<Recordset id="rs-id"> ! <Query> SELECT field1, {{field_name}} FROM table-name WHERE id = '{{id}}' ! </Query> ! </Recordset> ! ]]> ! </programlisting> ! <para>Each <recordset> has a unique ID. Later, when we use this recordset (e.g. in <repeat>) we refer to it by this ID. </para> ! <para>It also has a <Query> element, which contains the query to be executed. The query may contain variables, which are replaced at the time that the query is executed. </para> <tip> ! <para>If there is any <emphasis>smaller-than</emphasis> operator (<) in the contents of a <Query> element, then either replace it by &lt; or enclose the query in CDATA marks.</para> </tip> ! <para>There is also a <emphasis><dbCommand></emphasis> element, which is in fact identical to <recordset> but is usually used for insert/update/delete queries (which usually do not give a result other that successful/unsuccessful and cannot be used to construct a <emphasis>Recordset</emphasis> object). </para> </section> <section id="tpl-db-type"> <title>Types of Recordsets</title> ! <para>The <Recordset> can also have a "type" attribute: ! <programlisting><![CDATA[<Recordset id="rs-id" type="rs-type"\>]]></programlisting></para> <para>This attribute can have one of the values: (EditableRS | StaticRS | DynamicRS | PagedRS). The default value (if the attribute is missing) is 'EditableRS'. </para> <para>An 'EditableRS' is a recordset 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 recordsets even for results that don't come from DB. </para> <para>A 'StaticRS' is a recordset that is opened only once in a page. It is more efficient for recordsets that are used many times in a page without changing (e.g. when a recordset fills a listbox and this listbox is used many times in the page). An editable RS is also static, so a recordset is by default static (if the "type" attribute is missing). This type needs to be declared explicitly only when for some reason we don't want the recordset to be editable (it just gets the results from the DB and it cannot be modified from the PHP code). </para> ! <para>A 'DynamicRS' is a recordset that executes its query each time that it is opened. Since the query can contain {{variables}} and the variables of the query are evaluated and replaced just before the execution, the result of the query can be different each time that it is executed. It is useful e.g when we have a <repeat> nested inside another <repeat>: the recordset of the inner <repeat> will be opened and refreshed for each record of the outer recordset, and since it can contain variables that are defined by the outer <repeat>, it can have different results each time that it is repeated. </para> <para>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. A page is a group of consecutive records. All the pages (except the last one) have the same number of records and they form a partition of all the records of the query. If the recordset is of type 'PagedRS' then the attribute 'recs_per_page' must be defined as well, which specifies the size of the page. This type of recordset is usually used to display queries that have many results which usually cannot fit in a single HTML page. </para> </section> <section id="tpl-db-rsnavig"> <title>rsNavig</title> ! <para>Suppose that we have a <repeat> which is connected to a paged recordset. Then just records of one page (the current page) of the recordset are displayed in the XHTML page. In order to navigate to the other pages of the recordset we need to know what is the next page, previous page, last page, etc. </para> ! <para>In this case the element <emphasis><rsNavig></emphasis> is useful: ! <programlisting><![CDATA[<rsNavig rs="paged-rs-id"> ... </rsNavig>]]></programlisting></para> ! <para>The attribute "rs" of <rsNavig> contains the id of a <emphasis>PagedRS</emphasis> recordset. The framework gets from the recordset some navigation variables and makes them available in the scope of <rsNavig>. These variables are: </para> <itemizedlist> <listitem> *************** *** 305,347 **** </listitem> </itemizedlist> ! <para>In the following section there is an example of using &amp;lt;rsNavig&amp;gt;. </para> <section id="tpl-db-rsnavig-xmp"> <title>Example</title> ! <para>&amp;lt;rsNavig&amp;gt; is usually used in the header or footer of a paged list, in order to provide navigation to the other pages of a recordset. Here is an example of the footer of such a list: </para> ! <programlisting>&lt;rsnavig rs="tcards_rs"&gt; ! &lt;table class="list_footer" border="0" cellspacing="0"&gt; ! &lt;tr&gt; ! &lt;td width="25%"&gt; Found: {{AllRecs}} Technological Cards ! &lt;/td&gt; ! &lt;td width="25%"&gt; Page {{CurrPage}} of {{LastPage}} ! &lt;/td&gt; ! &lt;td&gt; ! &lt;if condition="'{{CurrPage}}' &gt; '{{PrevPage}}'"&gt; ! &lt;a href="javascript:SendEvent('tcardList','next','page=1')"&gt; ! &amp;amp;lt;&amp;amp;lt;First ! &lt;/a&gt; ! &amp;nbsp;&amp;nbsp; ! &lt;a href="javascript:SendEvent('tcardList','next','page={{PrevPage}}')"&gt; ! &amp;amp;lt;Prev ! &lt;/a&gt; ! &amp;nbsp;&amp;nbsp; ! &lt;/if&gt; ! &lt;if condition="'{{NextPage}}' &gt; '{{CurrPage}}'"&gt; ! &lt;a href="javascript:SendEvent('tcardList','next','page={{NextPage}}')"&gt; ! Next&amp;amp;gt; ! &lt;/a&gt; ! &amp;nbsp;&amp;nbsp; ! &lt;a href="javascript:SendEvent('tcardList','next','page={{LastPage}}')"&gt; ! Last&amp;amp;gt;&amp;amp;gt; ! &lt;/a&gt; ! &amp;nbsp;&amp;nbsp; ! &lt;/if&gt; ! &lt;/td&gt; ! &lt;/tr&gt; ! &lt;/table&gt; ! &lt;/rsnavig&gt; ! </programlisting> </section> </section> --- 313,357 ---- </listitem> </itemizedlist> ! <para>In the following section there is an example of using <rsNavig>. </para> <section id="tpl-db-rsnavig-xmp"> <title>Example</title> ! <para><rsNavig> is usually used in the header or footer of a paged list, in order to provide navigation to the other pages of a recordset. Here is an example of the footer of such a list: </para> ! <programlisting> ! <![CDATA[<rsnavig rs="tcards_rs"> ! <table class="list_footer" border="0" cellspacing="0"> ! <tr> ! <td width="25%"> Found: {{AllRecs}} Technological Cards ! </td> ! <td width="25%"> Page {{CurrPage}} of {{LastPage}} ! </td> ! <td> ! <if condition="'{{CurrPage}}' > '{{PrevPage}}'"> ! <a href="javascript:SendEvent('tcardList','next','page=1')"> ! &lt;&lt;First ! </a> ! ! <a href="javascript:SendEvent('tcardList','next','page={{PrevPage}}')"> ! &lt;Prev ! </a> ! ! </if> ! <if condition="'{{NextPage}}' > '{{CurrPage}}'"> ! <a href="javascript:SendEvent('tcardList','next','page={{NextPage}}')"> ! Next&gt; ! </a> ! ! <a href="javascript:SendEvent('tcardList','next','page={{LastPage}}')"> ! Last&gt;&gt; ! </a> ! ! </if> ! </td> ! </tr> ! </table> ! </rsnavig> ! ]]> ! </programlisting> </section> </section> *************** *** 353,384 **** <title>WebBox</title> <para>A WebBox is a template which has also some PHP code associated with it. It is a self-contained and independent template which can be easily included in other pages or in other applications. In fact, it may also have some JavaScript code, CSS stylesheets, SQL queries etc., associated with it. </para> ! <para>It is denoted by the tag <emphasis>&amp;lt;WebBox&amp;gt;</emphasis> and it has an ID attribute: ! <programlisting>&lt;webbox id="box-id"&gt; ! &lt;!-- content of WebBox --&gt; ! &lt;/webbox&gt; ! </programlisting> The identifier must be different for each WebBox used in the application. </para> ! <para>A WebBox is defined inside a template file and the TPL code of the WebBox is inside the &amp;lt;WebBox&amp;gt; tag (is the content of the &amp;lt;WebBox&amp;gt; element). </para> </section> <section id="tpl-webclass"> <title>WebClass, WebObject</title> ! <para><emphasis>&amp;lt;WebClass&amp;gt;</emphasis> defines a web class and <emphasis>&amp;lt;WebObject&amp;gt;</emphasis> declares an object of the class: </para> ! <programlisting>&lt;WebClass ID="className" Path="path/to/className.php"&gt; ! &lt;Parameter name="param1" default="default value" /&gt; ! &lt;Parameter name="param2" /&gt; ! &lt;!--# . . . . . . . . . . . . . . . . #--&gt; ! &lt;!--# the template of the web class #--&gt; ! &lt;!--# . . . . . . . . . . . . . . . . #--&gt; ! &lt;/WebClass&gt; ! &lt;WebObject Class="className" name="wObj1" param1="value1" param2="value2" /&gt; ! &lt;WebObject Class="className" name="wObj2" param2="value2" /&gt; ! &lt;WebObject Class="className" name="wObj3" param1="{{nr}}+1" param2="red" /&gt; ! </programlisting> <para>The WebClass does not produce any output in the resulting XHTML page. A WebObject uses the template of its class. </para> ! <para>The "path" attribute of the &amp;lt;WebClass&amp;gt; declares the path of the file that contains the PHP code of the WebClass. It is optional, and if it is not given, the current folder is searched for the file <filename>className.php</filename> (the folder of the template that contains the &amp;lt;WebClass&amp;gt; definition). </para> ! <para>The &amp;lt;Parameter&amp;gt; elements declare the names and optionally the default values of the parameters of the webobjects. These parameters can be used inside the template of the webclass like template variables, e.g. {{#param1}}. If a parameter doesn't get a value in the &amp;lt;WebObject&amp;gt; declaration, then its default value is used (if it doesn't have a default value, then it is handled like an undefined variable). When a &amp;lt;WebObject&amp;gt; is rendered, the value of the parameters is evaluated as a mixed expression (a PHP expression that contains {{#template variables}}). </para> ! <para>When several objects of the same class are declared, the template of the webclass is repeated for each of them. The webclass designer should take this into account when building the webclass. E.g. if there is such an &amp;lt;input&amp;gt; in the webclass template: ! <programlisting>&lt;input type="text" name="staff"&gt;</programlisting> There will be several such inputs in the HTML code, and its value cannot be accessed like this: <emphasis>document.form.staff.value</emphasis></para> </section> --- 363,396 ---- <title>WebBox</title> <para>A WebBox is a template which has also some PHP code associated with it. It is a self-contained and independent template which can be easily included in other pages or in other applications. In fact, it may also have some JavaScript code, CSS stylesheets, SQL queries etc., associated with it. </para> ! <para>It is denoted by the tag <emphasis><WebBox></emphasis> and it has an ID attribute: ! <programlisting><![CDATA[<webbox id="box-id"> ! <!-- content of WebBox --> ! </webbox> ! ]]></programlisting> The identifier must be different for each WebBox used in the application. </para> ! <para>A WebBox is defined inside a template file and the TPL code of the WebBox is inside the <WebBox> tag (is the content of the <WebBox> element). </para> </section> <section id="tpl-webclass"> <title>WebClass, WebObject</title> ! <para><emphasis><WebClass></emphasis> defines a web class and <emphasis><WebObject></emphasis> declares an object of the class: </para> ! <programlisting> ! <![CDATA[<WebClass ID="className" Path="path/to/className.php"> ! <Parameter name="param1" default="default value" /> ! <Parameter name="param2" /> ! <!--# . . . . . . . . . . . . . . . . #--> ! <!--# the template of the web class #--> ! <!--# . . . . . . . . . . . . . . . . #--> ! </WebClass> ! <WebObject Class="className" name="wObj1" param1="value1" param2="value2" /> ! <WebObject Class="className" name="wObj2" param2="value2" /> ! <WebObject Class="className" name="wObj3" param1="{{nr}}+1" param2="red" /> ! ]]> ! </programlisting> <para>The WebClass does not produce any output in the resulting XHTML page. A WebObject uses the template of its class. </para> ! <para>The "path" attribute of the <WebClass> declares the path of the file that contains the PHP code of the WebClass. It is optional, and if it is not given, the current folder is searched for the file <filename>className.php</filename> (the folder of the template that contains the <WebClass> definition). </para> ! <para>The <Parameter> elements declare the names and optionally the default values of the parameters of the webobjects. These parameters can be used inside the template of the webclass like template variables, e.g. {{#param1}}. If a parameter doesn't get a value in the <WebObject> declaration, then its default value is used (if it doesn't have a default value, then it is handled like an undefined variable). When a <WebObject> is rendered, the value of the parameters is evaluated as a mixed expression (a PHP expression that contains {{#template variables}}). </para> ! <para>When several objects of the same class are declared, the template of the webclass is repeated for each of them. The webclass designer should take this into account when building the webclass. E.g. if there is such an <input> in the webclass template: ! <programlisting><![CDATA[<input type="text" name="staff">]]></programlisting> There will be several such inputs in the HTML code, and its value cannot be accessed like this: <emphasis>document.form.staff.value</emphasis></para> </section> *************** *** 389,428 **** <section id="tpl-var"> <title>Var</title> ! <para><emphasis>&amp;lt;Var&amp;gt;</emphasis> elements declare variables that can be used anywhere in the template in the current scope and in the scopes inside it: ! <programlisting>&lt;var name="SUM"&gt;({{field1}} + {{field2}} + {{field3}})&lt;/var&gt; ! </programlisting></para> <para>They are identified by their name, and their value is calculated using their content as an expression. The value of the expression is calculated in this way: first, any template variable inside it is found and replaced, then the resulting string is evaluated as a PHP expression. </para> ! <para>The value of the expression is evaluated at the time that the template is rendered. So, if a variable is inside a &amp;lt;repeat&amp;gt; element, then it may have different values for different iterations: ! <programlisting>&lt;var name="ROW_COLOR"&gt; ({{CurrentRowNr}}%2 ? "grey" : "white") ! &lt;/var&gt; ! &lt;tr class="{{ROW_COLOR}}"&gt; . . . &lt;/tr&gt; ! </programlisting></para> </section> <section id="tpl-tpl"> <title>Template</title> ! <para>The <emphasis>&amp;lt;template&amp;gt;</emphasis> element has no effect other then defining a new scope. E.g the variable defined below will be available only inside the body of &amp;lt;template&amp;gt;: ! <programlisting>&lt;template&gt; ! &lt;var name="test"&gt; . . . &lt;/var&gt; . . . ! &lt;/template&gt; ! </programlisting></para> </section> <section id="tpl-xmp"> <title>Example</title> ! <para>The <emphasis>&amp;lt;example&amp;gt;</emphasis> tag can be used for examples about the framework templates. It can be used like this: ! <programlisting>&lt;example style="border: 1px solid #eeeeee;"&gt; test ! &lt;b&gt;test&lt;/b&gt; {{test}} ! &lt;include src="{{content_html}}" /&gt; ! &lt;/example&gt; ! </programlisting></para> ! <para>It is converted by the framework to an &amp;lt;xmp&amp;gt; element, like this: ! <programlisting>&lt;xmp style="border: 1px solid #eeeeee;"&gt; test ! &lt;b&gt;test&lt;/b&gt; {{test}} ! &lt;include src="{{content_html}}" /&gt; ! &lt;/ xmp&gt; ! </programlisting></para> </section> </section> --- 401,439 ---- <section id="tpl-var"> <title>Var</title> ! <para><emphasis><Var></emphasis> elements declare variables that can be used anywhere in the template in the current scope and in the scopes inside it: ! <programlisting><![CDATA[<var name="SUM">({{field1}} + {{field2}} + {{field3}})</var>]]></programlisting></para> <para>They are identified by their name, and their value is calculated using their content as an expression. The value of the expression is calculated in this way: first, any template variable inside it is found and replaced, then the resulting string is evaluated as a PHP expression. </para> ! <para>The value of the expression is evaluated at the time that the template is rendered. So, if a variable is inside a <repeat> element, then it may have different values for different iterations: ! <programlisting><![CDATA[<var name="ROW_COLOR"> ({{CurrentRowNr}}%2 ? "grey" : "white") ! </var> ! <tr class="{{ROW_COLOR}}"> . . . </tr> ! ]]></programlisting></para> </section> <section id="tpl-tpl"> <title>Template</title> ! <para>The <emphasis><template></emphasis> element has no effect other then defining a new scope. E.g the variable defined below will be available only inside the body of <template>: ! <programlisting><![CDATA[<template> ! <var name="test"> . . . </var> . . . ! </template> ! ]]></programlisting></para> </section> <section id="tpl-xmp"> <title>Example</title> ! <para>The <emphasis><example></emphasis> tag can be used for examples about the framework templates. It can be used like this: ! <programlisting><![CDATA[<example style="border: 1px solid #eeeeee;"> test ! <b>test</b> {{test}} ! <include src="{{content_html}}" /> ! </example> ! ]]></programlisting></para> ! <para>It is converted by the framework to an <xmp> element, like this: ! <programlisting><![CDATA[<xmp style="border: 1px solid #eeeeee;"> test ! <b>test</b> {{test}} ! <include src="{{content_html}}" /> ! </ xmp> ! ]]></programlisting></para> </section> </section> *************** *** 430,449 **** <chapter id="transitions"> <title>Transitions</title> ! <para/> <section id="trans-how"> <title>How is Done a Transition</title> ! <para/> </section> <section id="trans-phpvars"> <title>Sending PHP Variables to the Application</title> ! <para/> </section> <section id="trans-sendevent"> <title>Sending an Event to the Application</title> ! <para/> </section> <section id="trans-links"> <title>The Difference Between Transitions and Links</title> ! <para/> </section> </chapter> --- 441,478 ---- <chapter id="transitions"> <title>Transitions</title> ! <para>A transition is the move of the application from one state to another (usually from one page to another). A state of the application is composed of a certain main template file and some state variables (persistent variables of the application whose lifetime may be as long as the time that the application is active). A transition is usually triggered by a client-side event in the browser, such as: clicking a link, pressing a button, submitting a form, timeout of a javascript timer, etc. </para> <section id="trans-how"> <title>How is Done a Transition</title> ! <para>In the phpWebApp a transition is done by calling the function <emphasis>GoTo()</emphasis> which is declared by the framework itself, e.g. ! <programlisting>GoTo('page1.html')</programlisting></para> ! <para>In this case, the GoTo() function sends a request to the web-server for another page. This request is processed by the framework, which loads the template <filename>page1.html</filename> (found in the templates folder of the application) processes it and sends it to the browser. </para> ! <para>If a path is specified for the template, e.g. <emphasis>GoTo('folder1/page1.html')</emphasis> , then this path is relative to the TPL_PATH. If the page that is to be loaded is the same as the current page (e.g. we are in page <filename>page1.html</filename> and we want to load again the page <filename>page1.html</filename>), then this syntax can be used: GoTo('thisPage'); the framework remembers itself what is the current page and loads it again. This syntax is handy in the case of generic weboxes which may be included in several pages, and they don't know in which page they will be included. </para> ! <para>Usually, before making a transition you need to make some validations (e.g. when the user fills a form and submits it to the application). These data validations can be done in the client-side by using a javascript function. For example: ! <programlisting><![CDATA[<a href="javascript: on_link()"> Link </a> ! <input type="button" value="Button" onClick="on_button()"> ! <form onSubmit="on_submit(); return false;"> ! ]]></programlisting> ! The functions on_link(), on_button() and on_submit() usually do some client-side validations and error checkings and then, if everything is OK, they cause a transition by calling the function GoTo(). </para> </section> <section id="trans-phpvars"> <title>Sending PHP Variables to the Application</title> ! <para>Like usual links which can send variables to the server, like this: ! <programlisting><![CDATA[<a href="page1.php?var1=val1&var2=val2"> Link </a>]]></programlisting> ! a transition can send variables as well: ! <programlisting><![CDATA[<a href="javascript: GoTo('page1.html?var1=val1&var2=val2')"> Link </a>]]></programlisting> ! These variables will be declared as PHP global variables by the framework and may be used in the PHP code of the application. However the use of these global variables is discouraged, because there are better ways to send variables to the application. </para> </section> <section id="trans-sendevent"> <title>Sending an Event to the Application</title> ! <para>An important variable that is sent to the application almost in each transition is the variable 'event'. This variable sends to the application a server-side event that should be handled by the application. The format of an event variable is like this: ! <programlisting><![CDATA[event=targetBox.eventName(arg1=val1;arg2=val2;arg3=val3)]]></programlisting> ! When the framework gets the variable 'event', it builds an object of class Event and forwards it to the appropriate WebBox for handling. </para> </section> <section id="trans-links"> <title>The Difference Between Transitions and Links</title> ! <para>Caution: Although the transitions seem quite similar to the HTML links, they are actually very different. An HTML link requests a page from a web-server, while a transition requests a page of the application from the framework. So, all the pages of the application should refer to each-other only by using transitions, and to the external pages (pages outside the application) only by using links. If a page of the application refers to another page of the application by a link, this may break the consistency of the application. Such a mistake may happen if the page has an HTML form, because this form usually submits to its action, by not using a transition. To overcome this, we should declare the form like this: ! <programlisting><![CDATA[<form name="form1" onSubmit="return false;"> or ! <form name="form1" onSubmit="on_submit(); return false;"> ! ]]></programlisting></para> </section> </chapter> |