Updating from 2.1 to 3.0

1. Introduction

Version 3.0 of the Adventure PHP Framework brings a huge number of new features and changes. This article describes which new functionality affects your existing application and how to upgrade to the new version applying optimizations at the same time.

This article mainly focuses on upgrading from the 2.X line. In case you are running on an older version from the 1.X generation please migrate to 2.1 first. Hints and advices can be found under Articles.

2. The APF parser

In Version 3.0 the APF parser has been rewritten completely. The main driver for this decision were limitations of the old version complicating application development and rising the need for workarounds in some cases.

The prior implementation of the parser was not capable of resolving all tag structures - especially regarding hierarchy assignment - which led to parser issues and thus application crashed or tags not being parsed which in turn influences functionality. In addition, tag registration needed to be done on a per-instance level again and again.

Another problem was timing. Analyzing templates based on a list of known tags instead of the tag definition and order within the template certain workarounds for timing issues needed to be implemented.

All those issues are now solved with the new parser and this allows to apply various optimizations to your application. Some of them are already described in article Migration from 2.1 to 3.0.

The new parser features the following advantages over version 2.1:

  • Tags are analyzed and parsed according to their definition within the template instead of a list of known tags. This means that release 3.0 supports all tag structures and nesting patterns. Tags that are not parsed or tag structures leading to parser errors are gone.
  • Analyzing tags based on the template structure removes the direct dependency between tags and their hierarchy level. Starting with 2.0 each tag can be used in any hierarchy level or tag structure (theoretically) with the same combination of prefix and name. This eases implementation a lot and saves you from writing tag wrappers that have been necessary in the past to use tags in certain hierarchy levels.
  • With version 3.0 tags are registered globally. This means that you can use a tag that has been registered with a unique combination of prefix and name in any template and hierarchy level. This allows you to register tags within your bootstrap file centrally and just once for the entire application.
  • The extended templating syntax is available in all templates and hierarchy levels. Details can be taken from chapter Extended template functionality.
  • Many new features (see Roadmap) such as iterators in forms or within a <html:template /> tag can now be realized out-of-the-box.

The following chapters describe all optimization options in detail.

2.1. Automated migration

As a first step updating to the new version as well as optimizing your application is executing the migration scripts as described under Migration from 2.1 to 3.0. This process already optimizes your application based on the components of the APF.

2.2. Optimization of tag registration

To simplify your templates the APF team recommends the following adaptions of your application:

  • Extract all <core:addtaglib /> tags from your templates and replace them by appropriate Document::addTagLib() statements within your bootstrap file. In case your template contains tags such as
    APF template
    <template:addtaglib class="DOCS\pres\taglib\InternalLinkTag" prefix="int" name="link" /> <core:addtaglib class="DOCS\pres\taglib\InternalLinkTag" prefix="int" name="link" />
    replace it by
    PHP code
    Document::addTagLib('DOCS\pres\taglib\InternalLinkTag', 'int', 'link');
    Please be sure to register tags before the front controller is started.
  • Extract all self::addTagLib() statements from your application - e.g.
    PHP code
    class FooTag extends Document { public function __contruct() { self::addTagLib('DOCS\pres\taglib\InternalLinkTag', 'int', 'link'); } ... }
    - and add them to the bootstrap file.
  • Now, consolidate the created list to get rid of duplicate tag registrations.
In case a module consists of a central template and several sub templates you may want to do tag registration via <core:addtaglib /> tag(s) within the main template. Due to the fact that the main template is analyzed by the parser before the succeeding templates included by <core:importdesign /> all tags registered within the main template are also available within sub templates from a timing perspective.

2.3. Re-usage of registered tags

The APF parser has been optimized in version 3.0 to able to resolve tags with the same combination of prefix and name in any hierarchy. Tag structure

APF template
<core:addtaglib class="..." prefix="template" name="link"/> <int:link /> <html:template> <template:addtaglib class="..." prefix="template" name="link"/> <template:link /> </html:template>

can be simplified to

APF template
<core:addtaglib class="..." prefix="template" name="link"/> <int:link /> <html:template> <int:link /> </html:template>

<int:link /> must be registered only once within an application: either via a consolidated <core:addtaglib /> tag within a template or within the index.php.

2.4. Removing wrapper tags

In previous versions it has been necessary to define wrapper tags or re-register tag implementations under a separate prefix and name to work around some weaknesses of the APF parses. Until and including 2.1 the parser wasn't able to translate tags with the same prefix and name into the appropriate hierarchy level as the template analysis was done based on a list of registered tags.

Version 3.0 removes this weakness and you can now remove any kind of workarounds to this issue. In order to optimize you application based on release 3.0 the following examples describes the full potential of the new APF parser.

In order to realize tag structure

APF template
<html:iterator name=""> ... <iterator:fallback> ... [<fallback:placeholder name="" />] [<fallback:getstring namespace="" config="" entry="" />] [<fallback:addtaglib class="" prefix="" name="" />] ... </iterator:fallback>] ... </html:iterator>

in prior releases (details of the tag signature see Special-tags) a wrapper tag was necessary to allow declaration of the child tags such as they are assigned to the correct instance and not to <html:iterator /> directly by accident.

The respective source code is as follows:

PHP code
class HtmlIteratorTag extends Document { public function __construct() { $this->tagLibs[] = new TagLib('APF\tools\html\taglib\HtmlIteratorFallbackTag', 'iterator', 'fallback'); ... } ... } class HtmlIteratorFallbackTag extends TemplateTag { public function __construct() { $this->tagLibs[] = new TagLib('APF\core\pagecontroller\PlaceHolderTag', 'fallback', 'placeholder'); $this->tagLibs[] = new TagLib('APF\core\pagecontroller\AddTaglibTag', 'fallback', 'addtaglib'); $this->tagLibs[] = new TagLib('APF\core\pagecontroller\LanguageLabelTag', 'fallback', 'getstring'); } }

Since the 3.0 parser is able to resolve the tag structure correctly the (separately implemented) <iterator:fallback /> tag can easily be replaced by the "real" TemplateTag. For your project this means:

  • HtmlIteratorFallbackTag can be removed completely and the tag registration of the <iterator:fallback /> tag can be re-written to
    PHP code
    Document::addTagLib('APF\core\pagecontroller\TemplateTag', 'iterator', 'fallback');
  • In addition, the tag structure can be re-written to
    APF template
    <html:iterator name=""> ... <iterator:fallback> ... [<html:placeholder name="" />] [<html:getstring namespace="" config="" entry="" />] [<core:addtaglib class="" prefix="" name="" />] ... </iterator:fallback>] ... </html:iterator>
    since <html:placeholder /> can also be used within an <iterator:fallback /> tag.

Reducing tag registrations and implementation not only saves code but also reduces the complexity of your application. For this reason, it is recommended to search for similar patterns and re-write them with the capabilities of the new APF parser in mind.

2.5. Switching to the extended templating syntax

In order to improve the readability of your templates it is recommended to switch from place holder notation <html:placeholder /> to the extended templating syntax which provides a far compact notation.

This chance can easily be done on the command line with the migration script shipped with the APF for all template files:

Please be sure to change to the source directory of your application to avoid unexpected results.
Code
$ /path/to/migration/migrate-place-holders.sh /cygdrive/c/xampp/php/php ############################################# # APF 3.0 automatic place holder migration # ############################################# Checking PHP executable available ... [OK] Using given php executable at /cygdrive/c/xampp/php/php. PHP Version: 5.4.16. ############################################# Starting migration ... ############################################# Migration done! Place holders are now written in extended templating syntax.
Please make sure to execute the automated migration of your code base before. Details can be taken from Migration from 2.1 to 3.0.

3. Autoloading

Version 3.0 of the APF supports using composer to struture and manage your projects. To avoid issues with loading classes the APF team recommends to follow PHP standard PSR-2 regarding code structure.

Important is especially the one class per file rule.

Please note, that the APF follows the rules described under the PSR-2 and PSR-4 standard in most cases. With the source code format the APF team has defined custom rule sets. For details, please refer to the APF Coding Standard.

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.