feat(content-gate): add per-block access control for Group, Stack, and Row blocks#4646
Open
feat(content-gate): add per-block access control for Group, Stack, and Row blocks#4646
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ix setRegistration param
Contributor
There was a problem hiding this comment.
Pull request overview
Adds per-block visibility controls for core/group, core/stack, and core/row blocks using Newspack Content Gate access rules, enabling editors to show/hide individual blocks to specific reader segments without creating a full gate.
Changes:
- Adds a new editor Inspector “Access Control” panel and registers block attributes for visibility mode + rule configuration.
- Adds a PHP
render_blockfilter to enforce per-block visibility on the frontend, with per-request caching. - Adds PHPUnit + Jest coverage and wires the new editor bundle into Webpack.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
webpack.config.js |
Adds a new build entry for the block-visibility editor script. |
includes/content-gate/class-content-gate.php |
Includes the new Block_Visibility feature file. |
includes/content-gate/class-block-visibility.php |
Implements server-side attribute registration, editor asset enqueue, and frontend render filtering/caching. |
src/content-gate/editor/block-visibility.tsx |
Registers attributes and injects the Inspector panel UI for target blocks. |
src/content-gate/editor/editor.scss |
Styles the Access Control panel UI elements. |
src/content-gate/editor/index.d.ts |
Adds shared TS types used by the content-gate editor code. |
tests/unit-tests/content-gate/class-block-visibility.php |
Adds PHPUnit tests for rule evaluation, rendering behavior, and caching. |
src/content-gate/editor/block-visibility.test.ts |
Adds Jest tests for the attribute registration filter. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use [] not stdClass as default for newspackAccessControlRules block attribute - Add comment on get_post_type() === false in enqueue_block_editor_assets - Fix setRegistration to not mutate its parameter; use immutable spread - Fix counting_rule test to use unique ID per run to avoid closure issues - Fix "Visiblity" typo in VisibilityControl help text - Guard test_rule registration against duplicate registration across tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Bypass access control during REST requests so blocks are never hidden in the editor's block renderer or preview contexts - Defensively cast newspackAccessControlRules to array in case the block parser yields a stdClass for the object-typed attribute - Fix FormTokenField empty label; use config.name + hideLabelFromVision Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cover the case where a user with edit_post capability on the current post sees all blocks regardless of access rules, and verify that a non-editor is still subject to normal rule evaluation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Blocks can now be linked to one or more existing content gates instead
of defining access rules inline. Gate rules are resolved server-side at
render time so any change to a gate is immediately reflected in every
block that references it.
- Add newspackAccessControlMode attribute ('gate' default, 'custom')
- Add newspackAccessControlGateIds array attribute for gate links
- Gate mode uses OR logic: reader must satisfy any one selected gate
- Deleted/unpublished gates are silently skipped; a block with only
inactive gates passes through with no restriction
- Localize available published gates to newspackBlockVisibility JS data
- Add GateControls FormTokenField component to the inspector panel
- Add mode toggle (Gate / Custom) with Gate as the default
- Add 7 new PHPUnit tests covering gate mode evaluation paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
All Submissions:
Changes proposed in this Pull Request:
Adds per-block visibility controls to
core/group,core/stack, andcore/rowblocks, allowing editors to show or hide individual blocks based on one or more content gates, or custom rules using the same Registered and Paid access rules used by content gates."Gate" mode:

"Custom" mode:

"Custom" mode exists because publishers often want to control per-block visibility at a different and/or more granular level than content gates. To use a real-world example, a subscriber might have access to restricted content across the site if they have an active subscription to either a Digital-Only or Print+Digital subscription product, but PDF issue embeds on magazine-focused pages should be visible only to Print+Digital subscribers.
Editor UI (
edit_others_postscapability required, on supported post types only):FormTokenField; free-text rules render aTextControl.Frontend evaluation (via
render_blockfilter):visiblemode renders the block only to matching readers;hiddenmode renders it only to non-matching readers.Access_Rules::evaluate_rules(), using the same AND/OR grouped logic as content gates.user_id + md5(rules)) so repeated blocks with identical rules evaluate only once.New files:
includes/content-gate/class-block-visibility.php— PHP class withrender_blockfilter, server-side attribute registration, and asset enqueue.src/content-gate/editor/block-visibility.tsx— React/TS entry: attribute registration filter, Inspector HOC, and all panel components.src/content-gate/editor/index.d.ts— Shared TypeScript types for the content-gate editor directory.tests/unit-tests/content-gate/class-block-visibility.php— 24 PHPUnit tests.src/content-gate/editor/block-visibility.test.ts— 7 Jest tests for the attribute registration filter.Closes NPPD-1430.
How to test the changes in this Pull Request:
Prerequisites:
NEWSPACK_CONTENT_GATESistrue(n wp config set NEWSPACK_CONTENT_GATES true --raw).n build newspack-plugin. Confirmdist/content-gate-block-visibility.jsexists.Inspector panel:
Frontend — "Custom" mode with "visible" visibility:
Frontend — "Custom" mode with "hidden" visibility:
Verification sub-option:
Front-end — "Gate" mode
Post type guard:
Content_Restriction_Control::get_available_post_types(). Confirm the Access Control panel does not appear and the JS asset is not enqueued.Editors are exempt:
Graceful degradation:
Other information: