Download the PHP package sandstorm/cookiepunch without Composer

On this page you can find all versions of the php package sandstorm/cookiepunch. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package cookiepunch

Sandstorm.CookiePunch

A Neos package that blocks elements like <script> and <iframe> server-side — before the markup reaches the browser — and ships Klaro as the consent UI to selectively unblock them once the user agrees.

Contents

Features

How it works

CookiePunch combines server-side markup rewriting with the client-side Klaro consent UI. On every render, the CookiePunch.blockTags(...) Eel helper walks the markup and breaks the configured tags: src becomes data-src, type becomes data-type, <script> tags get type="text/plain", and a data-name="<service>" attribute is added when a service is in play. The browser refuses to fetch or execute the broken tags. Klaro then reads data-name, shows a consent UI, and on accept swaps the attributes back so the browser fetches and runs the original content.

The service identifier is the single string that ties (a) the YAML/inline blocking config, (b) the data-name in the rewritten markup, and (c) the switch in the Klaro modal together. Keep it consistent across all three and the rest follows.

Installation

This puts the dependency in the outer composer.json / composer.lock (usually in your repo root or /app).

Important: If you want to declare CookiePunch settings inside one of your Flow packages, also add the composer dependency to that package's composer.json to ensure correct Flow package and configuration loading order.

For exhaustive references, see FullServiceConfig.yaml.

Minimal setup

Two files get a working consent modal on every page. Drop them into your site package and reload:

This blocks every <iframe> and <script> (except Neos' own), shows the consent modal, and is enough to verify the install. The 6 Steps below layer in real services, pattern matching, and editor integrations. See also Examples/Settings.CookiePunch.Basic.yaml.

Basic Configuration and Usages

Step 1: Adding the consent-modal

Drop a CookiePunch.fusion file in your site package:

This adds the consent modal and starts blocking every <iframe> and <script>. The !node.context.inBackend flag keeps the Neos backend functional.

Reload the page — it will likely look broken. Open the DevTools console and call klaro.show() to confirm Klaro is loaded; the next steps fix the breakage. For the full list of tag names you can pass to blockTags, see Supported tags.

Step 2: Always allow your own JavaScript

Some scripts (main.js, app.js, …) must always be allowed or your site won't work. You most likely have a Fusion prototype that bundles them — something like Vendor.Site:HeaderAssets — and that's the natural place to attach neverBlockTags:

For a one-off script tag, attach the helper directly:

The same effect can be achieved via a YAML pattern (Step 3), but the helper makes the intent — I checked, this script is required — explicit at the call site.

Step 3: Blocking via YAML config

Create Configuration/Settings.CookiePunch.yaml. Tip: register the package's schema.json in your IDE for auto-completion.

The config has two parts: consent drives the Klaro UI (purposes group services), while blocking matches tags by substring pattern and either lets them through (block: false), blocks them permanently (block: true), or attaches them to a service so the user can allow them via consent (service: anchor).

Given the config above, this input markup:

…is transformed into this output markup:

For substring-matching rules, the wildcard *, and the difference between block: false / block: true / service: …, see How blocking transforms markup.

Step 4: Providing a link to your privacy statement

The default URL is /privacy. Override it with a string for the simplest case:

For most projects you'll want editors to pick the privacy page from the inspector. Add a reference property on your Homepage NodeType:

…and point CookiePunch at it. site is already the Homepage, so no q(site).find(...) is needed:

For other approaches (XLIFF translation key, dedicated PrivacyPage node type), see Privacy URL alternatives.

Step 5: Let the user reopen the consent modal later

Place a link in Neos (e.g. in your privacy statement) with href="#open_cookie_punch_modal". A click handler picks it up and opens the modal — the browser does not reload because event.preventDefault() is called internally.

Alternatively call klaro.show() from your own JavaScript.

Step 6: Styling

Override the CSS variables Klaro exposes via YAML:

For the full variable list, see Manual styling.

Advanced Usages

Full list of consent / service options

Most inline comments are copied directly from the annotated config.js of Klaro for convenience.

Supported tags

CookiePunch.blockTags(...) and CookiePunch.neverBlockTags(...) accept any of these tag names:

iframe, script, audio, video, source, track, img, embed, input.

The same set is allowed as keys under Sandstorm.CookiePunch.blocking.tagPatterns in YAML — see schema.json.

Pattern reference

Patterns under tagPatterns.<tagName> are matched against the raw rendered tag string with strpos() — i.e. it's a substring match. Anything in the tag (src URL, attribute name, attribute value, …) is fair game.

The Packages/Neos.Neos pattern, for example, matches all of these:

Each pattern carries one of three actions:

Wildcard ("*")

The reserved key "*" flips the default for a tag name. Use sparingly — it defeats the purpose of documenting which services are in use.

The most defensible case is <img>: by default you usually do not want every image blocked, only specific tracking pixels. Add img to the blockTags call so CookiePunch processes it, then flip the default:

How blocking transforms markup

When CookiePunch breaks a tag, it does so by attribute rewriting — nothing is removed from the DOM:

A tag with no data-name stays broken forever — there is no service to drive its restoration.

Blocking a rendered Fusion subtree

An already-blocked piece of markup is not re-blocked when running the Eel helpers later on Neos.Neos:Page. This means we can hook into specific plugins to block them and attach them to a service.

This is especially useful for inline <script>...</script> tags that cannot be matched by a URL pattern.

Adding a contextual consent for non-iframe elements

When blocking a <script> you may end up with a broken UI as some styles or markup never run. Use the helper below to wrap parts of the rendered Fusion tree so Klaro can swap the broken content for a contextual consent.

Another use case: <audio> or <video> tags (with or without nested <source> tags). You may want to block them so a visitor's IP address isn't sent to a third-party server before consent.

Let the editor choose a service from the inspector

If editors can place HTML (e.g. via a Vendor.Site:Content.Html node type), they can introduce markup that sets cookies. With the default config, CookiePunch blocks this content — and if the markup matches no YAML pattern, it stays blocked permanently.

Add Sandstorm.CookiePunch:Mixin.ConsentServices to the affected node type to expose a service dropdown in the inspector:

Then wire the chosen service into the actual blocking:

Let the editor change the text of the consent

All texts of the consent notice and modal live in the Fusion prototype Sandstorm.CookiePunch:Config.Translations. Each key maps to a Klaro string — ok, decline, consentNotice.description, consentNotice.learnMore, consentModal.title, consentModal.description, privacyPolicy.text, contextualConsent.*, and more. The complete list is in Resources/Private/Fusion/Config.Translations.fusion.

You can override any of these from Fusion. To let editors maintain them, wire the paths to inspector properties on a dedicated node.

1. A node holding the editable texts

2. Wire the properties into Config.Translations

Use || CookiePunchConfig.translate(...) for keys where an empty inspector field should fall back to the bundled Klaro translation instead of blanking the string:

3. Enable HTML rendering for the descriptions

Neos.Neos:NodeLink renders a full <a href="…">…</a> tag, so any text containing the {imprint} substitution now contains HTML. Allow Klaro to render it:

4. Flush the cache when editors change the texts

The override reads from q(site).find(...) and is rendered inside the cached Neos.Neos:Page. Add Neos.Caching.nodeTypeTag('Vendor.Site:Document.CookieConsentTexts') to the consent cache — see Caching the consent.

Notes & caveats

Caching the consent

Sandstorm.CookiePunch:Consent ships without a @cache block. It is rendered inside the cached Neos.Neos:Page, so any dynamic read it makes — q(site).find(...) for conditional services, dynamic services, or editor-maintained texts — gets baked into each page's cache entry. Without explicit cache tags, editing the source nodes never reaches already-cached pages.

Override the prototype once with the canonical block and merge all the entry tags the rest of your setup needs:

Why this lives in one place. The entryTags keys must be unique within the block — if you copy the snippet from two Advanced sections that each define entryTags { 1 = ...; 2 = ... }, the later override silently wins and your first feature stops invalidating. Keep one @cache block in your project and add a new numbered tag for each Advanced feature you adopt.

Privacy URL alternatives

Beyond the simple-string and Homepage-property forms shown in Step 4, two other paths are available.

XLIFF translation key

Dedicated PrivacyPage node type

Manual styling

To take full control of the consent UI's CSS, disable the bundled stylesheet and provide your own. Note this couples your styling to Klaro's class names — it can break on package updates.

The original Klaro stylesheet ships at Resources/Private/KlaroCss/klaro.css if you want to fork from it.

Translations

Klaro already provides translations for many languages. They are exposed as XLIFF files in Resources/Private/Translations.

You can override translations by:

Example: translating service labels

Service labels in your Settings.CookiePunch.yaml can be translated like this:

Where:

Screenshot 2022-06-07 at 14 37 57

Conditional Rendering of Services in the Consent Modal

You can decide at runtime whether a switch should appear in the consent modal:

For a complete example see Examples/Settings.CookiePunch.WithWhenConditions.yaml.

This is useful in multi-site setups, and to prevent unnecessary consent switches when e.g. no YouTube video has ever been added to the content (the Vendor.Site:Content.YouTube node type above stands in for whichever content type embeds a YouTube video in your site).

Notes:

  1. The when value must be an Eel expression that evaluates to boolean.
  2. With no when condition, the default is ${true} — the switch always renders for that service.
  3. When querying the content repository with q(...), only site is available. documentNode and node are not.
  4. Klaro stores past consent decisions in a cookie, so removing and re-adding e.g. a YouTube video will not re-prompt users who already consented.

Important: every node type referenced in your when expressions needs a matching Neos.Caching.nodeTypeTag(...) on the consent cache (e.g. Vendor.Site:Document.RootPage for q(site).property(...), Vendor.Site:Content.YouTube for q(site).find('[instanceof ...YouTube]').count()). See Caching the consent for the canonical block.

Preventing an empty consent modal

If all when expressions evaluate to false you can hide the modal entirely:

Editor-defined dynamic services

Let the editor choose a service from the inspector lets editors pick from a predefined list of services. Sometimes you want them to create a new service on the fly — e.g. a content element where the editor pastes a third-party embed, names the service, and a matching switch appears in the consent automatically.

The trick is to override Sandstorm.CookiePunch:Consent and append dynamically-built services to servicesRemainingAfterWhenConditions (the same property used in Conditional Rendering). The service key is derived by hashing the editor's typed name, so the same value can be used on both the blocking side and the consent side.

1. A content element node type

2. Render and block the element's own markup

The element renders the embed, then blocks it and attaches the contextual consent. The service key is the md5 of the editor's serviceName:

3. Register a service for every embed

Override the consent prototype to scan the site for these elements and append one service per distinct name:

Then add Neos.Caching.nodeTypeTag('Vendor.Site:Content.CookieConsentEmbed') to the consent cache so a newly published embed flushes every page's consent — see Caching the consent.

4. Declare the purpose

Every purpose a service references must exist under consent.purposes (for its title/description and translations):

Notes & caveats

Per-service lifecycle callbacks (onInit / onAccept / onDecline)

Each service can declare JavaScript snippets that run when Klaro initialises, when the user accepts, and when the user declines:

Each value is the body of a JS function. The strings are exposed via window.cookiePunchCallbacks and registered with Klaro before the main bundle loads — so they work under strict CSP without unsafe-eval. (Prior to v5 these were registered via eval(). See MIGRATIONS.md.)

A complete service config showing every supported key — including these callbacks — is in Examples/Settings.CookiePunch.FullServiceConfig.yaml.

Contextual Consent Only Mode

If you don't want to show the cookie banner or modal initially, use the global contextualConsentOnly mode introduced with version 4.4.0.

Troubleshooting

The consent modal doesn't appear

Please check

This could be the problem

How to fix

Add the Fusion include from Step 1. If CSP blocks the inline script, either allow script-src 'unsafe-inline' (not recommended) or attach a nonce/hash to the consent's script tag.

A service switch is missing from the modal

Please check

This could be the problem

How to fix

Open the DevTools console and inspect window.cookiePunchConfig — every service the server emitted is listed there. If yours is missing, the issue is in the Fusion/YAML; if it's present but the switch isn't, see Caching the consent and flush the page cache.

Content stays blocked even after the user accepts

Please check

This could be the problem

How to fix

Make data-name and the service name byte-identical. For dynamic services, ensure the consent's @cache is tagged on the embed node type so updates propagate.

The Neos backend looks broken

Please check

This could be the problem

How to fix

Always pass !node.context.inBackend as the third argument:

Edits to dynamic-source nodes don't show up on already-published pages

Please check

This could be the problem

How to fix

Add the missing Neos.Caching.nodeTypeTag('Vendor.Site:Document.X') to the consent cache — see Caching the consent.

Iframes work after unblocking but are the wrong size or in the wrong place

Please check

This could be the problem

How to fix

Block the JS too — even though it doesn't set any cookies — and attach it to the same service as the iframe. The JS will then run after the iframe is unblocked.

Migration guide

For upgrade notes between major versions, see MIGRATIONS.md.

Contributing

For test, build, and translation workflows, see CONTRIBUTING.md.


All versions of cookiepunch with dependencies

PHP Build Version
Package Version
Requires neos/neos Version ^9.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sandstorm/cookiepunch contains the following files

Loading the files please wait ...