How to access page title in Django templates? - django

How can I get the page title in the template? I know there are ways to do this with javascript, but I'll prefer a template-tag or a variable if it exists.

The page title is an html element (<title>Title Here</title>), and django has no idea what that is.
Django's templates render the raw HTML text, which a browser parses and only then does the concept of a page title exist for javascript to parse.
If you need it in django, you'd want to ensure django is building that title tag and you would access it in the same way you'd display any other variable in a template.
It's probably best left to the DOM tools since a title might be created in any number of ways. If you absolutely need it in django, I would probably parse the final rendered HTML with an HTML parser like BeautifulSoup.
title = BeautifulSoup(mytemplate.render(Context({}))).html.head.title

Related

Django - safely render HTML in template

I am building a django web application where the user can submit text via a tinymce editor.
For that task I use the django-tinymce extension.
The question:
Is it secure to render the HTML in the template using the safe filter like so ? :
{{ richtext | safe }}
If not, how can it be made safe ?
If the html is coming from a reliable source, such as yourself, then it's (most probably) safe. But if you're allowing your site's users to submit their own html markup, then it's not safe.
But sometimes it is necessary to display html markup in django's templates and there's no choice but to use the safe filter. In those cases, the solution is to "sanitize" the html code.
"Sanitizing" means you keep only the safe html tags in the data and remove all the unsafe or unwanted tags (like script or style tags).
For sanitizing the data, you can use the bleach library.
Here's an example (taken from docs):
import bleach
bleach.clean('an <script>evil()</script> example')
# Output -> u'an <script>evil()</script> example'
There's also django app for this library: django-bleach.

Allowing users to edit page content in Django website

I have a Django-powered site that's like a mini CMS. I want to let users with no HTML knowledge edit the contents of the page. The problem is that most of the pages have some more or less complex HTML bits in them (for example a Bootstrap accordion), which needs to be intact for the page to not break.
I tried setting up an WYSIWYG editor, but that turned out to be a disaster, because it heavily alters my HTML (removes attributes, adds p tags all over etc).
Is there a viable option to let people change the text of the page, but not the HTML structure?
For reference, my Page model looks like:
class Page(models.Model):
title = models.CharField(max_length=150)
content = models.TextField()
Have you tried django-content-edit (https://pypi.org/project/django-content-edit/) by David Burke.
Basically you then create HTML part of your pages and add CMS_CONTENT -tags to different places. Editing content is done using WYSIWYG -control in Django admin, where available features (links, images, styles, ...) can be limited using configurations. That gives you pretty good control of everything.
It has it's own problems, like it easily messes up HTML stuff you have added in RAW view, because it automatically opens content in WYSIWYG view, which seems to remove HTML tags it does not understand/support. It also doesn't work YET with Django 2.0, because on_delete is now mandatory for ForeignKey and OneToOneField model fields.
I know this is very old question, but I answered anyway.

Render a block through a template that will be added to an existing page as well as it's own

I have a page which is for album/picture management with 2 sections: Albums and Pictures.
When an album is selected the pictures block needs to change via AJAX to reflect the album selected.
This means the rendered pictures block needs to be provided to the Albums page as well as be available as it's own View for the AJAX source.
I understand I could solve this by making the pictures block always render from AJAX even when the album page loads, however I would like to deliver the default album pictures within the initial page load if possible. In order to do that, I'd like to render the pictures block via the same template in the Album page view as is used for the Picture AJAX View.
I'm only familiar with providing templates as a template_name property within an TemplateView object.
I guess I could simply call an instance of PictureView using inclusion_tag, and pull the data I need out of the render_to_response (I haven't tried this yet, I'm just theorizing) however that seems a bit dirty to me. I'm wondering if there's a more elegant solution to this problem?
Thanks!
jQuery, Django templates, JS templating and backbone.js should tie this together.
I would suggest having a dedicated template for the Pages block. Include this template in the Django template for your page.
For dynamic updates use a JS templating library such as included in underscore.js or moustache.js. You can change the template demlimiters used so that they are the same as djangos.
Include the raw Pages block template into a javascript template block - use the django ssi tag.
Use django-tastypie to set up an api that returns the data for Photos as JSON. Your template library can then use data to fill in the template in the JS template block and you can then replace the Photo block with this rendered HTML. Use of backbone.js should ease the tying of DOM elements and JS events.
If I understand your question correctly, I did something similar once with the subsection having its own template file, which only describes that one section of the page. I used the include tag to include it into the page template, so it loaded when the page did and then rendered that template with updated values and replaced it on the page with AJAX when the content was meant to change.
Is that an option for you?

TinyMCE plugin custom tags in Django

I am building a custom image insert plugin for TinyMCE. The idea is that each article already has a relationship with a collection of images through an ArticleImage model which allows the user to provide an article-specific caption. The TinyMCE will then insert a custom tag (something like <myapp:image image-id="9389" caption="Caption override">) which is rendered as a preview of the image and caption in the editor, and rendered into <figure><img src="images/9389.jpg" /><figcaption>Caption override (Photo: photographer)</figcaption></figure>. This could equally be something like <myapp:poll> or <myapp:video>.
My question is: what is the best way (and where is the best place) to parse this 'dummy tag' into its rendered HTML in the Django view?
Or is there another, better approach?
IMHO, the best place to render custom markup, is in the template via a templatefilter.
I would risk myself to say that using a templatefilter to render custom markup is the "djangoish" way, since that's the way to go with django.contrib.markup.
Storing the custom tag in the model is a good idea, because then you can change the template filter implementation, which would be impossible if the custom tag is processed before storage.

Django - Static content display based on URL

I'm working on a Django site with a basic three column design. Left column navigation, center column content and right column URL specific content blocks.
My question is about the best method of controlling the URL specific content blocks in the right column.
I am thinking of something along the lines of the Flatpages app that will make the content available to the template context if the URL matches a pre-determined pattern (perhaps regex?).
Does anyone know if such an app already exists?
If not, I am looking for some advice about the best way to implement it. Particularly in relation to the matching of patterns to the current URL. Is there any good way to re-use parts of the Django URL dispatcher for this use?
Django CMS is a good suggestion, it depends on how deep you want to go. If this is just the beginning of different sorts of dynamic content you want then you should go that way for sure.
A simple one-off solution would be something like this:
You would just need to write a view and add some variables on the end of the URL that would define what showed up there. Depending on how fancy you need to get, you could just create a simple models, and just map the view to the model key
www.example.com/content/sidecontent/jokes/
so if "jokes" was your block of variable sidecontent (one of many in your sides model instances) the urls.py entry for that would be
(r'^content/sidecontent/(?P<side>)/$,sides.views.showsides),
and then in your sides app you have a view with a
def showsides(request, side):
Sides.objects.get(pk=side)
etc...
For something like this I personally would use Django CMS. It's like flatpages on steroids.
Django CMS has a concept of Pages, Templates, and Plugins. Each page has an associated template. Templates have placeholders where you can insert different plugins. Plugins are like mini-applications that can have dynamic model-based content.
Although Django-CMS is an interesting suggestion, there are quite a few projects that do specifically what you've requested - render blocks of content based on a URL. The main one that I know about is django-flatblocks.