Developer / API
Twig variable
craft.gdpr (registered on CraftVariable::EVENT_INIT, backed by yui\gdpr\services\Variables)
exposes the current site's consent state to templates. All methods read from the current site's
SiteSettings record, so a site with no configured settings returns safe defaults (false/empty).
| Method | Returns |
|---|---|
activated() | Whether the consent banner is turned on for the current site. |
render() | Whether the banner should render on this request — respects IP restriction, existing consent, and Show after consent. |
renderTemplate() | Whether the configured template asset should be output (vs. a headless integration). |
getTemplate() | The configured popup template path. |
getRenderPosition() | Where the popup hooks into the page: before-body-end or after-body-start. |
headline() / description() | The configured banner headline/description text. |
updated() | Human-readable last-update timestamp for the site's consent settings. |
groups() | The site's CookieGroup records (with their cookies), or an empty array if unconfigured. |
hideCheckboxes() | Whether per-group checkboxes are hidden from the banner (showCheckboxes off). |
showAfterConsent() | Whether the banner should still render after consent was given (for revisiting choices). |
showAcceptAllButton() | Whether an "Accept all" button is shown. |
consentGiven() | Whether the current visitor already has a valid consent cookie. |
getUid() | The consent_uid of the visitor's stored Consent record. |
getConsent(slug) | Whether the visitor consented to a specific cookie group (by slug); falls back to the group's required flag when no explicit choice was recorded. |
getConsents() | The decoded consent payload from the visitor's cookie. |
getRefreshDataAttr() | data-refresh/data-refreshTime HTML attributes for the banner's auto-refresh behavior. |
consentModeV2Enabled() | Whether Google Consent Mode v2 is enabled for the site. |
loadCss() / loadJs() | Register the plugin's CP-configurable CSS/JS asset bundles (CSSAssets/JSAssets), if enabled in settings. |
Consent is read from a per-site cookie (name configurable per SiteSettings) whose value carries
the consent_uid plus a boolean per cookie-group slug. A stored consent is invalidated
automatically if the site's settings were updated (dateInvalidated) after the consent was given.
Site routes
Registered in Gdpr::customSiteRoutes(), handled by ConsentController (allowAnonymous):
| Route | Action | Purpose |
|---|---|---|
gdpr/show | consent/show | Returns the visitor's current consent payload as JSON. |
gdpr/account/cookie-consent | consent/view | Renders the customer-facing cookie-consent account page. |
gdpr/account/download | consent/download | Downloads the logged-in customer's account and order data as a CSV zip (GDPR data export). Requires the yui shop plugin. |
gdpr/account/anonymize | consent/anonymize | Anonymizes the logged-in customer's name/address fields on their orders, customer record, and storage entry. Requires the yui shop plugin. |
gdpr/account/delete | consent/delete | Reserved for a full customer-data deletion flow — not yet implemented (no-op controller action). |
The consent update endpoint (POST to actionUpdate on ConsentController, wired from the
front-end banner) accepts site_id plus either acceptAll, declineAll, or per-group
group-<slug> fields, writes a new Consent record, and sets the consent cookie.
CP routes
Registered in Gdpr::customAdminCpRoutes():
| Route | Purpose |
|---|---|
gdpr, gdpr/dashboard/save-layout | CP dashboard (KPI/trend widgets) and its saved layout. |
gdpr/consents, gdpr/consents/<page> | Paginated list of recorded consents. |
gdpr/site, gdpr/site/consent, gdpr/site/consent/<page> | Site-level settings and its consent sub-views. |
gdpr/site/invalidate | Invalidates all currently stored consents for the site (bumps dateInvalidated, forcing re-consent). |
gdpr/group, gdpr/group/<groupId> | Create/edit a cookie group. |
gdpr/license/* | License activation/redeem/revoke/copy-token (shared license-panel pattern). |
Dashboard modules
DashboardService extends the shared CoreDashboardService and reports on the current site's
gdpr/consents table for the selected date range: total consents, fully-accepted, fully-declined,
and partial-consent counts, plus a trend series. Each KPI links back into gdpr/consents.
Events consumed
GDPR does not define its own custom events. It listens to the shared platform events:
CraftVariable::EVENT_INIT— registers thegdprTwig variable.Plugins::EVENT_AFTER_LOAD_PLUGINS— detects whether theyui(Craft Shop) plugin is installed, since customer data export/anonymize require it.UrlManager::EVENT_REGISTER_SITE_URL_RULES/EVENT_REGISTER_CP_URL_RULES— registers the routes above.UserPermissions::EVENT_REGISTER_PERMISSIONS— registers thegdpr:site-settingsandgdpr:cookie-groupspermission groups (and their nested activate/template/content/view-consents, create/edit/delete permissions).View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS— exposes the plugin's bundled front-end templates under thegdprtemplate root.
It also injects markup via two view hooks on the front end: before-head-end (consent scripts,
must load before GTM) and either before-body-end or after-body-start (the popup itself,
depending on the Render position setting), plus profile-nav-links for the customer account
navigation link.
Console commands
Registered under the gdpr module (console-only, via RetentionController):
# Delete consent records older than N days (default: 365)
php craft gdpr/retention/clear [--days=<n>] [--sid=<siteId> | --handle=<siteHandle>]
Pass either --sid or --handle to scope deletion to one site — passing both is an error. With
neither, consents are cleared across all sites. This command is destructive and irreversible.
Data-privacy note for integrators
The Download, Anonymize, and (planned) Delete account actions are the plugin's GDPR
data-subject-rights implementation for yStore customers. They currently cover the customer record,
orders, and the yui storage entry keyed by customer email — any additional customer data your own
plugin or integration stores under that customer will not automatically be included and should be
handled separately.