django-soapbox 1.6¶
This application provides a mechanism for creating and displaying messages – such as announcements or site information – on a Django-powered site. Messages can be turned on or off, and can be set to display globally or only on a subset of a site’s URLs.
Documentation contents¶
Installation guide¶
The 1.6.1 release of django-soapbox supports Django 2.2 and 3.0 on the following Python versions:
- Django 2.2 supports Python 3.5, 3.6, 3.7, and 3.8.
- Django 3.0 supports Python 3.6, 3.7, and 3.8.
Normal installation¶
The preferred method of installing django-soapbox is via pip, the standard Python package-installation tool. If you don’t have pip, instructions are available for how to obtain and install it, though if you’re using a supported version of Python, pip should have come bundled with your installation of Python.
Once you have pip, type:
pip install django-soapbox
If you don’t have a copy of a compatible version of Django, this will also automatically install one for you.
Installing from a source checkout¶
If you want to work on django-soapbox, you can obtain a source checkout.
The development repository for django-soapbox is at <https://github.com/ubernostrum/django-soapbox>. If you have git installed, you can obtain a copy of the repository by typing:
git clone https://github.com/ubernostrum/django-soapbox.git
From there, you can use git commands to check out the specific revision you want, and perform an “editable” install (allowing you to change code as you work on it) by typing:
pip install -e .
Next steps¶
To learn how to use django-soapbox, see the usage overview.
Usage overview¶
The goal of django-soapbox is to provide a way to display persistent
messages on either all pages, specific pages, or a subset of pages on
a Django-powered site. To begin using django-soapbox, install it, then add soapbox to your INSTALLED_APPS setting
and run manage.py migrate to install the Message
model.
You can then begin creating Message
instances through the
admin interface, indicating which URLs you’d like them to appear on.
Provided models¶
-
class
soapbox.models.
Message
¶ The core of django-soapbox is the
Message
model, which represents messages to be displayed on your site. This model has four fields and one important custom method:-
message
¶ A
TextField
containing the text of the message to display. This can be plain text, or can include HTML.
-
is_active
¶ A
BooleanField
(defaults toTrue
) indicating whether the message is currently active; only active messages will be retrieved by the standard helpers built in to django-soapbox.
-
is_global
¶ A
BooleanField
(defaults toFalse
) indicating whether the message is global; a global message does not need to haveurl
(see below) set, and will match any URL.
-
-
class
soapbox.models.
MessageManager
¶ Also provided on
Message
is a custom manager, accessible as the attributeobjects
, which defines two useful methods:-
active
()¶ Returns a
QuerySet
of allMessage
instances which haveis_active
set toTrue
. This is defined as a customQuerySet
method, so it can also be “chained” with otherQuerySet
methods. For example, the following would retrieve allMessage
instances which are both global and active:Message.objects.filter(is_global=True).active()
Return type: QuerySet
-
Validation requirements¶
While Message
instances are relatively freeform, there are
two requirements you must abide by; failure to do so will result in
validation errors being raised when trying to save the
Message
:
- Each
Message
must either haveis_global
set toTrue
, or specify some URL prefix to match inurl
. - A
Message
cannot have bothis_global
set toTrue
and simultaneously have a URL prefix to match specified inurl
(in other words, aMessage
can be global, or “local” to some URL prefix, but never both at the same time).
Message URL matching¶
The message-retrieval helpers provided in django-soapbox will only
retrieve messages which are active and which match a particular URL
you pass to them; typically, this will be the URL of the current
request. The matching process is case-sensitive and uses the following
algorithm, implemented in the match()
method of
Message
.
- If the
Message
has is_global set toTrue
, immediately returnTrue
. - Strip leading and trailing slashes from the URL, and from the
url
field of theMessage
, and split each on internal slashes to yield a list of path components. - If the list of components from the
url
field of theMessage
is longer than the list from the passed-in URL, immediately returnFalse
. - Return
True
if the list of components from theurl
field, and the corresponding list of components from the beginning of the passed-in URL, are equal. Otherwise, returnFalse
.
This means that a Message
will match not only a URL which is
an exact match for its own url
, but also any URL of
which its url
is a prefix. So, for example, if the
url
field contained /foo/, it would match on
/foo/ and on /foo/bar/.
Retrieving and displaying messages¶
There are two helpers built in to django-soapbox for retrieving and displaying messages in templates.
One is a context processor, which will add a variable
soapbox_messages to the context of any template rendered with a
RequestContext
(required in order to have
access to the request path to determine the URL). To enable it, add
soapbox.context_processors.soapbox_messages to the context
processors enabled on your site. See the Django template options
documentation
for notes on how to do this.
If you prefer to have more fine-grained control of where messages will be retrieved and displayed, django-soapbox provides a template tag, get_soapbox_messages which can retrieve messages for a given URL and place them into a variable in the context. The syntax of the tag is:
{% get_messages_for_page [url] as [varname] %}
To use the tag, first add {% load soapbox %} to the template to load the django-soapbox template tag library, then call the get_messages_for_page tag, passing a URL – either a string, or a template variable which the tag will resolve – and the name of the context variable you’d like the message to be placed into. For example (presuming you have a context processor enabled which exposes the current HTTP request to your template):
{% load soapbox %}
{% get_messages_for_page request.path as soapbox_messages %}
{% for message in soapbox_messages %}
<p>Important message: {{ message }}</p>
{% endfor %}
What django-soapbox is not¶
Importantly, django-soapbox is not a system for displaying one-time “flash”-type notifications to an individual user; for that, use Django’s built-in message framework. It also is not a system for users to send messages to each other; for that, email or a custom user-message tool is more appropriate.
Instead, django-soapbox is for displaying messages to all users, on any URLs the messages match, each time they visit those URLs. Most often this is useful for site-wide or section-specific announcements all users need to see.
Security considerations¶
The tools provided in django-soapbox are designed around the
assumption that only trusted administrators of your site will be
permitted to create Message
instances. In particular, a
Message
will, by default, mark its contents as safe for display,
and so the Django template system will not perform autoescaping of
the contents. This is useful for allowing HTML messages – for
example, containing links to longer announcements on their own pages
– but if opened to arbitrary or untrusted users would be a serious
cross-site scripting vulnerability
Because of this, it is recommended that you only use the Django administrative interface to create Message instances, and that you carefully restrict the soapbox.add_message permission to only a small number of trusted administrators.