In our ongoing development of the HD Shop extension, we've established the core functionalities for listing and detail pages. Now, it's time to enhance our product presentation by integrating images and videos. This update will enable us to display a single image for the listing page and a gallery of multiple images or videos in the product detail view.
Configuring TCA for Media Fields
To handle media files, we define two fields in our TCA configuration: image
for the main product image and gallery
for additional media. Update the Configuration/TCA/tx_hdshop_domain_model_product.php
file as follows:
'image' => [
'label' => 'Image',
'config' => [
'type' => 'file',
'maxitems' => 1,
'allowed' => 'common-image-types',
]
],
'gallery' => [
'label' => 'Gallery',
'config' => [
'type' => 'file',
'allowed' => 'common-media-types',
]
]
To keep the backend form structured, we create a palette for these fields and assign them to a dedicated tab:
'images' => [
'showitem' => 'image, --linebreak--, gallery',
],
Now, integrate this palette into the product’s backend view by adding:
--div--;Images & Media, --palette--;;images,
This configuration creates a new "Images & Media" tab, grouping the media fields for a clean and organized backend interface.
Updating the Extbase Model
Next, we modify the Product model to support media handling. Extend Classes/Domain/Model/Product.php
with the following properties and methods:
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy;
/**
* @var FileReference|null
*/
protected $image;
/**
* @var ObjectStorage<FileReference>|null
* @phpstan-var ObjectStorage|LazyLoadingProxy|null
* @Extbase\ORM\Lazy
*/
protected $gallery;
/**
* @return FileReference|null
*/
public function getImage()
{
return $this->image;
}
/**
* @param FileReference|null $image
*/
public function setImage($image)
{
$this->image = $image;
}
/**
* @return ObjectStorage|null
*/
public function getGallery()
{
if ($this->gallery instanceof LazyLoadingProxy) {
$this->gallery = $this->gallery->_loadRealInstance();
}
return $this->gallery;
}
/**
* @param ObjectStorage|null $gallery
*/
public function setGallery($gallery)
{
$this->gallery = $gallery;
}
Explanation
- The
image
property stores a single FileReference
for the main product image. - The
gallery
property is an ObjectStorage<FileReference>
that holds multiple media files. - The
@Extbase\ORM\Lazy
annotation ensures that gallery data loads only when necessary, optimizing performance.
Rendering Media in Fluid Templates
To display media in the frontend, we update our Fluid templates.
Listing Page:
<f:if condition="{product.image}">
<f:image image="{product.image}" width="300" fileExtension="webp" />
</f:if>
This ensures that the product image appears at 300px width in WebP format.
Detail Page:
<f:if condition="{product.gallery}">
<f:for each="{product.gallery}" as="image">
<f:image image="{image}" width="300" fileExtension="webp" />
</f:for>
</f:if>
Best Practices
- Always validate media fields before rendering to prevent errors.
- The
gallery
field supports both images and videos, so adjust your frontend accordingly.
Conclusion
By integrating media support into the HD Shop extension, we've enhanced product presentation and usability. This update improves the overall user experience and ensures products are displayed in the best possible way.
Next, we’ll look into image cropping variants to further refine our media management. Stay tuned!