diff --git a/etemplate/doc/etemplate.html b/etemplate/doc/etemplate.html new file mode 100644 index 0000000000..902ff20255 --- /dev/null +++ b/etemplate/doc/etemplate.html @@ -0,0 +1,462 @@ + + + +
+A developers tutorial how to write an application with the new eTemplates.
+It is also an introduction how to write a phpgw- and setup(3)-compatible app.
As an example we will run now through the necessary steps to create a simple media database using eTemplates and +other tools and classes from the eTemplate app: db-tools and class.so_sql.inc.php.
+Out media database should have the usual fields: name, author, description, type: BOOK, CD, VIDEO and should be able +to edit records and search for them.
+As a preaquistion you need to get / checkout the etemplate app, install the app via setup/manage applications and +enable your account for using the app (Admin/User account: check eTemplates).
+ +Each app need a name, eg. 'et_media'. We now need to create the following directory structur above the eGroupWare dir: +
+et_media that has to be identical to our app-name + + setup files necessary for the setup Programm, give the webserver write-permission to that dir + + inc class-files + + templates templates, still needed to store the images and get around a lot of complains from the api + + default + + images here goes our images / icons ++ +
That files contains the necessary information for setup to install the app.
++<?php + $setup_info['et_media']['name'] = 'et_media'; + $setup_info['et_media']['title'] = 'eT-Media'; + $setup_info['et_media']['version'] = '0.9.15.001'; + $setup_info['et_media']['app_order'] = 100; // at the end + $setup_info['et_media']['tables'] = array('phpgw_et_media'); + $setup_info['et_media']['enable'] = 1; + + /* Dependencies for this app to work */ + $setup_info['et_media']['depends'][] = array( + 'appname' => 'phpgwapi', + 'versions' => Array('0.9.14','0.9.15','0.9.16','1.0.0','1.0.1') + ); + $setup_info['et_media']['depends'][] = array( // this is only necessary as long the etemplate-class is not in the api + 'appname' => 'etemplate', + 'versions' => Array('0.9.14','0.9.15','0.9.16','1.0.0') + ); ++ +
To enable setup to create a db-table for us and to supply the so_sql-class with the necessary information, we need to define
+the type and size of the fields / columns in our db-table.
+We can use the db-Tools from the etemplate app to create the file for us:
Now we need a nice edit dialog and use the eTemplate editor to set it up:
+ ++
As you see above i added an application titel, a horizontal rule after it and some space (empty label's). Do so if you want.
+ +The index page is only used if someone clicks on the navbar icon (or on the black cross as we haven't supplied one so far).
+Create the file /et_media/index.php with the following content:
+<?php + $GLOBALS['phpgw_info']['flags'] = array( + 'currentapp' => 'et_media', + 'noheader' => True, + 'nonavbar' => True + ); + include('../header.inc.php'); + + header('Location: '.$GLOBALS['phpgw']->link('/index.php','menuaction=et_media.et_media.edit')); + $GLOBALS['phpgw_info']['flags']['nodisplay'] = True; + exit; ++ +
As a first step, we only save new entries. The code of the app is in /et_media/inc/class.et_media.inc.php:
+ ++<?php +/**************************************************************************\ +* eGroupWare - eTemplates - Tutoria Example - a simple MediaDB * +* http://www.eGroupWare.org * +* Written by Ralf Becker <RalfBecker AT outdoor-training DOT de> * +* -------------------------------------------- * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 2 of the License, or (at your * +* option) any later version. * +\**************************************************************************/ + +/* $ Id: class.et_media.inc.php,v 1.2 2002/10/19 11:11:03 ralfbecker Exp $ */ + +include_once(PHPGW_INCLUDE_ROOT . '/etemplate/inc/class.so_sql.inc.php'); +$GLOBALS['phpgw_info']['flags']['included_classes']['so_sql'] = True; ++ +
This loads the class so_sql, in a way that more than one class may use it (would be nice if we had an api-function for that).
+ ++class et_media extends so_sql +{ + var $types = array( + '' => 'Select one ...', + 'cd' => 'Compact Disc', + 'dvd' => 'DVD', + 'book' => 'Book', + 'video' => 'Video Tape' + ); ++ +
These are a few messages to show the user what happend, we show it via 'msg' in content in the first Label-field after the app-title.
+As one of the messages contain a %s to be used with sprintf, we have to run them manualy through lang().
+ function et_media() + { + $this->tmpl = CreateObject('etemplate.etemplate','et_media.edit'); + + $this->so_sql('et_media','phpgw_et_media'); // sets up our storage layer using the table 'phpgw_et_media' + $this->empty_on_write = "''"; // what to write in the db, if a column is empty, the default is NULL + + $this->public_functions += array( // this function can be called external, eg. by /index.php?menuaction=... + 'edit' => True, + 'writeLangFile' => True + ); + } ++ +
This is the contructor of the class, it does the following for us: +
+ function edit($content='',$msg = '') + { + if (is_array($content)) // we are called as callback for the dialog / form + { + if ($content['id'] > 0) // if we have an id --> read the entry + { + $this->read($content); + } + $this->data_merge($content); // merge content with our internal data-array ($this->data) + + if (isset($content['save'])) // save the entry ($this->data) + { + $msg .= !$this->save() ? lang('Entry saved') : lang('Error: writeing !!!'); + } + elseif (isset($content['read'])) + { + unset($content['id']); // not set by user, so dont use for seach + $found = $this->search($content,False,'name,author'); // searches by using the no-empty fields + + if (!$found) // search returned empty + { + $msg .= lang('Nothing matched search criteria !!!'); + } + else + { + $this->init($found[0]); // set data-array with the content of the first match + } + } + } + + // now we filling the content array for the next call to etemplate.exec + + $content = $this->data + array( // the content to be merged in the template + 'msg' => $msg + ); + $sel_options = array( // the options for our type selectbox + 'type' => $this->types + ); + $no_button = array( // button not to show + ); + $preserv = array( // this data is preserved over the exec-call (like a hidden input-field in form) + 'id' => $this->data['id'] + ); + $this->tmpl->exec( + 'et_media.et_media.edit', // setting this function as callback for the dialog + $content,$sel_options,$no_button,$preserv + ); + } +} ++ +
The edit function is called from our index.php file or as callback for this form / dialog. In that case $content is an array +with the content the user put into the fields of the dialog.
+Let first have a look what happend if we called the first time (or what we do to show the dialog again with the changed data):
+
Now let's have a look what happens if the user submits the form and our callback is called: +
Now we are able to store entries in the db and retrive them by searching the database for patterns in the different fields.
+We are only lacking some way to show if we get more than one match on a search, that's what we are going to implement next:
First we need to create an other eTemplate to show the list: 'et_media.show'
+ +As you see the templates includes an other template: 'et_media.show.rows'
+ +We need some code / a function in the class to call the template and fill the content:
+ ++ function show($found) + { + if (!is_array($found) || !count($found)) + { + $this->edit(); + return; + } + reset($found); // create array with all matches, indexes starting with 1 + for ($row=1; list($key,$data) = each($found); ++$row) + { + $entry[$row] = $data; + } + $content = array( + 'msg' => lang('%d matches on search criteria',count($found)), + 'entry' => $entry // et_media.show.rows uses this, as we put 'entry' in the Options-field + ); + $this->tmpl->read('et_media.show'); // read the show-template + + $this->tmpl->exec('et_media.et_media.edit',$content); // exec it with the edit-function as callback + } ++ +
This function is called by edit with the matches of a search:
+To call the show function, we need to make some changes to the edit-function too:
+ ++ elseif (isset($content['read'])) + { + unset($content['id']); // not set by user, so dont use for seach + $found = $this->search($content,False,'name,author'); // searches by using the no-empty fields + + if (!$found) // search returned empty + { + $msg .= lang('Nothing matched search criteria !!!'); + } + elseif (count($found) == 1) // only one match --> show it in the editor + { + $this->init($found[0]); + } + else // multiple matches --> use the show function/template + { + $this->show($found); + return; + } + } + elseif (isset($content['entry']['edit'])) // the callback from for the show function/template + { // the id is set via the button name of '$row_cont[id]' + list($id) = each($content['entry']['edit']); // note its not only ['edit'] !!! + if ($id > 0) + { + $this->read(array('id' => $id)); + } + } ++ +
While makeing this changes we can add a [Cancel] and [Delete] button too:
+ +
+ elseif (isset($content['cancel']))
+ {
+ $this->init();
+ }
+ elseif (isset($content['delete']))
+ {
+ $this->delete();
+ $this->init();
+ }
+
+
+ $no_button = array( // no delete button if id == 0 --> entry not saved
+ 'delete' => !$this->data[$this->db_key_cols[$this->autoinc_id]]
+ );
+
+
+Of course we have to add this buttons to the template 'et_media.edit'. I trust you can add 2 Submitbuttons with the names +'cancel' and 'delete', a Label and a nice helpmessages by now without looking at a screenshot ;-).
+ +To get rid of the stars '*' behind each Label and to be able to translate the app in other languages we need to create a lang-file
+There are 2 possibilties to create it automaticaly:
Anyway we have to use the TranslationTools to find and write the lang()-messages of our code!
+ +
+ /*!
+ @function writeLangFile
+ @abstract writes langfile with all templates registered here
+ @discussion can be called via [write Langfile] in eTemplate editor
+ */
+ function writeLangFile()
+ {
+ return $this->tmpl->writeLangFile('et_media','en',$this->types);
+ }
+
+
+To be able to put the eTemplates in CVS and to ship them with your app, you need to dump them in a file first. +
This is done in the eTemplate editor by putting the app-name or an template-name in the Name field and clicking on the button +[Dump4Setup]. This creates the file et_media/setup/etemplates.inc.php. The etemplate-class loads this file whenever it finds +a new version automaticaly.
+ +