Skip to content
This repository has been archived by the owner on Jan 26, 2019. It is now read-only.

registerHelpers as external method #12

Closed
joshpangell opened this issue May 17, 2013 · 9 comments
Closed

registerHelpers as external method #12

joshpangell opened this issue May 17, 2013 · 9 comments

Comments

@joshpangell
Copy link

Hey guys,

I see that there is a helper registration method, but it appears to only be an internal method as of yet. What extending this so that it could be used externally?

Here is an example usage with javascript: http://jsfiddle.net/teklocust/DA5Y6/1/

@joshpangell
Copy link
Author

As a followup, the addHelper method can be used externally. However, the $source does not appear modifiable. This is an example that is a modified version of the Mustache version found here.

$h = new Handlebars_Engine;
$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );

        $source = array_key_exists($source, $dictionary) ? $dictionary[$source] : $source;
        echo $source; // Only to show what the modified version should look like

        $buffer = $template->render($context);
        return $buffer;
});

$tpl = $h->loadTemplate('{{#_i18n}}Hello.{{/_i18n}} {{#_i18n}}My name is {{ name }}.{{/_i18n}}');
$tpl->render(array('name' => 'Josh'));

The desired output from this would be Hola. Me llamo Josh. but because the $source is not modifiable, it renders normally like Hello. My name is Josh.

@everplays
Copy link
Contributor

@joshpangell it can be done with another engine instance like:

$buffer = $template->getEngine()->render(array_key_exists($source, $dictionary) ? $dictionary[$source] : $source, $context);

have a look at 600215d.

but it would be better if we handle such situations without creating another engine instance. what do you think @fzerorubigd ?

@fzerorubigd
Copy link
Member

Modify the source, need to rebuild the Tokens array.
Normally, the helper output is plain string, and there is no need to re-compile it to tokens, but in this case, we need to create a way to inform the engine to recompile and replace the data in token array. some kind of new helpers. or simply we can change the behavior for all helpers.

@fzerorubigd
Copy link
Member

Need some help in this.
There is a simple way to solve this. Simply by re-compile the result of Helpers. so In this case you can do this :

$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );

        $source = array_key_exists($source, $dictionary) ? $dictionary[$source] : $source;
        return $source;
});

But there is a problem, which way is better :

1- should I change the return value? for example if Helper return a string the result is same as always, but (for example) return an array of string to tokenize every element in the array.
return array($source) means re-compile the $source, but return $source means to use it as is.
2- Just treat the result of Helpers as Handlebars and tokenize them again?

@everplays @joshpangell

@everplays
Copy link
Contributor

@fzerorubigd I like the second idea (php example) because it's simple to use and simple to implement but what about performance? also what'll happen to cache I mean which one of these'll be cached?: Hello, Hola or _i18n('Hello")?

@fzerorubigd
Copy link
Member

1- Caching is done in _tokenize ,the Holla {{name}} is cached (in array form), and calling with another name, make use of that cache.
2- About performance, return string, is doing whatever is done til now, but return some thing else (Handlebars_String?) make call to _tokenize again.

@fzerorubigd
Copy link
Member

Use this :

$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );
        $source = array_key_exists($source, $dictionary) ? $dictionary[$source] : $source;
        return new Handlebars_String($source);
});

@joshpangell
Copy link
Author

Hey guys, thanks for looking into this. However, the outcome is not quite correct. Given the

$h = new Handlebars_Engine;
$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );
        $source = array_key_exists($source, $dictionary) ? $dictionary[$source] : $source;
        return new Handlebars_String($source);
});

$tpl = $h->loadTemplate('{{#_i18n}}Hello.{{/_i18n}} {{#_i18n}}My name is {{ name }}.{{/_i18n}}');
$tpl->render(array('name' => 'Josh'));

The output from this is Hola. Me llamo {{ name }}. The string replace is working correctly, but the context is not being rendered.

However, the solution that @everplays pointed out works like a charm.

$h = new Handlebars_Engine;
$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );
        $buffer = $template->getEngine()->render(array_key_exists($source, $dictionary) ? $dictionary[$source] : $source, $context);
        return $buffer;
});

$tpl = $h->loadTemplate('{{#_i18n}}Hello.{{/_i18n}} {{#_i18n}}My name is {{ name }}.{{/_i18n}}');
$tpl->render(array('name' => 'Josh'));

Output: Hola. Me llamo Josh.

@everplays everplays reopened this Jun 7, 2013
@fzerorubigd
Copy link
Member

But I get the correct result with this code :

require("vendor/autoload.php");

$h = new Handlebars_Engine;
$h->addHelper('_i18n', function($template, $context, $args, $source) {
        $dictionary = array(
            "Hello." => "Hola.",
            "My name is {{ name }}." => "Me llamo {{ name }}.",
        );

        $source = array_key_exists($source, $dictionary) ? $dictionary[$source] : $source;
        //$buffer = $template->render($context);
        return new Handlebars_String($source);
});

$tpl = $h->loadTemplate('{{#_i18n}}Hello.{{/_i18n}} {{!comment }} {{#_i18n}}My name is {{ name }}.{{/_i18n}}');
echo $tpl->render(array('name' => 'Josh'));

Output is :

Hola.  Me llamo Josh.

-- I think you should update your copy, with composer or whatever you using.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants