Created
July 2, 2011 17:59
-
-
Save evildmp/1061461 to your computer and use it in GitHub Desktop.
Inserts for Django CMS - freestanding placeholders for templating
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The easiest thing is to explain how you use them: | |
1. define an insertion point in your template(s) using | |
{% insert "my_insertion_point" %} | |
The {% insert %} templatetag will then get_or_create() the appropriate | |
Insert in the database | |
2. the user visits the Insert in the admin, and adds plug-based | |
content to its Placeholder. | |
3. there is no step three | |
Now, every page containing the {% insert "my_insertion_point" %} will | |
render the Insert's placeholder. Of course this can be controlled through | |
the inheritance of blocks in the usual way. | |
You can have as many {% insert "<some_name>" %}s in your templates (and | |
therefore associated Insert objects) as you wish. | |
So this does two things: it provides a way to put content into freestanding | |
placeholders, and a very easy - automatic - way to associate those with | |
templates. | |
Where this might be useful: | |
{% insert "newsflash" %} | |
It will sit there dormant in your templates until it's needed, | |
when you add your content to the newsflash Insert in the Admin: | |
"Don't bother coming to work, the building's on fire". | |
{% insert "footer" %} | |
You want a footer on every page, perhaps one that itself contains | |
Django CMS plugins for dynamic content. | |
{% insert "menu" %} | |
Someone has cleverly created a Django CMS plugin that allows you to | |
configure a menu, using simple options instead of a difficult | |
templatetag. Just insert the {% insert "menu" %} templatetag where you | |
want the menu, and insert the plugin into the Insert's placeholder | |
in admin. | |
{% insert "news_banner" %} or {% insert "festival" %} | |
You can now do template-level management in the Django admin. Put | |
your site's banners' complex HTML code into Snippet plugins, then | |
put each of those into a Insert; now you can drop different page | |
banners into different templates. Or define your template's CSS | |
files with a Snippet. | |
Further work that's required: | |
* it's not multilingual, but it ought to be | |
* needs tests | |
* maybe there should be a way of passing extra context to it in the template | |
# the model | |
from django.db import models | |
from django.utils.translation import ugettext_lazy as _ | |
from cms.models.pluginmodel import CMSPlugin | |
from cms.models.fields import PlaceholderField | |
class Insert(models.Model): | |
insertion_point=models.SlugField( | |
unique = True, | |
max_length = 60, | |
help_text = "Matches the parameter passed to the {% insert %} tag in your templates" | |
) | |
content = PlaceholderField('insert',) | |
description = models.TextField( | |
max_length=256, | |
null = True, blank = False, | |
help_text = "To help remind you what this is for" | |
) | |
def __unicode__(self): | |
return self.insertion_point | |
# the admin | |
from django.contrib import admin | |
from django import forms | |
from cms.admin.placeholderadmin import PlaceholderAdmin | |
class InsertForm(forms.ModelForm): | |
class Meta: | |
model = Insert | |
widgets = {'description': forms.Textarea( | |
attrs={'cols':80, 'rows':5,}, | |
), | |
} | |
class InsertAdmin(PlaceholderAdmin): | |
pass | |
admin.site.register(Insert, InsertAdmin) | |
# the templatetag | |
from django import template | |
from django.template.defaultfilters import safe | |
from models import Insert | |
from classytags.arguments import Argument | |
from classytags.core import Tag, Options | |
register = template.Library() | |
class RenderInserter(Tag): | |
name = 'insert' | |
options = Options( | |
Argument('insertion_point'), | |
Argument('width', default=None, required=False), | |
) | |
def render_tag(self, context, insertion_point, width): | |
inserter, created = Insert.objects.get_or_create(insertion_point = insertion_point) | |
request = context.get('request', None) | |
if not request: | |
return '' | |
if not inserter.content: | |
return '' | |
return safe(inserter.content.render(context, width)) | |
register.tag(RenderInserter) | |
# for the template | |
{% insert "an_insertion_point" %} wherever required |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think this is old, will it work with django-cms 3?