Project: Wrap operator

About

This is a simple wrap ('wrapper') operator to directly call any system and user-defined functions in template.

Useful for calling string formatting functions that are missing in ez from php and adding your own functions without need to code extra extensions.

This solution is also very useful for turning poorly performing tpl code into fast tpl code by moving performance intensive operations into php code.

Description

Essentially, this is a simple wrapper operator to directly call any system and user-defined functions in template.

It does not concern me much if doing so is good idea or ' pfui' as someone said once on the #ezpublish irc channel.

Undoubtedly care has to be taken to avoid security and caching problems, etc.

But it makes life a lot easier for me because I don't have to re-implement / write existing text processing functions in template language and do not need to set up separate extension to every small operator I need.

It's a swiss army knife - you can cut your hand but no one is forcing you to :)

Thoughts

I am not sure exactly what datatypes can be passed to functions from template like this.

Should work ok for integers, strings and boolean I think. If you are more informed about ez internals, please comment.

Using wrap_user_func with return_output=true() should enable easy embedding of existing php applications in templates, called through the user function. I have tested just simple test case but maybe someone can think of something more useful and post specific instructions..

Download

Documentation

Commit log s

Usage

There are two operators which you can use in your templates to call functions

  • wrap_php_func (string function_name, array parameters [, boolean return_output])
  • wrap_user_func (string function_name, array parameters [, boolean return_output])

Parameters

  • function_name : Name of called function (ex. ereg_replace)
  • parameters : array of parameters to pass to function (ex. array('sour', 'sweet', 'Grapes are sour.') )
  • return_output : If set true(), the OUTPUT from the called function is returned, not its return value.

Returns

The return value of function you call.

If return_output is set true(), the OUTPUT from the function is returned instead.

  • This can be used to embed ( include website ) external applications in your template!

Security

Function names callable through operator must be explicitly listed in wrap_operator.ini , anything else is not allowed.

  • There is [PHPFunctions] section for enabling calling system functions through wrap_php_func and [UserFunctions] for user defined functions.

PHP functions

Calling internal php functions. For example: you want to use ereg_replace php function.

Using PHP ereg_replace

1. Add line to [PHPFunctions] section in wrap_operator.ini

[PHPFunctions]
PermittedFunctionList[]=ereg_replace

2. Call it in your template

{wrap_php_func('ereg_replace', array('sour', 'sweet', 'Grapes are sour.'))}

Using PHP str_replace

1. Add line to [PHPFunctions] section in wrap_operator.ini

[PHPFunctions]
PermittedFunctionList[]=str_replace

2. Call it in your template

{def $result=wrap_php_func('ereg_replace', array('sour', 'sweet', 'Grapes are sour.'))}
{def $str_js_escaped=wrap_php_func("str_replace", array("'", "\\'", $prod.name ) )}
{def $str_newlines_striped=wrap_php_func("str_replace", array("\n", "", $str_desc_raw ) )}

User defined functions

Calling internal php functions.

Contribute your own user functions

Functions you have written can be easily shared by pasting them to forum, wiki or svn. So share yours :)

  • 'getXMLString.php' - Accepts a variable containing a valid xml string, a variable containing the name of the search string, returns the contents of search string name variable contents or false if string name does not exist in xml dom.
  • 'getLeadingSentences.php' - Quick and dirty way to get number of leading sentences in text, stolen from somewhere. Accepts a search variable and max (numeric) limit variable.

The function ' wrap_user_func' expects each user function to be defined in separate file.

extension/wrap_operator/userfunctions/{user_function_name}.php

It uses include_once to read it in, so be sure to use <?php ?> around user function source code file.

Example simple user defined function

Suppose you want to use following silly function in template

<?php
function silly_thing($who)
{
return($who . ' is silly!');
}
?>

Steps

To do this you must ...

1. Save the function in file

extension/wrap_operator/userfunctions/silly_thing.php

2. Add line to [UserFunctions] section in the override setting file, ' wrap_operator.ini'

[UserFunctions]
PermittedFunctionList[]=silly_thing

3. Call it in your template

{wrap_user_func('silly_thing', array('This function'))}

Having ability to call your php functions like this is a very nice feature I think, kind of simplified plugin system for operators.

No need to write whole extension for each simple function.

Example complex user defined function

Suppose you want to do the following in php called from a template operator.

<?php
 
   // Quick and dirty way to get the contents of an xml string.
   function getXMLString($name = false, $data, $ret = false, $debug = false)
   {
       // given string $data, will return the text string content of the $name attribute content of a given valid xml document.
       if ( $debug )
       ezDebug::writeNotice( $name, 'getXMLString:name' );
 
       // get information out of eZXML
       $xml = new eZXML();
       $xmlDoc = $data;
 
       if ( $debug )
       ezDebug::writeNotice( $data, 'getXMLString:data' );
 
       // continue only with content
       if( $xmlDoc != null and $name != null )
       {
           $dom = $xml->domTree( $xmlDoc );
           $element = $dom->elementsByName( "$name" );
 
           // print_r ( $name );
           $string = $element[0]->textContent();
           $ret = $string;
       }
 
       if ( $debug )
       ezDebug::writeNotice( $ret, 'getXMLString:ret' );
 
       return $ret;
    }
?>

Steps

1. Enable function. Add line to [UserFunctions] section in the override setting file, ' wrap_operator.ini'

[UserFunctions]
PermittedFunctionList[]=getXMLString

2. Example template call, variable assignment and output

{def $user_city=wrap_user_func('getXMLString', array('city', $order.data_text_1) )}
 
{$user_city}

Debugging

  • Turn on template debugging to see data that is passed to and from function and error messages
  • Look at examples
  • Look at code
  • Scratch head. Repeat 2x
  • See Support

Support

  • Comments, suggestions for improvement and user defined functions are very welcome!
  • Either post on forum or log on to #ezpublish irc channel on irc.freenode.net to bug zurgutt (author).