A showcase of custom WordPress block development using the Gutenberg block editor with ACF.
This project demonstrates a reusable, maintainable approach to building custom Gutenberg blocks.
A base Block class provides a foundation for all custom blocks with:
- Auto-generated metadata — Block names and titles are derived from class names (
Awards→awards, "Awards") - ACF integration — Registered with Advanced Custom Fields for flexible content management
- Preview system — Automatic preview image loading from convention-based paths
- Blade templating — Renders views using Blade templates for expressive, maintainable markup
- Flexible data processing — Override the
with()method to transform data before rendering
The Awards block demonstrates:
- Inheriting from the base
Blockclass - Using reusable traits (
ImageTrait) for common functionality - Data sanitization and security (
esc_url()for links) - Looping through ACF repeater fields
- Responsive layout with Tailwind CSS
- Data escaping — All output escaped with appropriate WordPress functions (
esc_url(),esc_html()) - Conditional rendering — Preview images displayed without field data to prevent errors
- Error handling — Debug-friendly error messages in WP_DEBUG mode
- Field validation — Graceful handling of empty or missing ACF fields
- Roots/Sage theme framework — Modern WordPress theme structure
- Blade templating — Clean, expressive template syntax
- Tailwind CSS — Utility-first styling
- Organized namespace structure — PSR-4 autoloading ready
app/
├── Blocks/
│ ├── Block.php # Base class for all blocks
│ └── Awards.php # Example block implementation
├── Traits/
│ └── ImageTrait.php # Reusable image utilities
└── resources/
└── views/
└── blocks/
└── awards.blade.php # Block template
Block Registration: Blocks are automatically registered via the base class register() method, which handles ACF setup and render callbacks.
Template Integration: Views access processed data passed from the PHP class, keeping logic and presentation cleanly separated.
Extensibility: Adding new blocks requires only creating a new class and template—no boilerplate registration code.
This architecture is ideal for:
- Building reusable block libraries
- Maintaining consistent block patterns across projects
- Teams needing standardized block development workflows
- Projects requiring ACF block integration with modern PHP practices
Built by: Drazen Biljak
Portfolio: GitHub