How to extend the html Twig escaper? - symfony

I'm progressively migrating an existing Symfony application to VueJS.
The issue I recently discovered is the {{ stuff }} markup are always interpreted by VueJS, even if the content come from a rendered twig variable.
To avoid this, I would like to extends the html escaper to replace { and } by the respective { and } html codes.
How can I do that properly? The escaping is inside a twig_escape_filter without a service I can override.
I also tried to make a custom escape strategy guesser, returning my vue escaping, itself calling the twig_escape_filter with html escaping before replacing the needed characters. All my source code was escaped. :-D
Thanks for the help.

In fact you could solve this problem in your javascript as simple as that:
import Vue from 'vue';
Vue.options.delimiters = ['${', '}'];
Now you can use double brackets ({{ }}) for twig like you did before and ${ } for VueJs.
EDIT: What you want to do is impossible. You can indeed convert {{ }} to its corresponding html entities using a simple filter like this:
new \Twig_Filter('yourFilter', function ($string) {
return htmlentities($string, ENT_HTML5);
}, ['is_safe' => ['html']])
but since Vue runs on top of your rendered html, the conflict you present will still occur (because html will render these html entities as brackets).
Your only solution is to use a more specific delimeter for your Vue like this one, to avoid this conflict:
Vue.options.delimiters = ['$vue{', '}'];

Related

Conditional handlebars with plop and react

I am working on a template for a react component with plop.js and I am using conditional handlebars to render some content conditional upon an argument passed along with the command used to generate the content. Here is the conditional content of the template:
{{#ifCond "withStyles"}}import * as styles from "./{{pascalCase name}}.styles";{{/ifCond}}
When I use the line above, it returns "cannot read properties of undefined (reading "replace") which might be due to using {{pascalCase name}} inside the {{ifCond}} so how can we achieve the same thing in a correct way as it seems wrong.
Thanks in advance.

How to get current year in a Nunjucks template within Apostrophe CMS

I am in the process of adding a copyright line to the footer of a website that I have been working on and I cannot find the best way to get the current dynamically into the footer so I never have to set it again. I have tried multiple things, including a global setting that can be accessed from anywhere, but nothing has worked.
Any feedback would be appreciated. Thanks.
Write an ApostropheCMS nunjucks helper function. See those docs for the general issues around this. Your specific function could look like:
self.addHelpers({
thisYear: function() {
return new Date().getFullYear();
}
});
If you put that in construct of a module of your own, let's say it's called helpers, then you can call it in Nunjucks as {{ apos.helpers.thisYear() }}.
These are very handy, just remember they cannot do any async work.

WordPress template using React. Incorrect chars

I am creating a WordPress template, using React. I have a WP Post that looks perfect in DB. To retrieve data from the server I use Axios, using the new API feature included in WordPress.
This is how the title looks in the DB:
Hello world! I'm leaving
This is the code I use to retrieve the title from DB:
axios.get('/paintings-project/wp-json/wp/v2/posts').then(
function(response){
self.setState({posts: response.data})
}
);
This is how the post title looks when rendered:
Hello world! I’m leaving
The char ' is escaped, and the backslash used for escaping is encoded.
On the other hand, when rendering HTML content from the post, the HTML appears as a string, instead of rendered as HTML. Like this:
<h1>Welcome’ to WordPress’.</h1> <p><strong>This is your first
post. Edit or delete it, then start writing!</strong></p> <p> </p>
I expected the WordPress APIs would work straight without need of special encoding / decoding in BE or FE. Am I doing something wrong?
Thanks
React doesn't allow you to render strings as HTML in that way. You're going to have to use the dangerouslySetInnerHTML attribute (docs) to render your HTML string in your component.
Something like:
renderStr() {
return {__html: this.state.dataToRender};
},
render() {
return <div dangerouslySetInnerHTML={renderStr()} />;
}
Bear in mind, as the attribute name suggests, you'll want to make sure that the HTML you're rendering is safe. If it's coming from user input, make sure to sanitize the input before storing/rendering it or you can expose yourself and others to security risks. You can use an NPM dependency like sanitizer or sanitize-html, or you can write a function to do it yourself.

HTML tags (i.e <p>) inside my angular brackets {{}}

I'm working in an angular app where the JSON documents i'm getting includes several object. But while fetching the posts contents it also includes the HTML tags (i.e <p>) inside my angular brackets {{}} the problem here is i want only the contents not the HTML tags. Either give me a solution to get rid of that or tell me how to use html tags inside {{<p> hello <p>}} . I want to get an output of angular to show the paragraphed "hello" instead of <p>hello<p>.
Give me a solution to ge an output as hello instead of <p>hello<p>
thanks in advance!
Thanks for the response!
I Used the angular binding ng-bind. That working fine for me. I've used
<p ng-bind-html="post.name"></p> . Now the problems solved :)
I'm not sure if there is a 'best practice' solution for this, I don't think angular is currently handling this. Try using a function that strips the html tags like this:
{{stripInput(inputObject)}}
stripInput(html) {
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
credit to this post. Some other good answers are there if this doesn't work :)

including existing dom-element with handlebars

Is there a way to include an existing dom-element through Handlebars, while being able to keep a reference to said dom-element?
to explain:
I have a jquery-element $el of which I want to include the dom-element ($el[0]) in a handlebars template.
I have some jquery code that uses $el.html("new stuff") after handlebars has included the template (again: this template contains $el[0]
The usual solution would be to rewrite the code by providing a selector so jquery can access the element. However, the code that needs to change $el doesn't know where in the template $el[0] will be used, since this is configurable. Having to specify the selector by config is possible obviously but this doesn't really feel dry to me.
So, any way to do this?
I implemented this with a handlebars helper that injects a unique id and post-render keeps a ref from uniqueid -> element to bind.
On postrender I simply find the elements with the unique-ids and update each element to it's mapped el to bind.

Resources