Django ignore TemplateSyntaxError. Vue Syntax - django

I'm building a pwa on top of django.
In the pwa.html I use valid vue syntax:
{{ counter() }}
or
{{ el| removehtml() | truncate(40) }}
Works flawless in a non Django project.
I get an TemplateSyntaxError on runserver, how can I ignore this, cause this is valid for vue syntax.

I found 2 solutions:
either in vue with delimiters:
el: '#app',
delimiters: ['[[', ']]'],
data: {
message: ...
}
...
than in template [[ vuefunc() ]] instead of default {{ vuefunct() }}
or with django verbatim
{% verbatim %}
{{ vuefunct() }}
{% endverbatim %}

Please note that Django does not use Jinja. It has its own template syntax, explained here in the documentation.
If you have any exposure to other text-based template languages, such
as Smarty or Jinja2, you should feel right at home with Django’s
templates.
The syntax may look like Jinja, but the functions could be different.

Related

{{ }} is not getting parsed by pyjade as expected with django

I have line of pyjade
a.js-track(data-track-data="{\"Job ID\":\"{{ job_details|get_or_na:'id' }}\",\"Job Title\":\"{{ job_details|get_or_na:'title' }}\",\"Company Name\":\"{{ job_details|get_or_na:'organization'|get_or_na:'name' }}\"}", data-track-dynamic-attrs="[\"Stakeholder\"]",href="{% url 'job_detail' job_details.title|slugify job_details.id %}")
which is being rendered as
<a href="/job/operations-manager/b1ac846e-6834-40c4-8bcf-122c093820b1/" data-track-data="{"Job ID":"{{ job_details|get_or_na:'id' }}","Job Title":"{{ job_details|get_or_na:'title' }}","Company Name":"{{ job_details|get_or_na:'organization'|get_or_na:'name' }}"}" data-track-dynamic-attrs="["Stakeholder"]" class="js-track">
I expect it to {{ }} being replaced by intended values rather than being rendered with html.
I am using 4.0.0 version of pyjade here as templating language.
Try to use #{value}
And for the conditions try to create a variable before the line so you can have more control
- var condition = inline_condition
p= condition

Using AngularJS template tags in Django [duplicate]

I want to use AngularJS with Django however they both use {{ }} as their template tags. Is there an easy way to change one of the two to use some other custom templating tag?
For Angular 1.0 you should use the $interpolateProvider apis to configure the interpolation symbols: http://docs.angularjs.org/api/ng.$interpolateProvider.
Something like this should do the trick:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Keep in mind two things:
mixing server-side and client-side templates is rarely a good idea and should be used with caution. The main issues are: maintainability (hard to read) and security (double interpolation could expose a new security vector - e.g. while escaping of serverside and clientside templating by themselves might be secure, their combination might not be).
if you start using third-party directives (components) that use {{ }} in their templates then your configuration will break them. (fix pending)
While there is nothing we can do about the first issue, except for warning people, we do need to address the second issue.
you can maybe try verbatim Django template tag
and use it like this :
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
{% verbatim %}
<div ng-app="">
<p>10 is {{ 5 + 5 }}</p>
</div>
{% endverbatim %}
If you did separate sections of page properly then you can easily use angularjs tags in "raw" tag scope.
In jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
In Django template (above 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
We created a very simple filter in Django 'ng' that makes it easy to mix the two:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
The ng filter looks like this:
from django import template
from django.utils import safestring
register = template.Library()
#register.filter(name='ng')
def Angularify(value):
return safestring.mark_safe('{{%s}}' % value)
So I got some great help in the Angular IRC channel today. It turns out you can change Angular's template tags very easily. The necessary snippets below should be included after your angular include (the given example appears on their mailing lists and would use (()) as the new template tags, substitute for your own):
angular.markup('(())', function(text, textNode, parentElement){
if (parentElement[0].nodeName.toLowerCase() == 'script') return;
text = text.replace(/\(\(/g,'{{').replace(/\)\)/g, '}}');
textNode.text(text);
return angular.markup('{{}}').call(this, text, textNode, parentElement);
});
angular.attrMarkup('(())', function(value, name, element){
value = value.replace(/\(\(/g,'{{').replace(/\)\)/, '}}');
element[0].setAttribute(name, value);
return angular.attrMarkup('{{}}').call(this, value, name, element);
});
Also, I was pointed to an upcoming enhancement that will expose startSymbol and endSymbol properties that can be set to whatever tags you desire.
I vote against using double parentheses (()) as template tag. It may work well as long as no function call is involved but when tried the following
ng:disabled=(($invalidWidgets.visible()))
with Firefox (10.0.2) on Mac I got a terribly long error instead of the intended logic. <[]> went well for me, at least up until now.
Edit 2012-03-29:
Please note that $invalidWidgets is deprecated. However I'd still use another wrapper than double braces. For any angular version higher than 0.10.7 (I guess) you could change the wrapper a lot easier in your app / module definition:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
API docs.
You could always use ng-bind instead of {{ }}
http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
I found the code below helpful. I found the code here: http://djangosnippets.org/snippets/2787/
"""
filename: angularjs.py
Usage:
{% ng Some.angular.scope.content %}
e.g.
{% load angularjs %}
<div ng-init="yourName = 'foobar'">
<p>{% ng yourName %}</p>
</div>
"""
from django import template
register = template.Library()
class AngularJS(template.Node):
def __init__(self, bits):
self.ng = bits
def render(self, ctx):
return "{{%s}}" % " ".join(self.ng[1:])
def do_angular(parser, token):
bits = token.split_contents()
return AngularJS(bits)
register.tag('ng', do_angular)
If you use django 1.5 and newer use:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
If you are stuck with django 1.2 on appengine extend the django syntax with the verbatim template command like this ...
from django import template
register = template.Library()
class VerbatimNode(template.Node):
def __init__(self, text):
self.text = text
def render(self, context):
return self.text
#register.tag
def verbatim(parser, token):
text = []
while 1:
token = parser.tokens.pop(0)
if token.contents == 'endverbatim':
break
if token.token_type == template.TOKEN_VAR:
text.append('{{')
elif token.token_type == template.TOKEN_BLOCK:
text.append('{%')
text.append(token.contents)
if token.token_type == template.TOKEN_VAR:
text.append('}}')
elif token.token_type == template.TOKEN_BLOCK:
text.append('%}')
return VerbatimNode(''.join(text))
In your file use:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Source:
http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
You can tell Django to output {{ and }}, as well as other reserved template strings by using the {% templatetag %} tag.
For instance, using {% templatetag openvariable %} would output {{.
I would stick with a solution that uses both django tags {{}} as well angularjs {{}} with a either a verbatim section or templatetag.
That is simply because you can change the way angularjs works (as mentioned) via the $interpolateProvider.startSymbol $interpolateProvider.endSymbol but if you start to use other angularjs components like the ui-bootstrap you will find that some of the templates are ALREADY built with standard angularjs tags {{ }}.
For example look at https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html.
If you do any server-side interpolation, the only correct way to do this is with <>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Anything else is an XSS vector.
This is because any Angular delimiters which are not escaped by Django can be entered by the user into the interpolated string; if someone sets their username as "{{evil_code}}", Angular will happily run it. If you use a character than Django escapes, however, this won't happen.

regex in Django urls.py

Help me please to fix urls.py
People suggested this way, but it does't work for me.....
#urls.py
(r'^/user/(?P<username>)/subject/([\w|\W]+)/$', subject),
#template
{% for subject in subjects %}
<li>{{ subject.name }} {{ del_form.delete }}</li>
{% endfor %}
#error
PAGE NOT FOUND
Request URL: http://127.0.0.1:8000/user/root/subject/Math%20140
....
....
^/user/(?P<username>)/subject/([\w|\W]+)/$
You have an error in your regular expression. You should use a regex builder if you are new to this:
http://ryanswanson.com/regexp/ (Perl)
http://www.pyregex.com/ (Python)
I think you want something like this:
^user/(?P<username>.+)/subject/([\w|\W]+)/
But you might want to change the '.+' to something more restrictive:
^user/(?P<username>[^/]+)/subject/([\w|\W]+)/
Note also that you probably don't want that leading slash - due to the way Django feeds the initial URL to the URL dispatcher.

Handlebars.js in Django templates

I need a javascript templating system and i think handlebars.js does an excellent job in this case.
I'm having syntax conflicts with handlebars templates inside a django template because django tries to render handlebars variables.
Is there a tag in django templates to stop rendering a block with curly braces?
Something like:
{{ django_context_varable }} #works
{{% raw %}}
<script id="restaurants-tpl" type="text/x-handlebars-template">
<ul>
{{#restaurants}} #not rendered by django, plain text
<li>{{name}}</li>
{{/restaurants}}
</ul>
</script>
{{% endraw %}}
Edit
Likely i found this. It works fine.
Update
Django 1.5 supports verbatim tag natively.
I use a custom template tag for another js templating system, here:
https://gist.github.com/629508
Use in template:
{% load mytags %}
{% verbatim %}
{{ This won't be touched by {% django's %} template system }}
{% endverbatim %}
Edit: This custom template tag is no longer necessary, as Django's template language now supports the {% verbatim %} template tag.
Is there a tag in django templates to stop rendering a block with curly braces?
OLD Answer for Django 1.0-1.4: No, though you could though you could put the block in a separate file and include it without rendering or use a different templating engine.
New Answer: The answer above was correct in August 2011 when the question was asked and answered. Starting in Django 1.5 (released Feb 2013, though alpha/beta versions in late 2012), they introduced the {% verbatim %} and {% endverbatim %} which will prevent the django template engine from processing the content in the block.
So for the question asked the following will work in django 1.5+ out of the box:
{{ django_context_varable }} #works
{% verbatim %}
<script id="restaurants-tpl" type="text/x-handlebars-template">
<ul>
{{#restaurants}} #not rendered by django, plain text
<li>{{name}}</li>
{{/restaurants}}
</ul>
</script>
{% endverbatim %}
The documentation on verbatim is here. Yes, this was noted by others earlier, but as this is the accepted answer I should list the easiest solution.
I wrote a very small django application : django-templatetag-handlebars exactly for that purpose.
{% load templatetag_handlebars %}
{% tplhandlebars "tpl-infos" %}
{{total}} {% trans "result(s)." %}
<p>{% trans "Min" %}: {{min}}</p>
<p>{% trans "Max" %}: {{max}}</p>
{% endtplhandlebars %}
Render your block as usual using Handlebars.js API :
var properties = {
total: 10,
min: 5,
max: 4
};
var template = Handlebars.compile($('#tpl-infos').html()),
rendered = template(properties);
I wrote it the day #chrisv published its package, with a KISS approach in mind. It is mainly based on Miguel Araujo's gist : https://gist.github.com/893408.
for a deeper integration between handlebars and Django (including optional on-the-fly precompilation) check out my project at
https://bitbucket.org/chrisv/django-handlebars/
It basically works like this:
create HB template under
appdirectory/hbtemplates/myapp/template.html
(just like Django template)
in your app, use
{% handlebars myapp %}
template tag and render template like so:
Handlebars.templates["myapp.template.html"]({context:"value"});
Compile your handlebars first!
From handlebars precompiling documentation:
In addition to reducing the download size, eliminating client-side compilation will significantly speed up boot time, as compilation is the most expensive part of Handlebars.
You can compile templates in your build environment using handlebars npm module, or integrate it with a build tool like gulp with gulp-handlebars.
After compiling, your handlebars templates can be served as static resources and bypass server side rendering altogether. Makes it easier on caching too :)
Typical usage would look like this:
<div id="restaurants-tpl">
Waiting for content...
</div>
<script src="{% static 'js/handlebars.runtime.js' %}"></script>
<script src="{% static 'js/templates.js' %}"></script>
<script>
// Let django render this as a json string
properties = {{ properties }};
// Use Handlebars compiled template imported above
rendered_html = Handlebars.templates["restaurants-tpl"](properties);
// Set element content
document.getElementById("restaurants-tpl").innerHTLM = rendered_html;
</script>
Django's templating system doesn't support escaping blocks at a time. It would be easy to work around were it not for the fact that when templates are processed the tokenizer doesn't keep exact information on what the tokens looked like before they got tokenized.
I have used the following work-around which is ugly, but (sort of) works. Use different tag delimiters in your templates and a django template tag that translates those back to what you actually want:
#register.tag(name="jstemplate")
def do_jstemplate(parser, token):
while self.tokens:
token = self.next_token()
if token.token_type == TOKEN_BLOCK and token.contents == endtag:
return
self.unclosed_block_tag([endtag])
nodelist = parser.parse( ('endjstemplate',) )
parser.delete_first_token()
s = token.split_contents()
tmpl_id = Variable( s[1] ) if (len(s) == 2 and s[1]) else ''
return JsTemplateNode( nodelist, tmpl_id )
class JsTemplateNode(template.Node):
def __init__(self, nodelist, tmpl_id=''):
self.tmpl_id = tmpl_id
self.nodelist = nodelist
def render(self, context):
content = self.nodelist.render(context)
return u'<script id="%s" type="text/x-handlebars-template">%s</script>' % (
self.tmpl_id.resolve(context),
re.sub( ur'{\$(.*?)\$}', u'{{\\1}}', content ), )
For bonus points you can leverage Django's templates within your templates ...
which will probably cook your brain trying to untangle later:
{% jstemplate "restaurants-tpl" %}
{$#restaurants$}
<div id="<$name$<" class="{$type$}">
<ul class="info">
{$#if info/price_range$}<li><em>{{ trans "Price Range" }}:</em> {$info/price_range$}</li>{$/if$}
{$#if info/awards$}<li><em>{{ trans "Awards" }}:</em> {$info/awards$}{$/if$}
</ul>
<div class="options">
<button>{% trans "Reservation" %}</button>
</div>
</div>
{$/restaurants$}
{% jstemplate %}
Actually I wrote a custom template filter which goes like this:
from django import template
register = template.Library()
def handlebars(value):
return '{{%s}}' % value
register.filter('handlebars', handlebars)
and use it in a template like so:
{{"this.is.a.handlebars.variable"|handlebars}}
It's the simplest thing I could think of. You just have to put your handlebars variable name in quotes. I regret I hadn't got this idea before I struggled with ssi. It works also with keywords:
{{"#each items"|handlebars}}
Why not use jinja2 instead? IMO, they're both elegant to use. Here's an excellent article about it: Using Jinja2 with Django

Django - use template tag and 'with'?

I have a custom template tag:
def uploads_for_user(user):
uploads = Uploads.objects.filter(uploaded_by=user, problem_upload=False)
num_uploads = uploads.count()
return num_uploads
and I'd like to do something like this, so I can pluralize properly:
{% with uploads_for_user leader as upload_count %}
{{ upload_count }} upload{{ upload_count|pluralize }}
{% endwith %}
However, uploads_for_user leader doesn't work in this context, because the 'with' tag expects a single value - Django returns:
TemplateSyntaxError at /upload/
u'with' expected format is 'value as name'
Any idea how I can get round this?
You could turn it into a filter:
{% with user|uploads_for as upload_count %}
While a filter would still work, the current answer to this question would be to use assignment tags, introduced in Django 1.4.
So the solution would be very similar to your original attempt:
{% uploads_for_user leader as upload_count %}
{{ upload_count }} upload{{ upload_count|pluralize }}
Update: As per the docs assignment tags are deprecated since Django 1.9 (simple_tag can now store results in a template variable and should be used instead)
In Django 1.9 django.template.Library.assignment_tag() is depricated:
simple_tag can now store results in a template variable and should be used instead.
So, now simple tag we can use like a:
It’s possible to store the tag results in a template variable rather
than directly outputting it. This is done by using the as argument
followed by the variable name. Doing so enables you to output the
content yourself where you see fit:
{% get_current_time "%Y-%m-%d %I:%M %p" as the_time %}
<p>The time is {{ the_time }}.</p>