Silex and twig vars with punctation [duplicate] - twig

This question already has an answer here:
Accessing "dot" namespaced services in Twig view
(1 answer)
Closed 8 years ago.
I'm using Silex and Twig, and are having trouble printing some vars with punctations inside Twig:
$app['gateway.name'];
{{ app.gateway.name }}
If I had just a single punctation it would work fine, but not multiple.
Is this possible?

Yes, you can use square bracket notation in twig as well:
{{ app['gateway.name'] }}
See also: The template variables section of the twig docs.

Related

How to run an object's method in twig without rendering what it returns [duplicate]

I have seen the twig documentation about do tag, but I don't understand its use/useful.
The docs says the follow:
The do tag works exactly like the regular variable expression ({{ ...
}}) just that it doesn't print anything:
and show an example:
{% do 1 + 2 %}
What to solve exactly this tag ?
Good question! I found a link on GitHub to when this was proposed which might add some further info:
Sometimes you want to do things, or call some stuff, and ignore the output. For example if you use a |shift filter to remove some data from an array, doing {{ arr|shift }} will output the removed item, which is not always desirable.
Of course it's possible to do {% set null = arr|shift %}, which won't
output anything, but it also looks weird.
The example in the docs is poor as it explains nothing at all, as you pointed out.

Patternlab twig includes with params

I am using the node version of patternlab with twig as template engine. I am using twig because my codebase is written in twig - so using mustache it not an option.
I simple try to include an pattern:
<button type="button" class="btn {{ buttonClass }}">{{ cta }}</button>
in an other pattern with:
{% include "base-button" with {'buttonClass': 'btn-primary btn-xs'} %}
This does not work. The pattern is included but the variable buttonClass is not set.
Any Ideas?
This seems to be an issue with the twig integration in this repo https://github.com/pattern-lab/patternengine-node-twig.
There are other issues with twig core features described here: https://github.com/pattern-lab/patternlab-node/issues/554
I finally decided to switch to the php/twig edition and the same twig-patterns are working as expected. If anybody have to use the node edition, i recommend to use mustache.
I believe there are plans to pass the Twig rendering in Pattern Lab Node to PHP, however, this isn't ready yet, but using The Twig engine for Patternlab/Node you can pass a variable via an include. It doesn't work exactly the same as normal twig but it does work.
{% set buttonClass = 'btn-primary btn-xs' %}
{% include "components-button" with buttonClass %}
You can also pass multiple variables:
{% include "components-button" with buttonClass anotherVariable %}

what exactly is haswidgets and widgets in bolt (or twig rather )?

I was just going through the Default theme of bolt CMS, and i came actoss the following lines of code:
{% if haswidgets('aside_top') %}
{{ widgets('aside_top') }}
{% else %}
I googled twig haswidgets and also twig widgets , but i could't find anything.
can somebody explain what these two methods are ? and what exactly do they do ?
They are a feature of Bolt. Extensions can push content to specific places in the backend and also to some places in the frontend, as long as the theme supports that. They are called widgets. the haswidgets() and widgets() twig functions are for checking and displaying them.
You can find more info here https://docs.bolt.cm/3.1/templating/widgets and here https://docs.bolt.cm/3.1/extensions/intermediate/widgets

Wrap contextual html around a specific twig variable {{ product.name }}

I want to automatically wrap some html, lets say <span data-id=".."> when I call {{ product.name }} in my twig template.
So when in a twig template, I use {{ product.name }}, I want the output to be: <span data-type="product" data-id="8" data-prop="name">My product name</span>. I cannot use twig filters or macros, since I really need the template syntax to be {{ product.name }}, so the end-user (template designer), does not have to care about it.
The reason I need this is because I am building an on-page editting tool for twig templates, so I need to know the contexts of those variables from within HTML.
I have tried to override the Compiler that the Twig_Environment uses, but I cannot seem to alter the output of the twig variable node.
How can I do this?
EDIT
I wanted to mention that I need this to use the {{ product.name }} syntax, since other designers will work with those templates outside of Symfony 2. I want to make almost all twig variables editable in the front-end, so a solution with filters or macros can indeed work, but it kills the usability and readability of the platform I am writing. There is no public API currently in twig that can achieve what I want, that is why I am fiddling with the twig compiler. I do not have the required knowledge of the Twig internals to achieve this. If someone could point me into a direction that would be great!
UPDATE 2
I have found a place where I can achieve what I want. Every GetAttr node is compiled to $this->getAttribute($someContext, "property"). So if I can change the subclass of compiled twig template, I can achieve what I want. By default all twig templates extend from Twig_Template. I want to extend this method.
How can I change the subclass of all compiled twig templates?
UPDATE 3
I've found a way to use my own base class for all compiled twig templates. I can simply set it as an option on the twig environment, see this link. I hope to get it working tomorrow and I will post a proper answer on how I solved it all together. Not sure how I will handle escaping, since that will happen after the $this->getAttribute() is called.
I think macros are the best candidates for those kind of wrappings.
For example:
main.twig
{% import "macros.twig" as macros %}
{{ macros.display_product(product) }}
macros.twig
{% macro display_product(product) %}
<span data-id="{{ product.id }}" data-prop="name">{{ product.name }}</span>
{% endmacro %}
Context
product:
id: 8
name: My Georgeous Product
Result
<span data-id="8" data-prop="name">My Georgeous Product</span>
See fiddle
I've solved it by wrapping the PrintNode that is created when parsing a VAR_START token (inside the twig parser) with my own EditablePrintNode. In that node I traverse the expression that is compiled by the print node and get the necessary property path and pass that as an argument to a wrapper function around the default twig escape function that is compiled by the PrintNode.
I suggest to write a custom filter. You can find the doc here about how to write and configure in your environment
// an anonymous function
$filter = new Twig_SimpleFilter('my_custom_product_filter', function ($product) {
return '<span data-id="'.$product->getId().'" data-prop="name">'.$product->getName().'</span>';
});
You need to register as described in the doc
then you can use as follow:
{{ myProduct|my_custom_product_filter}}
Hope this help

Yii 2 registerJs in twig templates

In the Yii 2.0 guide it says you can register Javascript code in a twig template like this:
{registerJs key='show' position='POS_LOAD'}
$("span.show").replaceWith('<div class="show">');
{/registerJs}
Tried this but it will simply output the whole snippet {registerJs ... as text on the page without adding it to the page's Javascript Code.
Similar commands like registerJsFile or registerCss aren't working either.
Am I missing something? Thanks!
EDIT:
As Mihai P. noted below, {registerJs} is syntax for Smarty templates. So, the question is: is there a similar way to register inline JS in Twig templates? The documentation only mentions registering assets.
You can use this in your Twig template, which is the current view, to call registerJs.
{% set script %}
var app = new Vue({
el: '#vue-widget',
data: {
message: 'Hello Vue!'
}
})
{% endset %}
{{ this.registerJs(script,4,'vue-widget') }}
The question is 3 years old, I put it here for someone runs into a similar problem.
You can use this in the Twig template with View constant like below:
{{ this.registerJs('$("span.show").replaceWith(\'<div class="show">\');', constant('\\yii\\web\\View::POS_HEAD')) }}
And, you can also call registerJs inside the Yii2 controller, which I think it makes the code cleaner
$this->getView()->registerJs('$("span.show").replaceWith(\'<div class="show">\');', \yii\web\View::POS_HEAD);
Your example is copied from the smarty section not the twig. There are some examples in the twig section that you might want to try.

Resources