Content Bank API

This reference documents the current Content Bank implementation in BricksMembers: module boot, storage model, structure-editor integration, Bricks behavior, dynamic tags, cache invalidation, and the public helpers exposed to other runtime code.

Overview

The Content Bank is an opt-in BRM module that introduces reusable source posts and structure-specific proxy posts. A proxy is still a real WordPress post, but it stores a source reference and participates in shared-content resolution.

  • Admin surfaceBricksMembers → Content Bank via ContentBankPage
  • Editor surface — post meta box for source/proxy management via ContentBankSystem
  • Structure surface — staged Insert from Bank modal plus proxy creation during structure commit
  • Bricks surface — source-first builder redirects, dynamic tags, and conditions

Module Boot Path

  • src/Core/ModuleRegistry.php maps content_bank to brm_enable_content_bank.
  • src/Utilities/ModuleConfig.php exposes the module toggle in the normalized module config.
  • src/Compatibility/InternalHookBootstrap.php boots ContentBankSystem and registers ContentBankAjax only when the module is active.
  • src/Admin/Menu/AdminMenuRegistrar.php adds the dedicated Content Bank admin page when enabled.

The implementation is intentionally module-gated so the feature adds no runtime hooks when disabled.

Canonical Storage

The Content Bank uses standard WordPress posts plus BRM meta/taxonomy keys. There is no custom Content Bank table.

  • _brm_bank_item — marks a source post
  • _brm_bank_source_id — links a proxy to its source
  • _brm_bank_blocked_fields — meta keys that should stay empty on a proxy instead of inheriting
  • _brm_bank_title_customized, _brm_bank_content_customized, _brm_bank_excerpt_customized — stop core-field sync once a proxy diverges
  • brm_collection taxonomy — organizes source items in the library

Core field behavior is intentionally hybrid:

  • Meta delegates live from source to proxy until the proxy stores a local value or blocks that key.
  • Title/content/excerpt are copied to the proxy and synced from the source until the corresponding customization flag flips.

Core Service Layer

The main runtime lives in src/Modules/ContentBank/ContentBankService.php.

  • is_bank_item(), is_proxy(), get_source_id(), get_source_post() — identity and lookup helpers
  • create_proxy() — creates a real proxy post, initializes source/customization state, and applies optional levels/taxonomy args
  • detach_proxy(), remove_proxy() — proxy lifecycle actions
  • get_delegated_meta() — central meta-resolution hook target
  • sync_source_core_fields() — pushes title/content/excerpt changes into still-linked proxies
  • track_proxy_customization() — flips customization flags when a proxy diverges from its source
  • browse_bank_items(), save_collection(), import_bank_data(), export_bank_data() — admin/library flows

Request Registry and Batch Loading

Content Bank keeps request-local state in the RequestRegistry and primes loop data through BatchLoader integration.

  • bank_proxy — resolved proxy → source IDs
  • bank_local_meta — local meta keys present on a proxy
  • bank_blocked — blocked inherited meta keys per proxy
  • src/Batch/BatchBankLoader.php primes source lookups during batched post loads

This keeps proxy/source resolution cheap in query-loop heavy templates.

Structure Editor Integration

The structure integration deliberately uses the existing staged-edit flow instead of inventing an immediate-write side channel.

  • assets/admin/js/content-bank-structures.js opens the modal, browses source items via AJAX, and stages a create payload with bank_source_id.
  • src/Admin/StructureAdminController.php localizes the Content Bank strings and library URL into the structure admin runtime.
  • src/Structures/Ajax/StructureCommitAjax.php detects bank_source_id during staged creates and calls ContentBankService::create_proxy() instead of wp_insert_post().

The result is consistent with the rest of the structure editor: proxy insertion remains part of the same staged save/commit lifecycle.

Admin Page and Request Handling

ContentBankPage renders the dedicated admin screen. ContentBankSystem handles the corresponding admin request flows:

  • collection create/update/delete
  • source library export
  • JSON import of source items
  • proxy detach flows from the post editor

The current implementation uses BRM security wrappers, nonce verification, and capability checks around those paths. Import handling accepts JSON source-library files only. Export uses a normal download response with a sanitized filename.

Bricks Integration

Bricks integration is intentionally source-first.

  • filter_builder_edit_link() redirects proxy builder entry points to the source builder URL
  • maybe_redirect_proxy_bricks_builder() handles front-end proxy builder requests and redirects to the source unless the explicit proxy-edit flag is present
  • render_proxy_bricks_notice() explains whether the user is editing the shared source or localizing a proxy

Important implementation detail: BRM does not intercept Bricks saves and rewrite them back onto the source. If a proxy is edited directly in Bricks and saved, that proxy localizes its own Bricks meta and stops inheriting the shared layout for those keys.

Dynamic Tags and Conditions

Content Bank tags are registered through DynamicTagsManager and wired into Bricks rendering via InternalUtilityHookBootstrap.

  • {brm_bank_is_proxy}
  • {brm_bank_source_title}
  • {brm_bank_source_id}
  • {brm_bank_usage_count}
  • {brm_bank_collections}

The conditions layer is registered through InternalIntegrationHookBootstrap and evaluated by BricksConditionsRegistrar.

AJAX Endpoints

ContentBankAjax currently registers two admin AJAX handlers:

  • wp_ajax_brm_bank_browse — browse source items for the structure modal
  • wp_ajax_brm_bank_get_usage — retrieve proxy usage for a given source

Both use the normal BRM AJAX nonce. Browsing validates the requested post type and restricts results to items editable by the current user.

Public Runtime Helpers

brm-public-api.php currently exposes the following Content Bank wrappers:

  • brm_is_bank_item( $post_id )
  • brm_is_bank_proxy( $post_id )
  • brm_bank_get_source_id( $post_id )
  • brm_bank_get_usage_count( $post_id )

These helpers are safe to call from theme/plugin code because they return fallback values when the module is disabled.

Mutation Contract and Cache Invalidation

MutationContract owns the Content Bank cache invalidation rules.

  • bank_proxy_created()
  • bank_proxy_removed()
  • bank_source_updated()

These methods invalidate the brm_bank cache group and clear affected proxy/source request-runtime state.

Implementation Gotchas

  • Do not treat proxies as virtual records. They are normal posts and should continue to fit normal BRM structure/access/progress flows.
  • Do not reintroduce live core-field delegation for title/content/excerpt. The current model uses copied fields plus source sync for compatibility.
  • Do not add an immediate-write side path for structure insertion while the staged editor exists. Proxy creation should stay in the staged commit pipeline.
  • Do not assume editing a proxy in Bricks updates the source. Direct proxy saves localize that proxy.

Related Docs

  • User guide: docs/user-posts/45-content-bank-reusable-source-posts.html
  • Module doc: docs/modules/content-bank.md
  • Plan: docs/plans/content-bank-plan.md
Early Bird Deal

Start Building Your Membership Site Today

Create, sell, and manage your content without limits. BricksMembers gives you everything you need to build membership and LMS sites with Bricks Builder.

Lifetime updates & bug fixes • Premium support • 0% transaction fees • 60-day money-back guarantee