Using Django's urlize with CommonMark - python

I'd like to use Django's urlize function together with django-markwhat's CommonMark filter.
I'm imagining something like this:
{{ "http://example.com"|urlize|commonmark }}
Which outputs <p>http://example.com</p>. The issue here is that URLs already marked up in commonmark, like <http://example.com>, will get rendered with angled brackets around them.
If I apply urlize after commonmark, like this:
{{ "http://example.com"|commonmark|urlize }}
The urlize function doesn't detect the url in <p>http://example.com</p> (and it's mentioned in the urlize docs that it won't work as expected for html input).
I haven't come up with a solution yet, so let me know if you have any ideas.

For completeness, the easy answer is to switch to a Markdown parser which provides the behavior you want out of the box. Multiple extensions exist which give Python-Markdown the desired behavior.
However, if you want this behavior with CommonMark, which does not support this behavior itself, then you will need to create a custom urlize filter which operates on HTML. Fortunately, The Bleach library provides a linkify function which will handle that correctly.
Of course, you then need to create a template filter which wraps that:
from django import template
import bleach
from html5lib.tokenizer import HTMLTokenizer
register = template.Library()
#register.filter(is_safe=True)
def linkify(value):
return bleach.linkify(value, skip_pre=True, parse_email=True, tokenizer=HTMLTokenizer)
Note that I'm assuming you do want to parse email addresses as well as URLS, you do not want to have URLs in code blocks parsed, and you do not want CommonMark's output sanitized. Feel free to review Bleach's docs and adjust accordingly.
To use your custom filter, save the above code to a file named linkify.py within a templatetags directory in your app (see the Django docs for a full explanation). Then within a template, do the following:
{% load linkify %}
{{ "http://example.com"|commonmark|linkify }}

Related

Creating objects/functions within Jinja to better re-use code

I'm currently working on a practice blog site to learn more about web development and I am using Flask.
On my site, people can create blog posts and view the posts of others. Obviously, I want to make my code as re-usable as possible. So right now, depending on the page, I am grabbing some number of blog posts in my routes.py, and then passing them into a number of different pages (e.g. home page, profile page, search page).
Each of these pages has its own template since they all look different. However, the code for displaying the blog posts is the same in all of the sites, even though the blog posts themselves may differ. Is there any way in Jinja to create an object or function (e.g. render_as_blog_posts()) to which I could pass in the blog posts to and run in the template? For example:
routes.py
def profile():
blog_posts=profile_blog_posts
return render_template("profile.html",posts=blog_posts)
def search():
blog_posts=search_blog_posts
return render_template("search.html",posts=blog_posts)
profile.html:
<html>
<title>Profile</title>
{{ render_as_blog_posts(blog_posts) }}
</html>
search.html:
<html>
<title>Search</title>
{{ render_as_blog_posts(blog_posts) }}
</html>
I suppose, you're looking for the 'template inheritance' feature of Jinja2: https://jinja.palletsprojects.com/en/2.10.x/templates/#template-inheritance
Basically, you can achieve what you want in the different ways:
Template extension: https://jinja.palletsprojects.com/en/2.10.x/templates/#base-template
In this case you can define base template with common layout, common set of macroses and define special blocks in this template as a points of customization. Then, you can extend this template and fill blocks in the way specific for derived template (see samples by the provided link)
Templates import: https://jinja.palletsprojects.com/en/2.10.x/templates/#import
More specific feature which looks like exactly the same python's one. You can define special template which contains set of macros and then import this template into yours profile.html or search.html:
{% import 'commmon_functions.html' as common %}
Then you can refer functions from this file as a part of common namespace:
{{ common.render_as_blog_posts(blog_posts) }}

How do I find where a django template variable comes from in the python

Is there a good general way of finding the line of python code responsible for passing in variables to django templates? When newly picking up a large code base, and I see {{ x.y }} in the template, and nothing obviously related (by how things are named) to x in the {% load ... %}, what do I do? Where can I find this variable in the python so that I can change it or related code?
My current solutions tend to be tedious and overwhelming. It's a lot of searching, but I would like to be able to just know where to look.
Look at the URL of the page. Then go to urls.py and look at which view is linked to the URL. Then open views.py and search for the view which the URL linked to.
In that view, the variable 'x' should be there. If it's not, then check the template context processors and middlewares as karthikr suggested.

Django template filters, tags, simple_tags, and inclusion_tags

This is more of a general question about the distinctions between these four different kinds of django tags. I just read the documentation page on template tags:
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
But I'm finding it difficult to know when I should use one variation over another. For example, what can a template tag do that a simple_tag cannot? Is a filter limited to manipulating strings only and is that why the documentation says that template tags are more powerful because they can "do anything"?
Here is my perception of the distinctions:
template filters: only operate on strings and return strings. No access to models?
template tags: access to anything you can access in a view, compiled into nodes with a specified render function (it seems like the only advantage is that you can add variables to the context?)
simple_tags: take strings and template variables and returns a string, you are passed the value of the template variable rather than the variable itself (when would you ever want the variable itself over the value?)
inclusion tags: allow you to render arbitrary extra templates
Can someone give an example outlining when I would want to use one of these over another?
Thanks.
Template filters can operate on any object (and at most two at once). They're just functions that take one or two arguments. e.g.
# filter implementation
#filter
def myfilter(arg1, arg2):
....
# usage in template
{{ arg1|myfilter:arg2 }}
They are limited in that they cannot access the template context, and can only accept a limited number of arguments.
Use case: You want to use modify one of the variables in the context slightly before printing it.
Template tags can change the way the rest of the template is parsed, and have access to anything in the context in which they are used. They're very powerful. For example I wrote a template tag that subclasses {% extends %} and allows a template to extend different templates based on the current User.
You can easily recognise template tags when they are used, because they around surrounded in {% and %}.
Use case: You want to perform some logic that requires Python code and access to the template context.
Inclusion tags are still template tags, but Django provides some helpers (i.e. the #inclusion_tag decorator) to make it easy to write template tags of this kind.
Use case: You want to render one template into another. For example you may have an advertisement on your site that you want to use in different places. It might not be possible to use template inheritance to achieve what you want, so rather than copy/paste the HTML for the ad multiple times, you would write an inclusion tag.
The reason why you would use an inclusion tag over the existing {% include %} template tag, is that you may want to render the template with a different context to the one you are in. Perhaps you need to do some database queries, to select the correct ad to display. This is not possible with {% include %}.
Simple tags like inclusion tags, simple tags are still template tags but they have limited functionality and are written in a simplified manner. They allow you to write a template tag that accepts any number of arguments (e.g. {% mytag "some str" arg2 arg3 %} etc) and require you to only implement a function that can accept these arguments (and optionally a context variable to give you access to the template context.
Essentially they're an upgrade from template filters, because instead of accepting only 1 or 2 arguments, you can accept as many as you like (and you can also access the template context).

Django: custom serialization options?

I'm working on a Django-based web service and I'm trying to figure out what the best way to do my serialization will be.
The tricky requirement, though, is that I'd like to have pretty much full control over format of, and fields contained in, the response.
For example, the Django serializers (which, unfortunately, includes the wadofstuff serializer) automatically wrap the fields in { model: "app.Model", pk: 42, fields: { ... }}, which is great for creating fixtures, but isn't great for me — I'd like full control over the output.
Additionally, I'd like a serializer that is aware of Django's objects so, for example, it will do the Right Thing with a QuerySet or ManyToManyField.
Currently I'm thinking of using django-piston's emitters.py, but my experience with django-piston has only been mediocreª, so I'd like to see if there are other options.
So, are there any other options for customizable Django serializers?
ª: It's sparsely documented and tested, and I've had some problems with the serializer.
Have you looked at django-piston? It should have a bunch of stuff to make this easier.
(Not sure about serialization specifically, but Django RESTy web services.)
When I need some custom serialization really fast and my case doesn't require deserialization I just write django template that can make any format I want from list/queryset/object. You can then call render_to_string with proper context and you have your data serialized.
UPDATE: some short example
Let's say you want to get json format accepted by datatables.net plugin. Since there are some special parameters required serializing queryset using simplejson or sth else is impossible here (or might be not so easy at least). We found that fastest way to provide such structure is to create simple template like this one:
{
"sEcho": {{sEcho}},
"iTotalRecords": {{iTotalRecords}},
"iTotalDisplayRecords": {{iTotalDisplayRecords}},
"aaData":[
{% for obj in querySet %}
[
"{{obj.name}}",
"{{obj.message|truncatewords:20}}",
"{{obj.name}}"
]
{% if not forloop.last %}
,
{% endif %}
{% endfor %}
]
}
which renders to beatiful json that we were looking for. It gives you full control over the format also. Other advantages is the abillity to modify objects fields by using built-in django filters which in our case was really usefull.
I know this is not serialization as described in books but if f you want to convert some object to a custom format this solution might be the fastest one. For some reason django developers allowed to render template to any given format not only html, so why not to use it?
Example shown above is very specific but you can generate any other format. Of course writing deserializer for that could restore object from this format might be painfull but if you don't need it...
EDIT :
Now out at https://bitbucket.org/sebpiq/any2any/
I am currently writing a full-featured serialization framework for Django. The aim is precisely to have full control over the serialization. It would probably fill-in your requirements pretty well ! However, it is not ready yet. I estimate that in 1 or 2 weeks I will be able to release a first version.
You can still check the google code : http://code.google.com/p/django-serializable/ , even give some help if you are interested in it.
There will be a featured download when the first release will be out !

Rendering JSON objects using a Django template after an Ajax call

I've been trying to understand what's the optimal way to do Ajax in Django. By reading stuff here and there I gathered that the common process is:
formulate your Ajax call using some JavaScript library (e.g., jQuery), set up a URL pattern in Django that catches the call and passes it to a view function
in the Python view function retrieve the objects you are interested in and send them back to the client in JSON format or similar (by using the built in serializer module, or simplejson)
define a callback function in JavaScript that receives the JSON data and parses them, so to create whatever HTML is needed to be displayed. Finally, the JavaScript script puts the HTML wherever it should stay.
Now, what I still don't get is how are Django templates related to all of this? Apparently, we're not making use of the power of templates at all.
Ideally, I thought it'd be nice to pass back a JSON object and a template name, so that the data could be iterated over and an HTML block is created. But maybe I'm totally wrong here...
The only resource I found that goes in this direction is this snippet (769) but I haven't tried it yet.
Obviously, what's going to happen in this case is that all the resulting HTML is created on the server side, then passed to the client. The JavaScript-callback function only has to display it in the right place.
Does this cause performance problems? If not, even without using the snippet above, why not formatting the HTML directly in the backend using Python instead of the front-end?
Many thanks!
UPDATE: please use snippet 942 because it is an enhanced version of the one above! I found that the inheritance support works much better this way..
Hey thanks vikingosegundo!
I like using decorators too :-).
But in the meanwhile I've been following the approach suggested by the snippet I was mentioning above. Only thing, use instead the snippet n. 942 cause it's an improved version of the original one. Here's how it works:
Imagine you have a template (e.g., 'subtemplate.html') of whatever size that contains a useful block you can reuse:
........
<div id="results">
{% block results %}
{% for el in items %}
<li>{{el|capfirst}}</li>
{% endfor %}
{% endblock %}
</div><br />
........
By importing in your view file the snippet above you can easily reference to any block in your templates. A cool feature is that the inheritance relations among templates are taken into consideration, so if you reference to a block that includes another block and so on, everything should work just fine. So, the ajax-view looks like this:
from django.template import loader
# downloaded from djangosnippets.com[942]
from my_project.snippets.template import render_block_to_string
def ajax_view(request):
# some random context
context = Context({'items': range(100)})
# passing the template_name + block_name + context
return_str = render_block_to_string('standard/subtemplate.html', 'results', context)
return HttpResponse(return_str)
Here is how I use the same template for traditional rendering and Ajax-response rendering.
Template:
<div id="sortable">
{% include "admin/app/model/subtemplate.html" %}
</div>
Included template (aka: subtemplate):
<div id="results_listing">
{% if results %}
{% for c in results %}
.....
{% endfor %}
{% else %}
The Ajax-view:
#login_required
#render_to('admin/app/model/subtemplate.html')#annoying-decorator
def ajax_view(request):
.....
return {
"results":Model.objects.all(),
}
Of course you can use render_to_response. But I like those annoying decorators :D
There's no reason you can't return a rendered bit of HTML using Ajax, and insert that into the existing page at the point you want. Obviously you can use Django's templates to render this HTML, if you want.
When you are doing Ajax I don't think you have any use for templates.
Template is there so that you can generate dynamic HTML on the server side easily and hence it provides few programming hooks inside HTML.
In case of Ajax you are passing JSON data and you can format it as you want in Python.
and HTML/document elements will be generated on client side using the JSON by some JavaScript library e.g. jQuery on client side.
Maybe if you have a very specific case of replacing some inner HTML from server side HTML then maybe you can use templates but in that case why you would need JSON?
You can just query the HTML page via Ajax and change inner or outer or whatever HTML.
Templates are for the purpose of presentation. Responding with data in format X (JSON, JSONP, XML, YAML, *ml, etc.) is not presentation, so you don't need templates. Just serialize your data into format X and return it in an HttpResponse.
While templates are indeed just for presentation purposes, it shouldn't matter if you are doing it on the serverside or client side. It all comes down to separating the control logic that is performing an action, from the view logic that is just responsible for creating the markup. If your javascript control logic is having to handle how you are rendering or displaying the HTML, then you might be doing it wrong, but if you isolate that rendering logic to another object or function, and just passing it the data necessary for the render, then you should be fine; it mirrors how we separate our controllers, models and views on the server side.
Take a look at the github project: http://github.com/comolongo/Yz-Javascript-Django-Template-Compiler
It compiles django templates into optimized javascript functions that will generate your presentation html with data that you pass it. The compiled functions are in pure javascript, so there are no dependencies on other libraries. Since the templates are compiled instead of being parsed at runtime, the strings and variables are all already placed into javascript strings that just need to be concatenated, so you get a huge speed increase compared to techniques that require you to do dom manipulation or script parsing to get the final presentation. Right now only the basic tags and filters are there, but should be enough for most things, and more tags will be added as people start making requests for them or start contributing to the project.
You can use jquery.load() or similar, generating the HTML on the server and loading it into the DOM with JavaScript. I think someone has called this AJAH.
Unfortunately, Django templates are designed to be executed server side only. There is at least one project to render Django templates using Javascript, but I haven't used it and so I don't know how fast, well supported or up to date it is. Other than this, you have to either use the Django templates on the server or generate dynamic elements on the client without using templates.

Categories