Skip to main content

Content Gating/Protection

Yoko Core comes with a built in content gating feature that meets the needs of most Yoko Co clients.

Main Options

The main Content Gating settings live on the existing Yoko SSO and Content Protection settings screen.

Automatic Custom Introduction Generation

The Custom Introduction field in the Content Protection metabox can now be generated automatically for selected post types.

SettingDescription
Post TypesOpt-in list of public post types that should auto-generate the Custom Introduction field. This field uses Select2 for easier searching on sites with many post types. Nothing is enabled by default.
UnitsChoose whether generated introductions should be limited by words or paragraphs. Default: paragraphs.
LimitNumber of words or paragraphs to include. Default: 1.
Minimum Words Per ParagraphOnly used when the unit is paragraphs. If the first paragraph is shorter than this threshold and another paragraph exists, the generator includes the second paragraph too. Default: 20.

Generation Rules

  • Automatic generation only runs for the post types selected in settings.
  • Automatic generation only fills the Custom Introduction field when it is empty.
  • If an editor writes a Custom Introduction manually, future saves leave that value alone.
  • If the post content contains a WordPress More tag, everything before the More tag takes precedence over the global word or paragraph settings.
  • When paragraph mode is enabled and the limit is 1, a short lead paragraph can expand the generated preview to two paragraphs so the teaser still reads naturally.

Content Gating Metabox

When a post type has automatic Custom Introduction generation enabled, the Content Protection metabox shows an informational notice so editors know the field can be generated from the main content.

The metabox also includes a note explaining that the WordPress More tag overrides the automatic settings. This gives editors a lightweight per-post way to choose the exact preview break without changing global configuration.

Editorial Workflow

  1. Enable automatic generation for one or more post types in the settings screen.
  2. Leave the Custom Introduction field empty when you want Yoko Core to populate it automatically.
  3. Add a More tag in the post content when you need a hand-authored preview cutoff.
  4. Enter a Custom Introduction manually when a post needs a fully custom gated preview.

WP-CLI Regeneration

Use WP-CLI to preview or regenerate introductions in bulk:

wp yoko custom_excerpt --post_type=resource --dry-run
wp yoko custom_excerpt --post_type=resource --force
wp yoko custom_excerpt --post_type=resource --unit=paragraphs --limit=2

Behavior notes:

  • The command lives under the root wp yoko namespace.
  • If --unit and --limit are omitted, the command uses the saved Content Gating settings.
  • Use --force to regenerate posts that already have a saved Custom Introduction.
  • Without --force, posts with existing custom_excerpt meta are skipped.

Content Gating in the Block Editor

The hard gate's three fields — Access Restriction, Custom Restriction Message, and Custom Introduction — are edited in the Content Protection CMB2 metabox below the content. That metabox renders in the block editor and the classic editor alike, so there is one place to configure gating regardless of which editor a post type uses.

The email-access-link feature adds its own per-post controls too — a Soft Gate panel in the block editor's Document sidebar, or an equivalent metabox on classic-editor post types. See Soft Gate.

Both surfaces write the same post meta keys (content_restriction_allowed_roles, content_restriction_message, custom_excerpt), so moving a post between editors is safe.

Granular Restriction Messaging

When a visitor cannot see gated content, Content Gating shows one of two site-wide messages, chosen by login status:

  • Logged out → the Site-wide restricted content message for visitors setting.
  • Logged in but without sufficient permission → the Site-wide restricted content message for users without sufficient permission setting.

Sometimes a client wants the logged-in message to say different things depending on which tier the content belongs to — for example, an "upgrade to Prime" note for higher-tier content versus a "become a member" note for general member content.

You can do this from a single message using the [sso-if-content-requires] shortcode, which tests whether a given role is among the roles the requested content is gated to. There is no need to edit individual posts.

Which role should you test? (Important)

Content Gating hides a page from everyone except the roles you list in Limit access to the following roles — so the convention is to select every role that should get in. A page open to both Members and Prime Members therefore has both roles in its list.

That has a consequence for messaging: testing for the top tier (role="prime") is almost always true, because Prime members can see nearly everything. It cannot tell a Prime-exclusive page apart from a members-and-up page.

The reliable signal is the lowest tier that can access the page:

  • If the base Member role is in the list → it's general member content. A logged-in visitor who is denied simply isn't a member → show a "become a member" message.
  • If the base Member role is absent → the page is restricted to a higher tier (e.g. Prime only) → show an "upgrade" message.

Rule of thumb: branch on the lowest tier that can access, not on the exclusive one.

Example

Put both branches in the …without sufficient permission message field. Use each role's slug (matching is case-sensitive — the slug, e.g. member, not the "Member" label):

[sso-if-content-requires role="member"]
This content is available to members. Your account doesn't include membership access.
[/sso-if-content-requires]

[sso-if-content-requires role="member" not="true"]
This content is exclusive to Prime members. Upgrade your membership to view it.
[/sso-if-content-requires]

A logged-in non-member who hits general member content sees the first message; a logged-in visitor who hits Prime-only content (where the base Member role is not allowed) sees the second.

Edge case

This treats "anything the base tier can't access" as the higher tier. If you gate a page to some role that is neither the base tier nor the higher tier (a committee- or staff-only role, say), a denied visitor would fall into the second branch. For a straightforward two-tier membership model this doesn't arise.

Content-side vs. user-side conditions

[sso-if-content-requires] branches on what the content requires. To branch on what the current visitor has (their roles or login status), use [protect-content] — e.g. [protect-content role="prime" operation="show"]…[/protect-content]. Both shortcodes can be combined in the same message.

Block-Level Content Gating

Released in version 1.22.0

In addition to gating the content body of a post, you can apply Content Gating rules to individual blocks — including blocks that live outside the Post Content block in FSE templates (navigation, headers, sidebars, CTAs, etc.). Each block gets a Content Gating panel in the Gutenberg block inspector.

Content Gating Panel Controls

Inherit Content Gating from current post

When this toggle is on, the block is hidden whenever the current post has Content Gating rules that prevent the current user from viewing it. If the post has no gating rules (it is public), the block is always shown regardless of this setting.

This is the primary tool for making template elements — such as a "Members Only" banner, a protected navigation, or a sidebar call-to-action — disappear automatically for users who cannot access the current post.

Show only for roles

A multiselect token field listing all registered WordPress roles. When one or more roles are selected, the block is only rendered for logged-in users who have at least one of those roles. Logged-out users are always hidden.

This control is independent of post-level gating and can be used on any post, including unrestricted ones. It disappears from the panel while "Inherit Content Gating from current post" is toggled on.

tip

The two controls combine with AND logic: both must allow the user to see the block. If you enable Inherit and also select roles, the user must satisfy the post-level check AND have one of the listed roles.

Lock Icon in the Editor

Any block with Content Gating configured displays a small lock icon in its top-right corner in the editor whenever the block is not selected. The icon disappears when you select the block. It is editor-only and does not appear on the frontend.

How Blocks Are Hidden

Blocks are hidden server-side via the render_block filter — the block produces no HTML output for users who do not pass the gating rules. This works correctly in all contexts:

  • Single posts and pages: get_the_ID() returns the current post.
  • FSE templates: blocks outside Post Content inherit the post being viewed.
  • Query Loop: each block is independently checked against the loop item's post ID.
  • Admins: can_current_user_view_post() always returns true for administrators, so admins always see every block.

Everything above is the hard gate: PHP checks the visitor's role and filters the content server-side, so restricted content never reaches the browser.

Yoko Core also ships a soft gate — a cache-friendly, lead-generation gate where PHP always serves the full content and a client-side dialog asks for an email address in exchange for a magic link. It creates friction and captures leads; it does not protect anything.

The two never combine on one post: if a post has hard-gate roles set, soft gating does not run on it at all.

See Soft Gate for the full feature documentation, and Gravity Forms + Soft Gate for the Gravity Forms path.

PDF Gating

The build-in content gating feature supports gating PDF files when used in conjunction with the in-page PDF viewer. When the viewer is activated for all PDFs or a single PDF, the standard content protection metabox is revealed.

PDF Gating in Full Site Editing Block Themes

When using a FSE block theme, the PDF Viewer options allow you to select the template that should be rendered if the current user shouldn't have access to the PDF.