Multisite setup

feincms3-sites allows running a feincms3 site on several domains, with separate page trees etc. on each (if so desired).

Installation and configuration

Install the package:

pip install feincms3-sites

Inherit feincms3-sites’s page model instead of the default feincms3 abstract page. The only difference is that this AbstractPage model has an additional site foreign key, and path uniqueness is enforced per-site:

from feincms3_sites.models import AbstractPage

class Page(..., AbstractPage):
    pass

Add feincms3_sites to INSTALLED_APPS and run migrations afterwards:

INSTALLED_APPS.append("feincms3_sites")
./manage.py migrate

If you’re using feincms3 apps currently, replace feincms3.apps.apps_middleware with feincms3_sites.middleware.apps_middleware in your MIDDLEWARE. Otherwise, you may want to add feincms3_sites.middleware.site_middleware near the top. Both middleware functions either set request.site to the current feincms3_sites.models.Site instance or raise a Http404 exception.

The default behavior allows matching a single host. The advanced options fieldset in the administration panel of feincms3-sites allows specifying your own regex, allowing matching several hostnames. In this case you may also want to add feincms3_sites.middleware.redirect_to_site_middleware after the middleware mentioned above. If you’re also using the SECURE_SSL_REDIRECT of Django’s own SecurityMiddleware you have to add the redirect_to_site_middleware before SecurityMiddleware.

It is also possible to specify a default site. In this case, when no site’s regex matches, the default site is selected instead as a fallback. The code does not prevent you from setting more than one site as the default but sites are deterministically ordered so the same site will always be selected.

Multisite support throughout your code

Since feincms3-sites 0.6 a contextvar automatically provides the current site when inside either site_middleware or apps_middleware. The default implementation of Page.objects.active() filters by the current site. When you’re running queries on pages outside of a middleware you’ll have to use the contextvar facility yourself by running your code inside a with feincms3_sites.middleware.set_current_site(site) block.

Default languages for sites

In some configurations it may be useful to specify a default language per site. In this case you should replace django.middleware.locale.LocaleMiddleware with feincms3_sites.middleware.default_language_middleware. This middleware has to be placed after the site_middleware or apps_middleware.