{"id":13532100,"url":"https://github.com/jberghoef/wagtail-tag-manager","last_synced_at":"2025-04-09T20:11:35.108Z","repository":{"id":32850287,"uuid":"126696903","full_name":"jberghoef/wagtail-tag-manager","owner":"jberghoef","description":"A Wagtail add-on for managing scripts and tags. Ready to go with a cookie bar and consent management.","archived":false,"fork":false,"pushed_at":"2024-02-28T15:38:19.000Z","size":6587,"stargazers_count":77,"open_issues_count":17,"forks_count":23,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-09T20:11:30.183Z","etag":null,"topics":["consent","consent-management","cookie-consent","cookie-declarations","cookiebar","cookies","gdpr","tag-management"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/wagtail-tag-manager/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jberghoef.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["jberghoef"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-03-25T12:50:11.000Z","updated_at":"2024-12-27T21:17:39.000Z","dependencies_parsed_at":"2024-02-28T16:31:43.676Z","dependency_job_id":null,"html_url":"https://github.com/jberghoef/wagtail-tag-manager","commit_stats":{"total_commits":490,"total_committers":12,"mean_commits":"40.833333333333336","dds":"0.13469387755102036","last_synced_commit":"a89e457e86b323ebb431cd645552ab2c17e0c858"},"previous_names":[],"tags_count":103,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jberghoef%2Fwagtail-tag-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jberghoef%2Fwagtail-tag-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jberghoef%2Fwagtail-tag-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jberghoef%2Fwagtail-tag-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jberghoef","download_url":"https://codeload.github.com/jberghoef/wagtail-tag-manager/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consent","consent-management","cookie-consent","cookie-declarations","cookiebar","cookies","gdpr","tag-management"],"created_at":"2024-08-01T07:01:08.190Z","updated_at":"2025-04-09T20:11:35.082Z","avatar_url":"https://github.com/jberghoef.png","language":"Python","funding_links":["https://github.com/sponsors/jberghoef"],"categories":["Apps"],"sub_categories":["Content Management"],"readme":"# Wagtail Tag Manager\n\n[![CircleCI][circleci]](https://circleci.com/gh/jberghoef/wagtail-tag-manager)\n[![CodeCov][codecov]](https://codecov.io/gh/jberghoef/wagtail-tag-manager)\n[![Codacy][codacy]](https://www.codacy.com/app/jberghoef/wagtail-tag-manager)\n[![License][license]](https://opensource.org/licenses/BSD-3-Clause)\n[![Fossa][fossa]](https://app.fossa.com/projects/git%2Bgithub.com%2Fjberghoef%2Fwagtail-tag-manager)\n[![Version][version]](https://pypi.python.org/pypi/wagtail-tag-manager/)\n[![Downloads][downloads]](https://pepy.tech/project/wagtail-tag-manager)\n[![Black][black]](https://github.com/ambv/black)\n[![Prettier][prettier]](https://github.com/prettier/prettier)\n[![Gitpod ready-to-code][gitpod]](https://gitpod.io/#https://github.com/jberghoef/wagtail-tag-manager)\n\n[circleci]: https://circleci.com/gh/jberghoef/wagtail-tag-manager.svg?style=svg \"Circle CI\"\n[codecov]: https://codecov.io/gh/jberghoef/wagtail-tag-manager/branch/master/graph/badge.svg \"Codecov\"\n[codacy]: https://api.codacy.com/project/badge/Grade/2a59a006e69442bb809bf08f47028eb9 \"Codacy\"\n[license]: https://img.shields.io/badge/license-BSD-blue.svg \"License\"\n[fossa]: https://app.fossa.com/api/projects/git%2Bgithub.com%2Fjberghoef%2Fwagtail-tag-manager.svg?type=shield \"Fossa\"\n[version]: https://img.shields.io/pypi/v/wagtail-tag-manager.svg \"Version\"\n[downloads]: https://pepy.tech/badge/wagtail-tag-manager \"Downloads\"\n[black]: https://img.shields.io/badge/code%20style-black-000000.svg \"Black\"\n[prettier]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg \"Prettier\"\n[gitpod]: https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod \"Gitpod\"\n\nWagtail Tag Manager (WTM for short) is a [Wagtail](https://wagtail.io/) addon\nthat allows for easier and GDPR compliant administration of scripts and tags.\n\n![Screenshot](screenshots/screenshot.png \"Screenshot\")\n\n_In this package the term \"tag\" is being used for code snippets being injected\ninto HTML. This is not to be confused with tags used to identify content in the\nCMS, such as pictures and documents._\n\n## ‼️ Breaking changes\n\nAs of version 2.0, consent is stored differently in the `wtm` cookie. The reason for this change is\nto prevent so-called \"cache-busting\" and only refresh the WTM cookie after a certain period of time\n(specified in [`WTM_COOKIE_REFRESH`](#wtm_cookie_refresh)).\nThe cookie will now contain a `base64` and `uri` encoded JSON string which stores both the consent state\nand additional information. Old versions of the cookie\n(e.g. `necessary:true|preferences:unset|statistics:pending|marketing:false`) will automatically be\nupgraded when detected. Once decoded, it will look something like this:\n\n```json\n{\n  \"meta\": {\n    \"id\": \"b402114a-352f-488f-8481-834cd91a1b2b\",\n    \"refresh_timestamp\": 1694520568.531865,\n    \"set_timestamp\": 1694520573.685324\n  },\n  \"state\": {\n    \"necessary\": \"true\",\n    \"preferences\": \"unset\",\n    \"statistics\": \"pending\",\n    \"marketing\": \"false\"\n  }\n}\n```\n\nTo easily parse the cookie using JavaScript, you can use this code snippet:\n\n```js\nconst { meta, state } = JSON.parse(atob(decodeURIComponent(cookie_content_goes_here)));\n```\n\nYou can ready more on how to easily access this state from your front-end [here](#wtm_inject_script).\n\n## Features\n\nWagtail Tag Manager offers functionality similar to platforms like\n**Adobe Dynamic Tag Management**, **Google Tag Manager** and **Tealium iQ**\nwithout the need of a third party. It's fully integrated into Wagtail.\n\nThis approach comes with a couple of advantages, most prominently the ability\nto inject tags into a page before the response is send to a client.\n\n### Administrators\n\n- Manage scripts and tags from within Wagtail, with powerful options to define load order.\n- Store reusable content in constants and variables and easily add them to your tags.\n- Create triggers to load tags based on events in the browser.\n- Create cookie declarations to provide end-users with a full picture of the tracking taking place.\n\n### Developers\n\n- Create custom variables to give administrators functionality specific to your use-cases.\n\n## Table of content\n\n- [Disclaimer](#disclaimer)\n- [Requirements](#requirements)\n- [Instructions](#instructions)\n- [Template tags](#template-tags)\n  - [`wtm_instant_tags`](#wtm_instant_tags)\n  - [`wtm_lazy_manager`](#wtm_lazy_manager)\n  - [`wtm_cookie_bar`](#wtm_cookie_bar)\n  - [`wtm_include`](#wtm_include)\n- [Preference management](#preference-management)\n- [Context processors](#context-processors)\n- [Settings](#settings)\n  - [`WTM_TAG_TYPES`](#wtm_tag_types)\n  - [`WTM_INJECT_TAGS`](#wtm_inject_tags)\n  - [`WTM_MANAGE_VIEW`](#wtm_manage_view)\n  - [`WTM_COOKIE_EXPIRE`](#wtm_cookie_expire)\n  - [`WTM_COOKIE_REFRESH`](#wtm_cookie_refresh)\n  - [`WTM_CACHE_TIMEOUT`](#wtm_cache_timeout)\n  - [`WTM_PRESERVE_VARIABLES`](#wtm_preserve_variables)\n  - [`WTM_INJECT_STYLE`](#wtm_inject_style)\n  - [`WTM_INJECT_SCRIPT`](#wtm_inject_script)\n  - [`WTM_SUMMARY_PANELS`](#wtm_summary_panels)\n  - [`WTM_ENABLE_SCANNER`](#wtm_enable_scanner)\n  - [`WTM_CHROMEDRIVER_URL`](#wtm_chromedriver_url)\n- [Custom variables](#custom-variables)\n- [Page tag mixin](#page-tag-mixin)\n- [Lazy triggers](#lazy-triggers)\n- [Sandbox](#sandbox)\n- [Concept](#concept)\n- [Who's using it](#whos-using-it)\n- [License](#license)\n\n## Disclaimer\n\nThis package attempts to ease the implementation of tags by the new ePrivacy\nrules as defined by the European Union. I urge you to read about these new\nrules and ensure you are properly configuring your tags. This package is free\nand the author can not be held responsible for the correctness of your\nimplementation, or the assumptions made in this package to comply with the new\nePrivacy regulation.\n\nRead more about the [ePrivacy Regulation](https://ec.europa.eu/digital-single-market/en/proposal-eprivacy-regulation).\n\nIncluded in this package is a cookie bar which admittedly provides too little\ninformation to end users regarding the purpose of the scripts you are placing\non the website. For compliance, please use the `cookie_bar.html` template to\nchange the text shown in the cookie bar.\n\n## Requirements\n\n| Package | Version(s)           |\n| ------- | -------------------- |\n| Django  | 3.2, 4.0, 4.1, 4.2   |\n| Wagtail | 4.1, 4.2, 5.0. 5.1   |\n| Python  | 3.8, 3.9, 3.10, 3.11 |\n\n## Instructions\n\n**Installation:**\n\n```\npip install wagtail-tag-manager\n```\n\n**Add the application to your `INSTALLED_APPS`:**\n\n```python\nINSTALLED_APPS = [\n    # ...\n    'wagtail_modeladmin',\n    'wagtail_tag_manager',\n    # ...\n]\n```\n\nIf you wish to enable the cookie bar settings (allowing you to change to title\nand text displayed in the cookie bar), also include `wagtail.contrib.settings`\nin the `INSTALLED_APPS`.\n\n**Include the middleware:**\n\n```python\nMIDDLEWARE = [\n    # ...\n    \"wagtail_tag_manager.middleware.CookieConsentMiddleware\",\n    'wagtail_tag_manager.middleware.TagManagerMiddleware', # optional\n    # ...\n]\n```\n\nWTM offers two ways to implement it's functionality. You can either choose to\nuse the `TagManagerMiddleware` (which will rewrite the html on each request)\nor use the `{% wtm_instant_tags %}` and `{% wtm_lazy_manager %}` template\ntags.\n\nIf you prefer to use the template tags to inject tags into your templates,\nset the `WTM_INJECT_TAGS` and `WTM_INJECT_SCRIPT` settings to `False`\nand implement the template tags as follows:\n\n```html+django\n{% load wtm_tags %}\n\n\u003chead\u003e\n  {% wtm_instant_tags 'top_head' %} ... {% wtm_instant_tags 'bottom_head' %}\n\u003c/head\u003e\n\u003cbody\u003e\n  {% wtm_instant_tags 'top_body' %} ... {% wtm_instant_tags 'bottom_body' %} {% wtm_lazy_manager %}\n\u003c/body\u003e\n```\n\n**Include the urls:**\n\n```python\nfrom django.urls import include, path\nfrom wagtail_tag_manager import urls as wtm_urls\n\nurlpatterns = [\n    # ...\n    path('wtm/', include(wtm_urls)),\n    # ...\n    path('', include(wagtail_urls)),\n    # ...\n]\n```\n\n## Template tags\n\nAs an alternative to using the middleware you can use the `wtm_instant_tags`\nand `wtm_lazy_manager` template tags. Please be sure to use the\n`TagManagerMiddleware` OR the template tags, never both.\n\n### `wtm_instant_tags`\n\nTo load all instant tags at once:\n\n```html+django\n{% load wtm_tags %}\n\n\u003chead\u003e\n  ... {% wtm_instant_tags %}\n\u003c/head\u003e\n```\n\nTo load tags corresponding to a certain position:\n\n```html+django\n{% load wtm_tags %}\n\n\u003chead\u003e\n  {% wtm_instant_tags 'top_head' %} ... {% wtm_instant_tags 'bottom_head' %}\n\u003c/head\u003e\n\u003cbody\u003e\n  {% wtm_instant_tags 'top_body' %} ... {% wtm_instant_tags 'bottom_body' %}\n\u003c/body\u003e\n```\n\n### `wtm_lazy_manager`\n\n```html+django\n{% load wtm_tags %}\n\n\u003cbody\u003e\n  ... {% wtm_lazy_manager %}\n\u003c/body\u003e\n```\n\nOptionally, you can disable either the script and/or the styling.\n\n```html+django\n{% load wtm_tags %}\n\n\u003cbody\u003e\n  ... {% wtm_lazy_manager include_style=False include_script=False %}\n\u003c/body\u003e\n```\n\n---\n\n### `wtm_cookie_bar`\n\n![Cookie bar with form](screenshots/cookie-bar-with-form.png \"Cookie bar with form\")\n\n![Cookie bar with form and details](screenshots/cookie-bar-with-form-and-details.png \"Cookie bar with form and details\")\n\n```html+django\n{% load wtm_tags %}\n\n\u003cbody\u003e\n  {% wtm_cookie_bar %} ...\n\u003c/body\u003e\n```\n\n### `wtm_include`\n\nWTM comes with the `wtm_include` template tag to accommodate loading of\nresources and markup based on the tag strategy and consent given. It can be\nused as a way to load html, css or javascript files.\n\n```html+django\n{% load wtm_tags %}\n\n\u003cbody\u003e\n  ... {% wtm_include \"necessary\" \"css/style.css\" %} {% wtm_include \"necessary\" \"js/style.js\" %} {%\n  wtm_include \"necessary\" \"content.html\" %} ...\n\u003c/body\u003e\n```\n\nAlternatively, you can use it as a block:\n\n```html+django\n{% load wtm_tags %}\n\n\u003cbody\u003e\n  ... {% wtm_include \"statistics\" %}\n  \u003cscript\u003e\n    console.log(\"Included conditionally\");\n  \u003c/script\u003e\n  {% wtm_endinclude %} ...\n\u003c/body\u003e\n```\n\n### Preference management\n\nYou can use the following provided template tags to render a tag status\noverview, a table with cookie declarations or a consent form.\n\n```html+django\n{% wtm_tag_table %} {% wtm_declaration_table %} {% wtm_manage_form %}\n```\n\n## Context processors\n\nTo enable the context processors, add the following to your settings:\n\n```python\n\"context_processors\": [\n    # ...\n    \"wagtail_tag_manager.context_processors.consent_state\",\n]\n```\n\nYou can now use the following value in your templates:\n\n```html+django\n{{ wtm_consent_state.necessary }} {{ wtm_consent_state.preferences }} {{\nwtm_consent_state.statistics }} {{ wtm_consent_state.marketing }}\n```\n\nThese will return a boolean indicating wether or not tags specific to the\ncorresponding state should load.\n\n## Settings\n\n### `WTM_TAG_TYPES`\n\n```python\nWTM_TAG_TYPES = {\n    # key, verbose name, setting\n    \"necessary\": (_(\"Necessary\"), \"required\"),\n    \"preferences\": (_(\"Preferences\"), \"initial\"),\n    \"statistics\": (_(\"Statistics\"), \"initial\"),\n    \"marketing\": (_(\"Marketing\"), \"\"),\n}\n```\n\nAllows you to define the tag types available. This can be helpful if you'd like\nthe change the terminology used, or when you'd prefer to split a type in\nmultiple sections. Notice the two keywords (`required` and `initial`) used.\n\nTags marked as `required` can not be disabled and will always be included on\nevery page.\n\nTags marked as `initial` will be included as long as no explicit consent has\nbeen given by the end user, provided the browser allows cookies. While no\nconsent has been given, these tags will be loaded lazily to honor the browser\nsettings (which we can only read using javascript).\n\nThe third option is to mark a tag as `delayed`. This will ensure the tag will\nnot load on the first page load, but only from the second load forward.\n\n### `WTM_INJECT_TAGS`\n\n```python\nWTM_INJECT_TAGS = True\n```\n\nInstructs the middleware to inject all tags marked \"instant load\" in the\ndocument. Disable this if you would rather use the `{% wtm_instant_tags %}`\ntemplate tags.\n\n### `WTM_MANAGE_VIEW`\n\n```python\nWTM_MANAGE_VIEW = True\n```\n\nAllows you to enable or disable the included \"manage\" view allowing users to\nget insight in the tags running on your site and adjust their preferences.\nThe view is enabled by default.\n\n### `WTM_COOKIE_EXPIRE`\n\n```python\nWTM_COOKIE_EXPIRE = 365\n```\n\nSets the expiration time in days of WTM's cookies. Notice that this is only\napplicable to the consent cookies used by WTM, not any cookies placed by tags.\n\n### `WTM_COOKIE_REFRESH`\n\n```python\nWTM_COOKIE_REFRESH = 30\n```\n\nSets the refresh time in days of WTM's cookies. Notice that this is only\napplicable to the consent cookies used by WTM, not any cookies placed by tags.\n\n### `WTM_CACHE_TIMEOUT`\n\n```python\nWTM_CACHE_TIMEOUT = 1800\n```\n\nSets the amount of seconds the cache will be preserved. At the moment,\ncaching is only applied to constants, which will refresh when a constant is\nsaved. Default is 30 minutes.\n\n### `WTM_PRESERVE_VARIABLES`\n\n```python\nWTM_PRESERVE_VARIABLES = True\n```\n\nConfigures whether the variables are preserved for each request, or refreshed\nfor each tag applied to a response. When set to `False`, a query will be done\nfor each single tag which will add up quickly.\n\n### `WTM_INJECT_STYLE`\n\n```python\nWTM_INJECT_STYLE = True\n```\n\nChange to `False` to prevent WTM's included styles from loading. This is useful\nif you wish to style the cookiebar yourself.\n\n### `WTM_INJECT_SCRIPT`\n\n```python\nWTM_INJECT_SCRIPT = True\n```\n\nChange to `False` to prevent WTM's included scripts from loading. This is\nuseful if you don't want to use the inlcuded lazy loading and cookie bar\nfunctionality. While enabled, the script will expose the `window.wtm.consent()`\nfunction. When called, the function will retrieve the current consent state\nand information from the `wtm` cookie. This will like something like this:\n\n```json\n{\n  \"meta\": {\n    \"id\": \"b402114a-352f-488f-8481-834cd91a1b2b\",\n    \"refresh_timestamp\": 1694520568.531865,\n    \"set_timestamp\": 1694520573.685324\n  },\n  \"state\": {\n    \"marketing\": \"false\",\n    \"necessary\": \"true\",\n    \"preferences\": \"true\",\n    \"statistics\": \"true\"\n  }\n}\n```\n\n### `WTM_SUMMARY_PANELS`\n\n```python\nWTM_SUMMARY_PANELS = False\n```\n\nDisables or enables the summary panels visible on the Wagtail admin dashboard.\n\n![Admin summary panels](screenshots/summary-panels-admin.png \"Summary panels on the dashboard\")\n\n### `WTM_ENABLE_SCANNER`\n\n**This is an experimental feature.**\n\n```python\nWTM_ENABLE_SCANNER = False\n```\n\nWhen enabled, allows scanning of cookies placed on the website. Use this to\nautomatically generate cookie declarations. Will attempt to use Chrome Driver\nwhen available, and will fall back to regular requests if not.\n\n### `WTM_CHROMEDRIVER_URL`\n\n**This is an experimental feature.**\n\n```python\nWTM_CHROMEDRIVER_URL = \"http://0.0.0.0:4444/wd/hub\"\n```\n\nAllows configuration of the docker container running an instance of\n`selenium/standalone-chrome`.\n\nWhen developing, use the following command to run the docker container and\nensure that your site is configured be accessible over your computer's public\nip. Otherwise the docker container won't be able to access the website.\n\nhttps://hub.docker.com/r/selenium/standalone-chrome/\n\n## Custom variables\n\nIn addition to managing variables in the admin interface, variables can also be\ncreated in your source code by registering a `CustomVariable`.\n\n```python\nfrom wagtail_tag_manager.decorators import register_variable\nfrom wagtail_tag_manager.options import CustomVariable\n\n@register_variable\nclass Variable(CustomVariable):\n    name = \"Custom variable\"\n    description = \"Returns a custom value.\"\n    key = \"custom\"\n\n    def get_value(self, request):\n        return \"This is a custom variable.\"\n```\n\n![Admin custom variables](screenshots/custom-variables-admin.png \"Custom variables visible in the code editor\")\n\n## Page tag mixin\n\nIf you would like to include tags on a page, include the `TagMixin` mixin.\nUnder the \"Settings\" tab of the corresponding page type a list of tags will be\nshown. By selecting these, these tags will be included when the page loads.\n\nAdditionally, by selecting the \"Include children\" field, all descending pages\nof the configured page will also load the chosen tags.\n\nNote that the consent state is being applied to these tags. If the selected tag\nis marked as, for example, \"marketing\", the end-user still must allow this type\nof tags before is is being injected.\n\n```python\nfrom wagtail_tag_manager.mixins import TagMixin\n\nclass HomePage(TagMixin, Page):\n    pass\n```\n\n![Tag mixin admin](screenshots/tag-mixin-admin.png \"The tag mixin admin interface\")\n\n## Lazy triggers\n\nTriggers allow you to monitor events on the frontend of your website and load a\ntag after a specified event has occurred. By using conditions you are able to\nharness (custom) variables to only trigger a tag once your event complies with\nthe conditions that you specified.\n\n![Trigger admin](screenshots/trigger-admin.png \"The trigger admin interface\")\n\n## Sandbox\n\nTo experiment with the package you can use the sandbox provided in this\nrepository. To install this you will need to create and activate a\nvirtualenv and then run `make sandbox`. This will start a fresh Wagtail\ninstall, with the tag manager module enabled, on http://localhost:8000\nand http://localhost:8000/cms/. The superuser credentials are\n`superuser` with the password `testing`.\n\nVarious types of tags, constants and variables are enabled out of the box.\nCheck out the console in your browser to see them in action.\n\n## Concept\n\nWTM comes with the following tag types pre-configured:\n\n| Name        | Setting  |\n| ----------- | -------- |\n| Necessary   | Required |\n| Preferences | Initial  |\n| Statistics  | Initial  |\n| Marketing   | Default  |\n\nThese types correspond to the segmentation made by the EU [here](https://gdpr.eu/cookies/).\n\n| State                                                        | Required | Initial | Delayed | Default |\n| ------------------------------------------------------------ | -------- | ------- | ------- | ------- |\n| No cookies accepted.                                         | yes      | no      | no      | no      |\n| Cookies implicitly accepted through browser settings.        | yes      | yes     | yes¹    | no      |\n| Cookies explicitly accepted, noting tracking functionality.² | yes      | yes     | yes¹    | yes     |\n\n_¹ From the second page load onward._\n\n_² According to the ePrivacy regulation, mentioning that you are using tracking functionality is mandatory._\n\nNote that in the case of Statistics cookies or local storage, you are obliged\nto still show a notification at least once, noting that you are using cookies\nfor analytical and performance measurement purposes.\n\nWhen implementing Marketing cookies, the user has to explicitly give permission\nfor you to enable them for their session. When asking for permission, you must\nexplicitly state the tracking functionality of the script you are using.\n\nTo ease the implementation by this concept, Wagtail Tag Manager allows you to\ndefine a tag as \"Necessary\", \"Preferences\", \"Statistics\" or \"Marketing\".\nWhen properly configured, it'll take care of loading the correct tag at\nthe correct time, taking in account the following scenario's:\n\n1. The user has not accepted cookies.\n\n   |         | Required | Initial | Delayed | Default |\n   | ------- | -------- | ------- | ------- | ------- |\n   | Instant | yes      | no      | no      | no      |\n   | Lazy    | yes      | no      | no      | no      |\n\n2. The user has accepted cookies through browser settings.\n\n   |         | Required | Initial | Delayed | Default |\n   | ------- | -------- | ------- | ------- | ------- |\n   | Instant | yes      | yes¹    | yes²    | no      |\n   | Lazy    | yes      | yes     | yes²    | no      |\n\n   _¹ Will be loaded lazily._\n\n   _² From the second page load onward._\n\n   As the acceptance of \"Initial\" tags can only be verified client side, we'll\n   first load all the \"Initial\" tags lazy (whether they are instant or not).\n\n   Please note that we still have to show a message stating that we are using\n   tags with analytical purposes.\n\n3. The user has explicitly accepted cookies for your site.\n\n   |         | Required | Initial | Delayed | Default |\n   | ------- | -------- | ------- | ------- | ------- |\n   | Instant | yes      | yes     | yes     | yes     |\n   | Lazy    | yes      | yes     | yes     | yes     |\n\n## Who’s using it?\n\nI'd love to hear from sites and applications where WTM is being used. Please\ncontact me if you'd like your implementation to be listed here!\n\n## License\n\nTo make Wagtail Tag Manager accessible, it's is published under the BSD 3-Clause\n\"New\" or \"Revised\" License. For more information, please refer to the\n[LICENSE](LICENSE) file in this repository.\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fjberghoef%2Fwagtail-tag-manager.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fjberghoef%2Fwagtail-tag-manager?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjberghoef%2Fwagtail-tag-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjberghoef%2Fwagtail-tag-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjberghoef%2Fwagtail-tag-manager/lists"}