Parser secrets

1. Introduction

This page contains tips and tricks regarding the APF parser and the extension of functionality of the APF for special project solutions.

In case you have and further or special questions please consider posting to our Forum or create a feature request within our Issue Management Tool.

2. Addressing DOM elements

As mentioned in chapter Page controller the APF creates a DOM tree from template files and their content at runtime that is similar to browsers parsing HTML. For this reason, you can access each and every DOM node within the tree from within tags (see Implementation of tags) or controllers (see (Document-)Controller).

To achieve this you are provided a variety of methods that are tailored to specific use cases. The following chapters describe each of them in detail.

2.1. Access using convenience methods

Class BaseDocumentController provides a large number of methods that help accessing template elements. getTemplate() for instance returns the desired instance of a <html:template /> tags within the current document whereas setPlaceHolder() allows you to fill the value of a place holder.

Please find an overview of existing methods in chapter (Document-)Controller or within the API documentation.

2.2. Access using getChildNode()

Both Document::getChildNode() and Document::getChildNodes() allow requesting any kind of DOM node within the current document instance based on the desired type and a tag attribute.

In case you want to obtain the instance of a custom tag identified by the ident attribute within a document controller you may want to use the following code:

PHP code
use APF\core\pagecontroller\BaseDocumentController; class NewsController extends BaseDocumentController { public function transformContent() { try { $newsItem = &$this->getDocument()->getChildNode('ident', 'foo', 'VENDOR\..\tags\NewsTag'); ... } catch (InvalidArgumentException $e) { ... } } }

To retrieve a list of tag instaces - i.e. all radio buttons with the same name within a form - you can use the Document::getChildNodes() method:

PHP code
use APF\core\pagecontroller\BaseDocumentController; class FormController extends BaseDocumentController { public function transformContent() { try { $radioButtons = &$this->getForm('...')->getChildNodes('name', 'foo', 'APF\tools\form\taglib\RadioButtonTag'); ... } catch (InvalidArgumentException $e) { ... } } }

2.3. Access using getNodeById()

Both approach described in chapter 2.1 and chapter 2.2 are limited to instances within a certain DOM node. In case of chapter 2.1 this is the current document the controller is responsible for it's transformation and in Chapter 2.2 the radio buttons have been selected from a form.

In case you want to access DOM elements from an arbitrary place - i.e. from a document controller or a tag - that are located anywhere within the DOM tree you can either implement a recursive search or use the dom-id attribute to classify the desired DOM node(s).

Tags that have the dom-id attribute defined are automatically indexed and can be easily accessed using the Document::getNodeById() method with the appropriate ID.

To access a template (<html:template /> tag) from a document controller without knowing about the structure the tag is defined in, please add the dom-id attribute to the desired tag definition. Please make sure to define an id that is unique allover the entire project:

APF template
<html:template dom-id="gl-tmpl-foo" [name="foo"]> ... </html:template>

After that you can access it from any place within a controller via

PHP code
use APF\core\pagecontroller\BaseDocumentController; class ListController extends BaseDocumentController { public function transformContent() { $listTemplate = $this->getDocument()->getNodeById('gl-tmpl-foo'); ... } }

Please keep in mind that the index for accessing DOM nodes is created during the analysis phase. Details can be taken from the activity diagram of the page controller documentation. Using getNodeById() this means that the index is fully created not before the transformation phase starts. This is when tags are transformed (within Document::transform())) or document controllers are processed (within DocumentController::transformContent()).

Due to APF parser internals you can access the index already after execution of Document::onParseTime() within tags - means starting with Document::onAfterAppend() - for child structures. This works as the index is already created at this stage. Please note that this is not true for siblings and parent structures!

3. Overriding standard tags

In case APF standard tags are not sufficient for your project you can override them with your project specific solution without loosing support of several convenience methods.

To be abe to use all methods described in chapter (Document-)Controller with your custom tags, please ensure to implement the appropriate interface. The following table summarizes the necessary details:

Method(s) Description
BaseDocumentController::setPlaceHolder() and BaseDocumentController::setPlaceHolders() To use a custom implementation of the place holder tag please ensure to implement the APF\core\pagecontroller\PlaceHolder interface and override the shipped APF tag with your project solution.
BaseDocumentController::getTemplate() For project specific solutions of the template tag please implement the APF\core\pagecontroller\Template interface and override the standard APF tag.
BaseDocumentController::getForm() In case you intend to create a custom form implementation within your project please use interface APF\tools\form\HtmlForm. Overriding the APF implementation you can still use getForm().
BaseDocumentController::getLabel() To create an alternative implementation for the LanguageLabelTag tag, please implement interface APF\core\pagecontroller\LanguageLabel and override the APF tag with your project solution.

Please register your project specific tag(s) using Document::addTagLib() within your bootstrap file after including APF/core/bootstrap.php. Make sure to use the same arguments for prefix and name as the standard tag does but with a different implementation (class attribute).

4. Extended templating syntax

Within templates you can register and use different kind of expressions using the extended templating syntax. This capability can be used to keep templates clean and/or to simplify recurring tasks within templates.

Details can be read about in chapter Extended template functionality. Another interesting article on templating is available under Working with view models.

Comments

Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.
There are no comments belonging to this article.