Preparing the Product Model and Repository
In the previous step, we set up the basic extension structure and integrated the product table. Now, let’s take a closer look at handling products in the frontend.
To retrieve all available products, we need to prepare two essential components:
- Product Model: Represents product data as an object.
- Product Repository: Manages database operations for products.
Defining the Product Model
The Product model acts as a blueprint for product objects. It fetches data from the database and creates structured objects. This model is defined in:
Classes/Domain/Model/Product.php
<?php
namespace Hyperdigital\HdShop\Domain\Model;
class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
/**
* @var string
*/
protected $title = '';
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
}
Creating the Product Repository
The repository is responsible for fetching products from the database. Initially, we define a basic repository in:
Classes/Domain/Repository/ProductRepository.php
<?php
namespace Hyperdigital\HdShop\Domain\Repository;
class ProductRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
}
Extending the Product Controller
Now, let's extend our ProductController
to retrieve and display products in the frontend.
Injecting the Repository
To access the ProductRepository
, we add a constructor with dependency injection:
public function __construct(
protected readonly \Hyperdigital\HdShop\Domain\Repository\ProductRepository $productRepository
){}
This makes $this->productRepository
available for retrieving product data.
Implementing the List Action
We fetch all products and pass them to the view:
$products = $this->productRepository->findAll();
$this->view->assign('products', $products);
Debugging the Output
To verify the data, we add a debug statement in:
Resources/Private/Templates/Product/List.html
<f:debug>{_all}</f:debug>
Ensure that the plugin’s Storage Page is set to the folder where products are stored.
Resolving Debugging Issues
If you encounter an error like cannot access protected property $_localizeduid
, check your global settings in:
config/system/settings.php
Ensure that the ['SYS']['fluid']['namespace']['f']
configuration prioritizes TYPO3\CMS\Fluid\ViewHelpers
over TYPO3Fluid\Fluid\ViewHelpers
. If needed, adjust the order.
Creating the Product Listing Template
Now, let’s refine the product listing template.
Main List Template
Resources/Private/Templates/Product/List.html
<html data-namespace-typo3-fluid="true">
<f:render section="Main" partial="List/List1" arguments="{products: products}" />
</html>
This calls a partial file located at:
Resources/Private/Partials/List/List1.html
Partial for Product List
<html data-namespace-typo3-fluid="true" xmlns:f="http://www.w3.org/1999/html">
<f:section name="Main">
<f:if condition="{products}">
<div>
<f:for each="{products}" as="product">
<f:render section="product" arguments="{product: product}" />
</f:for>
</div>
</f:if>
</f:section>
<f:section name="product">
<div>
{product.title}
</div>
</f:section>
</html>
This template:
- Checks if products exist.
- Iterates through the list.
- Renders each product inside a separate section.
At this point, your frontend should display a list of product titles.
Implementing the Product Detail View
Next, we create a detail view that displays individual product information.
Defining the Detail Action
Our ext_localconf.php
defines an action called detail
, which maps to:
public function detailAction(\Hyperdigital\HdShop\Domain\Model\Product $product)
{
$this->view->assign('product', $product);
return $this->htmlResponse();
}
This action assigns the selected product to the view.
Debugging the Detail View
To verify the data, add a debug statement in:
Resources/Private/Templates/Product/Detail.html
<f:debug>{_all}</f:debug>
Linking Products to Their Detail Page
Modify the partial’s product
section to include a link:
<f:section name="product">
<div>
<f:link.action action="detail" arguments="{product: product}">{product.title}</f:link.action>
</div>
</f:section>
This generates clickable product titles linking to their respective detail pages.
Testing the Detail View
After clicking a product title, you should see the detailed view with debugging output.
Next Steps
In the next step, we will enhance the detail view by adding product images, prices, and additional attributes.