Skip to content

Feature flags

AMS uses environment-variable-based feature flags to toggle optional modules per deployment. For what each flag means to a client filling in the decision questionnaire, see the settings glossary; this page covers the implementation.

Available flags

AMS_EVENTS_ENABLED

Setting EVENTS_ENABLED
Env var AMS_EVENTS_ENABLED
Default False
Purpose Enable or disable the events module

When disabled (the default):

  • Event URL patterns are not registered — requests to /events/ return 404
  • Events admin sections are hidden — no add, change, or view permissions
  • Menu items with /events/ URLs are rejected during validation

Implementation pattern: The env var is read in config/settings/base.py as a boolean setting. This setting is then checked in:

  • config/urls.py — conditionally includes the events URL patterns
  • ams/events/admin.py — EventsFeatureFlagMixin gates all admin permissions
  • ams/events/validators.py — patch_menu_item_clean() validates menu item URLs (applied in apps.py ready())

AMS_RESOURCES_ENABLED

Setting RESOURCES_ENABLED
Env var AMS_RESOURCES_ENABLED
Default False
Purpose Enable or disable the resources module

When disabled (the default):

  • Resource URL patterns are not registered — requests to /resources/ return 404
  • Resources admin sections are hidden — no add, change, or view permissions
  • Menu items with /resources/ URLs are rejected during validation

Implementation pattern: The env var is read in config/settings/base.py as a boolean setting. This setting is then checked in:

  • config/urls.py — conditionally includes the resources URL patterns
  • ams/resources/admin.py — ResourcesFeatureFlagMixin gates all admin permissions

AMS_ENABLED_LANGUAGES

Setting LANGUAGES
Env var AMS_ENABLED_LANGUAGES
Default en
Purpose Control which languages are exposed to users, independently of which languages the codebase has scaffolding for

Comma-separated list of language codes (e.g. AMS_ENABLED_LANGUAGES=en,mi). Only codes present in AVAILABLE_LANGUAGES (config/settings/base.py) take effect. en should always be included — nothing enforces this, and omitting it leaves LANGUAGE_CODE pointing at a language not in LANGUAGES.

When a language isn't enabled (the default, for any language beyond en):

  • It's absent from LANGUAGES, WAGTAIL_CONTENT_LANGUAGES, the language switcher, and i18n_patterns() URL routing
  • setup_cms (which runs on every deploy via deploy_steps) does not create a Wagtail Locale/Site/HomePage for it, so no placeholder content goes live

Implementation pattern: The env var is read in config/settings/base.py as a list and used to filter AVAILABLE_LANGUAGES into LANGUAGES. Everything else (WAGTAIL_CONTENT_LANGUAGES, PathBasedSiteMiddleware, the translate_url templatetag, the language switcher template, setup_cms) already reads settings.LANGUAGES dynamically, so no other code needs to change to support a new language. As with other settings-based flags, this requires an app restart to take effect.

Future considerations

The current env-var approach is well-suited for flags that are set once per deployment and rarely change. If requirements evolve, consider these alternatives:

Database-backed flags (e.g. Wagtail BaseSiteSetting)

Suitable if flags need to be toggled at runtime without redeployment, or managed by non-technical admins via a UI.

Feature flag library (e.g. django-waffle)

Suitable if per-user, per-group, or percentage-based rollouts are needed (A/B testing, gradual feature rollouts).

Middleware-based gating

Suitable if URL patterns need to remain registered (e.g. reverse() must work globally) while still blocking access at the request level.