twig and quote character - symfony

in a twig template I want to insert javascript text like this :
<script type="text/javascript">
{{ "var applicationBundleName = '" ~ application_bundle_name ~ "';" | raw}}
</script>
When the html is rendered, I have this :
<script type="text/javascript">
var applicationBundleName = 'MyBundle_name';
</script>
While rendering the quotes are replaces by their html entities => javascript error
How can I say not to remplace special characters by their codes ? or maybe there is a nicer way to do that..
Thank you

You have to quote only the twig variable:
<script type="text/javascript">
var applicationBundleName = "{{ application_bundle_name|raw }}";
</script>
I'm not sure but I think that if the variable is a string you don't need to use de raw filter

Related

Unable to render value of a root-level variable inside of script setup with Vue3

Maybe codesandbox.io does not support <script setup>, or maybe I'm misunderstanding how to render a simple variable value. What renders is msg is instead of msg is hello world. What am I missing?
Live example: https://codesandbox.io/s/winter-surf-f79ohv?file=/src/components/HelloW.vue
Here is my HelloW.vue component:
<template>msg is {{ msg }}</template>
<script setup>
const msg = "hello world";
</script>

Stop GTM encoding '==' in string constant

When I inject this example GTM tag on a site the '==' in the src string is encoded as \x3d\x3d which fails to resolve. Is there a way to stop the encoding?
GTM tag:
<script type="text/javascript"> !function(o,t){var src="https://test#testsite.com/test/1MmE5ZDA4ZGExODZkOTQifQ==/assets/demo.js";
...
</script>
on page:
<script type="text/javascript"> !function(o,t){var src="https://test#testsite.com/test/1MmE5ZDA4ZGExODZkOTQifQ\x3d\x3d/assets/demo.js";
...
</script>
I had a similar issue trying to insert an src into an iframe. I was populating the query string with GTM variables that contained "=" but they would get encoded as %3D.
My solution was injecting the HTML tag on the page using Javascript instead.
OLD WAY (HTML)
<iframe height="1" width="1" frameborder="0" scrolling="no" src="https://www.something.com/?containerTagId={{containerID}}"></iframe>
NEW WAY (JAVASCRIPT)
<script>
var script = document.createElement('iframe');
script.height="1";
script.width="1";
script.frameborder="0";
script.scrolling="no";
script.name="conversion";
script.src = 'https://www.something.com/?containerTagId={{containerID}}';
document.body.appendChild(script);
</script>

jsView - How to render the content of a custom tag with its props as its data?

I have custom tag which can have itself as an inner tag and I want to bind it its props as data. I can change the first test tag title property and see the change but cannot do that for the inner test tag. I think it is because of the wrong arguments of this.tagCtx.content.render(). Below is the example:
<!DOCTYPE html>
<html>
<head>
<script src="js/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="js/jsrender.js" type="text/javascript"></script>
<script src="js/jquery.observable.js" type="text/javascript"></script>
<script src="js/jquery.views.js" type="text/javascript"></script>
<script id="testTemplate" type="text/x-jsrender">
<div>{^{>title}}{^{:content}}</div>
</script>
<script id="myTemplate" type="text/x-jsrender">
{^{test title='Test1'}}
{^{test title='Test2'}}
{{/test}}
{{/test}}
</script>
<script type="text/javascript">
$.views.tags({
test: {
render: function(){
this.tagCtx.props.content = this.tagCtx.content.render();
return this.template.render(this.tagCtx.props, this.tagCtx, this.tagCtx.view);
},
template: "#testTemplate"
}
});
$.templates({myTemplate: "#myTemplate"});
$(function () {
$.link.myTemplate('#container', {});
$('#editTitle').click(function () {
$.observable($.view('#container div:first div').data).setProperty('title', prompt());
});
});
</script>
</head>
<body>
<span id="editTitle">EditTitle</span>
<div id="container"></div>
</body>
</html>
The problem here is that the inner tag is being rendered as a string, not as a data-linked tag, since the this.tagCtx.content.render() call is simply calling the render method on the compiled template corresponding to the block content.
If you want to render as a data-linked tag, you need to call this.tagCtx.render().
In addition, in calling this.tagCtx.render() you need the tag to render its content, and not another template. Setting template: "#testTemplate" will cause the tag to use that template instead of the content. So what you need is something along these lines:
var template = $.templates("#testTemplate");
$.views.tags({
test: {
render: function() {
var tagCtx = this.tagCtx;
tagCtx.props.content = tagCtx.render();
return template.render(tagCtx.props, undefined, tagCtx.view);
}
}
});
You probably don't want to pass in tagCtx as context in the template.render(...) call. You can pass in tagCtx.ctx, or simply undefined...

How to compile an external handlebars template without using $.ajax

I have 2 files in a very simple web application
The first is a standard index.html and it looks something like the below
<body>
<div id="add-stuff"></div>
<script id="the-template" type="text/x-handlebars-template" src="some-template.erb.html"></script>
<script type="text/javascript">
var data = [];
var source = $("#the-template").html();
var template = Handlebars.compile(source);
$('#add-stuff').html(template(data));
</script>
</body>
The second is my handlebars template "some-template.erb.html" and it looks something like the below
<table>
{{#each item}}
<tr><td>{{ item.name }}</td></tr>
{{/each}
</table>
The problem with the inline javascript I have above is that when I try the ".html()" part it always returns an empty string (as I'm linking in the erb.html file).
I've found a work around that lets me achieve this if I use $.ajax to pull in the template but I'd much prefer something like the above (so I can include the template client side w/out any nested jQuery callbacks).
Is this possible? If not what can I do do improve the $.ajax based approach?
** the ajax based approach that works is shown below **
<body>
<div id="add-stuff"></div>
<script type="text/javascript">
$.ajax({
url: 'some-template.erb.html',
cache: true,
success: function (source) {
var data = [];
var template = Handlebars.compile(source);
$('#add-stuff').html(template(data));
}
});
</script>
</body>
Here is a link to the stackoverflow question that showed the $.ajax version in a bit more detail
maybe its already outdated, but I found your question today and I have a suggestion for you or people who are dealing with the same problem. It's not a perfect one, but for small templates an option if you don't want to use ajax.
What do you think about writing the template as string in a variable in an external JS-file and inlcude it via script tag?
template.js
var source = '<table>\
{{#each item}}\
<tr><td>{{ item.name }}</td></tr>\
{{/each}';
index.html
<body>
<div id="add-stuff"></div>
<script src="template.js"></script>
<script type="text/javascript">
var data = [];
var template = Handlebars.compile(source);
$('#add-stuff').html(template(data));
</script>
</body>

FosJsRoutingBundle with '_locale'

For example, i have a script like this:
Routing.generate('_moderation_profile_confirm',{'id':objectId,'_locale':'en'})
is correct, but when i remove the '_locale' parameter, it send me error like '_locale' must be set.
my route name _moderation_profile_confirm contains a '_locale' prefix but how can i send the 'current' locale for the routing manager?
I supouse you are in twig template:
You can use this shorthand and get current locale:
Routing.generate('_moderation_profile_confirm',{'id':objectId,'_locale':'{{ app.session.locale }} '})
I copy here the response I proposed here
https://stackoverflow.com/a/35223108/279326
To set the request locale to all your call to Routing.generate, you can override this method and add the {{app.request.locale}} param in every call. The following script has to be executed in a twig template and after including routing script.
<!-- Include JSRouting libs & exposed routes -->
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', {"callback": "fos.Router.setData"}) }}"></script>
<script>
$(function () {
// change name of initial method
Routing.generateImpl = Routing.generate;
// override generate fonction by adding a default _locale from request locale
Routing.generate = function (url, params) {
var paramsExt = {};
if (params) {
paramsExt = params;
}
if (!paramsExt._locale){
paramsExt._locale = '{{ app.request.locale }}';
}
return Routing.generateImpl(url, paramsExt);
}
})
</script>
Now you can use Routing.generate transparently without worry about the _locale param !
// in any JS file
var url = Routing.generate('mypath');
var url2 = Routing.generate('another path', {param: 1});
To clarify the code, it could be possible to isolate the previous script in a js file. For that a global variable has to be defined.
<!-- for exemple in the <head> of the page -->
<script>
var REQUEST_LOCALE = '{{ app.request.locale }}';
</script>
And so in the script you can use REQUEST_LOCALE
// this line
paramsExt._locale = '{{ app.request.locale }}';
// has to be replaced by
paramsExt._locale = REQUEST_LOCALE;

Resources