Django: namespacing for flatpages? - python

So I am new to Django (and complete the 7 part tutorial) as well as read the flatpages app documentation.
At the end of which, whoever wrote the Django documentation gives a demonstration as to how one would retrieve all the flatpages:
{% load flatpages %}
{% get_flatpages as flatpages %}
<ul>
{% for page in flatpages %}
<li>{{ page.title }}</li>
{% endfor %}
</ul>
I now have flatpages working (e.g. if I go to /pages/my_flatpage/ the default template I have renders. as I have included url(r'^pages/', include('django.contrib.flatpages.urls')) in the urlpatterns.
So I am now in another app of mine and want to link to these flatpages. Using the code above I create the links. However, when I click on them, they do not render as they are routed to /my_flatpage/ rather than /pages/my_flatpage/.
So I tried including the url pattern in my app, but that didnt work. How can I get the to go to the right place?

Since you're not hosting the pages directly at the root, the url attribute doesn't return the whole path. Instead you should use the URL reversing functionality as with any other object:
{% for page in flatpages %}
<li>{{ page.title }}</li>
{% endfor %}

Related

Macros in django templates

In jinja I can create macros and call it in my template like this:
{% macro create_list(some_list) %}
<ul>
{% for item in some_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endmacro %}
HTML code....
{{ create_list(list1) }}
{{ create_list(list2) }}
{{ create_list(list3) }}
I read in django docs that django templates hasn't macro tag. I'm interested in the best way to do something like this in django templates.
As you already said macros don't exist in django's templating languages.
There are template tags to do more difficult things in templates, but that's not what you're looking for either, because django's templating system also doesn't allow parameters being passed to functions.
The best thing for your example would be to use the include tag:
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#include
Here's how I would use it:
templates/snippets/list.html
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
templates/index.html
{% include 'snippets/list.html' with list=list1 %}
{% include 'snippets/list.html' with list=list2 %}
{% include 'snippets/list.html' with list=list3 %}
...
I found two packages to offer that:
https://github.com/twidi/django-templates-macros
https://github.com/nalourie/django-macros
they both look to work the same: install with pip, put in INSTALLED_APPS, {% load macros %} in the template, write and use them.
template/partials/example-partial.html
{%if partial_name == 'partial1'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
{%if partial_name == 'partial2'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
{%if partial_name == 'partial3'%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{%endif%}
templates/index.html
{% include 'partials/example-partial.html' with list=list1 partial_name="partial1"%}
{% include 'partials/example-partial.html' with list=list2 partial_name="partial2"%}
{% include 'partials/example-partial.html' with list=list3 partial_name="partial3"%}
... just start using jinja with Django.
it's very easy to turn it on
and you can use both template engines at the same time, of course for different files.
In the Django Template Language macros are not supported, but you can select the Jinja engine in order to use macros. Keep in mind that if you are building a plugable application, Django recommends using the DTL.
A Django project can be configured with one or several template
engines (or even zero if you don’t use templates). Django ships
built-in backends for its own template system, creatively called the
Django template language (DTL), and for the popular alternative
Jinja2.
The Django template language is Django’s own template system. Until
Django 1.8 it was the only built-in option available. It’s a good
template library even though it’s fairly opinionated and sports a few
idiosyncrasies. If you don’t have a pressing reason to choose another
backend, you should use the DTL, especially if you’re writing a
pluggable application and you intend to distribute templates. Django’s
contrib apps that include templates, like django.contrib.admin, use
the DTL.
Here is the link to the documentation for configuring other template engines: https://docs.djangoproject.com/en/dev/topics/templates/#configuration

A templating engine which supports generating a parser from a template

I am trying to make my templating engine for Python work backwards. That is, not only generate a document given a template and data, but also extract the data given a template and a document.
Given the page
<ul>
<li>What is your name, stranger?</li>
</ul>
and the template
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li>{{ question.text }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
it will return a latest_question_list containing that one item.
What tool do you use to do this? It does not have to support Django templates, other templating engines will do just fine.
This breakthrough happened already. This is called bidirectional or invertible parsing. See it discussed here https://news.ycombinator.com/item?id=16392654
And this paper https://dl.acm.org/doi/10.1145/1863523.1863525 "Invertible syntax descriptions: unifying parsing and pretty printing"
And this Haskell library https://hackage.haskell.org/package/roundtrip among others
source: https://news.ycombinator.com/item?id=25319810

integrating with existing html page django-page-cms

I have installed django-page-cms successfully i think. Like other cms, it is also for creating new pages. But I already have html pages in my project. How to integrate with that?
They want me to put place holder in html page, like:
{% load pages_tags %}
but I think this will bring the content from the already created page in admin
Can anyone tell me how to integrate with my existing pages?
First you need to create page in admin console. Then add the placeholder in your template
like what tutorial saying
{% get_page "news" as news_page %}
{% for new in news_page.get_children %}
<li>
{{ new.publication_date }}
{% show_content new body %}
{% endfor %}

Is it possible to load a custom template tag in base and use it in extented templates

I loaded a custom template tag note_extras.py in base.html.
base.html
<div id="wrap">
{% load note_extras %}
{% block content %}
{% endblock %}
</div><!--wrap-->
but it is not accessible at templates which is an extend of base.html ie::
home.html
{% extends "base.html" %}
{% block content %}
<div class="container">
{% create_tagmenu request.user.pk %}
</div>
{% endblock %}
it is working fine if i load note_extras in home.html ie:
{% extends "base.html" %}
{% load note_extras %}
....
In Django template language, you must load all needed template libraries in each of the templates.
I personally think it is a good idea because it makes templates more explicit (which is better than implicit). Ill give an example. Prior to Django 1.5, the default behavior for a url tag was to provide the view name in plaintext as well as all the needed parameters:
{% url path.to.view ... %}
There however was no way to provide the path to the view via a context variable:
{% with var='path.to.view' %}
{% url var ... %}
{% endwith %}
To solve that, starting with 1.3, you could import the future version of the url tag (which became the default in 1.5) by doing:
{% load url from future %}
{% url var ... %}
or
{% url 'path.to.view' ... %}
Now imagine that you would need to create a template which would extend from a base template which you did not create (e.g. one of django admin base templates). Then imagine that within the base template it would have {% load url from future %}. As a result, {% url path.to.view ... %} within your template would become invalid without any explicit explanation.
Of course this example does not matter anymore (starting with 1.5) however hopefully it illustrates a point that being explicit in templates is better than implicit which is why the currently implementation is the way it is.
If you want that a template tag is loaded in every template you want to do it in the init file of your app:
from django.template.loader import add_to_builtins
add_to_builtins('my_app.templatetags.note_extras')
In case anyone was wondering, add_to_builtins has been deprecated but one could still load a tag for all of the templates in the project via settings.TEMPLATES - supported for Django 1.9 onwards as described here:
https://stackoverflow.com/a/59719364/2447803

Getting different django administration title

I am trying to get a different header in django administration. I would like to put the company's name there instead. I am trying to do it through the docs. https://docs.djangoproject.com/en/1.5/intro/tutorial02/
Near the bottem, it says to add a TEMPLATE_DIRS setting, which I did.
So, if I have:
'/LPG/firstproject/firstproject/templates',
in my TEMPLATE_DIRS
and this is where the django source file of base_html is at
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/
What exactly does it mean when it says "Now copy the template admin/base_site.html from within the default Django admin template directory in the source code of Django itself"
Is this done with a command or how exactly do I do this?
Try this:
Inside your main template folder, create an admin folder. Inside it, create a file named base_site.html with the following content:
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}
{{ title }} | {% trans 'Your Site Title' %}
{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'Your Site Title' %}</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
Basically, if you want to override a django admin template, you have to match the path for the template and then create your own custom template.

Categories