Experimental project
This is a sandbox project, which contains experimental code for developer use only.
Render Builder modernizes the Drupal development experience by replacing verbose associative arrays with type-safe, fluent PHP classes. It allows developers to build render structures using methods like ->addClass(), ->setCache(), and ->addChild(), while maintaining full compatibility with Drupal's caching, attachment, and hook systems. Perfect for teams seeking better DX, IDE autocomplete, and maintainable code.
Features
Core Architecture
Object-Oriented Facade: Wraps Drupal's native render arrays in type-safe PHP classes.
Interface-Driven Design: All builders implement RenderBuilderInterface for consistency.
Event-Based Compilation: Uses RenderEvents::PRE_RENDER to convert objects to arrays automatically before rendering.
Recursive Processing: Automatically traverses nested arrays to convert any embedded builder objects.
Non-Invasive: Does not modify Drupal Core; works entirely within the contributed module space.
π¨ Developer Experience (DX)
Fluent API: Chainable methods (e.g., ->addClass()->setCache()->build()) for clean, readable code.
Type Safety: Leverages PHP 8.1+ features (typed properties, return types) for robust code.
IDE Autocomplete: Full support for method chaining and property hints in PhpStorm, VS Code, etc.
Factory Pattern: Includes RenderBuilderFactory for quick, static instantiation of builders.
Reduced Verbosity: Significantly less boilerplate compared to raw associative arrays.
Refactoring Safe: Renaming classes or methods is handled by IDE refactoring tools, unlike string array keys.
π‘ Caching & Performance
Built-in Cache Metadata: Dedicated methods for contexts, tags, and max-age.
Safe Defaults: Default cache max-age is set to 0 (uncached) to prevent accidental data leaks.
Automatic Injection: Cache metadata is automatically injected into the #cache key during build.
Performance Optimized: Compilation happens only once during the render pipeline.
π Attachments & Assets
Library Attachment: Easy method to attach Drupal libraries (->attachLibrary()).
CSS/JS Attachment: Direct methods to attach raw CSS or JS files (->attachCss(), ->attachJs()).
Drupal Settings: Support for attaching drupalSettings values (->attachDrupalSetting()).
Automatic Aggregation: Attachments are merged into the #attached array correctly.
π§± Included Render Builders
ContainerBuilder: Wrap elements in
MarkupBuilder: Handle raw HTML markup strings.
LinkBuilder: Create links with proper Url objects, routes, and paths.
ImageBuilder: Generate image tags with alt text, dimensions, and lazy loading.
TableBuilder: Construct complex tables with headers, rows, footers, and captions.
FormBuilder: Embed forms programmatically with arguments.
BlockBuilder: Render block plugins dynamically.
ViewsBuilder: Embed Views displays with arguments and display IDs.
βοΈ HTML & Attributes
Class Management: ->addClass() supports multiple classes and handles arrays correctly.
Attribute Setting: ->setAttribute() and ->setAttributes() for custom HTML attributes.
Attribute Merging: Automatically merges builder attributes with element-specific attributes (e.g., image #attributes).
π Compatibility & Integration
Hook Compatible: Converts objects early enough (PRE_RENDER) to allow hook_render_alter() to function normally.
Core Compatible: Works with Drupal 9.4, 10, and 11.
PHP Version: Requires PHP 8.1+ (for modern syntax features).
Mixable: You can mix builder objects with raw render arrays in the same structure.
Testable: Includes PHPUnit test suite for core builders.
π¦ Distribution & Maintenance
PSR-4 Autoloading: Fully compliant with Drupal's autoloading standards.
Composer Ready: Includes composer.json for easy dependency management.
Documentation: Includes README.md with usage examples.
Example Code: Includes example controllers demonstrating real-world usage.
Open Source: Licensed under GPL-2.0-or-later.
Post-Installation
Render Builder Module - Post-Installation Checklist
After enabling the Render Builder module, follow these steps to ensure it is functioning correctly and integrated properly into your development workflow.
β
1. Immediate Actions
Clear All Caches
The module registers an Event Subscriber (RenderCompilerSubscriber) and services. These are only recognized after a cache rebuild.
bash
12
Verify Module Status
Ensure the module is enabled and no errors are logged.
bash
1
Check watchdog logs for any service container errors:
bash
1
Check PHP Version
The module uses PHP 8.1+ features (typed properties, return static, union types).
bash
12
π 2. Developer Setup
Update Composer Autoload (If Installed Manually)
If you installed via the bash script (manual copy) instead of Composer, ensure Drupal recognizes the new namespace.
bash
12
Configure IDE (PhpStorm/VS Code)
To get the full benefit of type safety and autocomplete:
Indexing: Ensure your IDE indexes the modules/contrib/render_builder directory.
PHPStan/Psalm: Add the module to your static analysis configuration to catch type errors in your custom builders.
Imports: Start using the factory in your controllers:
php
1
Fix .info.yml Configuration Link (Important)
The provided .info.yml includes configure: render_builder.settings, but no settings form was implemented in the code.
Option A (Recommended): Remove the line from render_builder.info.yml if no settings are needed.
yaml
12
Option B: Implement a simple ConfigFormBase if you want to add settings (e.g., debug mode) later.
π§ͺ 3. Verification & Testing
Test the Compiler
Create a test route or use the Devel module's "Execute PHP" block to verify the compiler works.
Test Snippet:
php
12345678910111213
Run PHPUnit Tests
Verify the module's internal tests pass in your environment.
bash
1
π 4. Security & Best Practices
Markup Sanitization
The MarkupBuilder accepts raw strings. Do not trust user input.
β Bad: MarkupBuilder::markup($user_input)
β
Good: MarkupBuilder::markup(\Drupal\Component\Utility\Xss::filter($user_input))
Cache Defaults
The module defaults to max-age: 0 (uncached) for safety.
Action: Explicitly set cache metadata for production performance.
php
1
Performance Monitoring
Since the compiler traverses the render array recursively:
Monitor page load times on complex pages.
Ensure you aren't nesting builders too deeply (e.g., >50 levels), which could impact performance.
π 5. Integration & Workflow
CI/CD Pipeline
Add checks to your deployment pipeline:
Syntax Check: php -l on all module files.
Module Enabled: Ensure render_builder is in your core.extension.yml.
Cache Clear: Ensure drush cr runs after deployment.
Team Onboarding
Add to your project's README.md or developer handbook:
Link to the module's usage examples (examples/ControllerExample.php).
Define coding standards for when to use Builders vs. raw arrays.
Rule of Thumb: Use Builders for complex structures; raw arrays for simple markup.
π 6. Troubleshooting
Issue
Possible Cause
Solution
Class not found
Autoload not updated
Run composer dump-autoload and drush cr
Object not converting
Event subscriber not firing
Check render_builder.services.yml tags
Cache not working
Missing #cache key
Ensure ->setCache() is called before ->build()
Configure link 404
Missing settings form
Remove configure: line from .info.yml
PHP Parse Error
PHP version < 8.1
Upgrade server PHP version
π Summary Checklist
drush cr executed
PHP version verified (8.1+)
.info.yml configure line fixed (if needed)
Test snippet executed successfully
PHPUnit tests passing
Team notified of new coding standard
Security review completed for markup usage
Additional Requirements
Does this project need anything beyond Drupal core? Include any dependent modules, libraries, APIs, etc., that are required for this project to work.
Recommended modules/libraries
Are there any projects that enhance or improve the functionality of this project?
Similar projects
No Similar projects
You may continue to put additional information below here, if there are other things you think people need to know about your module!
Project information
- Project categories: Developer tools
- Ecosystem: Theming, Theming tools
- Created by ashrafmhd09 on , updated