In Liquid, one can remove a character X from a liquid string like so,
{{ 'random_string' | remove:'X' }}
E.g. the { character can be removed in this way.
However, removing the } character this way gives the following error,
Liquid syntax error (line 15): Variable '{{ 'random_string' | remove:"}' was not properly terminated with regexp: /\}\}/
Which probably has to do with the usage of the } character in the Liquid language.
Question
How do I remove the } character from the string?
One solution would be using the url_encode filter, then removing the encoded string:
{% capture my_variable %}hello}}worl}d{% endcapture %}
{{ my_variable | url_encode | remove: "%7D"}}
First, create your own tag.
<project>/<app>/templatetags/clean_string.py
Insert this code into it.
import re
from django import template
register = template.Library()
#register.filter
def clean_string(value):
regex = '[^-_.,!?#%\w\d]+'
return re.sub(regex, '', value)
After that, register it in the settings...
<project>/<projectName>/settings.py
'OPTIONS': {
'context_processors': [
...
],
'libraries': {
'clean_string': '<project>.templatetags.clean_string'
}
},
At the beginning of your .html template Add tag loading
{% load clean_string %}
This filter can be applied to any string.
For example:
{{ '[tes{t}!'|clean_string }}
The filter can be adjusted in a variable ...
regex = '[^-_.,!?#%\w\d]+'
Output:
test!
Related
I'm trying to implement a custom Django tag that will formulate an import statement in Javascript to load my vue3 app as well as its components template html files using a get request in axios.
The custom tag in my templatetags directory looks like this:
templatetags/vuecomponents.py
from django import template
from django.templatetags.static import static
register = template.Library()
#register.simple_tag
def v_load_app_component(app_name, script_name, components):
components = components.strip("[]").split(", ")
app_script = static(f"js/{script_name}.js")
comps = [static(f"components/{name}.html") for name in components]
return f"import {{{ app_name }}} from \"{app_script}?{components[0]}={comps[0]}\""
Right now it only loads the first component as I just want a prototype. The only issue is when I drop this into a template like so:
createpost.html
<script type="module">
{% v_load_app_component "creator" "internalpostform" "[internalpostform]" %}
// OUTPUTS:
// import { creator } from "static/js/internalpostform.js?internalpostform=internalpostform.html"
creator.mount("#app")
</script>
It outputs the relevant import statement as:
import { creator } from "static/js/internalpostform.js?internalpostform=internalpostform.html"
With the double quotes escaped. Even when I tried to apply the safe filter ({% v_load_app_component "creator" "internalpostform" "[internalpostform]"|safe %}) it still escaped the output of my custom tag function.
How can I make it to where the output of my custom tag doesn't automatically have symbols converted to html entities?
I found it after a little digging in Django's documentation. The safe filter is only for variables i.e. {{ variable|safe }} but does not apply to a tag {% tag "argument"|safe %}.
To prevent Django from escaping the output of a tag you simply use {% autoescape off %}
{% autoescape off %}
{% v_load_app_component "creator" "internalpostform" "[internalpostform]" %}
{% endautoescape %}
This results in the desired behavior.
I want to pass constant as an attribute in the twig template.
Code looks like this:
{% if presenter.hasErrors(constant('Admin\App\ViewPresenters\EditorPresenter::FORM_ERRORS') )%} and it throwing error Message: Argument 1 passed to Admin\App\ViewPresenters::hasErrors() must be of the type string, null given, called in /vendor/twig/twig/src/Extension/CoreExtension.php on line 1527, as far as I understand twig did not recognize it's an constant. Is there any wat to pass constant in twig as an argument?
In twig a backslash is used to escape special characters e.g. {{ '\'' }} will output '. So to create a litteral backslash in twig you need to "escape" the backslash
{{ constant('Admin\\App\\ViewPresenters\\EditPresenter::FORM_ERRORS') }}
You can see the difference in the outputted source code twigfiddle:
{{ constant('Admin\App\ViewPresenters\EditPresenter::FORM_ERRORS') }}
PHP source
echo twig_escape_filter($this->env, twig_constant("AdminAppViewPresentersEditorPresenter::FORM_ERRORS"), "html", null, true);
{{ constant('Admin\\App\\ViewPresenters\\EditorPresenter::FORM_ERRORS') }}
PHP source
echo twig_escape_filter($this->env, twig_constant("Admin\\App\\ViewPresenters\\EditorPresenter::FORM_ERRORS"), "html", null, true);
demo
This question maybe kind of silly but I'm a newbie for symfony anyway.
prescenario I pass a variable from controller into index.html.twig by doing this
return $this->render('index/index.html.twig', [ 'department'=>$departments,'URILink'=>$URILink,'departmentDetail'=>$departmentDetails,'contentCell'=>$this->mContentCell ]);
After using {% dump %} it shows me
"department" => array:3 [▶]
"URILink" => "http://localhost/index/department/"
"departmentDetail" => array:1 [▶]
"contentCell" => "department.html.twig"
Then I need to reuse the variable contentCell as string in template to form syntax similar to this ;
<div>{{ include ('department.html.twig'),[departmentDetail:departmentDetail]</div>
For my first attempt I tried this,
<div> {{ include ({{ContentCell}}),[departmentDetail:departmentDetail]}} </div>
Unfortunately it showed me this error
A hash key must be a quoted string, a number, a name, or an expression
enclosed in parentheses (unexpected token "punctuation" of value "{".
Any idea how could I use the variable
contentCell as string value appropriately?
try this:
{% include contentCell with { departmentDetail : departmentDetail} %}
Answer here pass data to twig
You can include a template like this per:
{{ include('YourBundle:ControllerName:yourAction.html.twig', {'variableName': yourData}) }}
Or like this per http://twig.sensiolabs.org/doc/tags/include.html
{% include 'template.html' with {'foo': 'bar'} %}
after try'n try at last I found the the trick how to do it
i take similar analogy for
{{dump(var)}}
so attempt to do this
{{include (contentCell,{'departmentDetail' : departmentDetail}) }}
and it work like charm :) nice
I have a series of templates which target the Twig variable {{ file }}, which currently outputs the file's src e.g. "/path/to/file.jpg".
I want to update the contents of file to an array so that it stores multiple properties e.g. {{ file.src }} {{ file.size }}.
If I make this change then all uses of {{ file }} will output Array.
Is it possible to set Twig so that it will instead target the first property of the array? In this case {{ file.src }}.
Many thanks!
You can't if your variable is a pure array, but you can do it with objects.
If you want your object to be usable like an array, you need to extend ArrayObject in your class.
You can implement the magic method __toString to make your object printable as a string (in your case, $this['src']).
Let's have an example.
1) Create the following class :
class File extends \ArrayObject
{
public function __toString()
{
if (isset($this['src']))
{
return $this['src'];
}
}
}
2) In a controller, initialize your object.
$file = new File();
$file['src'] = 'my_file.png';
$file['size'] = 42;
3) In your twig file, try it :
{{ file }}<br/>
{{ file.src }}<br/>
{{ file.size }}<br/>
4) Enjoy
I have this route:
_view_tag:
pattern: /topic/{tid}
defaults: {_controller: "MyCoreBundle:ViewTag:index" }
And I want to show url like this: example.com/topic/Web+development. I use href="topic/{{ topicname|url_encode() }}". It is works, but of course it is not proper way, so I change to href="{{ path('_view_tag', {'tid': topicname|url_encode() } ) }}". But it is not showing example.com/topic/Web+development, it shows example.com/topic/Web%2Bdevelopment.
I also try this:
{% set _tid = topicname|url_encode() %}
<a href="{{ path('_view_tag', {'tid': _tid } ) }}" ...
But still not working
My question is, how to make it show example.com/topic/Web+development using twig path function?
The path function takes care of url-encoding for you. Your problem is that your space got encoded twice: first to a +, then that got converted to %2b. This will work:
path('_view_tag', { 'tid': topicname } )