Skip to content

Example: product grid

A practical use of GridContainer: a 3-column product catalog tile, evenly spaced with setGap().

Example output image

<?php
require 'vendor/autoload.php';
use Kehet\ImagickLayoutEngine\Containers\ColumnContainer;
use Kehet\ImagickLayoutEngine\Containers\GridContainer;
use Kehet\ImagickLayoutEngine\Enums\Gravity;
use Kehet\ImagickLayoutEngine\Enums\ImageMode;
use Kehet\ImagickLayoutEngine\Items\Image;
use Kehet\ImagickLayoutEngine\Items\Text;
$width = 900;
$height = 600;
$imagick = new Imagick;
$imagick->newImage($width, $height, new ImagickPixel('white'));
$products = [
['name' => 'Trail Runner', 'price' => '89,00 €'],
['name' => 'Alpine Boot', 'price' => '129,00 €'],
['name' => 'Rain Shell', 'price' => '149,00 €'],
['name' => 'Wool Beanie', 'price' => '24,00 €'],
['name' => 'Camp Mug', 'price' => '15,00 €'],
['name' => 'Trekking Poles', 'price' => '59,00 €'],
];
$grid = new GridContainer;
$grid->setTemplateColumns(null, null, null);
$grid->setGap(24);
foreach ($products as $product) {
$card = new ColumnContainer;
$card->setBorder(draw(stroke: '#d4d4d4', strokeWidth: 2));
$card->setPadding(10);
$card->addItem(new Image(__DIR__.'/example-image-small.jpeg', ImageMode::FILL), forceSize: 160);
$nameDraw = draw(fill: 'black');
$nameDraw->setFont('DejaVu-Sans');
$card->addItem(new Text($nameDraw, $product['name'], initialFontSize: 26, gravity: Gravity::CENTER));
$priceDraw = draw(fill: '#16a34a');
$priceDraw->setFont('DejaVu-Sans');
$card->addItem(new Text($priceDraw, $product['price'], initialFontSize: 24, gravity: Gravity::CENTER));
$grid->addItem($card);
}
$grid->draw($imagick, 0, 0, $width, $height);
$imagick->setImageFormat('png');
$imagick->writeImage(__DIR__.'/product-grid.png');

Six cards auto-place into a 3-column grid (two implicit rows), with a 24px gap on both axes. Each card is itself a ColumnContainer, mixing a forced-height image with unforced name/price text that splits the remaining height evenly — the same nesting pattern used throughout the other guides, just placed onto a grid instead of a row or column.

The same layout as a template. The PHP builds the six cards with a foreach over $products; a JSON tree has no loops, so each card is written out individually — this is the kind of template you’d typically build with a small array_map() over your product list rather than by hand:

{
"type": "grid",
"templateColumns": [null, null, null],
"gap": 24,
"children": [
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Trail Runner","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"89,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
},
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Alpine Boot","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"129,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
},
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Rain Shell","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"149,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
},
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Wool Beanie","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"24,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
},
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Camp Mug","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"15,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
},
{
"type": "column",
"border": {"stroke": "#d4d4d4", "strokeWidth": 2},
"padding": 10,
"children": [
{"type":"image","file":"example-image-small.jpeg","mode":"fill","size":160},
{"type":"text","text":"Trekking Poles","fill":"black","font":"DejaVu-Sans","fontSize":26,"gravity":"center"},
{"type":"text","text":"59,00 €","fill":"#16a34a","font":"DejaVu-Sans","fontSize":24,"gravity":"center"}
]
}
]
}

llms.txt