I'm setting a {{ title }}
for every page of my project. Sometimes this title
is a static string such as Enter your Name
and sometimes it's based on a relevant object on that page, such as Employee.first_name
.
To create context['title']
, I'm using get_context_data
inside every class based view. But this seems to be resulting in me repeating a chunk of code every time, and I'm looking to reduce that somehow.
For example to write a custom title for each page, I'd have to write this:
def get_context_data(self, **kwargs):
context = super(SomeView, self).get_context_data(**kwargs)
context['title'] = 'Title for This page'
return context
I feel like it'd be ideal to have a mixin that I somehow just pass in the variable for title
and my context
dictionary will automatically have context['title']
added based on the passed in variable.
Is this possible? Is there a way to create a mixin such that all I have to do is pass in a variable, and it'll give me a context just for the title instead of writing out that chunk of code for every single view?
Yes, it's possible and easy:
class YourTitleMixin(object):
title = None # or your default title if you won't provide any
def get_title(self):
return self.title
def get_context_data(self, **kwargs):
context= super(YourTitleMixin, self).get_context_data(**kwargs)
context['title'] = self.get_title()
return context
And you use it:
def YourPageView(YourTitleMixin, DetailView):
title = "Your Page Title" # you can either use this ...
def get_title(self):
return self.get_object().name # ... or that, if your title should be generated from some data
But is this necessary? Are you using your title only once in template? Do you share one template between views? Maybe you can do it purely in your templates? For example:
{# base.html #}
<html>
<head>
<title>{% block page_title %}My page{% endblock %}</title>
</head>
</html>
{# detail.html #}
{% extends "base.html" %}
{% block title %}{{ article.name }} - {{ block.super }}{% endblock %}
{# will result in "article name - My Page". You don't need to use super if you don't want to #}
I usually solve this with a mixin:
class TitleMixin(object):
"""Pass a defined title to context"""
title = None
def get_title(self):
return self.title
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = self.get_title()
return context
In you views, you can then do:
class BlogIndex(TitleMixin, ListView):
title = 'Blog entries'
class EntryDetail(TitleMixin, DetailView)
def get_title(self): # for dynamic title, such as coming from a model field
return self.object.title
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With