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 patternsams/events/admin.py—EventsFeatureFlagMixingates all admin permissionsams/events/validators.py—patch_menu_item_clean()validates menu item URLs (applied inapps.pyready())
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 patternsams/resources/admin.py—ResourcesFeatureFlagMixingates 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, andi18n_patterns()URL routing setup_cms(which runs on every deploy viadeploy_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.