** This tag, as shown, can cause problems (infinite recursion being one) if you don't use it correctly. **
Our internal CMS has a pages app similar to Flatpages, and a "chunks" app similar to [django-chunks](http://blog.clintecker.com/2008/jul/6/django-chunks/). Because most of our other apps are template-tag driven (FAQs, job postings, news, events, etc) I wanted a way to be able to write django template code right into a page or chunk's body from within the django admin.
This tag will let you write django template code into, for example, a Flatpage's content and render it with the current context. So if you had a template tag called "get_latest_news" and wanted to add latest news to a flatpage, just enter this in the flatpage's content:
{% get_latest_news 5 as news %}
{% for article in news %}
<li>{{ article.title }}</li>
{% endfor %}
This ability has proven extremely useful to us. Please note this is just a "summary" snippet to illustrate the concept. Use in a production environment should include more robust error checking.
Together with my mentor, Dusty Phillips, I have developed a simple class that dynamically adds two fields to its subclasses.
This is useful in cases when a single piece of content is divided into translatable and non-translatable fields, connected by a 1-to-many relationship.
## Update 2009/03/30
Since its inception, this snippet has grown into a significantly more powerful solution for translatable content (I use it myself with great joy :). The project is now hosted on github:
[project page](http://github.com/foxbunny/django-i18n-model/tree/master)
## Update 2008/07/09
It is now possible to define `i18n_common_model` attribute in `class Meta` section. Here's an example:
class Meta:
i18n_common_model = "MyCommonModel"
As you can see, it has to be a string, not the real class, and it is case-sensitive.
## Example
class Article(models.Model):
author = models.CharField(max_length = 40)
class Admin:
pass
class ArticleI18N(I18NModel):
title = models.CharField(max_length = 120)
body = models.TextField()
class Admin:
pass
# optionally, you can specify the base class
# if it doesn't follow the naming convention:
#
# class Meta:
# i18m_common_model = "Article"
When the ArticleI18N class is created, it automatically gains two new fields. `lang` field is a CharField with choices limited to either `settings.LANGUAGES` or `django.conf.global_settings.LANGUAGES`. The other field is `i18n_common` field which is a ForeignKey to Article model.
## The conventions
* call the translation model `SomeBaseModelI18N`, and the non-translation model SomeBaseModel (i.e., the translation model is called basename+"I18N")
* the first convention can be overriden by specifying the base model name using the `i18n_common_model` attribute in `Meta` section of the `I18N` model
* I18N model is a subclass of `I18NModel` class
## Original blog post
[http://blog.papa-studio.com/2008/07/04/metaclasses-and-translations/](http://blog.papa-studio.com/2008/07/04/metaclasses-and-translations/)
- models
- i18n
- metaclass
- translated-content
This is a simple helper to make custom permission decorators for Django views.
Perhaps you have an edit_comment view which you want to make sure current user is the owner of:
>def edit_comment(request, comment_id):
>>if request.user == Comment(id=comment_id).user:
>>>... do authorized things ...
>>else:
>>>... do unauthorized things ...
>>...
>>...
In this view, you might do a quick check `if request.user == Comment(id=comment_id).user`, however you now need to duplicate this code all over the place whenever you want to check if a comment is owned by the current user.
Instead, you can use the built in login_required decorator, and your own decorator to do the test:
>@permission
>def user_owns_comment(request, comment_id):
>>return request.user == Comment(id=comment_id)
>
>@login_required
>@user_owns_comment
>def edit(request, comment_id):
>> ...
>> ...
>> ...
The "tester" function will post a message using the messages module built into Django, and redirect the user to the root. It allows access and executes the view if the tester function returns anything that evaluates to True.
Your permission tester should either strictly specify the same arguments as the view, or take additional *args, and **kwargs to prevent syntax errors on extra arguments being passed along.
- view
- decorator
- permission
This snippet provides support for dynamically importing templates. This helps you to avoid naming collisions and other problems.
The format is as follows:
1. `module.submodule.app:template.html`
2. `module.submodule.app:subfolder/template.html`
3. `module.submodule.app:/subfolder/template.html`
Assuming the module is located in '/var/', these would map (respectively) to:
1. `/var/module/submodule/app/templates/template.html`
2. `/var/module/submodule/app/templates/subfolder/template.html`
3. `/var/module/submodule/app/templates/subfolder/template.html`
The colon splits the the python module from the template directory, meaning you can import from anything that has a "templates" directory. This helps me to avoid naming collisions by specifying the application I'm referring to, without having to put long paths in my extends and include tags inside other templates. It's also dynamic in that if I move a library outside the old path, it has no effect on the templates.
To get this rolling, in your `settings.py` file, add the following::
>TEMPLATE_LOADERS = (
> 'addons.template_loader.load_template_source', # <--- add this
> 'django.template.loaders.app_directories.load_template_source',
> 'django.template.loaders.filesystem.load_template_source',
># 'django.template.loaders.eggs.load_template_source',
>)
- template
- dynamic
- import
- loader