EZP 5.2 / 2013.07
Version compatibility
This recipe is compatible with eZ Publish 5.2 / 2013.07
Custom tags
XMLText fieldtype supports a limited number of tags in its internal eZXML format to render HTML5. However, it is possible to extend the rendering by implementing custom tags.
As HTML5 rendering in eZ Platform is done through XSLT, you will need to create an XSL stylesheet to extend the rendering.
Note on legacy custom tags
To be able to edit a custom tag from admin interface, you'll still need to register your custom tag in the legacy kernel (at least the configuration part, template not being mandatory for edition).
Register your custom XSL stylesheet
To activate your custom tag rendering, you need to create an XSL stylesheet and to register it properly:
Each entry under custom_tags
is a hash having the following properties:
path | Absolute path to the XSL to import. Tip Use |
priority
| Priority of your stylesheet in the sequence of importing. The higher it is, the higher precedence it will have. In XSL imports, in case of template overrides, the last imported XSL always wins. Hence custom XSL are loaded in reverse priority order. |
Example of a custom XSL
The following example shows how to render the YouTube embed custom tag from jvEmbed legacy extension (see also related legacy configuration for content).
Note that all selected attributes are in custom
namespace (this is the case for all custom tags attributes in internal eZXML).
Tip
PHP functions are registered in the XSLTProcessor, so you can use global PHP functions and static method calls to enhance the XSLT process (using php-function
and php-functionString
XSLT functions, see further info).
However, given this is only for static PHP code, it is only suitable for very simple use cases! For most use cases, where you need to inject some service for your logic, for instance Repository, you'll need to use Pre-converters instead (see below).
Using Pre-converters
Pre-converters are services that preprocess the internal XML before the XSLT rendering occurs. It can be useful if you need to manipulate the data stored in eZXML.
An example of use is what is done in the EmbedTagBundle for videos : video links are transformed in embed links.
Pre-converters receive the whole DOMDocument object for the current field. So you can easily do XPath queries and do some DOM manipulation against it.
Registering a pre-converter
All pre-converters need to:
- Implement
eZ\Publish\Core\FieldType\XmlText\Converter
interface. - Be registered as a service, with
ezpublish.ezxml.converter
tag.
Overriding existing XSL templates
As XSL stylesheets apply for the whole resulted DOM, you can of course override existing templates. This is where the priority
property in configuration takes its sense.
Built-in XSL templates have 0 as priority
Consider the following example to switch from usage of <b>
to <strong>
:
6 Comments
Daniel Gracia
Hei, is there any example of using XSLTProcessor for using php functions?
thanx
Jérôme Vieilledent
You need to implement a PreConverter for this. See EmbedTagBundle for an example.
Daniel Gracia
Takk!
Daniel Gracia
Thanx for your suggestions, I manage calling a static function in my Boundle Controller.
Here is how i did it, i don't know if it's a good way to do it, but at least it worked and I'm not stuck anymore.
This way I understand that we can do more advanced things than just call to php core functions.
<xsl:variable name="urlToImage">
<xsl:value-of select="php:function('My\Name\Space\Controller\MyController::getImageUrlByID',$theNodeID)"/>
</xsl:variable>
Finally use the variable in an image tag <img src="{$urlToImage}" />
Feedback could be nice if you think I'm doing things wrong.
thanks!
André Rømcke
This works, but as soon as you need some external service inside MyController::getImageUrlByID, database or whatever, you should strongly prefer to use Pre-Converter.
Reason is that getImageUrlByID is a static function, hence can not use any properties/methods on the class, just static properties/functions. So while it is possible to inject Container to this class statically, it is considered very bad coding practice to do so by todays PHP standards. For one it makes it hard to test the functionality as you basically introduced globals this way, secondly globals in general tend to cause higher memory use as it does not free the use before after application shutdown.
Daniel Gracia
I see, thank you for the good advice.