Skip to content

Commit

Permalink
v.1.3.0 contd. php: handle dynamic function creation both for PHP < 7…
Browse files Browse the repository at this point in the history
….2.0 (create_function) and PHP >= 7.2.0 (create_function is deprecated, use workaround)
  • Loading branch information
Nikos M committed Mar 8, 2019
1 parent 857f7f7 commit 496d8ae
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 12 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Contemplate
===========

__Light-weight, fast and flexible "object-oriented" template engine for PHP, Python, Node, XPCOM and Browser client-side JavaScript__
__Light-weight, fast and flexible "object-oriented" template engine for PHP, Python, Node.js, XPCOM and Browser client-side JavaScript__


![Contemplate](/screenshots/contemplate.jpg)
Expand Down Expand Up @@ -105,16 +105,15 @@ The solution is inspired by _John Resig's post_ ([see above](http://ejohn.org/bl
* `Contemplate` does a __minimum parsing__ (and caching) in order to create dynamic templates
and trying to contain the needed functionality inside the common language subset(s).

* Most of the time this can be accomplished, the rest functionality is built with __custom functions__ which mostly resemble the `PHP`
syntax, yet work the same in all the engine's implementations.
* Most of the time this can be accomplished, the rest functionality is built with __custom functions__ which mostly resemble the `PHP` syntax, yet work the same in all the engine's implementations.

* __Uniform functionality__, Engine Implementations for __PHP__ , __Python__ , __Node__ , __XPCOM__ and __Browser client-side JavaScript__ (**NOTE** `javascript` engine supports **both sync and async operations both callback-based and promise-based**)
* __Uniform functionality__, Engine Implementations for __PHP__ , __Python__ , __Node.js__ , __XPCOM__ and __Browser client-side JavaScript__ (**NOTE** `javascript` engine supports **both sync and async operations both callback-based and promise-based**)

* Simple and __light-weight__ ( only one relatively small class for each implementation, no other dependencies ) `~50kB` minified, `~16kB` zipped

* __Fast__ , can cache templates dynamically (filesystem caching has 3 modes, `NONE` which uses only in-memory caching, `NOUPDATE` which caches the templates only once and `AUTOUPDATE` which re-creates the cached template if original template has changed, useful for debugging)

* Generated cached template code is __formatted and annotated__ with comments, for easy debugging (note: `javascript` cached templates are **`UMD` modules** which can be used in both `node`/`AMD`/`XPCOM`/`browser`)
* Generated cached template code is __formatted and annotated__ with comments, for easy debugging (note: `javascript` cached templates are **`UMD` modules** which can be used in both `node.js`/`AMD`/`XPCOM`/`browser`/`es6 module fallback`)

* Syntax __close to `PHP`__ (there was an effort to keep the engine syntax as close to `PHP` syntax as possible, to avoid learning another language syntax)

Expand Down
5 changes: 3 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
__1.3.0__
* PHP/JS/PY: support custom template finder per context or even an array of possible template dirs in order to find templates dynamicaly not already added/defined (js engine supports both sync and async operations plus promise-based) (see manual for details)
* PHP/JS/PY: add template function `vsprintf` similar to `sprintf` but accepts an array of arguments instead of them being passed individualy as separate arguments during function call (can be useful when needing to format string based on arguments from data or parameters)
PY: try to implement `sprintf`/`vsprintf` functionality as close as possible to original `php`/`js` `sprintf`/`vsprintf` (uses *old-style* string formatting with a couple of *hacks*, maybe in future use *new-style* `.format` method)
* JS: fix and complete async template loading, parsing and rendering (fix a small issue with async parsing not updating regex) and also do **static analysis** (during compilation) on dynamic templates used inside calling template (ie using `tpl`/`template` functions) and **pre-load them async** (if in async opreation) in order to be rendered without blocking. If sync operations everything functions as before
PY: try to implement `sprintf`/`vsprintf` functionality as close as possible to original `php`/`js` `sprintf`/`vsprintf` (uses *old-style* string formating with a couple of *hacks*, maybe in future use *new-style* `.format` method)
* JS: fix and complete async template loading, parsing and rendering (fix a small issue with async parsing not updating regex) and also do **static analysis** (during compilation) on dynamic templates used inside calling template (ie using `tpl`/`template` functions) and **pre-load them async** (if in async opreation) in order to be rendered without blocking. If sync operations, everything functions as before
PHP: handle dynamic function creation (eg for inline templates) for `PHP < 7.2.0` and `PHP >= 7.2.0` where `create_function` is deprecated

__1.2.5__
* JS: enable asynchronous template loading, parsing and writing so that performance can be even greater in `Node.js` where `sync` methods may block. `Contemplate.tpl`, `Contemplate.getTemplateContents`, `Contemplate.parseTpl` all accept a `callback` (`nodeback`) as last argument with signature `function(err, result)` which if given all processing becomes **asynchronous**. Also if `Promises` are supported *"promisified"* versions of the above methods exist i.e `Contemplate.tplPromise`, `Contemplate.getTemplateContentsPromise`, `Contemplate.parseTplPromise` all return a `Promise` which resolves and rejects accordingly.
Expand Down
26 changes: 21 additions & 5 deletions src/php/Contemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@
**/
if (!class_exists('Contemplate', false))
{
// create_function is depreceated in PHP 7.2.0+
if ( version_compare(PHP_VERSION, '7.2.0', '>=') )
{

function Contemplate_create_dynamic_function_($args, $code)
{
return eval('return function('.$args.'){'.$code.'};');
}
}
else
{
function Contemplate_create_dynamic_function_($args, $code)
{
return create_function($args, $code);
}
}
class ContemplateInlineTemplate
{
public $id = null;
Expand Down Expand Up @@ -78,7 +94,7 @@ public static function compile( $tpl )
}
$out .= ');';
// create_function is deprecated in PHP 7.2+
return @create_function('$args', $out);
return Contemplate_create_dynamic_function_('$args', $out);
}

public function __construct( $tpl='', $replacements=null, $compiled=false )
Expand Down Expand Up @@ -122,7 +138,7 @@ public function render( $args=null )
if ( $this->_renderer )
{
$renderer = $this->_renderer;
return $renderer( $args );
return call_user_func($renderer, $args);
}

$tpl =& $this->tpl;
Expand Down Expand Up @@ -2381,13 +2397,13 @@ protected static function create_template_render_function( $id, $contx, $seps=nu
));

// create_function is deprecated in PHP 7.2+
$fn = @create_function('&$data,$self,$__i__', $func);
$fn = Contemplate_create_dynamic_function_('&$data,$self,$__i__', $func);

$blockfns = array();
for($b=0; $b<$bl; $b++)
{
// create_function is deprecated in PHP 7.2+
$blockfns[$blocks[$b][0]] = @create_function('&$data,$self,$__i__', $blocks[$b][1]);
$blockfns[$blocks[$b][0]] = Contemplate_create_dynamic_function_('&$data,$self,$__i__', $blocks[$b][1]);
}
return array($fn, $blockfns);
}
Expand Down Expand Up @@ -2457,7 +2473,7 @@ protected static function get_cached_template( $id, $contx, $options=array() )
{
// already parsed code was given
// create_function is deprecated in PHP 7.2+
$tpl->setRenderFunction( @create_function('&$data,$self,$__i__', $parsed) );
$tpl->setRenderFunction( Contemplate_create_dynamic_function_('&$data,$self,$__i__', $parsed) );
}
else
{
Expand Down
6 changes: 6 additions & 0 deletions tests/funcs/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ function echo_($s)
}
include dirname(dirname(ABSPATH)).'/src/php/Contemplate.php';

$tpl = '<% for($v in $list) %><% $v %><% endfor %>';
Contemplate::add(array(
'inline' => array($tpl)
));

echo_(Contemplate::tpl('inline', array('list'=>array(1,2,3))));
echo_(Contemplate::queryvar("https://example.com?key1=1&key2[]=21&key2[]=22",null,array("key1")));
echo_(Contemplate::queryvar("https://example.com?key1=1&key2[]=21&key2[]=22",null,array("key2")));
echo_(Contemplate::queryvar("https://example.com?key1=1&key2[]=21&key2[]=22",array("key3"=>3,"key4"=>array(41,42))));
Expand Down

0 comments on commit 496d8ae

Please sign in to comment.