
Changes made to the application framework
that the framework users should know:
===========================================

-------------------------------------------------------------------
* The tag <textarea> is treated as preformated (similar to <pre>,
  <xmp> and <example>). This means that the indentation and the 
  white-space of its contents are preserved by the framework.
-------------------------------------------------------------------
* GoTo() can have a second optional parameter which specifies the action
  where the form is to be submitted. Default is the previous action.
  If it is 'index' then the filename will be removed from the previous
  action (ant the action will become in fact index.php in the path).
-------------------------------------------------------------------
* WebApp::addSVar() or $this->addSVar() initialize a state variable
  by calling $session->addVar().  Now the behaviour of $session->addVar()
  is modified so that it will not re-initialize a variable (it will
  not change the value of a variable, if it already exists). This is
  done in order to be able to set some state variables of a webbox
  without being afraid that init() will override them. 
-------------------------------------------------------------------
* Added function:
      WebApp::fill_template($tpl_file, $vars)
  This function processes the given template, replacing any variables,
  including any other templates, etc. and returns the resulting
  string. The parameter $vars(optional) is an array of variables
  (associative array), which can be used to replace the template vars.
  This function is different from:
      WebApp::getHtmlPage($tpl_file)         and from
      WebApp::constructHtmlPage($tpl_file)
  because they assume that the given template file is a main template
  (which has a prolog <?xml ...?> and an <html> root element),
  and also they append some extra things to the consructed page,
  like debug information, session variables, etc. 
-------------------------------------------------------------------
* Function WebApp::popup_window($name, $url, $features ='nil')
  can be used to open a pop-up window (in a new browser).
  Parameters $name, $url, and $features will be used in a 
  javascript statement like this:
      $name = window.open($url, $name, $features);
-------------------------------------------------------------------
* Added function:
      WebApp::GoTo($target_page, $target_object =UNDEFINED,
                   $event_name =UNDEFINED, $event_args =UNDEFINED)
  This function stops constructing the current page and starts
  loading and constructing the given target page.  Similar to
  the JS function GoTo(), it can also send an event to the new
  page that is going to be constructed.
-------------------------------------------------------------------
* Added debug options DEBUG_INCLUDES and DEBUG_WEBOBJECTS. They
  should be included in 'config/const.Debug.php' like this:

/**
 * if this constant is true, the framework outputs a box 
 * around each file that is included in the page
 */
define("DEBUG_INCLUDES", false);

/**
 * if this constant is true, the framework outputs a box 
 * around each webobject that is used in the page
 */
define("DEBUG_WEBOBJECTS", false);

-------------------------------------------------------------------
* Added the (framework) tag <unindented>. By default the framework indents
  all the templates that are processed or included. However sometimes may
  be usefull not to indent a part of a template. This can be done by
  including it inside the <unindeted> tag, like this:
    <unindented>
    {{file_revision}}
    </unindented>
-------------------------------------------------------------------

* Added support for multiple languages to the framework.
  translation / internationalization (i18n) / localization (l10n)

  It can use any one of the packages:
    - PHP-gettext (http://savannah.nongnu.org/projects/php-gettext/)
    - GNU gettext (http://www.gnu.org/software/gettext/gettext.html,
                   http://www.php.net/gettext)
  since both of them have some advantages or disadvantages.

  The disadvantages of GNU gettext are that it does not work if gettext
  package is not installed, or if the system is not configured for
  using translations of a language. Also, the gettext functions in the php
  seem not to be reliable, sometimes they get the translation from one
  place, sometimes from another (maybe this is a caching problem?).
  In general, it is a headache to make it work.
 
  The disadvantages of PHP-gettext are that it may not be as fast
  as GNU gettext, and there may be some gettext functionality that is
  not supported yet (not implemented yet).

  The application programer can choose the one that suits him best.
  The choice is made at 'config/const.Options.php':

    /** if true, then use the php-gettext instead of GNU gettext */
    define('USE_PHP_GETTEXT', true);

  Other translation constants that are defined at the options file
  are LNG and CODESET:

    /**
     * The constants LNG and CODESET set a default language and codeset for
     * the application. They are used for the localization (translation)
     * of the messages. They can be changed by calling: 
     *    $l10n->set_lng($lng, $codeset)   
     * where $l10n is a global variable and $codeset is optional.
     * LNG can be something like 'en_US' or 'en' or UNDEFINED.
     * CODESET can be UNDEFINED, 'iso-latin-1', etc.
     */
    define('LNG', 'sq_AL');
    define('CODESET', 'iso-latin-1');

  LNG sets a default language for the application, but it can also be
  changed dynamically, calling $l10n->set_lng($lng). With GNU gettext,
  LNG can also be UNDEFINED, and in this case the system default will
  be used. However, with PHP-gettext it should have a value (or a
  value should be set with $l10n->set_lng()).
  CODESET is used in GNU gettext, but it is not needed by PHP-gettext,
  so it can also be UNDEFINED. See the documentation of gettext 
  (`info gettext`) for more information about when and why it is needed.
 
  The framework allows to have separate translation (localization) files
  foreach template that is included and for each webobject. If the
  directory that contains the template (or webbox) contains also
  a subdirectory named 'l10n', then the framework will look inside
  this directory for the file that contains the translations of the
  messages of the template/webbox. It will look for the file
  l10n/lng/LC_MESSAGES/tplname.mo (or l10n/lng/LC_MESSAGES/webboxid.mo)
  which contains the translation messages of the template (or webbox).
 
  If the subdirectory 'l10n/' does not exist, the framework will 
  look for the file tplname.mo (or webboxid.mo) in the first 'l10n/'
  in the parent directory or in the ancestors. If even the application
  directory does not contain a 'l10n/' subdir, then the last place 
  to look for will be the system default (usually /usr/share/locale/).
 
  About the language code, if it is e.g. 'en_US', then it will search 
  first the folder 'en_US/' and then the folder 'en/'.
 
  If the file tplname.mo (or webboxid.mo) is not found at all in 
  the searched directories, then the last translation (*.mo) file
  that was found will be used for translating messages. This is usually
  the translation (*.mo) file of the containing template or webbox
  (from which this template/webbox is included directly or indirectly).
  
  This way of finding the translation files allows for modularity,
  because each webbox/template can have its own translation files,
  so using them in other applications can be done by just copying them
  there. But it is also flexible and does not enforce unnecessary
  or unneeded modularity, so that for example the whole application
  can have a single translation file, or sub-webbox-es can use the
  translation files of the main webbox.
 
  In general, translation files (*.mo) can be organized like this:

    - A single translation file 'app_name.mo' can be used for all the
      application. It can be placed in /usr/share/locale/lng/LC_MESSAGES/
      or in app_path/l10n/lng/LC_MESSAGES/ 

    - Generic webboxes, which are used in more that one application,
      can have their own translation file 'webbox_id.mo' (besides
      the application file 'app_name.mo'), which is placed in the
      same directory as the application file (see above).

    - Each important webbox can have a subdirectory 'l10n/', 
      in which is placed the translation file of the webbox,
      in /path/to/webbox/l10n/lng/LC_MESSAGES/webbox.mo .
      This file can contain the translations of all the sub-webbox-es
      and sub-templates as well (the ones that are included from this
      webbox), or they (their translations) can be in separate
      files in the same directory, which are named according to
      the template name or the webbox id.

    - Each webbox can have its own 'l10n/' directory, which contains
      its own translation files. This is the most modular aproach
      but it may not be always needed.

  Other combinations are possible as well, so it is up to the
  application and its developer to decide about it.
  
  In order to make a string translatable, it should be placed
  as an argument of the T_() function and should be surrounded
  by double quotes, like this: T_("Hello!") . This can be used
  both in the PHP code and in the HTML templates.

  In order to have variables inside a message, you have to make
  some tricks. E.g., to make translatable this message:
    --code
    $msg = "file '$filename' does not exist";
    print "Error: $msg.";
    ----
  It can be written like this:
    --code
    $msg = T_("file 'v_filename' does not exist");
    $msg = str_replace('v_filename', $filename, $msg);
    print "Error: $msg.";
    ----
  This allows the translator to change the position of the variable,
  if needed.

  Then, the rest is the same as described by the gettext documentation
  (see `info gettext`): the translatable strings are extracted
  automatically from the PHP code and HTML templates using the 
  xgettext program (see `info xgettext`), creating *.po files,
  then the strings are translated, then *.po files are converted
  to *.mo files using `msgfmt`, then they are installed (placed at
  the propper location in the application). The xgettext program
  should be called with the '-kT_' parameter, which means that
  'T_' is the name of the function whose strings will be extracted.

  Tip: In order to translating attribute values, use a {{variable}}
       inside the attribute value, and then in the PHP code that
       adds the variable, get the appropriate translation. E.g.

       <input type="button" value="{{Search>>}}" /> (in HTML)

       WebApp::addVar('Search>>', T_("Search>>"));  (in PHP)

  Tip: Some templates contain text, not just messages, which can
       also be mixed with HTML tags (see e.g. 
       'templates/search/help.html' in this case it is difficult
       to translate it using translation messages. The best way is
       to use a separate template for each language, like
       'help_en_US.html', 'help_sq_AL.html', etc.
       When the template is included, something like this can be
       used:
         <include src="{{./}}help_{{lng}}.html" />
       where {{lng}} can be defined in the php code like this:
         function onParse()
           {
             global $l10n;
             WebApp::addVar('lng', $l10n->lng);      
           }
 
  Tip: Since xgettext has the C syntax in mind, for strings 
       in multiple lines, it gives a warning: "unterminated string
       literal" and it does not get them right. To bypass this
       problem, a slash (\) can be added at the end of the lines,
       like in C strings. The framework will take care to remove it
       automatically and the lines will be as if there was no break
       between them. In case that you do want to preserve the break
       between the lines, then use '\n\' at the end of the lines.

       This is just a dirty trick, the clean solution would be to
       modify xgettext so that it reckognizes the syntax of php and
       html strings, but it is not so easy for me to do this, and
       until somebody does it, this trick solves the problem. 

-------------------------------------------------------------------

* Now it is possible to use translatable messages in the JS code
  (e.g. in the messages that are displayed by alert()). Same as
  in PHP and HTML, strings are translated by the function:
  T_("....").

  Attention: double quotes must be used ("), otherwise
             xgettext will not be able to extract them.

  In order to have variables inside a message, you have to make
  some tricks. E.g., to make translatable this message:
    --code
    var new_node_id = prompt("Rename node '" + node_id + "' to:");
    ----
  It can be written like this:
    --code
    var msg = T_("Rename node 'v_node_id' to:").replace(/v_node_id/, node_id);
    //var msg = T_("Rename node 'v_node_id' to:");
    //msg = msg.replace(/v_node_id/, node_id);
    var new_node_id = prompt(msg);
    ----
  This allows the translator to change the position of the variable,
  if needed.

  Note: How it Works
  The JS function T_(msgid), which is included in the page by
  the framework, returns the translation msgstr of the given msgid.
  This translation is retrived from a list of translated messages,
  which is contained by the JS object l10n of class L10n, which is
  included in the page by the framework. If you view the source of
  the page, you will see near the end something like this:
    --code 
    <script type="text/javascript" language="javascript"
            src="web_app/l10n/class.L10n.js"></script>
    <script type="text/javascript" language="javascript">
    //<![CDATA[
      l10n = new L10n();
      l10n.addMsg("You are deleting this node and all the subnodes.",
                  "You are deleting this node and all the subnodes.");
      l10n.addMsg("ID cannot be empty.", "ID cannot be empty.");
      l10n.addMsg("Title cannot be empty.", "Title cannot be empty.");
      l10n.addMsg("Please give an ID.", "Please give an ID.");
      l10n.addMsg("Please give a title.", "Please give a title.");
      l10n.addMsg("Rename 'v_item' to:", "Rename 'v_item' to:");
      l10n.addMsg("Your are deleting 'v_item'!",
                  "Your are deleting 'v_item'!");
      l10n.addMsg("Uploading:", "Uploading:");
      l10n.addMsg("Please wait...", "Please wait...");
    //]]>
    </script>
    ----
  This is generated automatically by the framework. For each JS file
  that it includes in the <head> of the page, it also scans it for
  translatable messages, gets their translation, and includes lines
  l10n.addMsg(msgid, msgstr), as above.

-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
