Thread: [phpwebapp-commits] CVS: books/content/initial_xml phpwebapp_manual_en.xml,1.3,1.4
Brought to you by:
dashohoxha
From: Dashamir H. <das...@us...> - 2006-02-11 11:05:51
|
Update of /cvsroot/phpwebapp/books/content/initial_xml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9284 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.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** phpwebapp_manual_en.xml 12 Nov 2005 12:15:20 -0000 1.3 --- phpwebapp_manual_en.xml 11 Feb 2006 11:05:38 -0000 1.4 *************** *** 4,8 **** "http://docbook.org/xml/4.2/docbookx.dtd"> ! <book id="phpwebapp_manual" lang="en"> <title>The phpWebApp Manual</title> <bookinfo> --- 4,8 ---- "http://docbook.org/xml/4.2/docbookx.dtd"> ! <book id="phpwebapp_manual"> <title>The phpWebApp Manual</title> <bookinfo> *************** *** 97,103 **** <para>It is clear that such a mix of codes is a bad thing and a bad practice and it must be avoided as much as possible. </para> <para>The HTML syntax offers a possibility to take out the JavaScript code and the CSS code in separate files. It is like this: </para> ! <programlisting>&lt;script language="javascript" src="file.js"&gt;&lt;/script&gt; ! &lt;link rel="stylesheet" href="file.css" type="text/css" /&gt; ! </programlisting> <para>However there is no standard way to clearly separate the HTML, PHP and SQL codes. You can try to keep the degree of mixing of HTML and PHP code at a minimum level by carefully designing the application. E.g. you can place all the PHP code unrelated to the HTML generation (the code that contains the logic of the application) in a separate file and keep the file that generates the HTML page as lean as possible. </para> <para>A better solution to separate the HTML and PHP codes is to use a template engine. It uses templates for generating the final HTML page. Each template is a pure HTML file, which also has some slots or variables in it. The values of these variables are calculated by the PHP code and they are passed to the engine. Then the engine reads the templates, replaces the variables by their values and thus generates an HTML page which is sent to the browser. </para> --- 97,105 ---- <para>It is clear that such a mix of codes is a bad thing and a bad practice and it must be avoided as much as possible. </para> <para>The HTML syntax offers a possibility to take out the JavaScript code and the CSS code in separate files. It is like this: </para> ! <programlisting> ! <![CDATA[<script language="javascript" src="file.js"></script> ! <link rel="stylesheet" href="file.css" type="text/css" /> ! ]]> ! </programlisting> <para>However there is no standard way to clearly separate the HTML, PHP and SQL codes. You can try to keep the degree of mixing of HTML and PHP code at a minimum level by carefully designing the application. E.g. you can place all the PHP code unrelated to the HTML generation (the code that contains the logic of the application) in a separate file and keep the file that generates the HTML page as lean as possible. </para> <para>A better solution to separate the HTML and PHP codes is to use a template engine. It uses templates for generating the final HTML page. Each template is a pure HTML file, which also has some slots or variables in it. The values of these variables are calculated by the PHP code and they are passed to the engine. Then the engine reads the templates, replaces the variables by their values and thus generates an HTML page which is sent to the browser. </para> *************** *** 143,147 **** <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> --- 145,149 ---- <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; &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> *************** *** 188,192 **** <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> --- 190,194 ---- <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> *************** *** 235,240 **** </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> --- 237,241 ---- </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> *************** *** 270,274 **** <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> --- 271,276 ---- <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> *************** *** 277,281 **** <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> --- 279,283 ---- <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> *************** *** 287,291 **** <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> --- 289,293 ---- <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>n 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> *************** *** 402,406 **** <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: --- 404,409 ---- <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: *************** *** 441,451 **** <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> --- 444,475 ---- <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 template file and some session variables (session variables are 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, submiting a form, timeout of a javascript timer, etc. </para> ! <caution> ! <para>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> ! </caution> ! <section id="goto"> <title>How is Done a Transition</title> ! <para>In the phpWebApp a transition is done by calling the JavaScript function <emphasis>GoTo()</emphasis> which is declared by the framework itself, e.g. ! <programlisting>GoTo('page1.html');</programlisting> ! In this case, the <emphasis>GoTo()</emphasis> 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> (in the folder TPL of the application) processes it and sends it to the browser. </para> ! <para>If a path is specified for the template, e.g. ! <programlisting>GoTo('folder1/page1.html');</programlisting> ! then this path is found in the folder TPL. 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: ! <programlisting>GoTo('thisPage');</programlisting> ! the framework remembers itself what is the current page and loads it again. This syntax is handy in the case of generic webboxes 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> *************** *** 453,487 **** <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> ! <chapter id="webbox-es"> <title>WebBox-es</title> ! <para/> </chapter> <chapter id="webclass-es"> <title>WebClass-es and WebObject-s</title> ! <para/> </chapter> <chapter id="events"> --- 477,742 ---- <form onSubmit="on_submit(); return false;"> ]]></programlisting> ! The functions <emphasis>on_link()</emphasis>, <emphasis>on_button()</emphasis> and <emphasis>on_submit()</emphasis> usually do some client-side validations and error checkings and then, if everything is OK, they cause a transition by calling the function <emphasis>GoTo()</emphasis>. </para> </section> ! <section id="sending-variables"> <title>Sending PHP Variables to the Application</title> ! <para>Usual links can send variables to application (on the server), like this: ! <programlisting><![CDATA[<a href="page1.php?var1=val1&var2=val2"> Link </a> ! ]]></programlisting></para> ! <para>Similarly, a transition as well can send variables to the application, like this: ! <programlisting><![CDATA[<a href="javascript: GoTo('page1.html?var1=val1&var2=val2')"> Link </a> ]]></programlisting></para> + <para>These variables will be declared as PHP global variables by the framework and may be used in the PHP code of the application. </para> + <tip> + <para>The use of these global variables is discouraged, because there are better ways to send variables to the application.</para> + </tip> + <note> + <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 <emphasis>event</emphasis> . 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>event=targetBox.eventName(arg1=val1;arg2=val2;arg3=val3)</programlisting> + When the framework gets the variable <emphasis>event</emphasis> , it builds an object of class <emphasis>Event</emphasis> and forwards it to the appropriate WebBox for handling. (For more details on events see <xref linkend="events"/> .)</para> + </note> </section> </chapter> ! <chapter id="webbox"> <title>WebBox-es</title> ! <para>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. </para> ! <para>Each page of a WebApp should contain at least a webbox, unless it is very simple (doesn't have server-side logic). A webbox can be composed of other webboxes. WebBox-es are the components that are used to build a web application. (Component in OOP is called a class that has only one object). </para> ! <para>It is denoted by the tag <emphasis><WebBox></emphasis> and it has an ID attribute: ! <programlisting><![CDATA[ <webbox id="boxId"> ! <!-- content of WebBox --> ! </webbox> ! ]]></programlisting></para> ! <para>The identifier of the box is very important and must be different for each box used in the application. </para> ! <section id="webbox-files"> ! <title>The Files Related to a WebBox</title> ! <para>The files related to the webox <emphasis>boxId</emphasis> are: <filename>boxId.php</filename> , <filename>boxId.db</filename> , <filename>boxId.js</filename> , <filename>boxId.css</filename> , etc. All of them are optional, only the template (HTML) of a WebBox is required. They are included automatically by the framework, if they exist in the same folder with the webbox. Other related files may be subtemplates, images etc., which are not included automatically by the framework. </para> ! <caution> ! <para>All the files of a WebBox (.php, .js, .css, .db, etc.) must have the same name as the ID of the WebBox, otherwise the framework will not reckognize them as belonging to this WebBox.</para> ! </caution> ! <itemizedlist> ! <listitem> ! <para>The file <filename>boxId.js</filename> contains the javascript functions of the webox (which is just usual JS code). It is included automatically by the framework at the <head> of the page. The framework looks for the file <filename>boxId.js</filename> in the same folder with the WebBox; if it exists there, then the framework includes a line like this in the <head> of the page: ! <programlisting><![CDATA[<script type="text/javascript" language="javascript" src="path/to/boxId.js"></script>]]></programlisting></para> ! </listitem> ! <listitem> ! <para>Similarly, the file <filename>boxId.css</filename> contains any stylesheet (CSS code) that is specific to the WebBox. If the file <filename>boxId.css</filename> exists, the framework includes in the <head> of the page a line like this: ! <programlisting><![CDATA[<link type="text/css" rel="stylesheet" src="path/to/boxId.css" />]]></programlisting></para> ! </listitem> ! <listitem> ! <para>The file <filename>boxId.db</filename> contains the <dbCommand> and <Recordset> elements that are used in the PHP code or in the template. If it exists, it is included automatically by the framework, before the template of the WebBox is parsed. (See the documentation about interacting with the database for more details). </para> ! </listitem> ! <listitem> ! <para>The file <filename>boxId.php</filename> contains the PHP code of the WebBox. Similarly, if it exists, it is included automatically by the framework, before the template of the WebBox is parsed. (See the following section, <xref linkend="webbox-phpcode"/> , for more details.) </para> ! </listitem> ! </itemizedlist> ! <para>Some tips: </para> ! <tip> ! <para>You can place more than one WebBox in a template file, however it is recomended to place each WebBox in a separate template, without other HTML code that does not belong to it. It is recomended to name this template <emphasis>boxId.html</emphasis> .</para> ! </tip> ! <tip> ! <para>A WebBox (and its related files) can be placed in any directory, together with other WebBox-es and templates; the framework has no restrictions about this. However, it is recomended to place all the files related to a WebBox in a separate folder, named <emphasis>boxId</emphasis> , for better readability and structure of the application.</para> ! </tip> ! </section> ! <section id="webbox-phpcode"> ! <title>The PHP Code of a WebBox</title> ! <para>The PHP code of a WebBox is placed in the file <filename>boxId.php</filename> which is in the same folder as the template containing the WebBox. Most of the PHP code and the logic of the WebBox is encapsulated inside a PHP class name <emphasis>boxId</emphasis> , which extends the interface (or the abstract class) WebObject, like this: ! <programlisting>class boxId extends WebObject { . . . }</programlisting> ! This makes the PHP code of the application more object-oriented and better organized. </para> ! <para>The class <emphasis>boxId</emphasis> can override the functions of the interface WebObject: eventHandler($event), onParse(), onRender(), etc., or can define other functions that can be used inside these functions. It can also define handle functions for each of the WebBox events. </para> ! <para>The functions of WebObject that can be overriden by the WebBox are these: </para> ! <itemizedlist> ! <listitem> ! <para><programlisting>function init()</programlisting> ! Called only the first time that the WebBox is loaded (only once in a session). Can be used to initialize the state variables of the WebBox. </para> ! </listitem> ! <listitem> ! <para><programlisting>function onParse()</programlisting> ! Called by the framework before the WebBox is parsed. It is usually used to give value to some template variables that affect the parsing. E.g. if we have this line in a template: ! <programlisting><![CDATA[ <include src="{{content_file}}" />]]></programlisting> ! then the variable <emphasis>{{#content_file}}</emphasis> must have a value before this line is parsed, and usually this value is given in the onParse() function, according to the application logic. </para> ! </listitem> ! <listitem> ! <para><programlisting>function afterParse()</programlisting> ! Called by the framework after the WebBox is parsed. </para> ! </listitem> ! <listitem> ! <para><programlisting>function onRender()</programlisting> ! Called by the framework before the WebBox is rendered. It is usually used to add {{#variables}} that are used in the template. </para> ! </listitem> ! <listitem> ! <para><programlisting>function eventHandler($event)</programlisting> ! Called by the framework to handle an event of the WebBox that does not have a specific event handler. It typically has a switch statement on the variable '$event->name', and performs some actions depending on the case. It also can extract and use the arguments of the event from the '$event->args'. </para> ! </listitem> ! </itemizedlist> ! <para>The class may also contain functions like this: ! <programlisting><![CDATA[ function on_eventName($event_args) ! ]]></programlisting> ! for each event of the WebBox, where <emphasis>eventName</emphasis> is the name of the event, and the parameter $event_args is an associative array that contains the event arguments and their values. The value of the arguments can be accessed like this: ! <programlisting><![CDATA[ $var_value = $event_args['var_name']; ! ]]></programlisting> ! Or, all the arguments can be extracted in the current scope like this (see the PHP function <emphasis>extract()</emphasis> ): ! <programlisting> extract($event_args);</programlisting></para> ! </section> ! <section id="webbox-statevars"> ! <title>State Vars of the WebBox</title> ! <para>Each webox can have its own state (session/persistent) vars. </para> ! <para>Usually, the initialization of the state vars of the webbox is done in the function <emphasis>init()</emphasis> , using the function <emphasis>WebObject::addSVar()</emphasis> or <emphasis>WebObject::addSVars()</emphasis> , like this: ! <programlisting> $this->addSVar('var_name', $var_value); ! $this->addSVars($associated_array); ! </programlisting></para> ! <important> ! <para>A state var is initialized only once! This means that in case that addSVar() is called for a state variable that already exists (is already initialized), then it will not change its value.</para> ! </important> ! <para>Inside the class (PHP code) of the webbox, its state vars can be modified and accessed like this: ! <programlisting> $this->setSVar('var_name', $var_value); ! $this->setSVars($associated_array); ! $var_value = $this->getSVar('var_name'); ! $assoc_arr = $this->getSVars(); ! </programlisting></para> ! <para>Outside the class of the webbox <emphasis>boxId</emphasis> , its state variables can be accessed like this: ! <programlisting> WebApp::setSVar('boxId->var_name', $var_value); ! $var_value = WebApp::getSVar('boxId->var_name'); ! </programlisting></para> ! <para>It is also possible to initialize a state variable of a webbox from outside of the webbox (e.g. from the init() of the parent webbox), like this: ! <programlisting> WebApp::addSVar('boxId->var_name', $var_value); ! </programlisting></para> ! <para>All the state variables of a webbox can be retrieved as an associative array: ! <programlisting> $vars = WebApp::getSVars('boxId'); ! extract($vars); ! </programlisting></para> ! <para>The state vars of the webbox can be accessed from the JS code as well, like this: ! <programlisting> session.setVar('boxId->var_name', var_value); ! var_value = session.getVar('boxId->var_name'); ! </programlisting></para> ! <para>The state variables of the webbox can be used in the template of the webbox in the usual way: {{#var_name}} and they are valid only in the scope of this webbox (and shadow any other {{#variables}} with the same name that are defined in the enclosing scopes. In case that a state variable of a webbox needs to be used in a template outside its own webox, then its full name should be used, like this: <emphasis>{{#boxId->var_name}}</emphasis></para> ! <para>If the constant DEBUG_STATEVARS in <filename>config/const.Debug.php</filename> is set to <emphasis>true</emphasis> , then the framework outputs at the end of the page the state variables for each webbox and their values, which helps to debug them. </para> ! </section> ! <section id="webbox-processing"> ! <title>How a WebBox is Processesed</title> ! <para>In order to use the webbox features correctly, it is usefull to know the steps that the framework follows for calling the PHP code of the WebBox. In general, the framework constructs the HTML page (that is sent to the browser) in two phases: first it parses (loads) all the relevant templates and builds a structure in memory, then it uses these templates to render (generate) the HTML page. The following list describes these steps according to the order that they happen: </para> ! <orderedlist numeration="arabic"> ! <listitem> ! <para>At the time that the framework is about to load (parse) the WebBox, it includes the file <filename>boxId.php</filename> (if it exists). </para> ! </listitem> ! <listitem> ! <para>If this is the first time that this WebBox is loaded (in this session), then it calls the function <emphasis>init()</emphasis> , which can be used to initialize the state variables of the WebBox. </para> ! </listitem> ! <listitem> ! <para>If there is an event sent to this WebBox, the framework calls the corresponding event handler <emphasis>on_eventName($event_args)</emphasis> . If such a function is not defined, it calls the general event handler of the WebBox: <emphasis>eventHandler($event)</emphasis> . </para> ! </listitem> ! <listitem> ! <para>The framework calls the function <emphasis>onParse()</emphasis> which may define any parse-time template variables. </para> ! </listitem> ! <listitem> ! <para>The framework parses the template (HTML code) of the WebBox and loads it in a structure in memory. Any parse-time variables can be used during the parse. </para> ! </listitem> ! <listitem> ! <para>The function <emphasis>afterParse()</emphasis> is called. </para> ! </listitem> ! <listitem> ! <para>After all WebBox-es and templates of the application are parsed, the framework starts to render (generate) the HTML page that is sent to the browser. </para> ! </listitem> ! <listitem> ! <para>The function <emphasis>onRender()</emphasis> is called before starting to render the template of the WebBox. Any <emphasis>render-time</emphasis> template variables are defined here. </para> ! </listitem> ! <listitem> ! <para>Finally, the template of the WebBox is rendered and any {{#variables}} in it are replaced by their value. </para> ! </listitem> ! </orderedlist> ! </section> </chapter> <chapter id="webclass-es"> <title>WebClass-es and WebObject-s</title> ! <para>The concept of WebClass and WebObject is similar to the classes and objects in the OOP (Object-Oriented Programing). </para> ! <section id="webcl-template"> ! <title>The Template Syntax</title> ! <para>The element <WebClass> defines a web class, but it by itself does not produce any HTML output in the rendered page. The element <WebObject> declares an object of the class and the content (the template) of the <WebClass> is used to render this object. They are used like this: </para> ! <programlisting> ! <![CDATA[ <webclass id="classId" path="path/to/classId.php"> ! <parameter name="param1" default="default value" /> ! <parameter name="param2" /> ! <!--# . . . . . . . . . . . . . . . . #--> ! <!--# the template of the web class #--> ! <!--# . . . . . . . . . . . . . . . . #--> ! </webclass> ! ! <webobject class="classId" name="wObj1" param1="value1" param2="value2" /> ! <webobject class="classId" name="wObj2" param2="value2" /> ! <webobject class="classId" name="wObj3" param1="{{nr}}+1" param2="red" /> ! ]]> ! </programlisting> ! <para>The <emphasis>path</emphasis> attribute of the <WebClass> declares the path of the file that defines the PHP code of the WebClass. It is optional, and if it is not given, then the current folder (the folder of the template that contains the <WebClass> definition) is searched for the file <filename>classId.php</filename></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 <emphasis>mixed expression</emphasis> (a PHP expression that contains {{#template vars}}). </para> ! <caution> ! <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> ! Then there will be several such inputs in the HTML code, and its value cannot be accessed like this: ! ! <programlisting> document.form.staff.value</programlisting></para> ! </caution> ! <para>To help the webclass designers to avoid the problem described above, the framework declares for each webobject these variables: ! <itemizedlist><listitem><para>{{#class_name}} -- the name of the class </para></listitem><listitem><para>{{#obj_name}} -- the name of the object </para></listitem><listitem><para>{{#obj_id}} -- the object id ('{{#class_name}}::{{#obj_name}}') </para></listitem><listitem><para>{{#obj_count}} -- count of the objects of the same class, starting from 1 </para></listitem></itemizedlist> ! These vars can be used inside the template of the webclass, if the webclass designer needs them, e.g.: ! <programlisting><![CDATA[ <input type="text" name="staff_{{obj_count}}"> ! ]]></programlisting></para> ! </section> ! <section id="webcl-vars"> ! <title>WebObject Variables</title> ! <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> ! Then there will be several such inputs in the HTML code, and its value cannot be accessed like this: ! <programlisting> document.form.staff.value</programlisting></para> ! <para>To help the webclass designers to avoid the problem described above, the framework declares for each webobject these variables: ! <itemizedlist><listitem><para>{{#class_name}} -- the name of the class </para></listitem><listitem><para>{{#obj_name}} -- the name of the object </para></listitem><listitem><para>{{#obj_id}} -- the object id ('{{#class_name}}::{{#obj_name}}') </para></listitem><listitem><para>{{#obj_count}} -- count of the objects of the same class, starting from 1 </para></listitem></itemizedlist> ! These vars can be used inside the template of the webclass, if the webclass designer needs them, e.g.: ! <programlisting><![CDATA[ <input type="text" name="staff_{{obj_count}}"> ! ]]></programlisting></para> ! <para>Other variables that can be used in the template of the webclass are its parameters, its state variables, and the variables that are declared in the PHP code (similar to WebBox-es). </para> ! </section> ! <section id="webcl-php"> ! <title>The PHP Code</title> ! <para>The PHP code of the webclass <emphasis><WebClass ID="classId"></emphasis> is contained in the file <filename>classId.php</filename> . The framework includes it automatically, if it exists. This file defines a class named <emphasis>classId</emphasis> which extends the class <emphasis>WebObject</emphasis> , and which is very similar to the PHP code of a WebBox: </para> ! <programlisting> ! <![CDATA[<? ! class classId extends WebObject ! { ! . . . . . ! } ! ?> ! ]]> ! </programlisting> ! <para>The same as in the case of a WebBox, this class can override the functions of <emphasis>WebObject</emphasis> , which are called by the framework at certain moments during the time that the webobject is processed. </para> ! <para>These functions are: </para> ! <itemizedlist> ! <listitem> ! <para>init() -- called only the first time that a WebObject is loaded </para> ! </listitem> ! <listitem> ! <para>onParse() -- called before the template of the WebClass is parsed </para> ! </listitem> ! <listitem> ! <para>afterParse() -- called after the template of the WebClass is parsed </para> ! </listitem> ! <listitem> ! <para>onRender() -- called before the HTML of a WebObject is rendered </para> ! </listitem> ! <listitem> ! <para>on <emphasis>eventName($event</emphasis> args) -- called to handle an event of a WebObject </para> ! </listitem> ! <listitem> ! <para>eventHandler($event) -- generic event handler, if no special event handler exists </para> ! </listitem> ! </itemizedlist> ! <para>A WebObject can also have its own state variables, which are similar to the state variables of a WebBox. </para> ! </section> ! <section id="webcl-webbox"> ! <title>WebBox-es</title> ! <para/> ! </section> </chapter> <chapter id="events"> |