Of Meta Tags and Context Processors
August 27, 2007
We just launched a site that required heavy utilization of <meta> tags. The most demanding aspect of this process was the requirement that the tags be freely editable for any page.
The difficulty that arises is relating these tags to different types of objects (flat pages, products, etc). Eventually we went with a simple method: assigning tags to the URL path, pulling them into the templates globally via a context processor.
I created a ‘metatags’ app with a simple model:
from django.db import models
class MetaInformationManager(models.Manager):
def get_metatags(self, path):
try:
return self.get(url=path)
except self.model.DoesNotExist:
return self.get(url='default')
class MetaInformation(models.Model):
url = models.CharField(maxlength=100, unique=True)
keywords = models.TextField()
description = models.TextField()
objects = MetaInformationManager()
class Admin:
list_display = ('url', 'keywords', 'description')
search_fields = ('url', 'keywords', 'description')
class Meta:
ordering = ['url']
As you can see, we’ll be pulling the tags using the get_metatags method which will pull out the ‘default’ tags if they don’t exist for this page.
Now to pull them into the templates we create a context processor:
from myproject.metatags.models import MetaInformation
def metatags(request):
return {'meta':MetaInformation.objects.get_metatags(request.path)}
Which has to be added to our settings file. Note: since TEMPLATE_CONTEXT_PROCESSORS is not in settings.py, we must add the context processors that Django uses by default. Here is my TEMPLATE_CONTEXT_PROCESSORS:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
'myproject.metatags.context_processors.metatags',
)
Now, if you installed the meta tags app and sync’d your db you will be ready to use your tags — just make sure to create a ‘default’ set of data!
Lastly, our base.html template will have the following lines within your <head> tags:
<meta name="description" content="{{ meta.description|escape }}" />
<meta name="keywords" content="{{ meta.keywords|escape }}" />
Context processors have many uses, giving another, more global way, of passing data to your templates.
Add your comment
No HTML; Only URLs and line breaks are converted.
Comments
Hiya-
Don't know how much you can give away, but I'm wondering if since you're maintaining URL mappings in the db, are you essentially using catchall middleware (like flatpages does) to grab all unclaimed URLs and do the lookup?
It's an interesting approach to pull away "ownership" of the URL from the actual model so a consistent URL/metainfo object can be applied across models -- tag-like I guess... anyhow any info you can share on the basic setup would be appreciated.
cheers-
Posted by ToddG
It's much simpler than that. The context processor pulls the meta information based on `request.path` (e.g., /about/ or /contact/). If that doesn't exist, it pulls the default meta information (which is required by this setup).
Posted by SuperJared
Ah, so you're just using request.path as a key to lookup in your metainfo table when rendering the page -- nothing to do with resolving what view to call(?).
I think I might have given myself an idea while misunderstanding you... thanks!
Posted by Todd