This documentation page describes advanced functions of the framework, that are designed for special application cases of more complex software designs.
The iterator tag was introduced in version 1.6 (final) to simplify the display mechanism of objects or associative arrays. For this reason an iterator tag defined within a template file must be filled by the document controller with the desired data. The definition of the tag looks as follows:
<html:iterator name="">
...
[<iterator:addtaglib namespace="" class="" prefix="" name="" />]
[<iterator:getstring namespace="" config="" entry="" />]
[<iterator:placeholder name="" />]
...
<iterator:item [getter=""]>
<item:placeholder [name=""][getter=""] />
[<item:getstring namespace="" config="" entry="" />]
[<item:addtaglib namespace="" class="" prefix="" name="" />]
</iterator:item>
...
</html:iterator>The <html:iterator /> tag defines the iterator and the <iterator:item /> tag contains the graphical description of how a data element should be displayed. Inside the data element a various number of placeholders and HTML tags (<item:placeholder />) can be defined. The name of the placeholder is equal to the name of the class attribute or array offset at the same time. In order to change the name of the get method, the optional tag attribut getter must be added to the <iterator:item /> tag definition. Please note, that the tag implementation uses the get() function as the default getter.
Description of the attributes:[A-Za-z0-9])
[A-Za-z0-9_])
[A-Za-z0-9])
<html:iterator name="...">
<iterator:item getter="getProperty">
<item:placeholder name="DisplayName" />
</iterator:item>
</html:iterator>public function getProperty($name)<html:iterator name="...">
<iterator:item>
<item:placeholder getter="getDisplayName" />
</iterator:item>
</html:iterator>public function getDisplayName()To use the tag it must be announced using the
<core:addtaglib
namespace="tools::html::taglib"
class="HtmlIteratorTag"
prefix="html"
name="iterator"
/>directive.
The following code fragment shows, how to use the iterator tag:
class list_controller extends BaseDocumentController {
public function transformContent(){
...
// Get a reference om the iterator tag
$Iterator = &$this->getIterator('...');
// Fill the data container with a list of objects or associative arrays
$Iterator->fillDataContainer(...);
// Display on the place of definition ...
$Iterator->transformOnPlace();
// ... or insert the content of the tag into a place holder
$this->setPlaceHolder('...',$Iterator->transformIterator());
...
}
}In case the entries of a list or table should be added ascending numbers you may add a <item:placeholder /> tag within an <iterator:item /> that takes the name IterationNumber. Sample:
<html:iterator name="">
<iterator:item [getter=""]>
<item:placeholder name="IterationNumber">
</iterator:item>
</html:iterator>In case the iterator tag is used in conjunction with the Pager the numbers on the second page should not start with 1 again. For this reason, the <html:iterator /> needs to know about the pager you are using providing the pager attribute pointing to the appropriate pager configuration.
Within the below example the iterator tag uses the values within the PagerExample section inside the /apps/config/modules/pager/{ENVIRONMENT}_pager.ini configuration file.
<html:iterator name="" pager="PagerExample">
<iterator:item [getter=""]>
<item:placeholder name="IterationNumber">
</iterator:item>
</html:iterator>The media stream tags enable the developer to store and deliver GUI ressources directly from the namespace of a specific module. For this reason, the framework contains an abstract implementation of a streaming taglib and several dedicated taglibs, that generate a media url. Further, a generic front controller action is included, that streams the media files, that are requested by the tags.
In order to use the tags you must be sure, that the front controller action, that is intended to deliver the desired files, has a valid configuration for the current context. The action config is expected to be contained in the
/config/tools/media/actions/{CONTEXT}/{ENVIRONMENT}_actionconfig.inifile. The content of the file can be taken from the following code box:
[streamMedia]
FC.ActionNamespace = "tools::media::actions"
FC.ActionClass = "StreamMediaAction"
FC.InputClass = "StreamMediaInput"
FC.InputParams = ""A example configuration file is also included in the apf-configpack-* release file under tools/media/actions/.
In order to generate dynamic media urls, the following taglibs are included in the framework:
To be able to use one of the taglibs, the tag must be introduced to the desired scope using the <*:importdesign /> tags. The following code box shows an real life application example:
<core:addtaglib
namespace="tools::form::taglib"
class="HtmlFormTag"
prefix="html"
name="form"
/>
<html:form name="TestFormular">
<form:addtaglib
namespace="tools::media::taglib"
class="FormMediaInclusionTag"
prefix="form"
name="mediastream"
/>
<img src="<form:mediastream namespace="modules::mymodule::pres::images" filename="phone_icon.png" />" alt="" />
<form:text name="phonenumber" />
<br />
<form:button name="send" value="Absenden" />
</html:form>As you can take from the example above, the <*:mediastream /> tags expect the following attributes to be filled:
[A-Za-z0-9:])
[A-Za-z0-9_.-])
<core:addtaglib
namespace="tools::media::taglib"
class="MediaInclusionTag"
prefix="html"
name="mediastream"
/>
<img src="<html:mediastream
namespace="config::modules::mymodule::pres::images"
filename="phone_icon.png"
id="PhoneIcon"
/>"
alt=""
/>class example_controller extends BaseDocumentController {
public function transformContent(){
$mediaStreamTag = &$this->getMediaStreamTagByID('PhoneIcon');
$mediaStreamTag->setAttribute($mediaStreamTag->getAttribute('namespace').'::'.$this->getContext());
}
private function &getMediaStreamTagByID($id){
$children = &$this->getDocument()->getChildren();
foreach($children as $objectId => $DUMMY){
if(get_class($children[$objectId]) == 'MediaInclusionTag'){
return $children[$objectId];
}
}
throw new InvalidArgumentException('No media stream tag contained within the current document!');
}
}class example_controller extends BaseDocumentController {
public function transformContent() {
$FileTemplate = &$this->getTemplate('file');
$mediaStreamTag = &$this->getMediaStreamTagByID('FileIconID', $FileTemplate);
$mediaStreamTag->setAttribute('extension', 'png');
$mediaStreamTag->setAttribute('filebody', 'dateinameOhneEndung');
}
private function &getMediaStreamTagByID($id, TemplateTag &$template) {
$children = &$template->getChildren();
foreach ($children as $objectId => $DUMMY) {
if (get_class($children[$objectId]) == 'MediaInclusionTag'
&& $children[$objectId]->getAttribute('id') == $id
) {
return $children[$objectId];
}
}
throw new InvalidArgumentException('No media stream tag contained within the current template "'
. $template->getAttribute('name') . '"!');
}
}Since release 1.14 the front controller action that is used to deliver the media resources (StreamMediaAction) includes the possibility to explicitly configure allowed file extensions along with their MIME types. Thus, you can add or remove extensions. Within the default setup, the following types are allowed:
In order to re-define the existing values the configuration file {ENVIRONMENT}_allowed_extensions.ini must be present under tools::media::{CONTEXT}. Within there, you can specify the allowed file extensions as follows:
[Default]
jpg = "image/jpg"
xml = "text/xml"
psd = "application/psd"<generic:importdesign
modelnamespace=""
modelfile=""
modelclass=""
modelmode="NORMAL|SINGLETON|SESSIONSINGLETON"
namespaceparam=""
templateparam=""
[getmethod=""]
[dependentactionnamespace=""
dependentactionname=""
[dependentactionparams=""]]
/>[A-Za-z0-9:])
[A-Za-z0-9_])
[A-Za-z0-9_])
NORMAL|SINGLETON|SESSIONSINGLETON)
[A-Za-z0-9_.-])
[A-Za-z0-9_.-])
[A-Za-z0-9_])
<core:addtaglib
namespace="tools::html::taglib"
class="GenericImportTemplateTag"
prefix="generic"
name="importdesign"
/>Within a discussion about reusable template fragments (e.g. forms), the idea occurred to design a taglib, that can import various content to the scope of the current document. Thanks to the generic DOM structure of the GUI elements of the framework, this task is quite easy.
In order to provide a generic and reusable function, the 1.8 branch now features the <core:appendnode /> tag, that can import any content from a defined template. To use the tag, you must provide two attributes similar to the importdesign tag: namespace and template.
To include reusable fragments, the following code must be placed within the desired template:
<core:appendnode namespace="..." template="..." [includestatic="true" ]/>If you want to reuse a special template, that is ised to display a domain object of your application, it is suitable to define this tag within a seperate template file (namespace: sites::testsite::pres::templates::generic; template: generic_templates). The tag definition my look like this:
<html:template name="ReusableTemplate">
...
<template:placeholder name="DisplayName">
...
</html:template>In order to use the html template within another template file, the fragment can be included using the following tag definitions:
<core:appendnode namespace="sites::testsite::pres::templates::generic" template="generic_templates" />The usage of the elements imported by the <core:appendnode /> tag is identical to the previous approach. This is because the elements are directly appended to the current children list within the DOM tree. Especially, the document controller's methods (e.g. getTemplate()) can be used as well.
To address the template printed in chapter 4.1, the following code snippet can be used:
$tmpl = &$this->getTemplate('ReusableTemplate');Due to the fact, that template parsing is done identically to the importdesign tag, the developer must care of the tags included in the special template. If necessary, tags have to be announced using the adequate core:addtaglib statements.
Further, the tag creates transformation marker tags within the origin template, to enable the transformOnPlace() feature of the included tags supporting this. Please be aware, that the sequence of definition is equal to the marker tag order!
In case you want to include static content of the included template such as
<div class="formattingContainer">
<html:template name="ReusableTemplate">
...
</html:template>
</div>includestatic must be set to true.
JetBRAINS supports the development of the APF with PHPStorm licenses and we feel confidential that PHPStorm strongly influences the APF's quality. Use PHPStorm!
Proud to useIntelligent PHP IDE for coding, testing and debugging with pleasure