diff --git a/etemplate/doc/db_tools.gif b/etemplate/doc/db_tools.gif deleted file mode 100644 index 4bc440e7cd..0000000000 Binary files a/etemplate/doc/db_tools.gif and /dev/null differ diff --git a/etemplate/doc/editor.gif b/etemplate/doc/editor.gif deleted file mode 100644 index 95a1ac669e..0000000000 Binary files a/etemplate/doc/editor.gif and /dev/null differ diff --git a/etemplate/doc/etemplate.html b/etemplate/doc/etemplate.html index 981ab47c4a..59816897ef 100644 --- a/etemplate/doc/etemplate.html +++ b/etemplate/doc/etemplate.html @@ -1,461 +1,703 @@ - - - -
-A developers tutorial how to write an application with the new eTemplates.
-It is also an introduction how to write a eGW- and setup(3)-compatible app.
A developers tutorial how to write an application with the new
+eTemplates.
It is also an introduction how to write a eGW- and
+setup(3)-compatible app.
The eTemplates +
consist out of rows and cols with + input-fields of several types +
+there is a dialog-editor (one part + of the etemplate-app) to create the eTemplate +
+eTemplates can be (and are + usually) nested, eg. a template-field can contain an other eTemplate +
+each field / cell of the template + can have a label which is automaticaly run through lang() (the + content of the field can be run through lang() too) +
+the dialog editor can write all + labels in a lang-file (mergeing it with the existing ones) +
+eTemplates have a name of the form + app.function[.subtemplate] which is used to call them up +
+they can have further keys, on + loading the class picks the most appropriate one for a user: +
group: the id of a group if the + template is just for that group (that allows admin to show differnt + views to each group) +
+lang: the 2 or 5 letter language + code (or empty for a non-language specific template) +
+template set: they belong too (if + the template-set key is empty it is an default-template) +
+version: version number like: + '0.9.15.001' +
+they are stored in an array and in + serialized form in the db-table 'phpgw_etemplate' +
+the dialog editor can dump all + templates of an app for distribution (so they can be in the CVS too) +
+they encapsulate differnt UI (User Interface) types from the
+ app: at the moment only a HTML one is ready, but a GTK one (using
+ php-gtk, running
+ as native app under linux and win32) and XUL is under
+ development.
Here is a first screenshot of the DB-Tools as native
+ Linux Application:
+
+
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).
- +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:
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('1.2.005','1.2.006') + ); + $setup_info['et_media']['depends'][] = array( // this is only necessary as long the etemplate-class is not in the api + 'appname' => 'etemplate', + 'versions' => Array('1.2') + );
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 application to create the
+file for us:
+
start the etemplate app and click + on the button up, right which says db-Tools +
+select Application: eT-Media +
+type 'egw_et_media' in the field + in front of the [Add Table] button and click on the button +
+now use [Add Column] to create the + necessary fields as shown on the screenshot +
+Click on [Write Table] (you need + to give the webserver write-permission to the setup-dir of et_media + or you will get an error message, leave the write-permission as it + is necessary later on too, click on write again) +
+log out and log into setup and + start manage applications +
+eT-Media is shown as not installed + and only install is offerd, check it and submit +
+you can now log out from setup, the db-table is now created +
+In order to be able to use your eT-Media application, do not + forget to give yourself access to it (Admin/User account: check + eT-Media)
+Now we need a nice edit dialog and use the eTemplate editor to set it up:
- - - +Now we need a nice edit dialog and use the eTemplate editor to set +it up: +
-
start the etemplate app and type + 'et_media.edit' in the name field. Save the template in order + to create it
+an empty template is displayed. An + eTemplate can be thought off as a “grid”. The first cell may be + a bit tricky to find, but will be highlighted when moving the mouse + over it. On my computer this cell appears in pink as illustrated + below:
+
Double
+ click on the pink spot will bring the following dialog:
The
+ top row allows you to add column and rows to the template. We will
+ need 2 columns and 6 rows
Create the following label in the + first top left cell:
+
+
+
In the top right cell, we will create a user entry and call + it “name”: this is the same name as thee column in our + egw_et_media table. This is important as those fields will be + populated automatically for us by eGroupWare:
+
Complete
+ the template as follows. The widget used for “type” is a
+ Selectbox, the one used for “description” is a textarea. Note
+ that the name of the input is “descr” and not description, as
+ this is the name of the column in the table. Finally on the last row
+ we have two widgets of type “Submitbutton” of names “read”
+ and “save” and of corresponding label.
Then before moving to the next stage save the template as an XML +file by clicking on “Export XML”. Once again the server must have +write permissions on the directory.
+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'); + $GLOBALS['egw']->redirect_link('/index.php', 'menuaction=raphatest.ui_et_media.edit'); +
An eGroupWare application is organised around 3 application +layers:
+the storage layer, managed by a “Storage Object” (so). + This object is responsible for handling all access to the storage + engine
+the business layer, managed by a “Business Ojbect” (bo). + This object is responsible for all the business logic
+the user interface layer, managed by a “User Interface” + (ui) object. This object is responsible for all interaction with the + user, including displaying and gathering data to and from the user
+For this, we create 3 files in the “inc” directory, called +class.so.et_media.inc.php, class.bo_et_media.inc.php, +class.ui_et_media.inc.php. In this simple application, the bo and so +layers will be fairly minimal, this said it is a good idea to create +the application using the right standards from the start.
+Here is the file /et_media/inc/class.so_et_media.inc.php:
+<?php + include_once(PHPGW_INCLUDE_ROOT . '/etemplate/inc/class.so_sql.inc.php'); - -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.
+ /** + * General storage class for et_media + */ + class so_et_media extends so_sql + { + function so_et_media() + { + $this->so_sql('et_media','egw_et_media'); + $this->empty_on_write = "''"; + } + }
+
+
The file /et_media/inc/class.bo_et_media.inc.php:
+<?php + /** + * Business Object for et_media + */ + class bo_et_media + { + var $types = array( + '' => 'Select one ...', + 'cd' => 'Compact Disc', + 'dvd' => 'DVD', + 'book' => 'Book', + 'video' => 'Video Tape' + ); -5. setting up the index page
-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).
+ function bo_et_media() + { + $this->so =& CreateObject('et_media.so_et_media'); + } + + function save($content) + { + $this->so->save($content); + } -
-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; -- -6. the code of class.et_media.inc.php
-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 -/**************************************************************************\ + function read($content) + { + $this->so->search($content); + } + }
+
+
+And finally the start of the +/et_media/inc/class.ui_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> * +* 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 $ */ +/* $ 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'); -
- -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 +class ui_et_media { - var $types = array( - '' => 'Select one ...', - 'cd' => 'Compact Disc', - 'dvd' => 'DVD', - 'book' => 'Book', - 'video' => 'Video Tape' - ); -+ var $public_functions = array( + "edit" => True, + "writeLangFile" => True + );
+The $public_functions array defines which public functions can be +accessed by the user.
+The constructor initialises the template engine and the Business +Object:
+function ui_et_media() + { + $this->tmpl =& CreateObject('etemplate.etemplate', 'et_media.edit'); + $this->bo =& CreateObject('et_media.bo_et_media'); + $this->html =& $GLOBALS['egw']->html; + + if(!@is_object($GLOBALS['egw']->js)) + { + $GLOBALS['egw']->js =& CreateObject('phpgwapi.javascript'); + } -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().
+
+
Finally, the edit function is the one which does all the work from +a user perspective.
+function edit($content='') +{ + if (is_array($content)) // we are called as a call back + { + $r_id = $content['id']; + if ($r_id>0) // if we have an id -> read the entry + { + $content = $this->bo->read($content['id']); + } -- function et_media() - { - $this->tmpl = CreateObject('etemplate.etemplate','et_media.edit'); + if (isset($content['save'])) + { + unset($content['save']); + $msg .= (!$this->bo->save($content))?lang('Entry Saved'):lang('Error: while saving'); + } + elseif (isset($content['read'])) + { + unset($content['id']); + unset($content['read']); + $found = $this->bo->so->search($content, False, 'name, author'); - $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 + if (!$found) + { + $msg .= lang('Nothing matched the search criteria'); + } + else + { + $content = $found[0]; + } + } + } + else + { + $content = array(); + } - $this->public_functions += array( // this function can be called external, eg. by /index.php?menuaction=... - 'edit' => True, - 'writeLangFile' => True - ); - } -+ //now we fill the content array for the next call to etemplate.exec -This is the contructor of the class, it does the following for us: + $content = $content + array ( + 'msg' => $msg + ); + + $sel_options = array( + 'type' => $this->bo->types + ); + + $no_button = array( + ); + $preserv = array( + 'id' => $this->data['id'] + ); + + $this->tmpl->exec( + 'et_media.ui_et_media.edit', // setting this function as the callback + $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):
- 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: while saving !!!'); - } - 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):
+
the $content array is set up with + our internal data-array (which is empty on the first call) and the + message +
+$sel_options has the options for + our selectbox: the options are an array where the keys are the + values returned by the selectbox and the values are what the + selectbox shows to the user. As we can have more than one selectbox + in a dialog, the key in $sel_options need to be the same as the name + of the selectbox. +
+$readonlys: if a fieldname is set + in $readonlys to True, its content is showed readonly (for regular + fields like type Text) or left out for buttons (we use this later to + show the delete-button only when an entry is loaded) +
+the array $preserv is preserved, + which means its stored in the app's session-data and is delivered + back like the content of the fields to the callback-function. We use + it here to store the id of the entry. This is similar to use a + hidden input-field in a form, but it does not need to be serialized + by the app and is NOT transmitted to the user and back. +
+at last we call etemplate::exec to show the template with the + content from $content and set the function itself as callback for + the dialog / form. +
+Now let's have a look what happens if the user submits the form +and our callback is called: +
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:
the callback (this function) is
+ not the submit-address of the form, the form get's always submitted
+ to the function process_exec of the etemplate class. This
+ function changes for some field-types the content (eg. a date-field
+ consists of 3 single fields, process_exec takes care that it is
+ delivered back as timestamp, as we set it in content before). It can
+ even submit the form back to the user if for a address-selection a
+ search for a pattern has to be performed and the matches are shown
+ to the user. In this case the callback is NOT called. The same is
+ true if an int field contains letters or is not within the minimum
+ or maximum set. Not all of the is allready working, it will
+ follow in the next days/weeks.
For the specialist
+ process_exec uses $_POST and ignores $_GET set as query in the url.
+
the so_sql function data_merge, + copies all values from $content, which are columns in the db-table, + in our internal data array. Values which are not real data, like + buttons pressed are not copied (!). +
+if $content['save'] is set, the + [Save] button has been pressed ('save' is the name NOT the label of + the save button), in that case we use so_sql's save function to save + the content of our internal data-array to the db. +
+the same check is used for the + [Read]: we uses the content of all fields to search db for matching + entries. The user can use wildcards to perform a search on all + field. The wildcards are '*' and '?', so_sql translates them into + sql-wildcards. +
+if the search return False we just + set our message var. +
+if something is found we use + so_sql's init-function to set the data of the first match. Lateron + we will show a list if more than one entry is found. +
+after that the content array is filled again as discriped + above. +
+Now we are able to store entries in the db and retrive them by +searching the database for patterns in the different fields. You can +try your new application now. You can create new records and save +them. By just entering the name or author, the database will find the +corresponding match and populate the form for you.
+
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'
+First we need to create an other eTemplate to show the list: +'et_media.show' as follows. This is made of a label of name +“msg” (to display messages), an HorizontalRule widget, and a +Template widget: we will use a “sub template” called +et_media.show.rows to display the rows of the search function. I have +set the option of the template widget to “entry” as this is the +name we will use to access to the data in the sub-template. +
+
+
The 'et_media.show.rows' template is +created as a 3x2 table. On the header row, two labels “Name” and +“Author” and one empty cell.
+On the second row, two labels of +name ${row}[name] and ${row}[author]. In the last cell a +submitButton of label “Edit” and of name “edit[$row_cont[$id]]” +
+
+
The class of the header row is “nmh” and the class of the +content row is “nmr”. eTemplate will automatically vary the +colors of the “nmr” class to provide a nice visual effect.
+Here is a view of the et_media.show template once the two +templates have been created:
+
+
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 - - -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:
+ $this->tmpl->exec('et_media.ui_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)); - } - } -+
We build an array with all the
+ matches, the index in that array is the row-number starting with 1
+ (!) ($entry = array('empty') + $found; would do the same).
The
+ names in the data-row (last row) of 'et_media.show.rows' are like
+ '${row}[name]'. Variable expansion is performed on each name and
+ expands that for the first row to '1[name]' which addresses the name
+ in the first match.
+
$content contains again 'msg' + which we set to the number of entris found and the above array with + the data of all rows under the key 'entry', as we put that in + Options for the field loading the sub-template 'et_media.show.rows'. + It not necessary to put something in Options-field / use a sub-array + for a sub-template, but it can be very helpful to organize a complex + content-array. (As an exercice you can remove 'entry' from the + Options-field and change the function arrcordingly). +
+we now explizitly read the + template 'et_media.show' (the constructor reed 'et_media.edit') and + execute it again with the edit function as callback (because of + that, show does NOT need to be listed in public_functions) +
+as 'et_media.show.rows' contains only one data-row, but + fieldnames with variables to expand, that row is autorepeated for as + many data we put into the content array (or the sub-array if we used + the Options-field). +
+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) + { + $content = $this->bo->so->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(); - } +
the first part should be + self-explaining, we call show with $found if it contain more than + one entry. +
+The show function uses edit as callback, the [Edit] buttons + in each row has 'edit[$row_cont[id]]' as name. If an [Edit] button + is pressed $content['entry']['edit'] is set to the id of the entry + of that row. We use that id to read the whole entry. +
+This is what the new “show” template looks like:
+
+
While makeing this changes we can add a [Cancel] and [Delete] +button too:
+ elseif (isset($content['cancel']))
+ {
+ $content = array(); // clear the contents
+ }
+ elseif (isset($content['delete']))
+ {
+ $this->bo->so->delete($r_id);
+ $content = array(); // clear the content
+ }
- $no_button = array( // no delete button if id == 0 --> entry not saved
- 'delete' => !$this->data[$this->db_key_cols[$this->autoinc_id]]
- );
-
-
+ $no_button = array( // no delete button if id == 0 --> entry not saved
+ 'delete' => !$this->content['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 ;-).
- +on cancel we just clear the + internal data-array with so_sql's init function. +
+on delete we have to call so_sql's + delete before (it deletes the db-row coresponding with our internal + data-array) +
+the last block checks if the id field is set (it can only be + set by a read or save) and disables the [Delete] button if not + ($this->db_key_cols[$this->autoinc_id] == '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:
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.
- +Use the [Write Langfile] button in
+ the eTemplate editor (put the app-name 'et_media' in the name-field
+ first)
That will omitt our own messages in the class!!!
+
We use a function in our class to call
+ etemplate::writeLangFile('et_media','en',$extra) and can so supply
+ some extra strings.
If we add this function to the
+ public_functions-array in our class, we can just call this function
+ via the
+ browser:
http://ourDomain/eGroupWare/index.php?menuaction=et_media.et_media.writeLangFile
+ (the errormsg can be savely ignored)
This is the function (don't
+ forget to add it like the edit-function to public_functions):
+
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.
the reference-documentation + of the eTemplates +
+for all functions and parameters + of the etemplate-class look in the comments (yes there are + comments) of the files: +
+class.uietemplate.inc.php for the + exec function +
+class.boetemplate.inc.php for the + variable replacement in names and about the autorepeat rows and + columns +
+class.soetemplate.inc.php for + writeLangFile and all functions to read, store and dump an + eTemplate +
+for all functions and parameters + of the so_sql-class look in the comments of the file + class.so_sql.inc.php +
+for setup, the necessary files of an app or the format of + tables_current.inc.php look at the exelent docu + of setup3 in the doc-dir of the setup app. +
+