Having Mustache templates both render and not, with Laravel/Blade and JavaScript - php

I'm using Laravel and all my templates are using Blade templating. There are a few parts of pages which need to be rendered both on the server side and by JavaScript. For these I'm using Mustache templates (with mustache-l4).
The problem is how to have Laravel render the templates, but also to include them in the page with the Mustache tags intact, for the JS to pick up.
For example, if I have a (simplified example) Blade template like this:
<html>
<head></head>
<body>
<h1>{{ $pageTitle }}</h1>
#include('partials/'.$partialName, array('some_text' => $pageText))
<script type="text/mustache">
#include('partials/'.$partialName)
</script>
</body>
</html>
which includes .mustache partials like this:
{{#some_text}}
<p>{{some_text}}</p>
{{/some_text}}
The Mustache partial is rendered on page load fine. BUT when it's included between the <script></script> tags I want it to be rendered verbatim. ie, the {{#some_text}} Mustache tags should be there in the rendered HTML. Then the JavaScript can read it in as a Mustache template.
I can see this might be possible by changing the tag delimiters on the server-side (Blade) templates but at this stage, with scores of Blade templates already working, I'd rather not.
I can't get my head round how to do this. Could I change the Mustache delimiters just for one of the times it's included, so it's only fully rendered then?

Another way would be to escape the tags with #
<div>#{{ $str }}</div>
<div>#{{"<a>Plain text</a>"}}</div>
will result in
<div>{{ $str }}</div>
<div>{{"<a>Plain text</a>"}}</div>
StackOverflow Answer

One way of doing this would be to change blade's content tag.
Like so :
Blade::setContentTags('[%', '%]');
So that {{}} tags will be considered as plain string.
For further information refer this snippet:
laravel-recipes

Related

How to create a reusable Twig component

I work on a Symfony 3 app which uses Twig for rendering. To make the code more readable and reusable, I need to split a screen in small parts, parts which could be used in other screens (for example a clock widget). At first it seems easy, I could use the include Twig method to include that part of code. The problem is that my clock uses some specific CSS and JS scripts to work.
What would be the best way to create a reusable components composed of HTML, CSS and JS ? Thx in advance !
There is no "Component" concept or approach in Twig, but still you can encapsulate CSS + HTML + JS code in one file and include it as an isolate piece of code:
<style>...</style> {# or use <link href="..."> #}
<div>...</div>
<script>...<script> {# or use <script src="..."> #}
However, probably Twig is not the correct tool to achieve it and you should look at some frontend framework (e.g. VueJS https://v2.vuejs.org/v2/guide/index.html) by passing the data through HTML attributes.
Probably you can use include passing your data to a specific partial component and render it dinamically.
Check it : https://twig.symfony.com/doc/3.x/tags/include.html

In Laravel 5.1 blade templates, how can I use #yield without the extra space added at the end?

I have a blade template master.blade that has the following code:
<title>#yield('meta-title')</title>
And then in any views that extend this template, the data can be passed in like this:
#section('meta-title')My Meta Title #stop
However, this ALWAYS adds a space at the end. If I remove the space in the code so it looks like the following, then it will not recognise the #stop and the page breaks:
#section('meta-title')My Meta Title#stop
Is there a way to achieve this functionality (dynamically inject content into the header without any spacing before or after) either using #yield or some other way?
Blade Template Docs
Pass a second parameter to #section, like so: #section('meta-title', 'My Meta Title'), no need for #stop
It is indeed in the docs: http://laravel.com/docs/5.1/blade#template-inheritance

With Mustache PHP, loading partials but not parsing tags

I have a Mustache template which includes some partials. I want to load the partial into a string in PHP, with the contents of the partials included in the string. But I don't want the template to be parsed.
eg, if I have this Mustache template, myTemplate.mustache:
{{> partials/myPartial }}
{{ my_text }}
and this is partials/myPartial.mustache:
{{ my_header }}
then I want to load myTemplate.mustache and have a PHP variable containing:
{{ my_header }}
{{ my_text }}
I can see how to get the contents of the template using new Mustache_Loader_Filesystem()->load() but that doesn't include the contents of the partial.
You can't see a way to do that, because it's not possible. Mustache itself never even deals with templates merged together like that, so there's no reason it would expose an API for getting them.
Because of the nature of partials, it's not as simple as replacing a partial tag with the contents of that template. For example, partials don't inherit delimiter changes and pragmas from templates which include them, so that would have to be addressed. Partials are also indented to the level of the tag which includes them, so replacing a partial tag with the contents of the partial would have to do this as well.
I supposed if you really want it, you could load the template and partials, then use the Mustache Tokenizer to find partials tags in the template source then replace them (recursively) with the contents of the associated partials. Then you'd have to figure out how to change delimiters at the start and end of the inlined partials (or disallow delimiter changes entirely, which you could do by throwing an exception if you encounter one while processing the parsed template). And I can't think of a way to remove pragmas once they're added, so you would either have to disallow pragmas, or ensure that all inlined partials were compatible with whatever pragmas were being used in parent templates.
It'd be a fair amount of work, to say the least.

How to Include # symbol in blade template page without it being processed as blade code in Laravel

So my dilemna is this.
<p>Email: info#example.com</p>
Is being processed as blade code and won't re-size in my responsive bootstrap web page in my Laravel 4 framework.
Any ideas on how to get blade to ignore the # symbol? It is probably a simple fix I just can't find it on the web.
Thanks
A really simple way would be this:
someone{{'#'}}email.com
{{ $whatever }} effectively gets transformed into <?= e($whatever) ?> (where e() does HTML escaping) so you can put a string there, and that will get output instead of a variable.
The following will avoid blade syntax:
<p>Email: info<?php echo urldecode('%40')?> example.com</p>
%40 is equivalent to #
There are also HTML helpers in Laravel,
you can use the following to generate a mailto tag with an obfuscated email address:
# Generating obsufscated mailto tag
{{ HTML::mailto('myemail#mail.com','Some person'); }}
// Generates :
Some person
View more of these helpers at http://www.laravel-tricks.com/tricks/generating-html-using-html-methods

How can I use a Smarty template from a Smarty template?

I've run into a funny problem. I need to use Smarty templates within a Smarty template.
Here is why. I use the same templates for various wiki websites, and each website has its own configuration. The configuration contains parts for the main template (such as changed titles and headings, etc).
Here is a simplified example. I've a file topic-list.template.html that's shared across all websites:
<div id="topics">
<h1>{$h1}</h1>
...
</div>
As you can see, this template file contains an <h1> tag that can be customized for each website.
Then for each of the websites I've a configuration file that looks like this (simplified):
$config = [
"h1-titles" => [
"topics" => "Showing Topics in {\$category}"
]
];
As you can see the configuration file contains a Smarty template.
So when I render the topic-list.template.html file, I've to render the $config['h1-titles']['topics'] first through $smarty->fetch("string":$config['h1-titles']['topics']), and then assign it to h1 Smarty variable. My simplified code looks like this:
$h1_tag = $smarty->fetch("string":$config['h1-titles']['topics']);
$smarty->assign('h1', $h1_tag);
$smarty->display('topic-list.template.html');
I wonder if I could somehow insert the $config['h1-titles']['topics'] in the topic-list.template.html file automatically and then it have all rendered in one go?
Please have a look at the docs on String Template Resources. You will immediately notice that your $smarty->fetch('string:…') approach can also be done within a template: {include file="string:…"}
I believe that {eval} tag may help you:
{eval} is used to evaluate a variable as a template. This can be used for things like embedding template tags/variables into variables or tags/variables into config file variables.
http://www.smarty.net/docs/en/language.function.eval.tpl

Categories