I'm having different languages on my web application.
Now i would like to do write: About us in the mustache file.
but then depending on the language the user has chosen (logic in the view/controller), it should display the correct translation for About us.
The translation would be something i have stored for exactly the words: About us
I have seen another webapplication that does it this way:
{{#lang}}About us{{/lang}}
But I dont understand how this is working? How can the lang() method in the view model grab the data within #lang, "About us" - and then replace it with something else, if exists.
(the procedure grabbing the translation from database or file, that matches "About us" do i not need to know)
I didn't know it is possible to reverse like that, sending the "About us" to the lang() method in view model?
Hope someone can explain and with example. Thanks
This is what I tried, in my view:
public function lang($input)
{
return "test" . $input;
}
But this does not work. (No argument passed to lang() )
I am using Mustache (Kostache) together with PHP in a MVC framework (kohana)
Assuming you have mustache defined as $m the following would add the function lang when the template was being parsed.
The key here is passing the function to mustache when rendering.
$data = new StdClass;
$data->lang = function($text) {
return "Requested lang: $text";
}
$m.render($template, $data);
This template
{{#lang}}About us{{/lang}}
Would become
Requested lang: About us
After alot of headache, very bad google results, here is the correct solution if you use Kostache 2 and Kohana 3.2/3.0 :
SIMPLY, in the Kohana_Kostache class at the factory() method where Mustache_Engine intializes, you add a helper function:
'helpers' => array(
'i18n' => function($text) {
return __($text);
}),
Since I use the Kohana Translation system, I called it i18n and it returns __($text), which is the $text translated if exists.
Related
Currently building a system that requires users to design a custom template for a PDF document generated by the application. To achieve this, I have saved a blade template in the database to be retrieved when the document is about to be converted into a PDF document.
I know Laravel's View component can pick up a blade template from the file system and render it as an HTML document. However, to achieve my objective, this component should be able to read a text field fetched from the database. This is not currently possible with Laravel and I suspect is largely due to security reasons.
The question now is, how else can this be achieved using Laravel or what may be the recommended way to get this done?
Based on your comments and re-reading your initial question, my best guess is that you need a macro replacement function. This is the method I use for email templates in my own applications, which are stored in the database. It sounds similar to what you are attempting to do.
Helpers.php
Some autoloaded helpers file.
if (!function_exists('macro_parse')) {
function macro_parse($body, $haystack, $pattern = '/{{([^}]+)}}/')
{
$replace = preg_replace_callback($pattern, function ($needle) use ($haystack) {
return $haystack[$needle[1]];
}, $body);
return $replace;
}
} else {
Log::error("macro_parse is already defined");
}
Usage
// a simple template example...
// you would retrieve this template from the database
$template = '<div>{{some_macro}}</div>';
// key/value pairs can be set from database values
$macros = [
'some_macro' => 'it works!'
];
// parse the template
$parsed = macro_parse($template,$macros);
dd($parsed); // <div>it works!</div>
You can then pass the filled template to the PDF generator.
i`m trying to call a ViewHelper Function from within a Controller in Typo3 (to add some additional header data)
Base is the Yag Gallery.
I edited the ItemListController.php and added the following:
$pager = $this->extListContext->getPagerCollection();
$prevLinkUid = $pager->getPreviousPage();
$arg = Tx_YAG_ViewHelpers_Namespace_GPArrayViewHelper::render([page:$prevLinkUid], $pager)
$test = '<link rel="test" href="' . $arg . '">';
$this->response->addAdditionalHeaderData($test);
The addAdditionalHeaderData function works well with other data (e.g. $prevLinkUid, so this part is functioning well).
If i understand the syntax of GPArrayViewHelper::render correctly, i need a pageUid as first argument and the pagerCollection as second argument (derived from this call within Resources/Private/Partials/Pager/Default.html
<extlist:link.action controller="{controller}" action="{action}" arguments="{extlist:namespace.GPArray(object:'{pagerCollection}' arguments:'page:{pager.previousPage}')}"><span><</span> </extlist:link.action>
)
However - if i try this Controller my page won't render, so i assume there is something wrong with the php code / function call, maybe even the syntax of the key value pair/first argument? Sorry, i'm not a professional in php
Any ideas how can i achieve this? I read that it may be difficult to use ViewHelpers from within other controllers?
there is a ViewHelperInvoker class which you can use to render a viewhelper in a controller:
$viewHelperInvoker = GeneralUtility::makeInstance(\TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInvoker::class);
$result = $viewHelperInvoker->invoke(
\TYPO3\CMS\Fluid\ViewHelpers\Format\CurrencyViewHelper::class,
[ 'currencySign' => '€' ],
new \TYPO3\CMS\Fluid\Core\Rendering\RenderingContext(),
function() {
return 12345.67;
}
);
https://github.com/TYPO3/Fluid/blob/master/src/Core/ViewHelper/ViewHelperInvoker.php
Viewhelpers are not supposed to be used outside of Fluid templates.
However, there might be an easier way to achieve what you want, e.g. with HeaderAssets. This way you can easily add snippets to the <head> of your page from within a controller action or page template.
Please really don't to that. What you can do is using the PageRenderer. E.g. using
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
$pageRenderer->addHeaderData($headerData);
I'm using this plugin to create slug-based URL's on a CakePHP 2 web application: https://github.com/josegonzalez/cakephp-dynamic-route
The documentation suggests that you would call a Cake controller like so:
posts/view?id=45
My URL's currently work as Cake's default behaviour. So using the example above posts/view/45 works but posts/view?id=45 does not.
When I call URL's as per the example I get a 404 error.
My functions are written like so (e.g. in PostsController.php):
public function view($id) {
// logic to load post by ID
// ...
}
There is almost no documentaiton for the above plugin. Has anyone used it or know where I'm going wrong? It seems you cannot pass a GET variable such as 'id' to the 'view' function, without re-factoring the code inside it to accept passed parameters?
The solution appears to be that some of the controller functions needed to be re-written to accept GET style parameters.
In the documentation a "spec" field looks like this:
posts/view?id=45
In a regular CakePHP application the route for that would be like this: posts/view/45
The plugin simply doesn't work if you put the second style of route (posts/view/45) into the "spec" field.
So the answer is the "spec" fields must be like so:
posts/view?id=45 and then your controller functions have to be re-written, e.g.
public function view($id) {
if (isset($this->request->params['id'])) {
$id = $this->request->params['id'];
}
}
Doing this means that it will work with a parameter (view?id=45) or a standard Cake call (view/45).
Please note this has nothing to do with the "slug" aspect of the plugin - the "slug" can be anything, as per the documentation examples: /why-isnt-this-pup-asleep or /manchester/cakephp-developers-dance-to-beyonce. The original question was asking if there was a way to map a "spec" given in the documentation to a Cake controller function without having to modify it like I have above. The answer seems to be no, you have to modify them!
I am having some trouble trying to "capture" the rendered html of an elmenet in cake php.
Say I have an element named "message.ctp"
I would like to do something like the following:
A making a $.getJSON request to an action in a controller say jsonAction(). Within this action I will perform some DB updates and return a json string. I would like to store the html is a part of the json object. Doable?
function jsonAction() {
//Do DB update
if(db update was ok) {
$response = array("completed" => true, "html" => $this->render("message"));
} else {
$response = array("completed" => false);
}
echo json_encode($response);
}
What seems to be happening right now is that the render method echos the rendered value instead of returning it.
Anyway I can achieve this?
Thanks
Regards
Gabriel
Forget elements for the time being.
First of all you have to separate everything that includes outputting stuff from the controller (either it is HTML or JSON or whatever).
For every controller action you have to have a corresponding view. So, for controller action jsonAction you should have a view names json_action.ctp (at the corresponding folder, e.g. if jsonAction is at MessagesController create a folder named /view/messages/json_action.ctp).
Set your variable from controller, display it at view and you are done. Do not forget to $this->layout = 'empty' from controller so that you display only what you have at the view.
Generally you should redo the CakePHP tutorials and reread the book it order to understand better the MVC (Model-View-Controller) pattern and CakePHP structure.
Do you mean this?
$myRenderedHtml = $this->element('message');
^^^^^^^
Using PHP, If I have a model (a class) where I various queries, whatever I need, and in my controller, I use myModel = new CustomerModel(); and later in the controller, say I call myMyodel in the controller (I know looks like codeigniter but I am not using a framework) to:
$data['query'] = myModel.OrderByLastName();
how do I pass that $data['query'] to a view, a separate .php page?
I don't wan to echo anything from my controller.
Also, was hoping this design, the way I explained it makes sense. Or am I wasting time with the model class?
Typically, you'd instantiate a view object:
$view = new View();
Pass it the info it needs():
$view->set($name1, $value1);
$view->set($name2, $value2);
...
Then invoke the view's renderer:
$view->render();
The way Django works is the controller basically renders a template using a templating system. It passes the data in Contexts, like this:
data['query'] = myModel.OrderByLastName();
context = {'data': data['query']}
page = loader.get_template('folder/template.phtml')
return render_to_page(page, context)
roughly.
Obviously, you're writing your own system so you've got some room on exactly how you implement it. I don't know if that's exactly what you want, but it might give you a workable idea.