PHP Templates ​
PHP templates (.visual.php) provide a programmatic, type-safe, IDE-friendly alternative to JSON and YAML templates. They use the TemplateBuilder fluent API to define page structure while maintaining full compatibility with the Theme Editor.
Alternative to JSON/YAML
PHP templates are a first-class alternative to JSON/YAML templates, not a replacement. Choose the format that best fits your workflow:
- JSON/YAML: Simple, declarative, designer-friendly → Learn more
- PHP: Programmatic, IDE support, developer-friendly
Why Use PHP Templates? ​
PHP templates offer developer-focused benefits while producing the same merchant-editable result as JSON/YAML:
✅ IDE Autocomplete - Full IntelliSense support
✅ Type Safety - Catch errors at development time
✅ PHP Features - Use variables, loops, conditionals
✅ Preset Classes - Import and use preset classes directly
✅ Refactoring - Easy to rename, move, and organize
✅ Comments - Document complex logic inline
✅ Theme Editor Compatible - Merchants can still customize everything visually
Quick Comparison ​
Here's the same template in JSON and PHP:
Both produce identical results in the Theme Editor. PHP provides better IDE support and type safety.
Basic Structure ​
PHP templates return a TemplateBuilder instance configured with sections and their order:
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
return TemplateBuilder::make()
->section('<section-id>', '<section-type>')
->section('<section-id>', '<section-type>', fn($section) => $section
->settings([...])
->blocks([...])
)
->order(['<section-id>', '<section-id>']);TemplateBuilder API ​
The TemplateBuilder class provides these methods:
| Method | Description |
|---|---|
make() | Create a new template builder instance |
section(string $id, string $type, ?callable $config = null) | Add a section to the template |
order(array $order) | Define the rendering order of sections |
id(string $id) | Set region ID (for header/footer regions) |
name(string $name) | Set region name (for header/footer regions) |
Section configuration callback receives a BlockBuilder instance with:
| Method | Description |
|---|---|
settings(array $settings) | Set section settings/properties |
blocks(array $blocks) | Add child blocks to the section |
Example: Simple Homepage ​
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
return TemplateBuilder::make()
->section('hero', 'visual-hero', fn($section) => $section
->settings([
'image' => 'https://example.com/hero.jpg',
'size' => 'large',
])
)
->section('featured-products', 'visual-featured-products', fn($section) => $section
->settings([
'heading' => 'Featured Products',
'nb_products' => 8,
])
)
->section('newsletter', 'visual-newsletter')
->order(['hero', 'featured-products', 'newsletter']);Using Preset Classes ​
PHP templates can directly reference preset classes, making configuration reusable and type-safe:
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
use Themes\MyTheme\Presets\HeroBanner;
use Themes\MyTheme\Presets\CategoryGrid;
return TemplateBuilder::make()
->section('hero-banner', HeroBanner::class)
->section('category-list', CategoryGrid::class)
->section('newsletter', 'visual-newsletter')
->order(['hero-banner', 'category-list', 'newsletter']);Learn More About Presets
See Presets documentation to learn about creating standalone preset classes that can be reused across templates.
Adding Blocks to Sections ​
Use PresetBlock to define child blocks within sections:
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
use BagistoPlus\Visual\Support\PresetBlock;
return TemplateBuilder::make()
->section('hero', 'visual-hero', fn($section) => $section
->settings([
'layout' => 'centered',
'padding' => 'large',
])
->blocks([
PresetBlock::make('heading')
->id('hero-title')
->settings([
'text' => 'Welcome to Our Store',
'level' => 1,
]),
PresetBlock::make('paragraph')
->id('hero-text')
->settings([
'text' => 'Discover amazing products',
]),
PresetBlock::make('button')
->id('hero-cta')
->settings([
'text' => 'Shop Now',
'style' => 'primary',
])
->static(), // Lock from editing
])
)
->order(['hero']);Advanced: Nested Blocks ​
PresetBlock supports deep nesting with the ->children() method:
PresetBlock::make('container')
->id('feature-grid')
->settings(['layout' => 'grid', 'columns' => 3])
->children([
PresetBlock::make('container')
->children([
PresetBlock::make('icon')->settings(['icon' => 'star']),
PresetBlock::make('heading')->settings(['text' => 'Quality']),
]),
PresetBlock::make('container')
->children([
PresetBlock::make('icon')->settings(['icon' => 'truck']),
PresetBlock::make('heading')->settings(['text' => 'Fast Shipping']),
]),
]),Example: Product Page Template ​
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
use BagistoPlus\Visual\Support\PresetBlock;
return TemplateBuilder::make()
->section('breadcrumbs', 'visual-breadcrumbs')
->section('product-info', 'visual-product-information', fn($section) => $section
->settings([
'section_width' => 'container',
'media_position' => 'left',
'gap' => 8,
])
->blocks([
PresetBlock::make('product-media-gallery')
->id('media')
->static()
->settings([
'aspect_ratio' => 'adapt',
'zoom' => true,
]),
PresetBlock::make('product-details')
->id('details')
->static()
->children([
PresetBlock::make('product-title')->id('title'),
PresetBlock::make('product-price')->id('price'),
PresetBlock::make('product-variant-picker')->id('variants'),
PresetBlock::make('product-buy-buttons')->id('buy-buttons'),
]),
])
)
->section('product-reviews', 'visual-product-reviews')
->order(['breadcrumbs', 'product-info', 'product-reviews']);Using PHP Features ​
PHP templates can leverage PHP's full power for dynamic configuration:
Variables and Loops ​
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
use BagistoPlus\Visual\Support\PresetBlock;
$featuredCategories = [2, 3, 5, 7];
$categoryBlocks = array_map(
fn($id) => PresetBlock::make('category')
->id("category-{$id}")
->settings(['category' => $id]),
$featuredCategories
);
return TemplateBuilder::make()
->section('categories', 'visual-category-list', fn($section) => $section
->settings(['heading' => 'Shop by Category'])
->blocks($categoryBlocks)
)
->order(['categories']);Conditionals ​
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
$builder = TemplateBuilder::make()
->section('hero', 'visual-hero');
// Add promotional banner only during sales
if (config('store.sale_active')) {
$builder->section('promo-banner', 'visual-promo-banner');
}
$builder->section('products', 'visual-product-list');
return $builder->order(['hero', 'promo-banner', 'products']);Helper Functions ​
<?php
use BagistoPlus\Visual\Support\TemplateBuilder;
use BagistoPlus\Visual\Support\PresetBlock;
// Helper function for repeated block patterns
function createFeatureBlock(string $id, string $icon, string $title, string $text): PresetBlock
{
return PresetBlock::make('container')
->id($id)
->children([
PresetBlock::make('icon')->settings(['icon' => $icon]),
PresetBlock::make('heading')->settings(['text' => $title]),
PresetBlock::make('paragraph')->settings(['text' => $text]),
]);
}
return TemplateBuilder::make()
->section('features', 'visual-features', fn($section) => $section
->blocks([
createFeatureBlock('fast-ship', 'truck', 'Fast Shipping', '2-3 day delivery'),
createFeatureBlock('secure', 'shield', 'Secure Payment', 'Your data is safe'),
createFeatureBlock('support', 'headset', '24/7 Support', 'Always here to help'),
])
)
->order(['features']);Choosing Between PHP and JSON/YAML ​
Both formats are fully interchangeable and produce identical results. Choose based on your editing experience preference:
| Choose PHP Templates When You Want | Choose JSON/YAML When You Want |
|---|---|
| IDE autocomplete and IntelliSense | Simple text file editing |
| Type safety and error checking | Direct, minimal syntax |
| To use PHP variables and loops | Quick manual editing |
| To reference preset classes directly | No PHP knowledge required |
| Code refactoring tools | Lightweight configuration files |
| Inline PHP comments and documentation | Visual, declarative structure |
| Working in PhpStorm/VSCode with PHP | Editing in any text editor |
Both formats:
- ✅ Are fully customizable by merchants in the Theme Editor
- ✅ Support sections, blocks, settings, and all features
- ✅ Generate the same output
- ✅ Allow the same level of merchant control
Migrating from JSON/YAML ​
To convert a JSON/YAML template to PHP:
- Create new
.visual.phpfile with same name - Import TemplateBuilder
- Convert sections to
->section()calls - Convert settings to
->settings()arrays - Convert blocks to
PresetBlock::make()calls - Add
->order()at the end
Example migration:
Next Steps ​
- JSON & YAML Templates - Learn about the declarative alternative
- Template Overview - Compare all template formats
- Presets - Create reusable preset classes for templates
- Available Templates - See all default page templates