Is there a way to insert a javascript variable into Bigcommerce Handlebars - handlebars.js

Using assignVar and getVar (Bigcommerce Handlebars helpers) I'm trying to create and insert a javascript variable like so:
<script>var exampleVar = "string";</script>
{{ assignVar "exampleVar" exampleVar}}
The result when using {{ getVar"exampleVar" }} is that it throws a "not a string error".
I tried {{ assignVar "exampleVar" "exampleVar"}} which outputs "exampleVar" (minus the quotes). I would like it to output "string" (minus the quotes).
Any thoughts?

You can't. Handlebars is already compiled in the server before it reaches the front end side. If the logic is done in javascript, then you should display the result via javascript too.

Related

Handle inside an interpolation

Im building a store in shopify and Im fairly new at this.
I want to interpolate a collection.handle inside an interpolation, like this:
style="color: {{ settings.tomas_{{collection.handle}} }} !important;"
this is in order to create a dry formula to modify the css for every collection. Ive created my page colors in settings with this pattern:
tomas_example_collection: "FFF",
tomas_second: "F1F1F1"
And they work if I hard code them, but I dont know how to interpolate inside an interpolation.
What would you recommend?
Thanks!!!
You can't pass liquid inside liquid.
You need to generate the target string outside before passing it.
In your case:
{%- assign target = 'tomas_' | append: collection.handle -%}
style="color: {{ settings[target] }} !important;"
We create a variable that will hold the string and pass it using square brackets to the settings object.

Translation of flash messages with parameters in Symfony 4

I have a problem with flash messages in Symfony 4 and translation.
Translation of simple flash messages is working fine:
$this->addFlash('success', 'flashmessage.project_deleted');
But now I want to add some parameters to the flash messages and I have no idea how to handle it. I tried a lot, but nothing is working. I want to show in the flash messages the title of projects after f.e. removing. For example:
$this->addFlash('success', sprintf('flashmessage.project_deleted: %s', $project->getTitle()));
But the translation is not recognized, because the parameter is replaces before translation happens (I think so). And it should also be possible to have parameters in the middle of a string and not only at the end or at the beginning and ideally more than one parameter.
I'm using this in my Controller which extends AbstractController.
Does anybody has a solution for this?
Usually you would pass in the parameters to the translation, so your code snippet should probably look your first example and then in twig you would have something like this:
{% for message in app.flashes('success') %}
<div class="alert alert-success">
{{ message|trans({ 'title': project.title }) }}
</div>
{% endfor %}
The translation then should contain the parameter that is replaced:
flashmessage:
project_created: 'The project "%title%" was created successfully.'
project_deleted: 'You successfully deleted the project "%title%".'
...
Obviously the downside is that you have to dynamically pass in the variables which does not make much sense for flash messages, as not all of them will require these parameters. Also, as you already mentioned, when you deleted the project you will probably not have it available anymore in the template.
Instead I would recommend translating the message before passing it into the flash bag:
$this->addFlash(
'success',
$this->translator->translate(
'flashmessage.project_deleted',
[
'title' => $project->getTitle(),
]
)
);
This will require that you pass in the translator to your controller. You could either create your own base controller similar to Symfony's AbstractController for this and create something like a $this->trans()-method to make it easier to translate things inside your controller. Also, you will still have to make sure that $project->getTitle() will still return a value, so you probably want to call this before you actually delete the entry or have the data in memory.
When you do it this way, then you should not translate the flash messages in the template itself because they are already translated. This will still work because when Symfony tries to translate the already translated message, e.g. You successfully deleted the project "foo". then it will not find a translation and just print the original text instead, but you will get warnings in your logs about missing translations. The solution is to remove the |trans in your template (see first snippet).
A possible solution is to add another flash with serialized parameters.
Then, when you display your flash message, check if that extra flash exists and, if so, deserialize it and use it as argument.
Example follows.
In controller:
$this->addFlash('success', 'flashmessage.project_deleted');
$this->addFlash('_params', serialize(['%project%' => $project->getTitle()]));
In template:
{% flashMessage = app.session.flashbag.get('info') %}
{% if app.session.flashbag.has('_params') %}
{% set flashParams = app.session.flashbag.get('_params')|first|unserialize %}
{{ flashMessage|trans(flashParams) }}
{% else %}
{{ flashMessage|trans }}
{% endif %}
You need to create a Twig extension that defines an unserialize filter (or use a library that provides it)
Since Symfony 5.2 you can use the TranslatableMessage object to achieve this.
https://symfony.com/doc/current/translation.html#translatable-objects
use Symfony\Component\Translation\TranslatableMessage;
$this->addFlash(
'success',
new TranslatableMessage(
'flashmessage.project_deleted',
['%project%' => $project->getTitle()]
)
);
Then in your Twig template you only need to use {{ flashMessage|trans }}.
This works without injecting the Translator service, or messing about with anything in Twig.
Have a look at the ICU Message Format: https://symfony.com/doc/current/translation/message_format.html

What is the purpose of "do" tag in twig

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.

Using Hugo, how can I access a variable from a partial file that is defined in base file?

I'm new to using Hugo and Go Templates. How can I access a variable from a partial file that is defined in base file using Hugo?
For eg: I have an index.html file which contains code that reads the data stored in the events.json file in the data directory and stores it in a variable. How can I access that variable from another file?
index.html
{{ $events := .Site.Data.events }}
{{ partial "people" . }}
people.html
// access the events variable from the index.html
{{ $events }}
I really hope this makes sense. I can try and clarify more if needed.
0.15 introduced a map that can be used for this.
index.html
{{ $events := .Site.Data.events }}
{{ partial "people" (dict "events" $events) }}
people.html
// access the events variable from the index.html
{{ .events }}
You could use the dict func:
{{ partial "people" (dict "page" . "events" $events) }}
You will then address them like {{ .page.someVar }} and {{ .events.someVar }} in the partial.
An alternative in your case could maybe, in the partial (as the previous poster said), address the .Site.Data.events directly from the partial.
According to Hugo documentation:
... partial calls receive two parameters.
The first is the name of the partial and determines the file location to be read.
The second is the variables to be passed down to the partial.
This means that the partial will only be able to access those variables. It is isolated and has no access to the outer scope.
This means, the events variable is outside of the scope of people.html. Your people.html cannot "see" it. One solution would be pass it down, like:
{{ partial "people" . $events }}
If it does not work, try different notation ($ vs. .).
If that does not work, you can always call your data file again, without variable, just like in the examples, that is, use {{ .Site.Data.events }} in your people.html partial.
Let me know in the comments how it goes, I'll try to improve my answer if necessary. I know it's a pain to get out of Hugo boundaries into Go territory :)

How do I include a variable in an "ifequal" handlebar?

I'm using Foundation for Sites which uses Panini and Handlebars for JS templating. I need an {{#ifequal}} statement that includes a js variable so that I can compare a URL parameter to a JSON
What I have right now:
{{#ifequal "Canada" this.destination}}
//do the thing
{{/ifequal}}
What I need is something like this:
{{#ifequal <script>document.write(destId)</script> this.destination}}
//do the thing
{{/ifequal}}
The js var "destId" is assigned earlier in the page when it's pulled out of the URL parameters, but of course I can't include the script inside the handlebars. If there's a way to pass a URL parameter directly into a handlebar that would also work.
as noted before on this question (link is here):
Handlebars partials take a second parameter which becomes the context for the partial:
{{> person this}}
In versions v2.0.0 alpha and later, you can also
pass a hash of named parameters:
{{> person headline='Headline'}}
You can see the tests for these
scenarios:
https://github.com/wycats/handlebars.js/blob/ce74c36118ffed1779889d97e6a2a1028ae61510/spec/qunit_spec.js#L456-L462
https://github.com/wycats/handlebars.js/blob/e290ec24f131f89ddf2c6aeb707a4884d41c3c6d/spec/partials.js#L26-L32

Resources