Strip javascript code before rendering in django templates - javascript

{% if posts %}
{% for p in posts %}
{{p|safe}}
{% endfor %}
{% endif %}
I want this to render html but not javascript, what should I do?

There is no filter in django that can do what ou want: strip javascript and leave html.
You can create a custom template filter to do that:
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
import re
register = template.Library()
#register.filter
#stringfilter
def stripjs(value):
stripped = re.sub(r'<script(?:\s[^>]*)?(>(?:.(?!/script>))*</script>|/>)', \
'', force_unicode(value), flags=re.S)
return mark_safe(stripped)
(Where to put template filters/tags: Custom template tags and filters/Code layout)
Brief explanation:
Create a folder named templatetags in your application folder. Add an empty file __init__.py (for it to be a package) and a module file that will contain the filter, my_filters.py. Copy the code in that file.
In the template file add (before any first use of the filter): {% load my_filters %}
Usage:
{% if posts %}
{% for p in posts %}
{{ p|stripjs }}
{% endfor %}
{% endif %}

Related

Print Django model data as JavaScript Array

I have printed a for loop as below in my HTML Template:
<td>
{% for athlete in booking.athlete.all %}
{{athletes.id}}
{% endfor %}
</td>
The Output in HTML is as below.
<td>
1
2
3
</td>
Is it possible to get the output to appear as [ "1", "2", "3" ], so we can then use this as a JS array or object?
I have tried a few things from the Django Template but it does not remove the additional white space.
The easiest way is probably to use a custom template tag to get the list of athlete.ids, and then the built-in json_script filter to render those ids as json.
Let's assume your app name is myapp. If you don't have any custom filters yet, create the directory myapp/templatetags/, and add an empty __init__.py file. Then in the file myapp/templatetags/myapp_filters.py add:
from django import template
register = template.Library()
#register.filter
def qs_to_id_list(qs):
return list(qs.values_list('id', flat=True))
In your template example, you would do:
{% load myapp_filters %}
{% for booking in bookings %}
<tr>
<td>{{booking.id}}</td>
<td>{{booking.program_type}}</td>
<td>{{booking.booking_time}}</td>
{# set a unique script id for easier access in javascript #}
{% with script_id='athletes-data-'|add:booking.id %}
{{booking.athlete.all|qs_to_id_list|json_script:script_id}}
{% endwith %}
</tr>
{% endfor %}
The json_script filter will render a block like this (in each table row):
<script id="athletes-data-5" type="application/json">[1, 2, 3]</script>
which can be accessed in your client-side javascript.

Webpack Encore not loading JavaScript in base template

I am using a Webpack Encore in my Symfony 4 project, and when including the Twig helper for JavaScript in my base.html.twig:
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
The JavaScript doesn't load, however, when including the exact same Twig helper in one of my templates (index.html.twig), the JavaScript loads in.
So my question is, why does the above Twig helper work in one of my templates, but not in my base template?
What preciel said is true, using a block inside a template that extends another template will overwrite the default code inside that said block.
However there is another solution than just moving the code outside the block in the base template and that's calling the parent() function
main.twig
{% extends 'base.twig' %}
{% block foo %}
{{ parent() }}
Bar
{% endblock %}
base.twig
{% block foo %}
Foo
{% endblock %}
output
Foo
Bar
demo
It's failing because it's inside your javascript block.
Your template extends base.html.twig, so whatever you place within your javascript block in any template will be inside the javascript block.
But if you do the same within base.html.twig it will just be ignored.
Just move {{ encore_entry_script_tags('app') }} out of your javascript block.
base.html.twig
{{ encore_entry_script_tags('app') }}
{% block javascripts %}
{# nothing here, your templates will overwrite it when you extends base.html.twig #}
{% endblock %}
Remember this: If it's inside your layout, which is base.html.twig, then don't place anything inside the {% block %} tags. It will just be ignored.

How to access Django crispy tag array within JavaScript?

I am working on a Django project. Within one of my apps I want to pass an array of numerical data from my views file to a template. I then want to have access to said data so that I am able to manipulate it within JavaScript.
I can successfully send the array to the template as a crispy tag via the render function. Unfortunately, I can only access said tag within the HTML itself but not within JavaScript.
views.py:
from django.shortcuts import render
sample_data = [1,2,3]
def home(request):
data = {
'message': sample_data
}
return render(request, 'blog/home.html', data)
home.html:
{% extends "blog/base.html" %}
{% block content %}
<body>
{{ message|safe }} <!-- can access crispy tag within HTML-->
<script>
var x = {{ message|safe }}; // can not access crispytag within javascript
</script>
</body>
{% endblock content %}
I want to be able access the crispy tag array within the templates' JavaScript. What do I need to change to be able to do this ?
I think you need add quotes to access django template tags in javascript
{% extends "blog/base.html" %}
{% block content %}
<body>
{{ message|safe }} <!-- can access crispy tag within HTML-->
<script>
var x = "{{ message|safe }}" // can not access crispytag within javascript
</script>
</body>
{% endblock content %}
hope it helps

How to cut twig correctly

I apologize if the question was raised somewhere, and I did not notice the decision.
I have the following files:
base.html.twig - which includes css и js.
blocks.html.twig - which includes blocks.
en.html.twig
sp.html.twig
ru.html.twig
blocks.html.twig
<h1>hello</h1>
<h2>holla</h2>
<h3>привет</h3>
Please tell me how to initialize the object (for example blocksLang and each h* block to place in this object), for including in different places. For example:
in en.html.twig
{% extends "base.html.twig" %}
{% include "blocks.html.twig" blocksLang.en %} //and it should render <h1>hello</h1>
in sp.html.twig
{% extends "base.html.twig" %}
{% include "blocks.html.twig" blocksLang.sp %} //and it should render <h2>holla</h2>
in ru.html.twig
{% extends "base.html.twig" %}
{% include "blocks.html.twig" blocksLang.ru %} //and it should render <h3>привет</h3>
Thank you for attention

Pass javascript code to base template in Twig using Symfony and Fragments

I am using Symfony and Twig and the fragment sub-framework more specifically the Internal sub-requests.
In any case when I request a template using a fragment include
{% render url('route_name') %}
and my fragment code looks like this for example
<div>[code here...]</div>
<script>[javascript here...]</script>
how can I get this javascript to load into a {% block %} in my base.html.twig file? If I extend my fragment and put {% extends '::base.html.twig' %} in the header it will include the entire layout of my site. I just want to be able to push the javascript from from fragment out to my base template.
In my base template I have a {% block %} such as this
{% block javascript_footer %}
[it inherits javascript from child templates...]
{% endblock %}
Thanks!
separate your javascript into another file and than include it into your base template and also into your fragment.
base template:
{% block javascript_footer %}
{% include '::javascript.html.twig' %}
{% endblock %}
your fragment:
<script>{% include '::javascript.html.twig' %}</script>
assuming that javascript.html.twig doesnt include <script> tag already

Categories

Resources