How to change mustache template data dynamically - php

I have just started working with Mustache template engine. I am currently using PHP implementation of it (https://github.com/bobthecow/mustache.php/wiki). I am using helpers to manipulate the way data is rendered.
$data = array("name" => "abhilash");
$template = "Hello {{name}}, {{#bold}}Welcome{{/bold}}";
$m = new Mustache_Engine(array(
"helpers" => array(
"bold" => function($content) {
return "<b>$content</b&gt";
})));
$html = $m->render($template, $data);
With the help of this I am able to render 'Welcome' with bold font. I would like to know if it is possible to manipulate $data with the help of helper function. For example if the template is like below and I have a helper function registered as dataSource, I would like to use it to collect some data (say key-value pair) from datasource_func_name() and append it to $data.
{{#dataSource}}datasource_func_name{{/dataSource}}
Hi {{name}}

That's normally not how you would use helpers. However, Mustache basically expects a data souce, so why not inject it directly?
$html = $m->render($template, $dataSource);

Related

Can we edit a mustache template in runtime?

Can I add new nodes to mustache template at run-time in PHP? Let's say below is a code where ProductDetails will contain few single products:
{{#ProductDetails}}
{{#SingleProduct}}
{{OldDetail}}
{{/SingleProduct}}
{{/ProductDetails}}
I want to add a new node like {{NewDetail}} just after {{OldDetail}} through some function in run-time(i.e just before I am compiling the template as these templates have been shipped to customers in such a way that only code to compile can be changed but not the template)? I don't want to do string manipulation(customers created few new templates with above parameters present at least but the spacing may change & few new entries can be added by them around nodes). Does mustache library provide any functions for that?
If I were you, I will try Lambdas.
Template.mustache will be like this:
{{#ProductDetails}}
{{#SingleProduct}}
{{OldDetail}}
{{/SingleProduct}}
{{/ProductDetails}}
And codes will be like:
$Mustache = new Mustache_Engine(['loader' => new Mustache_Loader_FilesystemLoader($YOUR_TEMPLATE_FOLDER),]);
$Template = $Mustache->loadTemplate('Template');
$OriginalOldDetail = '<h1>this is old detail</h1>';
echo $Template->Render([
'ProductDetails' => true,
'SingleProduct' => true,
'OldDetail' => function($text, Mustache_LambdaHelper $helper){
// Render your original view first.
$result = $helper->render($text);
// Now you got your oldDetail, let's make your new detail.
#do somthing and get $NewDetail;
$NewDetail = $YourStuff;
// If your NewDetail is some mustache format content and need to be render first.
$result .= $help->render($NewDetail);
// If is some content which not need to be render ? just apend on it.
$result .= $NewDetail;
return $result;
}
]);
Hope that will help.
(English is not my first language so hope you can understand what I'm talking about.)

How did you bind datas to a view in Codeigniter ( likes View Composers in laravel)?

If you have data that you want to be bound to a view each time that view is
rendered,a view composer can help you ...
This task can be easily archived in laravel, but I am now using Codeigniter, there is no view composers things. What I have done now is, I create a custom view method, just like below
public function view($page,$params=null,$return=false)
{
// Every time I invoke this method, $nav will be passed to 'navigation' view.
$nav=[
'user' =>'Adam'
];
//return the views as view_partials instead of displayed
$view_partials = array(
'navigation' => $this->obj->load->view('partials/nav',$nav,true),
'page_content' => $this->obj->load->view($page,$params,true)
);
// load layout with the view_partials which contain bound data.
$this->obj->load->view($this->_layout,$view_partials,$return);
}
This method returns views as 'string', it can not works with json or complex page.... Thank you.
Ok, lets make this simple
$this->load->view(path_to_htmlpage, $bound_data, FALSE);
or
$this->load->view(path_to_htmlpage, $bound_data); // by default 3rd param is FALSE
this will render html page
If you want to get html page as a string, set 3rd parameter to TRUE
$html_string = $this->load->view(path_to_htmlpage, $bound_data, TRUE);
check https://ellislab.com/codeigniter/user-guide/general/views.html
public function view($page,$params=null,$return=false)
{
$nav['user']='adam';
$data['navigation']= $this->load->view("partials/nav",$nav,true);
$data['page_content'] = $this->load->view($page,$params,true)
$this->load->view('your_page',$data);
}
in yor view page ie.your_page you can use variables $navigation and $page_content to display the pages

Laravel blade hardcode variable on compile

I'm moving some of my view strings to config because I want to use the same code for similar sites, and I'm wondering if there's a way to avoid a call to Config:: or Lang:: on every runtime.
<h1>{{ Config::get('siteName') }}</h1>
blade makes in into
<h1><?php echo Config::get('siteName'); ?></h1>
But I want it to be just plain HTML like
<h1>MySite</h1>
My approach is trying to make this when Blade compiles the views into plain PHP / HTML , is there any built-in way to do this? I've tried with some Blade methods like #string with no results
Thanks
On your controller do this
$siteName = Config::get('app.siteName');
View::make('xxx', array('siteName' => $siteName))
for example
And you will be able to retrieve te variable siteName on your view with only
{{$siteName}}
Hope this will help (Or maybe I doesn't understand the problem)
OK solved it by extending Blade
I created a blade tag such as
#hardcodeConfig('siteName')
And in my blade_extensions I did this:
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('hardcodeConfig');
$matches = [];
preg_match_all($pattern, $view, $matches);
foreach($matches[2] as $index => $key){
$key = str_replace([ "('", "')" ], '', $key);
$configValue = \Config::get( $key );
$view = str_ireplace($matches[0][$index], $configValue, $view);
}
return $view;
});
This does exactly was I was looking for, I created one for Config and another for Lang

ZF_FORM: How to add some view template for form element?

I created element in form object:
function createElement()
{
$template = new Zend_Form_Element_Hidden('field');
$template->addDecorator('ViewScript', array('placement' => 'prepend', 'viewModule' => 'admin', 'viewScript' => 'values.phtml'))
$this->addElement($template);
}
function setViewTemplate($values)
{
$view = new Zend_View();
$view->setScriptPath(APPLICATION_PATH . '/scripts/');
$view->assign('values', $values);
$this->getElement('field')->setView($view);
}
But in the view script 'values.phtml' I cannot get access to values like $this->values.
What I'm doing wrong here?
I know that it would be good to add own decorator, but it is interesting to use zends' decorators.
From the Zend Framework Documentation: Standard Form Decorators Shipped With Zend Framework Section
Zend_Form_Decorator_ViewScript
Additionally, all options passed to
the decorator via setOptions() that
are not used internally (such as
placement, separator, etc.) are passed
to the view script as view variables.
function setViewTemplate($values)
{
$this->getElement('field')
->getDecorator('ViewScript')
->setOptions('values', $values);
}
you can reslove it with using attribs
$template->setAttrib('key', 'value');
and in template
<?php echo $this->element->getAttrib('key'); ?>

Mustache php gettext()

I am experimenting with kostache, "mustache for kohana framework".
Is there any way I can use simple PHP functions in mustache template files.
I know logic and therefore methods are against logic-less design principle, but I'm talking about very simple functionality.
For example:
gettext('some text') or __('some text')
get the base url; in kohana -> Url::site('controller/action')
Bobthecow is working on an experimental feature that will allow you to call a function as a callback.
Check out the higher-order-sections branch of the repository and the ticket to go with it.
You could use "ICanHaz" http://icanhazjs.com/
and then you can declare your mustache templates as
<script id="welcome" type="text/html">
<p>Welcome, {{<?php echo __('some text') ?>}}! </p>
</script>
Well, you can do this now with Bobthecow's implementation of Mustache Engine. We need anonymous functions here, which are passed to the Template Object along with other data.
Have a look at the following example:
<?php
$mustache = new Mustache_Engine;
# setting data for our template
$template_data = [
'fullname' => 'HULK',
'bold_it' => function($text){
return "<b>{$text}</b>";
}
];
# preparing and outputting
echo $mustache->render("{{#bold_it}}{{fullname}}{{/bold_it}} !", $template_data);
In the above example, 'bold_it' points to our function which is pasalong withwith other data to our template. The value of 'fullname' is being passed as a parameter to this function.
Please note that passing parameters is not mandatory in Mustache. You can even call the php function wothout any parameters, as follows:
<?php
# setting data for our template
$template_data = [
'my_name' => function(){
return 'Joe';
}
];
# preparing and outputting
echo $mustache->render("{{my_name}} is a great guy!", $template_data); # outputs: Joe is a great guy!
Credits: http://dwellupper.io/post/24/calling-php-functions-for-data-in-mustache-php

Categories