block_content_visibility
Block Content Visibility exposes Drupal core's Condition Plugin System UI directly on the block_content add/edit form. Visibility conditions are stored on the block_content entity and evaluated at render time, so a single configuration applies across every placement of the block — classic block placements and Layout Builder inline blocks alike.
Why this module
Drupal core ships two layers of block visibility:
- Plugin layer — Condition plugins (User Role, Request Path, Language, etc.) provided by core and contrib.
- Placement layer —
BlockFormrenders condition plugin forms when you place a block at/admin/structure/block/add/<id>. Conditions are stored on the placement (blockconfig entity).
The placement layer works fine for blocks placed in exactly one region. It breaks down when:
- A reusable
block_contentis placed in multiple regions, themes, or Layout Builder sections, and you want the same visibility rules to apply everywhere. - Editors who manage content (
block_contententities) do not have permission to edit placements at/admin/structure/block. - You want visibility to travel with the content through Content Moderation revisions and translation.
This module adds a third layer — content-level visibility — by attaching a visibility_conditions base field to block_content and rendering Drupal's Condition Plugin UI on the entity form. Conditions are evaluated at render time via hook_block_access and AND-combined with any placement-level conditions.
Features
- Vertical-tabs UI on the standard
block_contentadd/edit form, with one tab per available Condition plugin and an explicit "Apply this condition" opt-in so only the rules you set get persisted. - Layout Builder support: the same UI surfaces inside the inline-block edit modal, courtesy of Block Form Alter (hard dependency).
- Per-instance visibility persisted on the
block_contententity in a revisionable base field, so visibility travels with revisions and translations. - Render-time evaluation that mirrors core's
BlockAccessControlHandler: per-condition context resolution, defensive forbid on missing context, full cache-metadata bubbling. - Coexists with placement-level visibility (logical AND). The placement edit form gets an inline warning when the underlying
block_contenthas content-level conditions, with a deep-link to edit them. - Permission-gated UI (
administer block content visibility): revoking the permission hides the form group but never silently disables active rules. - Settings form at
/admin/config/system/block-content-visibilityfor opting bundles in and hiding noisy or context-dependent plugins. - Zero new Condition plugins. The module is plumbing — its value scales with the plugins you already have enabled (core + contrib + your own).
Use cases
- Reusable promo banners. A "VIP free shipping" banner placed in three regions: configure the Mautic Segment condition once on the content; all three placements honour it.
- Language-specific blocks. A welcome block placed across multiple themes — set the Language condition once on the entity instead of per placement.
- Layout Builder personalisation. Editors compose pages with inline custom blocks and gate each block on a User Role or Cookie condition without leaving the Layout Builder modal.
- Marketing automation gates. Combine Mautic Audiences conditions with commerce conditions on a single seasonal banner.
How it works
A visibility_conditions base field (type string_long, revisionable, single-value, JSON-encoded payload) is attached to every block_content entity. The stored shape is the same array<plugin_id, configuration> that BlockForm::submitVisibility() writes to a placement. At render time, hook_block_access resolves the underlying entity (UUID lookup for classic blocks, block_revision_id for Layout Builder inline blocks), builds a ConditionPluginCollection, applies per-condition runtime contexts, AND-resolves, and returns an AccessResult with bubbled cache metadata.
Requirements
- Drupal ^10.3 || ^11
- PHP ^8.2
- Block Form Alter ^2.0
The module declares no hard dependency on any contrib Condition plugin. Whatever Condition plugins are enabled on the site become available in the Visibility tabs.
Similar projects
- Block Content Type Visibility — adds a Show/Hide UI for the existing node-type-style condition at
/admin/structure/block. Per-bundle, not per-instance; stays on the placement form. - Block Visibility Groups — groups blocks under shared site-admin conditions. Site-admin tool with a different scope.
- Block Visibility Conditions — contributes "Not Node Type" / "Not Taxonomy" condition plugins. Just plugins, no UI move.
- Drupal core issue #2916876 — open proposal to add visibility conditions to blocks within Layout Builder. Stores on the LB section/component, not on the
block_contententity; covers Layout Builder only. This module persists on the entity so visibility survives across all placements (LB and classic).