How to modify a template of a reusable app in Django? - django

For example, let's say I want to modify the breadcrumbs block of the admin/change_list.html template in the Django admin. If I try to override this template like this:
{% extends "admin/change_list.html" %}
{% block breadcrumbs %} ... my changes ... {% endblock %}
then Django goes into an infinite recursion when trying to load my override, because the "extends" tag tries to load the override rather than the original template.
An obvious way would be to copy & paste the entire source template, but this is exactly the thing I'm trying to avoid. So how can I modify a template without copying and pasting all of it into my project?

The complete details on overriding the admin templates are here: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates.
If you're only trying to change the template for a single app, you can simply save it as app_label/change_list.html. If you're trying to change it for a single model, you can save it as app_label/model_as_underscores/change_list.html.
If you're trying to change it for all your stuff, you can create a new template with a different name, and set its name as the change_list_template attribute on all your ModelAdmin subclasses. (On ModelAdmin, you can do the same thing with change_form_template, delete_confirmation_template, and object_history_template. On an AdminSite, you can override the index_template and login_template attributes in the same way.)
Both of these methods will allow you to extend from the original admin templates.

Related

base.html for Django Registration Redux

I am using django-registration-redux and everything works like a charm. However, I am a bit dissatisfied with the fact that it forces me to name the base template that it uses base.html, and that I have to put it in the templates directory.
I'd rather have it somewhere like this:
"/templates/registration/redux_base.html"
Is it possible to define this somewhere in my settings.py? I could not find that, but I think this must be possible. (Otherwise I am getting name clashes with other apps which is frustrating...)
Almost all templates from redux are extending template "registration/registration_base.html", except of templates for activation (for some reason they are extending directly from "base.html"). Template "registration/registration_base.html" looks literally like this:
{% extends "base.html" %}
So you can override that template (simply by creating "global" template for project on that location) and define here another {% extends %} or your whole new template.
But templates for email activation, as I mentioned above, are extending directly from "base.html" so if you are using them, you must overrite them separately.
Whenever it bothers you simply replace
{% extends "base.html" %}
with
{% extends "registration/redux_base.html" %}
And ofcourse create redux_base.html as you wish.

How to share a plugin (the content in a sidebar widget) in several templates in Django-CMS?

I want to add a common sidebar for all my templates on my site. Let's say, I want a picture and some text, that the final user could modify whenever she feels like without having to mess with my base.html template (the base class of all my templates).
To be clear, I know that I can put plugin place holders with the template tag:
{% placeholder sidebar %}
My problem is that if I have five 5 templates and the content of the sidebar is the same for all of them, the user have to go through all the pages and change them one by one.
On the other hand, it cannot be static because I want the user to be able to modify the content through the admin.
Specifically, I am trying to do this with the cmsplugin-contact which saves me the troubles of configuring forms and emails.
You can create a special page that isn't published and add a "sidebar" placeholder to the template. You then use the {% show_placeholder %} template tag to render that sidebar placeholder in the base template that each of your 5 other pages are using

django extends different base templates

I understand we can use "extends variable" in the template to switch between two different extended templates.
e.g.
views:
if something:
base = 'base1.html'
else:
base = 'base2.html'
return render_to_response ('template.html', {'base':base})
template.html:
{% extends base %}
Normally that works fine. However, my problem is that I am using django-registration of which I don't have to write my own view to handle the registration and login process. That also means that I am not able to pass the variable to the template. Though I do have the registration templates under my project directory. (like login.html)
Unfortunately, Django can't do this in the template:
{% if something %}
{% extends 'base1.html' %}
{% else %}
{% extends 'base2.html' %}
{% endif %}
The only way I know that the 'variable base' can be passed down to the auth-login is to write my own views like login, logout,etc. This seems like not fitting the DRY model and fairly error prone going forward.
Is there another way that I can accomplish this? Or any pointers to workaround the problem?
Thanks.
-P
If it's just 2 (or 3) options where that 'something' can be made to a Boolean, then you could use the yesno filter:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#yesno
So:
{% extends something|yesno:"base1.html,base2.html" %}
If you want something a bit more free-form, then you could make use of the extra context / custom context processor option mentioned above, and try something like:
{% extends selected_template|default:"base2.html" %}
where selected template is just the path to whatever base template you like.
To be honest this looks to me like a code smell - I've used django-registration a few times, I work on quite large sites and I never needed to extend a template from another template which is only known at run time.
Anyway, if you really want to pass a custom variable to a template rendered by 3rd party module, and you don't want to hack that module, then you have to use e.g. custom template context processor. Also, django-registration allows extra_context to be passed to its views, maybe that would be enough. You can also try monkey-patching. Or maybe you can try manipulating template folders or template loaders to get what you need.
But all these things are IMHO hacks and you shouldn't use different templates for one view, unless it's a generic view.
I think you should not place differences between the templates into the selection of different base templates. Having different base templates is what violates the DRY principle. Place the common things into a template, ie. registration.html, the differences into other templates that you call via 'include':
{%extends base.html%}
{%if something%}
{%include "type1.html"%}
{%else%}
{%include "type2.hmtl"%}
where the template names are the same as you would use in the view definition.
This probably isn't what you are looking for, but could you just include your conditionals in your base.html?

Django - Admin - Mandatory fields with ' * '

At present, Django admin will show all the mandatory fields with a bold labels. Is it possible mark with * in the label instead of bold labels?
The Django admin uses templates to render the add/edit page for a model. It is possible to replace that template with one of your own (which extends from the original template) overriding the template blocks you need to in order to make the changes you want to.
Check out the Django docs regarding overriding admin templates for more information.
It's the admin/change_form.html template which you would need to alter in some way (since this template renders the page shown when you add a new instance or edit an existing one). The existing templates already apply a required class to the appropriate labels, so I would create a new template which looks like this:
{% extends "admin/change_form.html" %}
{% block extrastyle %}
{{ block.super }}
<style type="text/css">
/* add an asterisk using CSS */
.required:after {
content: " *";
}
</style>
{% endblock %}
Apply to a Single Model
You should use a model admin class if you want this template to be used for specific models, setting the change_form_template attribute, as described in this section of the docs to the location of the template file you have created.
Apply to a Single App
If you want template to apply to models in an entire app create a templates folder inside the root of the app. Django will automatically look for templates there, so if you create a folder called admin and place a file in there called change_form.html it will automatically override the default Django template of that name (admin/change_form.html).
Project Wide
In order to apply this template project wide create a folder somewhere (not inside an app) called templates. Again place your new template in this directory at admin/change_form.html.
Next edit the template directories Django setting specifying the location of this directory in order to allow Django to find the template and override the default templates in the same way as before only project wide and not just app wide.
This is quite a complex set of things to do, especially for such a simple change and you may find it tricky if you have not worked with admin templates before (or even if you have).
Hopefully you now understand what is required to change an admin template, its actually fairly elagant (as is Django) but in my opinion not worth the effort just to change to some asterisks.

django: how to interconnect various logical pieces of a webpage

everyone. I'm just starting with django, so sorry for a possibly stupid question.
Imagine, I have a webpage with 3 logical pieces: content, dynamic menu, banners. It seems ok to me to have a template with something like:
{% include "banners.html" %}
{% include "menu.html" %}
{% include "content.html" %}
But then, how do I do it? Every piece has its separate logic in a separate view in its' separate app. How do I trigger execution of all three views and render all three templates?
P.S. Is there a sourceforge-like site for django apps where I could take a look at how people are doing stuff in real projects?
The standard way to do it is something as follows:
Templates:
Have a base.html that has the banners, menu and a body block which is empty.
For each template, extend the base.html and override the body block.
{% extends "base.html" %}
{% block body %}
-- Your this page's content goes here.
{% endblock %}
You can use the includes, where necessary, but prefer the extends where possible. Include was debated to be included in the template language.
Populating Context:
You now have a lot of templates with placeholders that need to be replaced with the real "context" values.
Pass the RequestContext, that should contain many standard requirements for the template.
For the values that you need in every template, write a template context processor.
Those context's that you need in this template, you populate in the view.
Using multiple app's views:
Most apps written for reuse will include template_name as a standard parameter, along with extra_context. You will need to call those views with these parameters.
Some apps go out of their way, to create a lazily evaluated response (like TemplateResponse) so that you can grab the context they populate, in your view.
Django reusable apps:
Are you kidding me? They are all over the Internet!
http://github.com/search?q=django&type=Everything
http://bitbucket.org/repo/all/?name=django
http://code.google.com/hosting/search?q=django&projectsearch=Search+projects