Skip to content

Instantly share code, notes, and snippets.

@evildmp
Created July 2, 2011 17:59
Show Gist options
  • Save evildmp/1061461 to your computer and use it in GitHub Desktop.
Save evildmp/1061461 to your computer and use it in GitHub Desktop.
Inserts for Django CMS - freestanding placeholders for templating
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
@chhantyal
Copy link

I think this is old, will it work with django-cms 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment