PHPackages                             lullabot/proxy\_block - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. lullabot/proxy\_block

ActiveDrupal-module[Utility &amp; Helpers](/categories/utility)

lullabot/proxy\_block
=====================

Renders a different block instead.

v1.6.5(1mo ago)096[2 issues](https://github.com/Lullabot/proxy_block/issues)[1 PRs](https://github.com/Lullabot/proxy_block/pulls)proprietaryPHPCI passing

Since Jul 28Pushed 1mo agoCompare

[ Source](https://github.com/Lullabot/proxy_block)[ Packagist](https://packagist.org/packages/lullabot/proxy_block)[ RSS](/packages/lullabot-proxy-block/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (25)Versions (39)Used By (0)

Proxy Block
===========

[](#proxy-block)

A Drupal module that provides a block plugin that can render any other block plugin the system. This allows for dynamic block selection and configuration through an administrative interface.

Overview
--------

[](#overview)

The proxy block is likely only useful for the A/B Blocks sub-module in the [A/B Tests](https://www.github.com/Lullabot/ab_tests) project.

Features
--------

[](#features)

- **Dynamic Block Selection**: Choose any available block plugin from a dropdown
- **AJAX Configuration**: Real-time configuration forms that update based on block selection
- **Context Mapping**: Pass page contexts to target blocks that require them
- **Access Control**: Respects target block access permissions
- **Cache Integration**: Properly handles cache metadata from target blocks
- **Layout Builder Compatible**: Works seamlessly in Layout Builder and traditional Block UI

Use Cases
---------

[](#use-cases)

- **A/B Testing**: Switch between different blocks for testing
- **Conditional Block Display**: Show different blocks based on configuration
- **Block Reusability**: Use the same block configuration in multiple places
- **Dynamic Content**: Change block content without rebuilding layouts

User Interface
--------------

[](#user-interface)

### Block Configuration

[](#block-configuration)

1. **Target Block Selection**

    - Dropdown list of all available block plugins (excluding the proxy block itself)
    - Option to select "Do not render any block" to hide the block completely
    - AJAX-powered selection that immediately updates the configuration form
2. **Target Block Configuration**

    - Dynamic configuration form that appears after selecting a target block
    - Shows the same configuration options as the target block would normally have
    - Updated in real-time via AJAX when changing target block selection
    - Displays informational message for blocks without configuration options
3. **Context Mapping** (when applicable)

    - Appears for blocks that require contexts (e.g., node, user, term contexts)
    - Dropdown for each required context to map to available page contexts
    - Required context mappings are marked as mandatory
    - Validates that all required contexts are properly mapped

### Administrative Experience

[](#administrative-experience)

The administrative interface follows Drupal's standard block configuration patterns:

- **Block Library**: Available through standard block placement UI
- **Layout Builder**: Can be added as any other block in Layout Builder
- **Configuration**: Accessed through standard block configuration forms
- **Validation**: Real-time validation of target block configuration and context mapping

Technical Architecture
----------------------

[](#technical-architecture)

### Core Components

[](#core-components)

#### ProxyBlock Plugin (`src/Plugin/Block/ProxyBlock.php`)

[](#proxyblock-plugin-srcpluginblockproxyblockphp)

The main block plugin that implements the proxy functionality:

- **Extends**: `BlockBase`
- **Implements**: `ContainerFactoryPluginInterface`, `ContextAwarePluginInterface`
- **Pattern**: Uses final class with constructor promotion and dependency injection

### Render Logic

[](#render-logic)

#### Initialization Phase

[](#initialization-phase)

1. **Block Creation**: Proxy block is instantiated by Drupal's block system
2. **Service Injection**: Required services (BlockManager, Logger, CurrentUser) are injected
3. **Configuration Loading**: Saved configuration is loaded from storage

#### Configuration Phase

[](#configuration-phase)

1. **Form Building**: Administrative configuration form is built
2. **Target Selection**: Available block plugins are enumerated and presented
3. **AJAX Handling**: Target block selection triggers AJAX callback
4. **Dynamic Form**: Target block configuration form is dynamically loaded
5. **Context Discovery**: Required contexts for target block are identified
6. **Validation**: Form submission validates target block configuration and context mapping

#### Render Phase

[](#render-phase)

1. **Target Block Creation**:

    ```
    $target_block = $this->blockManager->createInstance($plugin_id, $block_config);
    ```
2. **Context Mapping**:

    ```
    if ($target_block instanceof ContextAwarePluginInterface) {
      $this->passContextsToTargetBlock($target_block);
    }
    ```
3. **Access Control**:

    ```
    $access_result = $target_block->access($this->currentUser, TRUE);
    ```
4. **Content Generation**:

    ```
    $build = $target_block->build();
    ```
5. **Cache Metadata**:

    ```
    $this->bubbleTargetBlockCacheMetadata($build, $target_block);
    ```

### Context Handling

[](#context-handling)

The module handles context passing through a sophisticated mapping system:

#### Context Discovery

[](#context-discovery)

- Inspects target block's context definitions using `getContextDefinitions()`
- Identifies required vs optional contexts
- Builds mapping form for each context requirement

#### Context Mapping

[](#context-mapping)

- Maps proxy block's available contexts to target block's required contexts
- Supports both automatic mapping (same context name) and manual mapping
- Validates that all required contexts are mapped before allowing form submission

#### Context Application

[](#context-application)

```
protected function passContextsToTargetBlock(ContextAwarePluginInterface
$target_block): void {
  $proxy_contexts = $this->getContexts();
  $context_mapping = $this->getConfiguration()['context_mapping'] ?? [];

  // Map contexts based on configuration
  foreach ($target_context_definitions as $name => $definition) {
    $source_name = $context_mapping[$name] ?? $name;
    if (isset($proxy_contexts[$source_name])) {
      $target_block->setContext($name, $proxy_contexts[$source_name]);
    }
  }
}
```

### Cache Integration

[](#cache-integration)

The module properly handles cache metadata to ensure optimal performance:

#### Cache Contexts

[](#cache-contexts)

- Merges proxy block cache contexts with target block cache contexts
- Ensures cache varies on all relevant parameters

#### Cache Tags

[](#cache-tags)

- Bubbles target block cache tags to proxy block
- Adds proxy-specific cache tags for invalidation

#### Cache Max Age

[](#cache-max-age)

- Uses most restrictive max-age between proxy and target blocks
- Ensures proper cache invalidation timing

### Error Handling

[](#error-handling)

The module implements comprehensive error handling:

#### Plugin Creation Errors

[](#plugin-creation-errors)

- Catches `PluginException` during target block instantiation
- Logs errors with context information
- Gracefully degrades to empty render array

#### Context Errors

[](#context-errors)

- Catches `ContextException` during context mapping
- Logs context-related errors
- Continues execution with available contexts

#### Form Errors

[](#form-errors)

- Validates target block configuration
- Validates required context mappings
- Provides user-friendly error messages

Development Patterns
--------------------

[](#development-patterns)

This module follows several advanced Drupal development patterns:

### Functional Programming

[](#functional-programming)

- Uses `array_map`, `array_filter`, `array_reduce` instead of foreach loops
- Implements functional composition for data transformation
- Uses arrow functions for simple transformations

### Polymorphism Over Conditionals

[](#polymorphism-over-conditionals)

- Uses strategy pattern for different block types
- Leverages PHP 8 match expressions for clean branching
- Implements interface-based behavior detection

### Dependency Injection

[](#dependency-injection)

- Constructor promotion for clean dependency injection
- Auto-wiring of services through ContainerFactoryPluginInterface
- Minimal service coupling

### Modern PHP Features

[](#modern-php-features)

- PHP 8.1+ features including constructor promotion
- Strict typing with `declare(strict_types=1)`
- Final classes for performance and encapsulation
- Union types for intersection constraints

Installation
------------

[](#installation)

1. Place module in `modules/contrib/proxy_block` or install via Composer
2. Enable the module: `drush en proxy_block`
3. Clear caches: `drush cr`
4. The "Proxy Block" will be available in the block library

Configuration
-------------

[](#configuration)

No global configuration is required. Each proxy block instance is configured individually through the standard Drupal block configuration interface.

Compatibility
-------------

[](#compatibility)

- **Drupal**: 10.x, 11.x
- **PHP**: 8.1+
- **Layout Builder**: Full compatibility
- **Block UI**: Full compatibility
- **Context System**: Full integration

Limitations
-----------

[](#limitations)

- Only supports block plugins, not content blocks from the Block Library
- Context mapping requires manual configuration for complex scenarios
- Performance depends on target block performance characteristics

Security Considerations
-----------------------

[](#security-considerations)

- Respects all target block access permissions
- Does not bypass Drupal's security layer
- Validates all user input through Drupal's form API
- Logs security-relevant events for audit trails

Performance
-----------

[](#performance)

- Lazy-loads target blocks only when needed
- Properly caches target block output
- Minimizes database queries through proper caching
- Uses AJAX for responsive administrative interface

Contributing
------------

[](#contributing)

This module is not open to public contributions.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance92

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Recently: every ~1 days

Total

17

Last Release

39d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f2b22c5ce2b0ee6b619c41efe1ddb93ac84d910f59539363009b76810469c72?d=identicon)[lullabot](/maintainers/lullabot)

---

Top Contributors

[![e0ipso](https://avatars.githubusercontent.com/u/1140906?v=4)](https://github.com/e0ipso "e0ipso (31 commits)")

---

Tags

drupaldrupal-module

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lullabot-proxy-block/health.svg)

```
[![Health](https://phpackages.com/badges/lullabot-proxy-block/health.svg)](https://phpackages.com/packages/lullabot-proxy-block)
```

###  Alternatives

[symfony/polyfill-php73

Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions

2.4k602.0M85](/packages/symfony-polyfill-php73)[beacon-hq/bag

A comprehensive immutable value objects implementation

18314.4k4](/packages/beacon-hq-bag)[shish/microhtml

A minimal HTML generating library

1148.6k3](/packages/shish-microhtml)[selvinortiz/doxter

Slick markdown editor and smart text parser.

249.0k](/packages/selvinortiz-doxter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
