[phpwebapp-commits] CVS: web_app/doc changes_3.txt,NONE,1.1 xhtml_template_specification.txt,1.3,1.4
Brought to you by:
dashohoxha
From: Dashamir H. <das...@us...> - 2004-07-13 16:15:45
|
Update of /cvsroot/phpwebapp/web_app/doc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8906/doc Modified Files: xhtml_template_specification.txt to_do.txt changes.txt Added Files: changes_3.txt Log Message: --- NEW FILE: changes_3.txt --- Changes made to the application framework that the application developer should know: =========================================== -------- afterParse() ---------------------------- * - WebObject::afterParse() is like WebObject::onParse(), only that it is called after the WebObject is parsed. -------- webobject vars -------------------------- * - The framework declares for each webobject these variables: {{obj_id}} -- the object id ({{class_name}}::{{obj_name}}) {{class_name}} -- the name of the class {{obj_name}} -- the name of the object {{obj_count}} -- counts the objects of the same class, starting from 1 These vars can be used inside the template of the webclass, if the webclass designer needs them, e.g.: <input type="text" name="staff_{{obj_count}}"> -------- transmitVars() -------------------------- * - function transmitVar(var_name, var_value) This function sends the var_name (which has the given var_value) to the server side as a PHP global variable. It can also be used in the template as a tpl variable: {{var_name}}, since all PHP global variables can be used as tpl variables. It should be used carefully, because any tpl variable with the same name will override its value. It must be called before GoTo(). - function transmitVars(var_list) Similar to transmitVar() but can transmit more than one variable. The format of var_list is: var1=val1&var=val2&var3=val3. Must be called before GoTo(). -------- formWebObj ---------------------------------- * - formWebObj is a webobject that makes easy the handling of big forms (which have many inputs) and their data connection to the databaze. It is used like this: when you have a webbox that has a big form, in the PHP code of the webbox you include the class 'formWebObj', and then inherit this class, instead of inheriting 'WebObject' ('formWebObj' itself extends 'WebObject', so this is OK). E.g.: <WebBox ID="editProject"> <form name="bigForm"> . . . . . . . . <!--# many <input>s, <select>s, etc. here #--> . . . . . . . . </form> </WebBox> ---------------------------------------------- <? include_once FORM_PATH."formWebObj.php"; class editProject extends formWebObj { . . . . . . . . . . } ?> ---------------------------------------------- <? class formWebObj extends WebObject { . . . . . . . . . . . } ?> Then, in the JS code of the webbox you can use these JS functions which have been declared and included by the 'formWebObj': getEventArgs(form); /** * Returns all the data in the inputs of the given form * so that they can be sent as event args, e.g. * GoTo("thisPage?event=editProject.save(" + getEventArgs(form) + ")"); */ saveFormData(form); /** * Transmit the data of the form, so that * the changed values are not lost. * Must be called before GoTo(). */ This is useful when the page is refreshed for some reason, but you don't want to lose the values that are inputed in it. There are also these two functions that are used internally by 'formWebObj', but you can use them as well, if you need them: function getFormData(form) //returns all the data filled in the given form function setFormData(form, formData) //fills the form with the given data ------------- date WebObject ------------------------------- * - The webobject date can be used to select the date from a calendar. It can be used like this: First include the webclass that defines it: <Include SRC="{{DATE_PATH}}date.html" /> (DATE_PATH is defined by the framework) Then declare as many date objects as needed: <WebObject Class="date" Name="information_date" /> <WebObject Class="date" Name="contact_date" /> etc. When an object of class date is declared, the framework replaces it with this html code: <input type="text" class="datebox" onFocus="blur()" name="information_date" value="{{information_date}}"> <input type="image" ...(the calendar that selects the date)> So, it requires a default value {{information_date}}, which can be declared in the PHP code of the webox that uses the date object. If you want to modify it, you can copy it to a path local to the application, modify it and use the modified copy, e.g. <Include SRC="{{./}}date/date.html" /> -------------------------------------------------------------- * - <Repeat rs="{{tpl_var}}"> The attribute rs of the <Repeat> tag can contain variables (so that the same repeat can use different recordsets, according to the logic of the program). These variables are evaluated now in render time (before they were evaluated in parse time) because this is more convenient. ------------- listbox WebObject ------------------------------- * - The WebClass "listbox" is used to display a list of values with the <select> tag of HTML. These values are taken from a recordset (which can be retrieved from DB or can be supplied by PHP code. The recodset associated with the listbox must have two fields: 'id' and 'label'. 'label' is the field displayed, and 'id' is the value that is selected, saved in DB and retrieved from DB. Recordset example: <Recordset ID="listbox::country"> <Query> SELECT country_id AS id, country_name AS label FROM countries </Query> </Recordset> Usage example: <WebObject Class="listbox" Name="country" rs="rs_id" width="---------------" /> The attribute "rs" is optional. Its default value (if not specified) is {{obj_id}} (in the example above, it would be 'listbox::country'). The attribute "width" is also optional; it is used as the last line of the list, in order to keep the width of the <select> to a certain size (which can also be used as a nothing selected (none of the above) value). This WebClass uses a <select> tag like this: <select name="country"> (name="{{obj_name}}") . . . . . </select> So, this should be kept in mind when accessing the selected value and when giving an initial value. If the 'listbox' is used inside a 'formWebObj' webbox, then it takes care of it automatically. -------------------------------------------------------------------- * - The tag <WebObject> can be written in several lines (for making it more readable, in case that it has many attributes) and the parser can handle it. E.g. <WebObject Class = "listbox" Name = "country" rs = "rs_id" width = "---------------" /> -------------------------------------------------------------------- * - define("VAR_NOT_FOUND", "{var_name}"); is added to 'config/const.Settings.php' This constant sets the format of the error message that is displayed when a {{variable}} is not found. 'var_name' is replaced by the actual variable name. Examples: "'var_name' is not defined", "", "undefined", etc. It cannot contain "{{var_name}}" inside. -------------------------------------------------------------------- * - The recordsets declared by the <Recordset> tag were by default of type "StaticRS". Now the default type is "EditableRS", because this is more useful (and anyway EditableRS extends StaticRS). It can be declared explicitly as "StaticRS" only when the programer has strong reasons to disallow the modification of this recordset from the PHP code. -------------------------------------------------------------------- * - The JS code of a <WebBox> is included automatically by the framework at the <head> of the page. The framework looks for the file 'box_id.js' (or 'class_id.js', in case of a <WebClass>) 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: <script language='javascript' src='path/to/box_id.js'></script> Similarly, for the CSS code, the framework includes a line like this: <link type='stylesheet' src='path/to/box_id.css' ....> in the <head> of the page. ---------------- SendEvent() ---------------------------------------- * - js function: SendEvent(obj_id, event_name, event_args) Sends an event to the server-side (PHP) code. obj_id -- the object to which the event is sent event_name -- the name of the event event_args -- the arguments of the event, optional It is defined in 'func.GoTo.js' which is included automatically by the framework in each page. This function uses GoTo() to send an event to a webobject (or webbox). Its target is always 'thisPage' (so, it cannot switch to another page of the application, like GoTo()) and it cannot send global PHP variables (like GoTo()). So, GoTo() is more general, but SendEvent() should be more common and more frequently used. ---------------- WebObject table ------------------------------------- * - WebObject 'table' is used to display the content of a table inside a page. It is used like this: <Include SRC="{{TABLE_PATH}}table.html" /> <WebObject Class="table" Name="offices" table="offices" fields="off_id,name" where="off_id < 10" /> If attribute 'table' is the name of the table that will be displayed. If it is not specified, its default value is {{obj_name}} (the value of attribute 'Name'). The attribute 'fields' is the list of fields that will be displayed. It is optional and its default value is "*" (all fields). The attribute 'where' is the select condition for selecting the records. It is optional and its default value is "" (all the records). ---------------- WebObject editableTable --------------------------- * - WebObject 'editableTable' is used to display and edit the content of a database table inside a page. It is used like this: <Include SRC="{{EDITABLE_PATH}}editableTable.html" /> <WebObject Class="editableTable" Name="offices" table="offices" fields="off_id,name" where="off_id < 10" /> WebObject 'editableTable' is like 'table', but it also allows to add new records to the table, to edit the existing records, to delete a record from the table, or to remove all the records of the table that are displayed. ---------------- NULL values ----------------------------------------- * - For a DB value that was NULL, the framework used to return UNDEFINED and, as a result, in the page was displayed {var_name}. Now, the constant NULL_VALUE is returned, which can be specified in the file 'config/const.Settings.php'. It can be "", "NULL", NULL, etc. ---------------- leftMenu webobject ---------------------------------- * - WebObject 'leftMenu' displays a menu, usually on the left side of the page. It is used like this: <Include SRC="{{LEFTMENU_PATH}}leftMenu.html" /> <WebObject Class="leftMenu" Name="su" items="{{./}}su_menu_items.php" /> The attribute 'items' is a PHP file that contains the items of the menu, like this: <? /** * The $menu_items array contains the items of the leftMenu. */ $menu_items = array( "item1" => " Menu Item 1 ", "item2" => " Menu Item 2 ", "item3" => " Menu Item 3 ", "etc1" => " . . . ", "etc2" => " . . . " ); ?> The item of the menu that is selected can be retrieved like this: $selected = WebApp::getSVar("leftMenu::su->selected_item"); If you need to change the look of the leftMenu, then make a local copy and modify 'leftMenu.css'. -------------------------------------------------------------------- * - config/const.Settings.php is divided into const.Options.php (some constants that can have optional values, depending on the application), and const.Debug.php (constants that enable or disable several debugging features of the framework). -------------------------------------------------------------------- * - The GoTo() function accepts only a string of the form GoTo("target.html?event=obj_id.event_name(event_args)"); Before it was possible to send some global PHP vars, by appending them after the event like this: &var1=val1&var2=val2 etc. This was deprecated and actually it is almost never used. In the rare cases when it is needed to send a global variable to PHP, the functions transmitVar() and transmitVars() can be used. The values of the event arguments could not contain '&' before, but now they can. They cannot contain ';', because it is used to separate event args from each-other, however, the JS function encode_arg_value(str), which is defined by the framework, can be used to replace them with '#semicolumn#', in cases that they need to contain ';'. The decoding (replacing '#semicolumn#' by ';') is done by the framework itself. -------------------------------------------------------------------- * - The expression of the <Var> tag can now be declared in several lines, like this: <Var name="class"> ( "{{item}}"=="{{{{obj_id}}->selected_item}}" ? "leftMenu-item-selected" :"leftMenu-item" ) </Var> -------------------------------------------------------------------- * - WebObject 'dbTable' is used to display and edit the content of a database table inside a page. It is used like this: <Include SRC="{{DBTABLE_PATH}}dbTable.html" /> <WebObject Class="dbTable" Name="offices" table = "offices" fields = "off_id,name" where = "off_id < 10" editable = "true" selectable = "true" /> It is like 'editableTable' but has two more attributes. The attributes 'editable' and 'selectable' have default values of "false". In this case the 'dbTable' behaves just like 'table'. When 'editable' has a value "true", then the table is editable, i.e. its records can be added, deleted or modified. When 'selectable' has a value "true", then it is possible to select a record from the displayed ones. The fields of the selected record are declared as global template variables and can be used where they are needed. It makes obsolete WebObjects 'table' and 'editableTable', however 'table' is still left in the framework because it is simpler than 'dbTable' and it can be easier to modify and customize to fit the needs of a certain application. -------------------------------------------------------------------- * - config/const.Debug.php: define("SHOW_ERROR_MESSAGES", true); If this constant is 'false' than the framework suppresses all the error and warning messages (that are generated by the framework). Usually it should be 'true' during the development and should be switched to 'false' when the application is deployed, in order not to confuse the users of the application with error messages that have no meaning for them. -------------------------------------------------------------------- * - The function: session.isset(var_name) can be used to check whether a certain variable egzists in the session or not. -------------- datebox WebObject ----------------------------------- * - The webbox 'date' is renamed to 'datebox' and the attributes (parameters) 'value', 'format', 'onchange' are added to it. <Include SRC="{{DATEBOX_PATH}}datebox.html" /> <WebObject Class="datebox" Name="information_date" value="{{info_date}}" format="YYYY-MM-DD" onchange="check_selected_date(this)" /> <WebObject Class="datebox" Name="proposal_date" /> <WebObject Class="datebox" Name="contact_date" /> etc. The attribute 'value' is used to initialize the datebox with an initial value. If it is not given, then the default is {{{{obj_name}}}} (in the example above it would be {{information_date}}). The attribute 'format' is used to specify the format of the date. The reckognized formats are: YYYY-MM-DD (default) MM/DD/YYYY MM-DD-YYYY DD/MM/YYYY DD-MM-YYYY Actually this is only the format of the display, because the internal format is allways YYYY-MM-DD, the format used by the databases. E.g. if the above datebox webobject is declared inside a form with the name 'editDoc', then "document.editDoc.information_date.value" returns the date in the internal format (in the format YYYY-MM-DD). The attribute 'onchange' (be carefull, all lowercase) is used to call any validation function at the time that the date is changed. If you pass 'this' as a argument to this function, then it refers to the display format. E.g. if 'date' is the parameter to which 'this' is passed, then "d = date.value;" gets the selected date in the display format (which is specified by the attribute 'format'), and "date.value = d;" sets the date of the datebox ('d' should be in the format specified by 'format'). -------------------------------------------------------------------- * - WebObject 'listbox' can now take another attribute, 'onchange' (all lowercase), where the programer can call some JS code when the selected value is changed. -------------------------------------------------------------------- * - PagedRS can also handle the queries which have GROUP BY. Along to the state variable 'rs_id->current_page' which keeps the current page of the PagedRS, there is the state variable 'rs_id->recount' which is set to true by the application when the records need to to be recounted (e.g. when a new record is added in DB, or when a record is deleted). Before, the number of the records in a PagedRS was counted only when current_page was 1, but this is not very convenient. -------------------------------------------------------------------- * - define("DISPLAY_CGI_VARS", false); (at 'config/const.Options.php') When this constant is true, then the CGI vars are displayed at the URL window of the browser. See also SHOW_EXTERNAL_LINK at const.Debug.php. -------------------------------------------------------------------- * - The framework now gets the user variables (browser variables) from $_GET, $_POST and $_REQUEST, in order to comply with PHP 4.2.0 The global object $request (of class Request, declared in /session/class.Request.php) can be used to get the browser variables: sourcePage, targetPage, sessionVars, strEvents, phpVars. -------------------------------------------------------------------- * - Changes in the structure of the files of the application; event_handler/on.firstTime.php is replaced by 'init.php', which is called (if it exists) the first time that the application is opened. define("FIRSTPAGE", "main.html"); in 'config/const.Settings.php' sets the first page of the application. -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- Index: xhtml_template_specification.txt =================================================================== RCS file: /cvsroot/phpwebapp/web_app/doc/xhtml_template_specification.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xhtml_template_specification.txt 13 Jul 2004 13:18:08 -0000 1.3 --- xhtml_template_specification.txt 13 Jul 2004 16:15:20 -0000 1.4 *************** *** 5,171 **** * Comments ========== ! <!--# Comments are denoted like this #--> ! <!--# diesis at the beginning, diesis at the end #--> ! <!--# ! Such comments are not included ! in the XHTML file that is generated. ! #--> ! <!-- ! Usual XHTML comments (like this one) are passed to ! the XHTML file that is generated from the template. ! --> * Include elements ================== ! <Include file="{{MSG_BOX}}"/> ! <!--- ! The <Include> element is used to include in templates ! parts that are the same in many templates. It also ! provides flexibility in the sense that the file that ! will be included may be a variable, so different files ! may be included in different cases. ! The file that is included will be processed as if it were ! in the place of the <Include> element (so it may contain ! elements, variables, etc). ! ---> * Repeat elements ================= ! <Repeat RS="art"> ! <!--- IfEmpty is included in XHTML in case that recordset specified has no records ---> ! <IfEmpty> ! <tr> ! <td>No articles found!</td> ! </tr> ! </IfEmpty> ! <!--- Here comes the part that is reapeated for each record in the recordset ---> ! <tr> ! <td> {{TI}} </td> ! <td> {{AU}} </td> ! . . . ! </tr> ! </Repeat> ! <!--- ! The <Repeat> element is connected with a recordset by the attribute ! "RS". Its content is processed for each row of the recordset. Before ! processing the content for a certan row, all the fields of the recordset ! are declared as variables with values taken from the current row. ! In case that the recordset is empty, then the element <IfEmpty> is ! processed instead. (Subject to be discussed). ! Subject to be discussed: should we also include <Header> and <Footer> ! elements? ! ---> * <If> element =============== ! <If condition="!{{PUBLIC_LIBRARY}}"> ! <!--- MyLibrary part comes here ---> ! <!--- . . . . . . . . . . . . . ---> ! </If> ! <!--- ! The content of the <If> element is processed conditionally, ! if the value of the attribute "condition" is true, then it ! is processed, otherwise it is not processed. ! The value of the condition is calculated as a PHP expression ! (after the template variables are replaced). ! ---> * <Recordset> elements ======================= ! <Recordset ID="rsID"> ! <Query> select {{R_NAME}} from table </Query> ! </Recordset> ! <!--- ! Each recordset has a unique ID. Later, when we use ! this recordset (e.g. in a <Repeat> element) we refer ! to it by this ID. It also has a <Query> element, which ! is executed using the default database connection. ! ---> * Recordsets that are displayed over several pages =================================================== ! <Recordset ID="art" RowsPerPage="10"> ! <Query>{{ART_QUERY}}</Query> ! </Recordset> ! <!--- ! Recordsets that have a RowsPerPage attribute are ! recordsets that are displayed over several pages. ! In this case some additional variables are declared ! which show which records are being displayed, how many ! pages are there, and at which page we are currently. ! These variables can be used anywhere in the template. ! Such variables are: {{art_PrevPage}}, {{art_CurrentPage}}, ! {{art_NextPage}}, {{art_NrPages}}, {{art_FirstRecord}}, ! {{art_LastRecord}}, {{art_NrRecords}}, etc. (their names ! are generated using the id of the recordset). ! Some of them are also saved as session variables. In our ! example, {{art_CurrentPage}} is a session variable and is passed ! from this page to the next one. ! ---> * <Var> elements ================= ! <Var name="MSG_SEARCH">"Results of search for: {{SEARCH_TERM}}"</Var> ! <Var name="ROW_COLOR">($Cnt%2 ? 'class="tabgrey"' : 'class="tabwhite"')</Var> ! <!--- ! <Var> elements declare variables that can be used anywhere in the ! template in the current scope and in the scopes inside it. They ! are identified by their name, and their value is calculated using ! their content. The value of a variable is calculated in this way: ! -first, any template variable inside them is found and replaced, ! -second, the resulting string is evaluated as a PHP expression, ! -finally, the resulting value is assigned to the variable. ! (This way of evaluation is subject to be discussed and refined.) ! A variable is evaluated at the time that it is processed, so that ! if a variable is inside a <Repeat> element, then it may have different ! values for different iterations. ! The scopes of the variables are determined by the elements <Repeat>, ! <If>, etc. (each of these elements defines a new scope). If two ! variables have the same name, then the one in the closer scope is ! used. If they are both in the same scope, then the one defined later ! overrides the other. ! ---> * Template variables ===================== ! <!--- ! Anywhere in XML where we can put character data, ! we can also put {{variables}}, which are replaced ! by their string values at the time of template ! processing and convertion to XHTML. ! To find the value of a variable: ! -The current scope is searched for it. ! -If it is not found, then the scope above it is searched, ! and so on until it is found. ! -If it is not found in any scope, then session variables ! are searched for it. ! -If it not found among session variables, then global variables ! of PHP are searched for it. ! -If it still is not found then its name is taken as its value ! (e.g. {{var1}} is replaced by "var1"). ! The order of search is subject to be discussed and refined. ! ---> --- 5,171 ---- * Comments ========== ! <!--# Comments are denoted like this #--> ! <!--# diesis at the beginning, diesis at the end #--> ! <!--# ! Such comments are not included ! in the XHTML file that is generated. ! #--> ! <!-- ! Usual XHTML comments (like this one) are passed to ! the XHTML file that is generated from the template. ! --> * Include elements ================== ! <Include file="{{MSG_BOX}}"/> ! <!--- ! The <Include> element is used to include in templates ! parts that are the same in many templates. It also ! provides flexibility in the sense that the file that ! will be included may be a variable, so different files ! may be included in different cases. ! The file that is included will be processed as if it were ! in the place of the <Include> element (so it may contain ! elements, variables, etc). ! ---> * Repeat elements ================= ! <Repeat RS="art"> ! <!--- IfEmpty is included in XHTML in case that recordset specified has no records ---> ! <IfEmpty> ! <tr> ! <td>No articles found!</td> ! </tr> ! </IfEmpty> ! <!--- Here comes the part that is reapeated for each record in the recordset ---> ! <tr> ! <td> {{TI}} </td> ! <td> {{AU}} </td> ! . . . ! </tr> ! </Repeat> ! <!--- ! The <Repeat> element is connected with a recordset by the attribute ! "RS". Its content is processed for each row of the recordset. Before ! processing the content for a certan row, all the fields of the recordset ! are declared as variables with values taken from the current row. ! In case that the recordset is empty, then the element <IfEmpty> is ! processed instead. (Subject to be discussed). ! Subject to be discussed: should we also include <Header> and <Footer> ! elements? ! ---> * <If> element =============== ! <If condition="!{{PUBLIC_LIBRARY}}"> ! <!--- MyLibrary part comes here ---> ! <!--- . . . . . . . . . . . . . ---> ! </If> ! <!--- ! The content of the <If> element is processed conditionally, ! if the value of the attribute "condition" is true, then it ! is processed, otherwise it is not processed. ! The value of the condition is calculated as a PHP expression ! (after the template variables are replaced). ! ---> * <Recordset> elements ======================= ! <Recordset ID="rsID"> ! <Query> select {{R_NAME}} from table </Query> ! </Recordset> ! <!--- ! Each recordset has a unique ID. Later, when we use ! this recordset (e.g. in a <Repeat> element) we refer ! to it by this ID. It also has a <Query> element, which ! is executed using the default database connection. ! ---> * Recordsets that are displayed over several pages =================================================== ! <Recordset ID="art" RowsPerPage="10"> ! <Query>{{ART_QUERY}}</Query> ! </Recordset> ! <!--- ! Recordsets that have a RowsPerPage attribute are ! recordsets that are displayed over several pages. ! In this case some additional variables are declared ! which show which records are being displayed, how many ! pages are there, and at which page we are currently. ! These variables can be used anywhere in the template. ! Such variables are: {{art_PrevPage}}, {{art_CurrentPage}}, ! {{art_NextPage}}, {{art_NrPages}}, {{art_FirstRecord}}, ! {{art_LastRecord}}, {{art_NrRecords}}, etc. (their names ! are generated using the id of the recordset). ! Some of them are also saved as session variables. In our ! example, {{art_CurrentPage}} is a session variable and is passed ! from this page to the next one. ! ---> * <Var> elements ================= ! <Var name="MSG_SEARCH">"Results of search for: {{SEARCH_TERM}}"</Var> ! <Var name="ROW_COLOR">($Cnt%2 ? 'class="tabgrey"' : 'class="tabwhite"')</Var> ! <!--- ! <Var> elements declare variables that can be used anywhere in the ! template in the current scope and in the scopes inside it. They ! are identified by their name, and their value is calculated using ! their content. The value of a variable is calculated in this way: ! -first, any template variable inside them is found and replaced, ! -second, the resulting string is evaluated as a PHP expression, ! -finally, the resulting value is assigned to the variable. ! (This way of evaluation is subject to be discussed and refined.) ! A variable is evaluated at the time that it is processed, so that ! if a variable is inside a <Repeat> element, then it may have different ! values for different iterations. ! The scopes of the variables are determined by the elements <Repeat>, ! <If>, etc. (each of these elements defines a new scope). If two ! variables have the same name, then the one in the closer scope is ! used. If they are both in the same scope, then the one defined later ! overrides the other. ! ---> * Template variables ===================== ! <!--- ! Anywhere in XML where we can put character data, ! we can also put {{variables}}, which are replaced ! by their string values at the time of template ! processing and convertion to XHTML. ! To find the value of a variable: ! -The current scope is searched for it. ! -If it is not found, then the scope above it is searched, ! and so on until it is found. ! -If it is not found in any scope, then session variables ! are searched for it. ! -If it not found among session variables, then global variables ! of PHP are searched for it. ! -If it still is not found then its name is taken as its value ! (e.g. {{var1}} is replaced by "var1"). ! The order of search is subject to be discussed and refined. ! ---> Index: to_do.txt =================================================================== RCS file: /cvsroot/phpwebapp/web_app/doc/to_do.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** to_do.txt 13 Jul 2004 13:18:08 -0000 1.1 --- to_do.txt 13 Jul 2004 16:15:20 -0000 1.2 *************** *** 1,21 **** * Parse the templates using an XML parser. - Fix the problems with <Repeat>. ! - There is a problem with the Repeat/Header tags, because the ! contents of the <Header> usually is not well-formed xml and ! this breaks the xml parsing. E.g. it may be something like this: ! <repeat rs="rs_id"> ! <header> ! <table> ! </header> ! <tr><td>{{xyz}}</td></tr> ! <footer> ! </table> ! </footer> ! </repeat> ! Think about how to solve this. ! - Handle XML errors (in templates) as gracefully as possible. - Use 'tidy' or any shell scripts for converting from HTML to XHTML. --- 1,21 ---- * Parse the templates using an XML parser. + - Handle XML errors (in templates) as gracefully as possible. + + In case of error, when popping the templates from the stack, + call also the corresponding function (e.g. end_IF()), + according to the type of the template. + + - The xml parser has problems with entities (e.g. < & etc.) + Why? + - Fix the problems with <Repeat>. + + Why the navigation vars work even without a <RSNavig> template? ! - class.WebPage.php::print_dbg_messages() ! Output debug messages using EditableRS and templates. ! ! - Use css styles to the other debug messages as well. ! - Substitute ereg_replace() with preg_replace(). - Use 'tidy' or any shell scripts for converting from HTML to XHTML. *************** *** 29,32 **** --- 29,33 ---- - Improve the output, so that the XHTML page that is generated is well-formed, well-indented, etc. + + fix some problems with the indentation + don't output <br></br>, but <br/> (similar for other empty tags) + don't apply indentation for tags <pre>, <xmp>, etc. *************** *** 37,52 **** conversion tool(s)). - Make any small improvments in the documentation. - Make a new release of phpwebapp that includes the latest changes in the parser any improvments in the docs, etc. - - - * class.WebPage.php::print_dbg_messages() - Output debug messages using EditableRS and templates. - - * Use css styles to the other debug messages as well. - - * Substitute ereg_replace() with preg_replace(). - - * Reformat all the files (automatically with emacs). --- 38,45 ---- conversion tool(s)). + - Reformat all the files (automatically with emacs). + - Make any small improvments in the documentation. - Make a new release of phpwebapp that includes the latest changes in the parser any improvments in the docs, etc. Index: changes.txt =================================================================== RCS file: /cvsroot/phpwebapp/web_app/doc/changes.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** changes.txt 16 Jul 2003 09:27:59 -0000 1.2 --- changes.txt 13 Jul 2004 16:15:20 -0000 1.3 *************** *** 1,450 **** Changes made to the application framework ! that the application developer should know: =========================================== ! -------- afterParse() ---------------------------- ! * - WebObject::afterParse() ! is like WebObject::onParse(), only that it is called after ! the WebObject is parsed. ! ! -------- webobject vars -------------------------- ! * - The framework declares for each webobject these variables: ! {{obj_id}} -- the object id ({{class_name}}::{{obj_name}}) ! {{class_name}} -- the name of the class ! {{obj_name}} -- the name of the object ! {{obj_count}} -- counts the objects of the same class, ! starting from 1 ! These vars can be used inside the template of the webclass, ! if the webclass designer needs them, e.g.: ! <input type="text" name="staff_{{obj_count}}"> ! ! -------- transmitVars() -------------------------- ! * - function transmitVar(var_name, var_value) ! This function sends the var_name (which has the given var_value) ! to the server side as a PHP global variable. It can also be used ! in the template as a tpl variable: {{var_name}}, since all PHP ! global variables can be used as tpl variables. It should be used ! carefully, because any tpl variable with the same name will ! override its value. ! It must be called before GoTo(). ! ! - function transmitVars(var_list) ! Similar to transmitVar() but can transmit more than one variable. ! The format of var_list is: var1=val1&var=val2&var3=val3. ! Must be called before GoTo(). ! ! -------- formWebObj ---------------------------------- ! * - formWebObj is a webobject that makes easy the handling of big ! forms (which have many inputs) and their data connection to the ! databaze. It is used like this: when you have a webbox that ! has a big form, in the PHP code of the webbox you include the ! class 'formWebObj', and then inherit this class, instead of ! inheriting 'WebObject' ('formWebObj' itself extends 'WebObject', ! so this is OK). E.g.: ! ! <WebBox ID="editProject"> ! <form name="bigForm"> ! . . . . . . . . ! <!--# many <input>s, <select>s, etc. here #--> ! . . . . . . . . ! </form> ! </WebBox> ! ---------------------------------------------- ! <? ! include_once FORM_PATH."formWebObj.php"; ! ! class editProject extends formWebObj ! { ! . . . . . . . . . . ! } ! ?> ! ---------------------------------------------- ! <? ! class formWebObj extends WebObject ! { ! . . . . . . . . . . . ! } ! ?> ! ! Then, in the JS code of the webbox you can use these JS functions ! which have been declared and included by the 'formWebObj': ! ! getEventArgs(form); ! /** ! * Returns all the data in the inputs of the given form ! * so that they can be sent as event args, e.g. ! * GoTo("thisPage?event=editProject.save(" + getEventArgs(form) + ")"); ! */ ! ! saveFormData(form); ! /** ! * Transmit the data of the form, so that ! * the changed values are not lost. ! * Must be called before GoTo(). ! */ ! This is useful when the page is refreshed for some reason, ! but you don't want to lose the values that are inputed in it. ! ! There are also these two functions that are used internally by ! 'formWebObj', but you can use them as well, if you need them: ! function getFormData(form) ! //returns all the data filled in the given form ! function setFormData(form, formData) ! //fills the form with the given data ! ! ------------- date WebObject ------------------------------- ! * - The webobject date can be used to select the date from a calendar. ! It can be used like this: ! First include the webclass that defines it: ! <Include SRC="{{DATE_PATH}}date.html" /> ! (DATE_PATH is defined by the framework) ! Then declare as many date objects as needed: ! <WebObject Class="date" Name="information_date" /> ! <WebObject Class="date" Name="contact_date" /> ! etc. ! ! When an object of class date is declared, the framework replaces ! it with this html code: ! <input type="text" class="datebox" onFocus="blur()" ! name="information_date" value="{{information_date}}"> ! <input type="image" ...(the calendar that selects the date)> ! So, it requires a default value {{information_date}}, which can ! be declared in the PHP code of the webox that uses the date object. ! ! If you want to modify it, you can copy it to a path local to ! the application, modify it and use the modified copy, e.g. ! <Include SRC="{{./}}date/date.html" /> ! ! -------------------------------------------------------------- ! * - <Repeat rs="{{tpl_var}}"> ! The attribute rs of the <Repeat> tag can contain variables ! (so that the same repeat can use different recordsets, ! according to the logic of the program). These variables ! are evaluated now in render time (before they were evaluated ! in parse time) because this is more convenient. ! ! ------------- listbox WebObject ------------------------------- ! * - The WebClass "listbox" is used to display a list of values with the ! <select> tag of HTML. These values are taken from a recordset (which ! can be retrieved from DB or can be supplied by PHP code. The recodset ! associated with the listbox must have two fields: 'id' and 'label'. ! 'label' is the field displayed, and 'id' is the value that is selected, ! saved in DB and retrieved from DB. ! ! Recordset example: ! <Recordset ID="listbox::country"> ! <Query> ! SELECT country_id AS id, country_name AS label ! FROM countries ! </Query> ! </Recordset> ! ! Usage example: ! <WebObject Class="listbox" Name="country" rs="rs_id" width="---------------" /> ! ! The attribute "rs" is optional. Its default value (if not specified) is ! {{obj_id}} (in the example above, it would be 'listbox::country'). ! ! The attribute "width" is also optional; it is used as the last line of the ! list, in order to keep the width of the <select> to a certain size (which ! can also be used as a nothing selected (none of the above) value). ! ! This WebClass uses a <select> tag like this: ! <select name="country"> (name="{{obj_name}}") ! . . . . . ! </select> ! So, this should be kept in mind when accessing the selected value ! and when giving an initial value. ! If the 'listbox' is used inside a 'formWebObj' webbox, then it ! takes care of it automatically. ! ! -------------------------------------------------------------------- ! * - The tag <WebObject> can be written in several lines (for making it ! more readable, in case that it has many attributes) and the parser ! can handle it. E.g. ! <WebObject Class = "listbox" Name = "country" ! rs = "rs_id" ! width = "---------------" /> ! ! -------------------------------------------------------------------- ! * - define("VAR_NOT_FOUND", "{var_name}"); ! is added to 'config/const.Settings.php' ! ! This constant sets the format of the error message that is displayed ! when a {{variable}} is not found. 'var_name' is replaced by ! the actual variable name. Examples: "'var_name' is not defined", ! "", "undefined", etc. It cannot contain "{{var_name}}" inside. ! ! -------------------------------------------------------------------- ! * - The recordsets declared by the <Recordset> tag were by default ! of type "StaticRS". Now the default type is "EditableRS", ! because this is more useful (and anyway EditableRS extends StaticRS). ! It can be declared explicitly as "StaticRS" only when the programer ! has strong reasons to disallow the modification of this recordset ! from the PHP code. ! ! -------------------------------------------------------------------- ! * - The JS code of a <WebBox> is included automatically by the ! framework at the <head> of the page. The framework looks for ! the file 'box_id.js' (or 'class_id.js', in case of a <WebClass>) ! 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: ! <script language='javascript' src='path/to/box_id.js'></script> ! ! Similarly, for the CSS code, the framework includes a line like ! this: <link type='stylesheet' src='path/to/box_id.css' ....> ! in the <head> of the page. ! ! ---------------- SendEvent() ---------------------------------------- ! * - js function: SendEvent(obj_id, event_name, event_args) ! ! Sends an event to the server-side (PHP) code. ! obj_id -- the object to which the event is sent ! event_name -- the name of the event ! event_args -- the arguments of the event, optional ! ! It is defined in 'func.GoTo.js' which is included automatically ! by the framework in each page. This function uses GoTo() to ! send an event to a webobject (or webbox). Its target is always ! 'thisPage' (so, it cannot switch to another page of the application, ! like GoTo()) and it cannot send global PHP variables (like GoTo()). ! So, GoTo() is more general, but SendEvent() should be more common ! and more frequently used. ! ! ---------------- WebObject table ------------------------------------- ! * - WebObject 'table' is used to display the content of a table inside a page. ! It is used like this: ! ! <Include SRC="{{TABLE_PATH}}table.html" /> ! ! <WebObject Class="table" Name="offices" ! table="offices" ! fields="off_id,name" ! where="off_id < 10" /> ! ! If attribute 'table' is the name of the table that will be displayed. ! If it is not specified, its default value is {{obj_name}} (the value ! of attribute 'Name'). ! ! The attribute 'fields' is the list of fields that will be displayed. ! It is optional and its default value is "*" (all fields). ! ! The attribute 'where' is the select condition for selecting the records. ! It is optional and its default value is "" (all the records). ! ! ---------------- WebObject editableTable --------------------------- ! * - WebObject 'editableTable' is used to display and edit the content ! of a database table inside a page. It is used like this: ! ! <Include SRC="{{EDITABLE_PATH}}editableTable.html" /> ! ! <WebObject Class="editableTable" Name="offices" ! table="offices" ! fields="off_id,name" ! where="off_id < 10" /> ! ! WebObject 'editableTable' is like 'table', but it also allows to ! add new records to the table, to edit the existing records, to delete ! a record from the table, or to remove all the records of the table ! that are displayed. ! ! ---------------- NULL values ----------------------------------------- ! * - For a DB value that was NULL, the framework used to return UNDEFINED ! and, as a result, in the page was displayed {var_name}. ! Now, the constant NULL_VALUE is returned, which can be specified ! in the file 'config/const.Settings.php'. It can be "", "NULL", NULL, etc. ! ! ---------------- leftMenu webobject ---------------------------------- ! * - WebObject 'leftMenu' displays a menu, usually on the left side of the page. ! It is used like this: ! ! <Include SRC="{{LEFTMENU_PATH}}leftMenu.html" /> ! ! <WebObject Class="leftMenu" Name="su" ! items="{{./}}su_menu_items.php" /> ! ! The attribute 'items' is a PHP file that contains the items of the menu, ! like this: ! <? ! /** ! * The $menu_items array contains the items of the leftMenu. ! */ ! $menu_items = array( ! "item1" => " Menu Item 1 ", ! "item2" => " Menu Item 2 ", ! "item3" => " Menu Item 3 ", ! "etc1" => " . . . ", ! "etc2" => " . . . " ! ); ! ?> ! ! The item of the menu that is selected can be retrieved like this: ! $selected = WebApp::getSVar("leftMenu::su->selected_item"); ! ! If you need to change the look of the leftMenu, then make a local ! copy and modify 'leftMenu.css'. ! -------------------------------------------------------------------- ! * - config/const.Settings.php is divided into const.Options.php ! (some constants that can have optional values, depending on the ! application), and const.Debug.php (constants that enable or ! disable several debugging features of the framework). ! -------------------------------------------------------------------- ! * - The GoTo() function accepts only a string of the form ! GoTo("target.html?event=obj_id.event_name(event_args)"); ! Before it was possible to send some global PHP vars, by appending ! them after the event like this: &var1=val1&var2=val2 etc. ! This was deprecated and actually it is almost never used. In the ! rare cases when it is needed to send a global variable to PHP, ! the functions transmitVar() and transmitVars() can be used. ! The values of the event arguments could not contain '&' before, ! but now they can. ! ! They cannot contain ';', because it is used to separate event args ! from each-other, however, the JS function encode_arg_value(str), ! which is defined by the framework, can be used to replace them ! with '#semicolumn#', in cases that they need to contain ';'. ! The decoding (replacing '#semicolumn#' by ';') is done by the ! framework itself. ! -------------------------------------------------------------------- ! * - The expression of the <Var> tag can now be declared in several ! lines, like this: ! <Var name="class"> ! ( ! "{{item}}"=="{{{{obj_id}}->selected_item}}" ? ! "leftMenu-item-selected" ! :"leftMenu-item" ! ) ! </Var> ! ! -------------------------------------------------------------------- ! * - WebObject 'dbTable' is used to display and edit the content ! of a database table inside a page. It is used like this: ! ! <Include SRC="{{DBTABLE_PATH}}dbTable.html" /> ! ! <WebObject Class="dbTable" Name="offices" ! table = "offices" ! fields = "off_id,name" ! where = "off_id < 10" ! editable = "true" ! selectable = "true" /> ! ! It is like 'editableTable' but has two more attributes. ! The attributes 'editable' and 'selectable' have default values of "false". ! In this case the 'dbTable' behaves just like 'table'. ! ! When 'editable' has a value "true", then the table is editable, ! i.e. its records can be added, deleted or modified. ! ! When 'selectable' has a value "true", then it is possible to select ! a record from the displayed ones. The fields of the selected record ! are declared as global template variables and can be used where they ! are needed. ! ! It makes obsolete WebObjects 'table' and 'editableTable', however ! 'table' is still left in the framework because it is simpler than ! 'dbTable' and it can be easier to modify and customize to fit ! the needs of a certain application. ! ! -------------------------------------------------------------------- ! * - config/const.Debug.php: define("SHOW_ERROR_MESSAGES", true); ! ! If this constant is 'false' than the framework suppresses ! all the error and warning messages (that are generated by the ! framework). Usually it should be 'true' during the development and ! should be switched to 'false' when the application is deployed, ! in order not to confuse the users of the application with error ! messages that have no meaning for them. ! ! -------------------------------------------------------------------- ! * - The function: session.isset(var_name) can be used to check ! whether a certain variable egzists in the session or not. ! ! -------------- datebox WebObject ----------------------------------- ! * - The webbox 'date' is renamed to 'datebox' and the attributes ! (parameters) 'value', 'format', 'onchange' are added to it. ! <Include SRC="{{DATEBOX_PATH}}datebox.html" /> ! <WebObject Class="datebox" Name="information_date" ! value="{{info_date}}" ! format="YYYY-MM-DD" ! onchange="check_selected_date(this)" /> ! <WebObject Class="datebox" Name="proposal_date" /> ! <WebObject Class="datebox" Name="contact_date" /> ! etc. ! The attribute 'value' is used to initialize the datebox ! with an initial value. If it is not given, then the ! default is {{{{obj_name}}}} (in the example above it would ! be {{information_date}}). ! The attribute 'format' is used to specify the format of the ! date. The reckognized formats are: ! YYYY-MM-DD (default) ! MM/DD/YYYY ! MM-DD-YYYY ! DD/MM/YYYY ! DD-MM-YYYY ! Actually this is only the format of the display, because the ! internal format is allways YYYY-MM-DD, the format used by ! the databases. E.g. if the above datebox webobject is declared ! inside a form with the name 'editDoc', then ! "document.editDoc.information_date.value" returns the date in ! the internal format (in the format YYYY-MM-DD). ! The attribute 'onchange' (be carefull, all lowercase) is used ! to call any validation function at the time that the date is changed. ! If you pass 'this' as a argument to this function, then it ! refers to the display format. E.g. if 'date' is the parameter to ! which 'this' is passed, then "d = date.value;" gets the selected ! date in the display format (which is specified by the attribute ! 'format'), and "date.value = d;" sets the date of the datebox ! ('d' should be in the format specified by 'format'). ! -------------------------------------------------------------------- ! * - WebObject 'listbox' can now take another attribute, 'onchange' ! (all lowercase), where the programer can call some JS code ! when the selected value is changed. ! -------------------------------------------------------------------- ! * - PagedRS can also handle the queries which have GROUP BY. ! Along to the state variable 'rs_id->current_page' which keeps ! the current page of the PagedRS, there is the state variable ! 'rs_id->recount' which is set to true by the application when ! the records need to to be recounted (e.g. when a new record is ! added in DB, or when a record is deleted). ! Before, the number of the records in a PagedRS was counted only ! when current_page was 1, but this is not very convenient. ! -------------------------------------------------------------------- ! * - define("DISPLAY_CGI_VARS", false); (at 'config/const.Options.php') ! When this constant is true, then the CGI vars are displayed ! at the URL window of the browser. See also SHOW_EXTERNAL_LINK ! at const.Debug.php. ! -------------------------------------------------------------------- ! * - The framework now gets the user variables (browser variables) ! from $_GET, $_POST and $_REQUEST, in order to comply with PHP 4.2.0 ! The global object $request (of class Request, declared in ! /session/class.Request.php) can be used to get the browser variables: ! sourcePage, targetPage, sessionVars, strEvents, phpVars. ! ! -------------------------------------------------------------------- ! * - Changes in the structure of the files of the application; ! event_handler/on.firstTime.php is replaced by 'init.php', which ! is called (if it exists) the first time that the application is ! opened. ! define("FIRSTPAGE", "main.html"); in 'config/const.Settings.php' ! sets the first page of the application. ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- ! -------------------------------------------------------------------- --- 1,69 ---- Changes made to the application framework ! that the framework users should know: =========================================== ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! ------------------------------------------------------------------- ! * <Repeat> syntax changed. ! There was a problem with the <Header>/<Footer> tags, because the ! contents of the <Header> usually is not well-formed xml and ! it breaks the xml parsing. E.g. it may be something like this: ! <repeat rs="rs_id"> ! <header> ! <table> ! </header> ! <tr><td>{{xyz}}</td></tr> ! <footer> ! </table> ! </footer> ! </repeat> ! In order to solve this, <Header> and <Footer> tags were removed at all. ! Now it can be done like this (which is well-formed xml): ! <table> ! <repeat rs="rs_id"> ! <tr><td>{{xyz}}</td></tr> ! </repeat> ! </table> ! For the case of paged recordsets, when we need the navigation variables ! (to get the next page, previous page, etc.) a new framework tag was added: ! <RSNavig rs="paged_rs_id"> ... </RSNavig> ! The tags <IfEmpty>, <Separator> and the dummy tag <RepeatBody> can be ! used the same as before. ! ------------------------------------------------------------------- ! * Parsing is done using an XML parser. This means that some ! restrictions that were due to the previous parser, now are remov... [truncated message content] |