How to make PhpStorm interpret custom delimiters? - phpstorm

I use Ractive templates in my Symfony application.
As my Ractive templates are in .twig files, I cannot use curly braces around my Ractive values, so I use Ractive's custom delimiters
For example, <p>{{text}}</p> becomes <p>[[text]]</p>.
It works perfectly, but my problem is that PhpStorm doesn't recognize the brackets as template values, which causes several annoying consequences:
There is no syntax coloration, the indentation is messed up, and there are warnings where there shouldn't be.
How can I make PhpStorm interpret my double brackets as template values ?
Edit: example of code:
<script type="text">
$(function () {
var a = new Analytics();
a.site = '{{ site.id }}'; {# Twig #}
a.run();
});
</script>
{# Below is ractive #}
<table class="table">
<tr class="general">
<th></th>
[[#each columns: i]]
[[#if stats]]
<th>[[trans('column.' + columns[i])]]</th>
[[/if]]
[[/each]]
</tr>
[[> totalLine]]
[[#each templates: t]]
[[> templateLine]]
[[/each]]
</table>

This is one example of an XY problem.
Your real problem (the "X problem") is Ractive syntax, specifically the {{ }}, is being treated as Twig by the parser. This can be solved by wrapping the Ractive template around a verbatim section to prevent Twig from treating that Ractive template like Twig.
The "Y problem" stems from your attempt to work around the "X problem". That is, IDE syntax highlighting when using custom delimiters.
Why the {{ }} syntax-highlighting on Ractive templates appear to work is because Twig has syntax that involves {{ }}. However, the highlighting knows nothing about Ractive at all. It just happens that both languages use {{ }} in a similar fashion that the syntax highlighter thinks it's Twig... and styles like Twig.
Also, most, if not all IDEs, only support single-language highlighting. Since your file is being treated as a Twig template, it gets Twig highlighting. Should multi-language syntax-highlighting be supported is determined by your IDEs vendor and there's nothing you can do about it (unless you make your own plugin of course).

I had the same question related to VueJS and Twig curly brackets.
The only solution I found is to autocomplete [[ construction with tab button so it appears as [[ _ ]].

Related

How to match a hexadecimal value in liquid templates with regex?

Desired result
Content editors can enter hexadecimal values in Shopify for a background-color. How can you check with Liquid template's control flow if a given input is a valid hexadecimal?
The regex that needs to be implemented:
^#(?:[0-9a-fA-F]{3}){1,2}$
The Liquid snippet where it should be added:
<div class="a-module" style="background-color: {{ bg_color }};">
...
</div>
The variable bg_color may only be a hexadecimal including the pound # character.
How can above be achieved with regex?
Other solutions?
If this is not possible what are other methods to match a string in liquid templates?
Research
I could not find much about regex in liquid templates.
There is this issue: Regex for matching a tag in a Liquid template : ">" inside html tag
But I do not understand how it is to be implemented.
There is no regex in Shopify liquid, so there is no way to check it that way.
A better approach will be to use one of the color filters.
You can do something like this:
{% assign is_color = bg_color | color_to_rgb %}
{% if is_color %}
It's color
{% endif %}
Where if the color is valid it will return a rgb output, but if it's not it will return a null result making the variable false.
If you really need to use regex, the only option is to rely on Javascript and handle it once the DOM is ready.
What about create your own filter. And in this filter checking hexadecimal.
/^#[0-9a-f]{3,6}$/igm
https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-filters

What is the Difference Between Double Curly `{{ }}` and Triple curly `{{{ }}}` in Mustache Template?

I am using Mustache Template in my HTML DOM to generate some Dynamic contents.
I am using {{ }} inside HTML tags for that..
Now i want generate non HTML dynamic extension, for that i have {{{ }}}
But i dont know the difference between both.
so, what is the difference between these 2?
See the manual
The most basic tag type is the variable. A {{name}} tag in a basic
template will try to find the name key in the current context. If
there is no name key, the parent contexts will be checked recursively.
If the top context is reached and the name key is still not found,
nothing will be rendered.
All variables are HTML escaped by default. If you want to return
unescaped HTML, use the triple mustache: {{{name}}}.

How can I display a string that contains HTML with quotes in twig template?

How can I display a string (variable imgStr) that contains HTML with quotes in twig template?
String is :
<img src="{{ asset( 'bundles/meeting/images/uploads/c986889a9912f69f6324d5c79c2d072119411384.png') }}" height="500" />
1) If i use raw filer <br> {{ imgStr|raw }} <br> i am getting empty square instead of image. I believe the reason is ''/"" quotes inside the string.
2) How to use function template_from_string? According official documentation, i must add the Twig_Extension_StringLoader extension explicitly when creating your Twig environment. But i do not understand how to make this in Symfony2. I also did not find this function in Vendor/twig/extensions .
You can try loading the template_from_string extension declaring it as a service. Here you have it in yml format:
myproject.load_template_from_string:
class: Twig_Extension_StringLoader
tags:
- { name: twig.extension }
This way the extension is loaded on the compiler pass and then you can use it like this:
{% set router = "<script src=\"{{ asset('bundles/fosjsrouting/js/router.js') }}\"></script>" %}
{{ include(template_from_string(router))}}
Note: I had to escape the variable because it's declared inline on the same template, but it should work without a hitch with variables passed to the template.

Twig escaping HTML and rendering as raw

I hope someone can assist me on this issue.
I am pulling details from a database to display on a twig template (using Symfony2) but the way in which it is saved in the db makes it difficult to interpret the HTML.
Basically, the HTML tags are already translated as entities in the table, e.g.:
<p>Bach Flower Crab Apple Remedy:&nbsp;the "cleansing" Remedy can be used both internally and externally&nbsp;</p><p><strong>
And so on. I have researched the rendering options in twig and tried the following (based on me rendering a loop of product descriptions):
{% set strategy = 'html' %}
{% autoescape 'html' %}
{{ product.description|escape('html')|raw }}
{% endautoescape %}
and also just:
{{ product.description|raw }}
The first method just echoes the existing content (as entities) and the second method just renders the HTML tags to the page as follows:
<p>Bach Flower Crab Apple Remedy: the "cleansing" Remedy can be used both internally and externally.</p><p><strong>...
So, as you can see, I cannot find a way to actually interpret the HTML tags in order to display the description as it should be.
Is there a way to do this? I can't do it in the PHP as all it's doing is sending an object to the template which is looped through:
public function showAction(Request $request, $store_id=0)
{
$max = 1000;
$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$products = $repository->getProductsByStoreId($store_id,$max);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$products,
$request->query->get('page', 1),
20
);
$return['products'] = $pagination;
$return['categories'] = $this->getCategories();
return $this->render('AppBundle:tables:productstable.html.twig', $return);
}
Your core issue is that you do not have HTML in your database to begin with. At best Twig could be outputting some HTML entities, which will render visibly as "<p>...", and at "worst" Twig will escape the text to render it accurately as it actually is, which is "<p>...". Expecting Twig to output actual HTML which will render a paragraph is unrealistic, since that's not what your original data contains at all.
You'll have to HTML-decode that text in PHP first, and then output it in Twig with ..|raw. raw means that Twig will output it as is without further escaping it. Since it's nonsense to get the data from the database to then html_entity_decode it, you need to fix your data input here! Don't HTML encode data which is going into the database, it serves no purpose.
I think you have to write custom escaper plugin to decode html entities and use it like this:
{{ product.description|myawesomehtmlentitiesdecoder|raw }}
http://twig.sensiolabs.org/doc/filters/escape.html#custom-escapers for reference.
But generally, it's better to store HTML in database and then apply needed security filters on output.

How to make handlebars keep indentation when replacing a multi-line value?

Consider this handlebars template:
<div>
{{content}}
</div>
And the following data:
{
content: 'foo\r\nbar'
}
And the desired result (what I need):
<div>
foo
bar
</div>
But when compiling the handlebars template with the data I get this:
<div>
foo
bar
</div>
So, how to make handlebars keep indentation when replacing a multi-line value?
Of course, changing the data is not an option.
From the compile reference:
preventIndent: By default an indented partial-call causes the output of the whole partial being indented by the same amount. This can lead to unexpected behavior when the partial writes pre-tags. Setting this option to true will disable the auto-indent feature.
So, it follows that if you're able to set up your template so that content is rendered by a partial, e.g.:
<div>
{{> ContentPartial}}
</div>
Then before it's rendered, register the ContentPartial partial:
Handlebars.registerPartial('ContentPartial', '{{content}}')
then it will preserve indentation. (I actually discovered this feature when the auto-indentation screwed up formatting in my <textarea> and I had to disable it).
It's not possible. Handlebars didn't know anything about the place where data will be embedded. You have line break in data and you get line break in result, there is no and nowhere to get a tab (4 spaces) after foo, have just one line break.
One of the ways to deal with your problem is to use such helper, that knows about the indentation and process passed argument proper way.
See quick example.
Helper:
Handlebars.registerHelper('indent', function (data, indent) {
var out = data.replace(/\n/g, '\n' + indent);
return new Handlebars.SafeString(out);
});
used as:
{{indent foo ' '}}
will produce you multiline output with specified indentation.
Adding to #tobias-j answer, the partial can be written inline with no need to register it on the code.
So, your template can be written as:
{{#*inline "inlineContent"}}
{{content}}
{{/inline}}
<div>
{{> inlineContent}}
</div>
You can see it working on the playground.