Formidable
From TYPO3Wiki
| List Projects | The FORM cObj and RAD with TYPO3-project list pages | See Current Project Members, Wishlist |
| you can help if you like! |
|
Author: Jerome Schneider (typo3dev@ameos.com) | This document is published under The content is related to TYPO3 - a GNU/GPL CMS/Framework available from www.typo3.com |
Introduction
This document presents the API Ameos Formidable (ameos_formidable) (contact: r.geyer)
Home page of the project: http://formidable.typo3.ug
FORMidable is a development framework used to create applications where business-logic is separated from the design and from the PHP-code.
It's configured in XML. So basically, you create a plugin, create an XML configuration file, call the FORMidable in your plugin giving XML file path as parameter and the API executes what you configured. And you're done.
It heavily relies on default behaviors so the conf can be really short. But you can also customize every single feature if you need tailor made application.
Extensions using formidable: see search-results in TER
What you can do with FORMidable
Mainly automated forms for your website.
But what is an application, concretely ? Well:
- Flexible design, textfields, formfields, and much more
- Links, buttons, composite formfields, events to interact with the user
- Data management (create, update, delete ), data browsing, data searching, ...
The point is that every web application is based on this stuff.
FORMidable can (loves) handle this for you.
Screenshots
- Simple creation form
(here, fe_user account creation)
- Simple form, edition mode
- Highly customized forms and search forms
- Search + list of matching records
- Details of a record
- Anything else with links, buttons, images, textfields, ...
How does it works ?
An application is entirely described in an XML file. This conf defines a lot of subsections, to configure all the elements that make your application work.
Namely:
- renderlets: objects that will be displayed in your application ( text field, listbox, link, image, button, ... )
- validators: objects checking if the data returned by a renderlet is valid, or not ( required, email, unique in db, ... )
- renderer: one per application ; will process the HTML provided by renderlets ( dev layout, templated layout, ... )
- datahandler: one per application; will execute something with produced data ( insert in base, send mail, search in database, ... )
- actionlets: objects that will be executed when datahandler finishes it's job ( redirect to a page, send an email to someone, generate a report, ... )
As said before, FORMidable needs XML as a configuration. Let's see what's inside this XML.
Integration of FORMidable in my plugin
To use FORMidable in your code, you have to create a FORMidable object and to initialize it with some arguments:
- $this (always) : this parameter will be used to keep the reference to your plugin inside FORMidable
- path to your xml file
- uid of the record to edit, (optional, only if you want FORMidable to edit this record)
$this->oForm = t3lib_div::makeInstance("tx_ameosformidable");
$this->oForm->init(
$this,
t3lib_extmgm::extPath($this->extKey) . "xml/form1.xml",
25 // uid of the record to edit ( if edition needed ;)
);
And then you have to get the generated HTML by calling the render() method of this object. <PHP> :
$sHtml = $this->oForm->render();
And you're done !
Quick FORMidable:XML syntax
A typical XML looks like this
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<formidable version="0.8.0"
xmlns:datahandler="http://www.ameos.com/formidable/080/datahandler"
xmlns:datasource="http://www.ameos.com/formidable/080/datasource"
xmlns:renderer="http://www.ameos.com/formidable/080/renderer"
xmlns:renderlet="http://www.ameos.com/formidable/080/renderlet"
xmlns:validator="http://www.ameos.com/formidable/080/validator"
xmlns:actionlet="http://www.ameos.com/formidable/080/actionlet">
<meta>
<name>Create/edit an FE user</name>
<form formid="myuserform"/>
<debug>true</debug>
<displaylabels>true</displaylabels>
</meta>
<control>
<datahandler:DB>
<tablename>fe_users</tablename>
<keyname>uid</keyname>
</datahandler:DB>
<renderer:STANDARD/>
</control>
<elements>
<renderlet:TEXT name="username" label="User name"/>
<renderlet:PASSWORD name="password" label="Password"/>
<renderlet:SUBMIT label="Submit"/>
</elements>
</formidable>
There are always 3 main sections in the XML ( 4 with the root ) . Each one of these 3 sections is required.
1 meta: global informations about the whole applications
2 control: holds the configuration for the datahandler (required), renderer (required) and actionlets (optional)
3 elements: section containing the renderlets
Each tag defining any renderlet / validator / renderer / datahandler / actionlet has to be declared as a part of the corresponding namespace ( renderlet:LISTBOX ; datahandler:DB ; renderer:TEMPLATE ; ... ). The second part of those tags, after the colon, defines the type of this tag, inside the namespace.
Each tag must be defined in lowercase, except for types of objects inside namespaces ( renderlet:LISTBOX, datahandler:RAW, ... ). What is called a boolean in the following XML REF is a string “true” or “false”, lowercased. What is called userobj is a tag that defines either:
- a callback to a PHP function inside an object
- a section on PHP code to execute inside a CDATA tag, returning something or not
- a section of TypoScript inside a CDATA tag.
Userobj are optional in most of the cases ; they give the ability to the developper to feed it's application with dynamically generated values rather than static XML ones.
XML REF
Renderlets
TODO
* added overrideSql method
* added _translatable() and i18n_shouldNotTranslate()
* added (experimental) support for custom and labelcustom on /data/items/item
* added support for programmaticaly defined events with initProgEvents()
* added support fo programatically defined server event in _hasThrown()
* added mode "orlike" in overrideSql() for searching with OR comparisons between words in a field
* /search/onfields is now userobjable in overrideSql(), thanx to Manuel Rego Casasnovas ; see lists.netfielders.de/pipermail/typo3-project-formidable/2007-June/000502.html
* childs initialization has been moved to method initChilds(), for childs re-init after renderlet init() if needed
* added mecanism for re-initalization of childs before rendering, for fresh display when displaying modalbox
* _getAjaxEvent(): added support for new namespace of event parameters rowInput::
* _getElementHtmlId(): adds a suffix to html id for repeated inputs (usefull for new params rowInput::)
* renderChildsBag() is now able to render templates on childs with /childs/template
* added /childs/autowrap=boolean ; allows to wrap child elements in default tag structure if no template for childs is provided
* _parseTemplateCode() is now able to substitute subparts like <!-- ###myrenderlet### begin--> ... <!-- ###myrenderlet### end--> instead of {myrenderlet} to allow templating childs in main template using subparts
* childs are now wrapped in <div class="formidable-rdrstd-rdtwrap">|</div> in default rendering (without template on childs)
* added the new concept of checkpoints
* added .label.tag to all renderlets, containing <label for="...">mylabel</label>
NEW rdt_i18n
* automatically handles translated records factorisation in lists with typoscript processed country flags
* can be fully customized with recombine
* added config to be able to change default flag icons / labels
* now automaticaly forced to renderOnly to avoid bugs in lister when working on a compiled table
* completely changed the internal way of handling automated events generation on rdt_i18n language flags, by using the new notion of programmaticaly defined events
* now values that don't correspond to a renderlet also are updated into sys_language childs when replicating changes on childs for non-translatable records of default-language
NEW rdt_modalbox
* Removed param $sHtml in function majixShowBox
* added mecanism for re-initalization of childs before rendering, for fresh display when displaying modalbox
* added a call to oDataHandler->refreshAllData() in majixShowBox(), for fresh data before rendering
NEW rdt_tinymce
* added support for EXT:my_ext_key like path in contentCss property
* can now give additional external config with /addconfig
NEW rdt_upload
* added complete rewrite of file upload
* takes as arguments
<data
targetdir="C:/Program Files/TYPO3_4.1.1/htdocs/Quickstart/uploads/"
overwrite="true/false"
cleanfilename="true/false"
multiple="true/false"
/>
* added {myrdt.filelist.ul} template channel
* getServerPath() now allows to pass a filename as parameter
NEW rdt_box
* added rdt_box
* rdt_box is now default true on activelistable
* {LLL:EXT:...} tags are now substituted in html property of the box
* renderChildsBag() is now able to render templates on childs with /childs/template
* _parseTemplateCode() is now able to substitute subparts like <!-- ###myrenderlet### begin--> ... <!-- ###myrenderlet### end--> instead of {myrenderlet} to allow templating childs in main template using subparts
* added /childs/autowrap=boolean ; allows to wrap child elements in default tag structure if no template for childs is provided
NEW rdt_lister
* creation of the brand new concept of renderlet-based list
* lot easier to set-up
* several listers can be used in the same xml file
* completely useable without javascript
* lot of work on accessibility, uses GET urls to trigger sorts and page navigation
* can be cached by typo3, if used in a USER ( not USER_INT ) plugin, and property /cachehash="true"
* can be interfaced with a renderlet:SEARCHFORM or directly to a datasource ( typically datasource:DB )
* some behaviors known in datahandler:LISTER have been ported, some will be, some have been modified
* great care has been accorded to improve performance thru usage of references in internal jobs, and by complete rewrite of the DATA engine
* added french translation for list actions on sort/browse
* list recursivity possible
* activelistable is now default TRUE, to allow lister recursivity
* now supports /process on columns, to allow disabling a column on some condition
* renderonly is now always TRUE
NEW rdt_searchform
* creation of the brand new concept of renderlet-based searchform
* multiple searchforms can now be used simultaneously in the same xml file
* acts as a filter between renderlet:LISTER and datasource:DB
renderlet:*
This conf applies to all renderlets. Some renderlets might redefine default values for these properties, though.
| Property | Data type | Description | Default | Advice |
| /name | string [a-zA-Z0-9_-] |
Name and id of the field in the form. Name of the corresponding column in the database, also. If none given, an anonymous name will be automatically generated. You have to give a name if you want to be able to place the HTML produced by this renderlet into an HTML template ( if you don't know the name, you can't use its tag in the template ) |
random anonymous | Always give a name unless YNWYD. |
|
/label |
string, <userobj> |
Label of the field which will be displayed in your application
|
empty string |
Always try to use LLL:EXT localized strings |
|
/readonly |
boolean, <userobj> |
Whether or not to allow modifications on this field.
|
false |
|
|
/renderonly |
boolean, <userobj> |
Whether or not to consider data produced by this formfield in the datahandler.
|
false |
Useful when the renderlet value is not meant to be inserted in the database, for instance a formfield used only to build the interface. |
|
/type |
string |
This property is a system property. It's automatically set to the type of the renderlet declared in the <renderlet:XYZ> tag, where here type would be set to XYZ.
|
renderlet type inside the namespace, lowercased |
|
|
/custom |
string, <userobj> |
This property is a placeholder where you can place anything you want to be inserted in the HTML of the renderlet.
<custom>class=”red”</custom>
|
empty string |
|
|
/wrap |
string, <userobj> |
Works like the typoscript .wrap property.
|
| |
If used with renderer:TEMPLATE, you can use template tags inside the wrap if needed :) |
|
/process |
boolean, <userobj> |
This boolean will give you the possibility to tell FORMidable not to evaluate this renderlet at runtime, meaning that you will be able to use complex tests to determine if the application should or not consider this field. |
true |
Useful when you can't use modifiers because needed informations about whether or not to use this renderlet are not available at pre-compilation time |
|
/recombine |
<userobj> TS |
This tag allows user to give a TS template that will be used to generate the graphical layout of this renderlet.
<recombine> <userobj> <ts><![CDATA[ 10 = COA 10 { 5 = TEXT 5.value < params.label 5.wrap = <div>|</div> 10 = TEXT 10.value < params.input 10.wrap = <div class='myclass'>|</div> } ]]> </userobj> </recombine> </TS>
|
empty |
REALLY powerful if you need tailor-made graph layout for your application. |
|
/activelistable |
boolean, <userobj> |
If true and if used with datahandler:LISTER, the renderlet will be displayed as a fully functional form field in the list.
|
false |
Set to true on renderlet LINK, BUTTON, ... if you want them to be displayed as active links or button in your list ; |
|
/data |
XML subconf |
This tag is the placeholder of all configuration that deals with available data, defaultvalue of the renderlet, available items for listboxes, checkboxes groups, ... |
empty |
|
|
/data/defaultvalue |
string, <userobj> |
Defines the default value for this renderlet.
|
empty |
|
|
/data/value |
string, <userobj> |
Defines the value for this renderlet.
|
empty |
|
|
/data/items |
XML subconf |
Placeholder for the collection of items that will be used by the renderlet.
Array( Array("caption" => "Item 1", "value" => "1"), Array("caption" => "Item 2", "value" => "2"), Array("caption" => "Item 3", "value" => "3"), ) See /data/items/item |
empty |
Makes sense only when the renderlet has to deal with a collection of items |
|
/data/items/item |
XML subconf |
Placeholder for an item in the collection
|
|
|
|
/data/items/item/caption |
string, <userobj> |
Defines the caption of this item. Can be a LLL:EXT locallang string. |
empty string |
|
|
/data/items/item/value |
string, <userobj> |
Defines the value of this item. |
empty string |
|
|
/search |
XML subconf |
Useful only when used with datahandler:LISTER
|
empty |
|
|
/search/overridesql |
string, <userobj> |
Redefines the portion of SQL given by this renderlet to the datahandler:LISTER to override the default LIKE search
<renderlet:CHECKSINGLE
name="xmasspecific"
label="Display only Xmas specific items">
<onclick submit="true"/>
<search>
<overridesql>
<userobj>
<php><![CDATA[
return "(xmasflag=1 OR (santaflag=1 AND eventdate='" . strftime("%Y") . "-12-25'))";
]]></php>
</userobj>
</overridesql>
</search>
</renderlet:CHECKSINGLE>
|
||
|
/search/mode |
string |
One of startswith, googlelike
|
empty |
Use the renderlet:CHOOSER with this to have a nice alphabetical-hash selector |
|
/search/onfields |
string |
Comma-separated list of columns to search on in the database |
empty |
|
|
/onclick, /onmouseover, /on... |
string, <userobj> |
Client & Server Events handling.
|
empty |
|
|
/validators |
XML subconf |
Placeholder for the collection of validators for this renderlet. See the section Validators for more informations |
|
|
|
/confirm |
string |
Enter the name of an other renderlet if you want a field to confirm the value of another field. Typically used for password validation. |
|
|
Examples
Note: screenshots of these examples are made using renderer:STANDARD
Plain renderlet:
<renderlet:TEXT>
<name>favcolor</name>
<label>Favourite color</label>
</renderlet:TEXT>
Which is equivalent to (always prefer this one ;) :
<renderlet:TEXT name="favcolor" label="Favourite color"/>
This renders as:
Renderlet with defaultvalue, custom & wrap
<renderlet:TEXT name="favcolor" label="Favourite color"> <custom>style="background-color: yellow; border: 4px orange dashed;"</custom> <data defaultvalue="red"/> <wrap><![CDATA[ <div style="background-color: pink;">This will be place before my textbox</div> <div style="margin: 10px; background-color: cornflowerblue">|</div> <div style="background-color: tomato;">And this, after. Thank you Mr. Wrap !</div> ]]></wrap> </renderlet:TEXT>
Renders as:
Using userobj for defaultvalue and label
<renderlet:TEXT name="favcolor">
<label>
<userobj>
<php><![CDATA[
$sTime = strftime("%H:%M:%S");
return "It's " . $sTime . " already ! Time to tell us your favorite color!";
]]></php>
</userobj>
</label>
<custom>style="background-color: yellow; border: 4px orange dashed"</custom>
<data>
<defaultvalue>
<userobj>
<php><![CDATA[
$aColors = array(
"red",
"blue",
"green",
"purple",
);
return $aColors[rand(0, (sizeOf($aColors) - 1))];
]]></php>
</userobj>
</defaultvalue>
</data>
<wrap><![CDATA[
<div style="background-color: pink;">This will be place before my textbox</div>
<div style="margin: 10px; background-color: cornflowerblue">|</div>
<div style="background-color: tomato;">And this, after. Thank you Mr. Wrap !</div>
]]></wrap>
</renderlet:TEXT>
Renders as:
$this->_oParent usage in userobj (from mail-list)
The trick is that you have access to your plugin in formidable. When in a userobj, $this->_oParent refers to your plugin
So you can set, in your plugin, before calling formidable:
$this->toto = "Hello, World !";
and in formidable, in the userobj where you need it:
echo($this->_oParent->toto); // or whatever php here
Using recombine
Note: Recombine unactivates the wrap ; so we dont use wrap here, only TS template
We give here only the <recombine> tag for this example. To get the full example XML for this renderlet, replace the <wrap> tag in the previous example with this <recombine> tag. <TS> :<recombine> <userobj> <ts><![CDATA[ 10 = COA 10 { 10 = TEXT 10.value < params.input 10.wrap ( This is processed by a Typoscript template :)<br /> <div style="background-color: red;">|</div> ) 20 = TEXT 20.value < params.label 20.wrap ( <div> The label of this renderlet is: <b style="background-color: black; color: white;">|</b> <br /> <div>Can you figure out the possibilities ?</div> </div> ) 30 = TEXT 30.value < params.help 30.wrap ( <div style="background-color: silver;"> This is an array of the available HTML-channels properties for a TEXT renderlet.<br /> | <i>See Documentation at <b>Multichannel Templates</b> for more informations</i> </div> ) } 10.wrap ( <div style="background-color: pink; padding: 10px;"> Everything inside this pink box is the render of the renderlet:TEXT<br /> | </div> ) ]]>
</userobj> </recombine> </TS>
Renders as:
renderlet:TEXT
No special conf. See renderlet:*
renderlet:TEXTAREA
TODO render(): added template channels .value.nl2br .value.htmlspecialchars .value.htmlspecialchars.nl2br
No special conf. See renderlet:*
Renders as:
renderlet:PASSWORD
No special conf. See renderlet:*
Renders as:
renderlet:DATE
TODO * added userobj support in date format for internationalization, cf. [TYPO3-project-formidable] "Internationalize date format" message of Manuel Rego Casasnovas * /data/datetime/displaytime is now default FALSE * /allowmanualedition is now deprecated by /data/datetime/allowmanualedition * /data/datetime/allowmanualedition is now default FALSE * added the %@ date format token in js, which returns the absolute timestamp of the selected day at 00:00:00 * added it's own js class for specialization of majixReplaceData() * added /data/datetime/emptystring configuring the text to display when no date selected with allowmanualedition="false" * calendar icon displays before field * modified the way UTC timestamp at midnight is generated * corrected polish translations thanks to Pawel Bandura (http://lists.netfielders.de/pipermail/typo3-project-formidable/2007-July/000621.html)
All configuration specific to this renderlet is found in /data/datetime/
This renderlet is designed to handle timestamps. It takes timestamp as an input, and returns timestamp as a value, plus human readable date as an HTML output.
|
Property |
Data type |
Description |
Default |
Advice |
|
/data/datetime/format |
strftime() string |
Strftime like string used to customize the display of the date. See http://www.php.net/strftime |
required |
|
|
/data/datetime/locale |
LOCALE string |
Locale code string to localize the date display See http://www.php.net/setlocale |
system LOCALE |
|
|
/data/datetime/displaytime/ |
boolean |
Whether or not to display the time selector in the js-calendar. |
false |
|
Examples
Plain renderlet:DATE
<renderlet:DATE name="birthdate" label="Birth date"> <data> <datetime format="%m/%d/%Y"/> </data> </renderlet:DATE>
Renders as:
Renderlet:DATE with time selector, userobj'd defaultvalue and custom property
<renderlet:DATE name="birthdate" label="Birth date"> <custom>style='width: 200px;'</custom> <data> <datetime format="The date is %m-%d-%Y %H:%M:%S" displaytime="true"/> <defaultvalue> <userobj> <php><![CDATA[ return mktime(13, 45, 23, 1, 1, 1998); ]]></php> </userobj> </defaultvalue> </data> </renderlet:DATE>
Renders as:
renderlet:FILE
* added /linktofile=boolean, default true * /data/targetdir is now userobj'able thanks to manuel rego casasnovas ; see lists.netfielders.de/pipermail/typo3-project-formidable/2007-June/000432.html
|
Property: |
Data type: |
Description: |
Default: |
Advice |
|
/data/targetdir |
string |
path to the directory where files will be uploaded, relative to the root path of the site;
|
required |
Note: uploaded file will be stored in the /data/targetdir/ directory. If filename already exists, it will be automatically renamed, suffixed with _(number) (look at the examples)
Examples
Plain renderlet:FILE
<renderlet:FILE name="photo" label="Upload your photo"> <data targetdir="typo3temp/"/> </renderlet:FILE>
Renders as:
Here, this file has been uploaded 8 times in the same folder, so it was suffixed _7. The link points to the file.
renderlet:UPLOAD
Similar to renderlet:FILE, but offers more possibilities in file handling.
|
Property: |
Data type: |
Description: |
Default: |
Advice |
|
/data/targetdir |
string |
path to the directory where files will be uploaded, relative to the root path of the site;
|
required |
|
|
/data/overwrite |
boolean |
Overwrite if file exists or rename it |
false |
|
|
/data/cleanfilename |
boolean |
Clean file name if weird chars are found |
false |
|
|
/data/multiple |
boolean |
allow field to contain multiple files, comma-separated value |
false |
Examples
Plain renderlet:UPLOAD
<renderlet:UPLOAD name="photo" label="Upload your photo"> <data targetdir="typo3temp/" /> </renderlet:UPLOAD>
renderlet:LISTBOX, renderlet:CHECKBOX, renderlet:RADIOBUTTON
TODO renderlet:LISTBOX * added call to overrideSql in sql build * implemented multiple listbox ability with /multiple=true/false thanks to Manuel Rego Casanovas (lists.netfielders.de/pipermail/typo3-project-formidable/2007-May/000308.html) * modified majixReplaceData() to be able to use either caption/value item arrays or more concise key=>value item arrays * majixSetAllSelected() for listbox multiple="true" * render(): added .value and .caption template channels
These renderlets use a collection of items to do their job.
|
Property |
Data type |
Description |
Default |
Advice |
|
/data/items |
XML subconf |
See renderlet:*/data/items |
required |
See renderlet:*/data/items |
renderlet:CHECKBOX returns a list of selected items values comma-separated as data.
Examples
Plain renderlet:LISTBOX
<renderlet:LISTBOX name="myexgirlfriends" label="My ex girlfriends"> <data> <items> <item caption="" value=""/> <item caption="Laetitia" value="laetitia"/> <item caption="Pamela" value="pamela"/> <item caption="Juddy" value="juddy"/> </items> </data> </renderlet:LISTBOX>
Renders as:
renderlet:LISTBOX using defaultvalue and userobj'd list of items
<renderlet:LISTBOX name="myexgirlfriends" label="My ex girlfriends">
<data defaultvalue="juddy">
<items>
<item caption="" value=""/>
<item caption="Laetitia" value="laetitia"/>
<item caption="Pamela" value="pamela"/>
<item caption="Juddy" value="juddy"/>
</items>
<userobj>
<php><![CDATA[
$aPre = array("Ash", "Ma", "Mela", "So", "Mama", "Juli");
$aPost = array("ley", "donna", "nie", "fia", "mia", "anna");
$aItems = array();
for($k = 0; $k < 5; $k++) {
$sPre = $aPre[rand(0, sizeOf($aPre) - 1)];
$sPost = $aPost[rand(0, sizeOf($aPost) - 1)];
$aItems[] = array(
"caption" => $sPre . $sPost,
"value" => strtolower($sPre . $sPost),
);
}
return $aItems;
]]></php>
</userobj>
</data>
</renderlet:LISTBOX>
Renders as:
renderlet:CHECKBOX, multiple defaultvalues
<renderlet:CHECKBOX name="myexgirlfriends" label="My ex girlfriends">
<data defaultvalue="juddy,pamela">
<items>
<item caption="Laetitia" value="laetitia"/>
<item caption="Pamela" value="pamela"/>
<item caption="Juddy" value="juddy"/>
</items>
<userobj>
<php><![CDATA[
$aPre = array("Ash", "Ma", "Mela", "So", "Mama", "Juli");
$aPost = array("ley", "donna", "nie", "fia", "mia", "anna");
$aItems = array();
for($k = 0; $k < 5; $k++) {
$sPre = $aPre[rand(0, sizeOf($aPre) - 1)];
$sPost = $aPost[rand(0, sizeOf($aPost) - 1)];
$aItems[] = array(
"caption" => $sPre . $sPost,
"value" => strtolower($sPre . $sPost),
);
}
return $aItems;
]]></php>
</userobj>
</data>
</renderlet:CHECKBOX>
Renders as:
renderlet:CHECKSINGLE
TODO * now uses only 0 or 1 as a value ; see lists.netfielders.de/pipermail/typo3-project-formidable/2007-June/000440.html * added support for custom labels in renderonly of single checkbox, thanks to Manuel Rego Casanovas (additional infos: lists.netfielders.de/pipermail/typo3-project-formidable/2007-May/000343.html) used like this: <renderlet:CHECKSINGLE name="test" label="LLL:EXT:my_extlocallang.xml:test" renderonly="true"> <labels> <checked>LLL:EXT:my_extlocallang.xml:test.checked</checked> <nonchecked>LLL:EXT:my_extlocallang.xml:test.nonchecked</nonchecked> </labels> </renderlet:CHECKSINGLE>
No special conf. See renderlet:*
renderlet:CHECKSINGLE automatically returns 1 if the checkbox is checked, 0 if not.
renderlet:CHOOSER
Renders as a list of push-button links. Selected value is returned by the renderlet. Submits automatically on change event.
|
Property |
Data type |
Description |
Default |
Advice |
|
/wrapitem |
wrap string |
Wrap property for items ( except selected item when /wrapselected given ) |
| |
|
|
/wrapselected |
wrao string |
Wrap property for selected item |
/wrapitem |
|
|
/separator |
string |
String used for separating each items of the list |
| ( equals to pipe ) |
|
Examples
Plain renderlet:chooser
<renderlet:CHOOSER name="nbres"> <data defaultvalue="50"> <items> <item caption="15" value="15"/> <item caption="50" value="50"/> <item caption="100" value="100"/> </items> </data> <wrap><![CDATA[display: | per page]]></wrap> <wrapselected><![CDATA[<span style='font-size: 20px;'>|</span>]]></wrapselected> <wrapitem><![CDATA[<span>|</span>]]></wrapitem> <separator><![CDATA[ - ]]></separator> </renderlet:CHOOSER>
Renders as:
renderlet:LINK
TODO * searchable="false" by default now
Displays as a link. Can also return URL only.
Useful for creating links with events handling. ( See events section ).
NOTE: for being displayed in a list managed by datahandler:LISTER, has to be set as /activelistable (= true).
See renderlet:*/activelistable for more informations.
|
Property: |
Data type: |
Description: |
Default: |
Advice |
|
/url |
string, <userobj> |
Url to be used in the link.
|
javascript:void(0); |
|
|
/urlonly |
boolean, <userobj> |
Whether or not to return only the URL |
false |
|
|
/label |
string, <userobj> |
If given, will be used as the caption of the link. If not, value will be used.
|
empty |
|
|
/custom |
string, <userobj> |
Use /custom to insert target if you need to |
empty |
|
|
/readonly |
boolean |
A renderlet:LINK is always readonly |
true (cannot be changed) |
|
|
/renderonly |
boolean |
As its value can't change, a renderlet:LINK cannot be saved in database. It can hold a value but only for programming commodities. |
true (cannot be changed) |
|
Examples
Plain renderlet:LINK
<renderlet:LINK name="mylink" label="Go to my website" url="http://www.ameos.com/"/>
Renders as:
Renderlet link with userobj and no label
<renderlet:LINK name="mylink"> <url> <userobj> <php><![CDATA[ return t3lib_div::locationHeaderUrl( $this->_oParent->pi_getPageLink( $GLOBALS["TSFE"]->id, "", array( "someparameter" => 1 ) ) ); ]]></php> </userobj> </url> </renderlet:LINK>
Notes: in a PHP userobj, $this always points to the FORMidable object, and $this->_oParent always points to the plugin calling FORMidable. See FORMidable CORE programming for more informations.
Renders as:
renderlet:BUTTON
A button useful for handling events. See events section for more information.
|
Property |
Data type |
Description |
Default |
Advice |
|
/renderonly |
boolean |
Always true |
true |
|
|
/readonly |
boolean |
Always true |
true |
|
|
/activelistable |
boolean, <userobj> |
Redefines default value as true ( different of renderlet:* ) |
true |
We want a button to be listable by default |
renderlet:IMAGE
TODO * can now handle default image thru /defaultpath * rewrite of path management system ; can now handle pathes like: /absolute/path/to/image.png http://localdomain/image.png http://foreigndomain/image.png EXT:ameos_formidable/res/images/too_cool.png typo3conf/ext/ameos_formidable/res/images/too_cool.png /typo3conf/ext/ameos_formidable/res/images/too_cool.png
Used for displaying image in your application. What else ? ;)
|
Property |
Data type |
Description |
Default |
Advice |
|
/path |
string, <userobj> |
Path to the image; relative to path site; without starting slash
|
required |
|
|
/imageconf |
TS <userobj> |
Typoscript used to reprocess image before displaying. See examples.
|
empty |
|
Examples
Plain renderlet:IMAGE
<renderlet:IMAGE>
<path>EXT:ameos_testform/res/atari.jpg</path>
</renderlet:IMAGE>
Renders as:
renderlet:IMAGE with imageconf (basepack's shaded effect) and width 100px max
<renderlet:IMAGE> <path>EXT:ameos_testform/res/atari.jpg</path> <imageconf> <userobj> <ts><![CDATA[ 10 < config.tx_ameosformidable.res.shared.xml.imageprocess.shaded 10.file.50.file < params.relwebpath 10.file.50.file.width = 100m ]]></ts> </userobj> </imageconf> </renderlet:IMAGE>
Renders as:
renderlet:IMAGE with imageconf (basepack's rounded effect) and width 100px max
<renderlet:IMAGE> <path>EXT:ameos_testform/res/atari.jpg</path> <imageconf> <userobj> <ts><![CDATA[ 10 < config.tx_ameosformidable.res.shared.xml.imageprocess.rounded 10.file.10.file < params.relwebpath 10.file.10.file.width = 100m ]]></ts> </userobj> </imageconf> </renderlet:IMAGE>
Renders as:
renderlet:SUBMIT
Renders as a submit button
|
Property |
Data type |
Description |
Default |
Advice |
|
/mode |
string, one of submit, refresh, draft, test |
See events section for more informations |
submit |
Validators
A validator is an object that will check the validity of a data produced by a renderlet against specified criteria.
They are declared inside a renderlet configuration, in an xml tag named <validators>, which is a placeholder for one or several <validator>.
Each validator has a type declared inside the validator namespace.
Ex: validator:DB, a validator of type DB that checks conditions inside database ; validator:NUM, checking numerical constraints on data; ...
A validator returns TRUE if data is OK, FALSE in the other case.
NOTE: Each validator returns TRUE if the data is empty, except the validator:STANDARD/required, returning FALSE if the data is empty. This allows to reject data only if given.
If validator returns FALSE, it also produce an error message corresponding to what's given in subsection <message> of the validator. You can use plain messages or localized LLL:EXT: ... locallang strings if needed.
Example
Note: screenshots of these examples are made using renderer:STANDARD
<renderlet:TEXT name="email" label="Your email address"> <validators> <validator:STANDARD> <required message="Email address is required"/> <email message="Email address not valid"/> </validator:STANDARD> <validator:DB> <unique message="This email is already used in database"/> </validator:DB> </validators> </renderlet:TEXT>
In this example, user has to enter it's email address; FORMidable will check if email is given, then if valid, then if not already in database for unicity.
Renders:
After submitting:
Let's give some weird data:
The datahandler will not process data until everything is valid in the form.
Displaying errors like this is the way renderer:STANDARD does by default. To have nicer, customized error messages, use renderer:TEMPLATE
validator:STANDARD
TODO * added minsize validator
This validator does the usual data-checks.
|
Property |
Data type |
Description |
Default |
Advice |
|
/required |
|
Checks that data is not empty |
empty |
|
|
/authentified |
|
Checks that fe-user is authentified |
empty |
|
|
/maxsize/value |
integer |
Checks that data length is < to value
|
empty |
|
|
/sameas/value |
string |
Value has to be the name of an other renderlet. Checks that the value for this renderlet is the same that the value for the given renderlet. |
empty |
Useful when checking password confirmation |
|
|
|
Checks that data is a valid email address |
|
|
|
/userobj |
<userobj> |
Executes the userobj for checking data. If you can't do it using hardcoded valitadors, use this validator.
|
|
|
Examples
validator:STANDARD/userobj
This example demonstrates how to perform custom validation on data:
<renderlet:TEXT name="email" label="Your email adress">
<validators>
<validator:STANDARD>
<userobj message="Sorry, we don't want hotmailers here">
<php><![CDATA[
$sValue = array_pop(func_get_args());
if(!empty($sValue)) {
if(strstr(strtolower($sValue), "@hotmail.com")) {
return FALSE;
}
}
return TRUE;
]]></php>
</userobj>
</validator:STANDARD>
</validators>
</renderlet:TEXT>
Renders as:
validator:DB
TODO * unique can now be used without defining value=true
Checks DB related conditions.
To be used only with datahandler:DB
|
Property |
Data type |
Description |
Default |
Advice |
|
/unique |
|
Checks that data is unique inside the table for this column. |
empty |
|
validator:FILE
TODO * now compatible with rdt_file and rdt_upload (single and multiple modes)
Checks FILE related conditions.
Useful for checking file after upload.
NOTE: WARNING: if file is rejected by any of validator:FILE, it will be deleted by FORMidable.
USE only for user-uploaded files. Not meant to test files existing on the server. They would be deleted.
|
Property: |
Data type: |
Description: |
Default: |
Advice |
|
/extension/value |
string csv |
Checks that file extension matches one of the list. Takes comma-separated list of file extensions to be matched. |
empty |
|
|
/filesize/value |
integer |
Checks that filesize is below or equal to given filesize. Filesize in Bytes. |
empty |
|
validator:NUM
Checks numeric related conditions.
|
Property |
Data type |
Description |
Default |
Advice |
|
/islower/value |
integer |
Checks that data is a number lower than given number. |
empty |
|
|
/ishigher/value |
integer |
Checks that data is a number higher than given number. |
empty |
|
|
/isbetween/value |
string csv |
Checks that data is a number between given lower and upper bound, comma-separated. |
|
validator:PREG
Checks validity of data against regex pattern. (See http://www.php.net/regex) Credit for this validator goes to Jérémy Lecour ( jeremy.lecour(a)nurungrandsud(dt)com )
|
Property |
Data type |
Description |
Default |
Advice |
|
/pattern/value |
string regex |
Checks data validity against regex. If pattern prefixed with !, then condition is reversed. |
empty |
Control
TODO * <datasources />
The <control> section of the XML is just a placeholder for the datahandler, the renderer and optionally actionlets. See datahandler, renderer and actionlets.
Datahandlers
TODO * created VOID datahandler for consistency with renderer:VOID ; does absolutely nothing with data * _P(): added fieldname parameter in method _P() * Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" ) * added bunch of i18n_ functions * added refreshStoredData(), refreshFormData(), refreshFormDataManaged() and refreshAllData()
Datahandler's job is to do something with the data produced by your application. Quite cool, huh ?
datahandler will be executed only when form is submitted and all validators are GO.
There are several datahandlers available.
datahandler:DB
TODO in this section * Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" ) * /i18n/update_childs_on_save="true" => manages synchronization of data with translated records for renderlets defining /i18n/translate="false" * added /process/afterinsertion
This is the most used datahandler. Designed to insert / update records into the given table. This datahandler works by default in CREATION mode. This means that it will insert form-data into the given table. To make it work in EDITION mode, when instanciating FORMidable, give the uid of the record you need to edit as a parameter.
Like this:
$this->oForm = t3lib_div::makeInstance("tx_ameosformidable");
$this->oForm->init(
$this,
t3lib_extmgm::extPath($this->extKey) . "xml/form.xml",
25 // uid of the record to edit
);
(See Integration of FORMidable in my plugin for more informations about this)
|
Property |
Data type |
Description |
Default |
Advice |
|
/tablename |
string |
Name of the DB table to work on. |
required |
|
|
/keyname |
string |
Name of the primary key in the given table. |
required |
|
|
/process/beforeinsertion |
<userobj> |
Define a userobj
here if you want to alter the data that are to be inserted /
updated into the database.
Takes an array of
values as an input, returns an array of values as an output.
See example below. |
empty |
Useful when you
want to add system fields to your table row, like pid, crdate,
...
If you want to cancel the modification of the data in DB, return an empty array() here |
Examples
Simple datahandler:DB working on fe_users table
<datahandler:DB>
<tablename>fe_users</tablename>
<keyname>uid</keyname>
</datahandler:DB>
datahandler:DB adding pid and crdate to the record using /process/beforeinsertion
<datahandler:DB>
<tablename>fe_users</tablename>
<keyname>uid</keyname>
<process>
<beforeinsertion>
<userobj>
<php><![CDATA[
$aData = func_get_arg(1);
$aData["pid"] = 343;
$aData["crdate"] = time();
return $aData;
]]></php>
</userobj>
</beforeinsertion>
</process>
</datahandler:DB>
datahandler:RAW
The job of datahandler:RAW is to give produced data to another data processor (typically a method of your plugin).
Useful if you want to use formidable as an interface manager, but still process data yourselves.
|
Property |
Data type |
Description |
Default |
Advice |
|
/callback |
<userobj> |
Userobj to be
executed to process form-data.
Reminder: you can
access to your plugin using:
$this->_oParent
in the PHP code of the userobj
|
required |
|
datahandler:LISTER
TODO * added userobj support on comparison in additional wheres * modified the way the lister generates pagination, pager has it's own template now * /ifempty is now userobj'able * Added standard internationalization (i18n) management main_datahandler, dh_db, dh_lister : i18n support ( thru /datahandler/i18n/use="true" ; /datahandler/i18n/sys_language_uid="something" ) * automatic management of filtering records on sys_language_uid if i18n activated ; filters on /datahandler/i18n/sys_language_uid if defined, or on current FE language if not * recombine now applies also to activelistable renderlets displayed in lists * additional wheres elements can now be better conditioned * added _processBeforeDisplay() ; rows can be altered before display in list
The job of datahandler:LISTER is to display a list of records selected in a table AND (optionally) to apply search filters to this selection to turn your form into a searchform.
The idea is to use the form generated by FORMidable as a searchform. Of course the searchform is to be used only when needed, because you can also just list the data of a table without search.
|
Property |
Data type |
Description |
Default |
Advice |
|
/tablename |
string |
The name of the table to work on |
required |
|
|
/keyname |
string |
Name of the primary key of this table |
required |
|
|
/template |
XML subconf |
Placeholder for the template configuration of the list |
empty |
Optional; if none given, the LISTER will try to build a default template for displaying records |
|
/template/path |
string, <userobj> |
The path to the HTML template file |
required |
EXT:my_ext/template.html |
|
/template/subpart |
string, <userobj> |
The subpart of this template to work on. |
required |
Something like ###MY_LIST### |
|
/template/customtags |
XML subconf |
Placeholder for custom tags that will be added to each row of the list. Collection of <tag> |
empty |
|
|
/template/customtags/tag |
XML subconf |
An item that will describe something to add to each row of the list |
empty |
|
|
/template/customtags/tag/name |
string |
Name of the tag that will be searched and substituted in every line of the list |
required |
|
|
/template/customtags/tag/value |
string, <userobj> |
The value that will be inserted in the template for each line. See example below |
required |
|
|
/search |
XML subconf |
Placeholder for configuring all the aspects of the search within records. |
empty |
|
|
/search/atstartup |
boolean, <userobj> |
Whether or not to display list at first display of the application. If false, list will be displayed only after first submit. |
true |
|
|
/search/keepinsession |
boolean, <userobj> |
Whether or not to keep list of uids matching search criteria (if any) in session for further usage. |
false |
See FORMidable CORE API programming |
|
/search/sql |
XML subconf |
Placeholder for modifying / overriding the SQL query executed to fetch records. |
empty |
|
|
/search/sql/query |
string, <userobj> |
SQL query that will be used to fetch records from the database |
empty |
Use it with a
<userobj> to build custom query if needed
See FORMidable CORE API programming |
|
/search/sql/wheres |
XML subconf |
Placeholder for defining SQL conditions that will be added to the one that FORMidable will automatically build for fetching records. |
empty |
|
|
/search/sql/wheres/beginbrace |
XML tag |
Adds a “(“
to the SQL query.
Define it like
this:
<beginbrace /> |
empty |
|
|
/search/sql/wheres/beginbrace |
XML tag |
|
empty |
|
|
/search/sql/wheres/endbrace |
XML tag |
Adds a “)“
to the SQL query.
Define it like
this:
<endbrace /> |
empty |
|
|
/search/sql/wheres/where |
XML subconf |
|
empty |
|
|
/search/sql/wheres/where/term |
string |
Column to apply the additional where |
required |
|
|
/search/sql/wheres/where/comparison |
string |
Type of comparison
that will be executed between this term and its value.
One of: IN, NOT IN, =, <, >, <=, >=, != Note that you'll need to place <, >, <= and >= in a CDATA tag to keep the XML parser happy |
required |
You don't need to care about quotes or braces here, FORMidable will automatically add what your conf needs to be SQL valid. |
|
/search/sql/wheres/where/value |
string, <userobj> |
The value this term will be compared to. |
required |
|
|
/search/sql/wheres/logic |
string |
One of: AND, OR |
|
|
|
/process |
XML subconf |
Placeholder for data processing directives |
empty |
|
|
/process/beforesearch |
<userobj> |
Takes an array of values to search as an input, returns the modified array of values. |
empty |
See datahandler:DB/process/beforeinsertion |
|
/process/duringlisterraw |
<userobj> |
Process raw
database values for each row that are to be displayed in the
list.
Takes an array of values to search as an input, returns the modified array of values. |
empty |
See datahandler:DB/process/beforeinsertion |
|
/process/duringlister |
<userobj> |
Process human
readable values for each row that are to be displayed in the
list.
Takes an array of values to search as an input, returns the modified array of values. |
empty |
See datahandler:DB/process/beforeinsertion |
|
/pager |
XML subconf |
Placeholder for all the configuration that deals with dispatching data across several pages. |
empty |
|
|
/pager/sort/ |
XML subconf |
Placeholder for sorting configuration |
empty |
|
|
/pager/sort/field |
string |
Default table column on which data will be sorted at first display. |
/keyname |
|
|
/pager/sort/dir |
string |
Default direction
on which data will be sorted at first display.
One of: ASC, DESC |
DESC |
|
|
/pager/rows |
XML subconf |
Placeholder for configuration |
empty |
|
|
/pager/rows/perpage |
number, <userobj> |
Number of records to display per page |
5 |
|

























