Site settings

You can define settings for your site that are editable by administrators in the Wagtail admin. These settings can be accessed in code, as well as in templates.

To use these settings, you must add wagtail.contrib.settings to your INSTALLED_APPS:

INSTALLED_APPS += [
    'wagtail.contrib.settings',
]

Defining settings

Create a model that inherits from BaseSetting, and register it using the register_setting decorator:

from django.db import models
from wagtail.contrib.settings.models import BaseSetting, register_setting

@register_setting
class SocialMediaSettings(BaseSetting):
    facebook = models.URLField(
        help_text='Your Facebook page URL')
    instagram = models.CharField(
        max_length=255, help_text='Your Instagram username, without the @')
    trip_advisor = models.URLField(
        help_text='Your Trip Advisor page URL')
    youtube = models.URLField(
        help_text='Your YouTube channel or user account URL')

A ‘Social media settings’ link will appear in the Wagtail admin ‘Settings’ menu.

Edit handlers

Settings use edit handlers much like the rest of Wagtail. Add a panels setting to your model defining all the edit handlers required:

@register_setting
class ImportantPages(BaseSetting):
    donate_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+')
    sign_up_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+')

    panels = [
        PageChooserPanel('donate_page'),
        PageChooserPanel('sign_up_page'),
    ]

You can also customize the editor handlers like you would do for Page model with a custom edit_handler attribute:

from wagtail.admin.edit_handlers import TabbedInterface, ObjectList

@register_setting
class MySettings(BaseSetting):
    # ...
    first_tab_panels = [
        FieldPanel('field_1'),
    ]
    second_tab_panels = [
        FieldPanel('field_2'),
    ]

    edit_handler = TabbedInterface([
        ObjectList(first_tab_panels, heading='First tab'),
        ObjectList(second_tab_panels, heading='Second tab'),
    ])

Appearance

You can change the label used in the menu by changing the verbose_name of your model.

You can add an icon to the menu by passing an ‘icon’ argument to the register_setting decorator:

@register_setting(icon='placeholder')
class SocialMediaSettings(BaseSetting):
    class Meta:
        verbose_name = 'social media accounts'
    ...

For a list of all available icons, please see the UI Styleguide.

Using the settings

Settings are designed to be used both in Python code, and in templates.

Using in Python

If access to a setting is required in the code, the for_site() method will retrieve the setting for the supplied site:

from wagtail.core.models import Site

def view(request):
    site = Site.find_for_request(request)
    social_media_settings = SocialMediaSettings.for_site(site)
    ...

Using in Django templates

Add the settings context processor to your settings:

TEMPLATES = [
    {
        ...

        'OPTIONS': {
            'context_processors': [
                ...

                'wagtail.contrib.settings.context_processors.settings',
            ]
        }
    }
]

Then access the settings through {{ settings }}:

{{ settings.app_label.SocialMediaSettings.instagram }}

Note

Replace app_label with the label of the app containing your settings model.

If you are not in a RequestContext, then context processors will not have run, and the settings variable will not be available. To get the settings, use the provided {% get_settings %} template tag. If a request is in the template context, but for some reason it is not a RequestContext, just use {% get_settings %}:

{% load wagtailsettings_tags %}
{% get_settings %}
{{ settings.app_label.SocialMediaSettings.instagram }}

If there is no request available in the template at all, you can use the settings for the default Wagtail site instead:

{% load wagtailsettings_tags %}
{% get_settings use_default_site=True %}
{{ settings.app_label.SocialMediaSettings.instagram }}

Note

You can not reliably get the correct settings instance for the current site from this template tag if the request object is not available. This is only relevant for multisite instances of Wagtail.

Using in Jinja2 templates

Add wagtail.contrib.settings.jinja2tags.settings extension to your Jinja2 settings:

TEMPLATES = [
    # ...
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'APP_DIRS': True,
        'OPTIONS': {
            'extensions': [
                # ...
                'wagtail.contrib.settings.jinja2tags.settings',
            ],
        },
    }
]

Then access the settings through the settings() template function:

{{ settings("app_label.SocialMediaSettings").twitter }}

Note

Replace app_label with the label of the app containing your settings model.

This will look for a request variable in the template context, and find the correct site to use from that. If for some reason you do not have a request available, you can instead use the settings defined for the default site:

{{ settings("app_label.SocialMediaSettings", use_default_site=True).instagram }}

You can store the settings instance in a variable to save some typing, if you have to use multiple values from one model:

{% with social_settings=settings("app_label.SocialMediaSettings") %}
    Follow us on Twitter at @{{ social_settings.twitter }},
    or Instagram at @{{ social_settings.Instagram }}.
{% endwith %}

Or, alternately, using the set tag:

{% set social_settings=settings("app_label.SocialMediaSettings") %}