0
votes

a few days ago I started using TYPO3 8.7.7 and I created a small website using Fluid powered TYPO3 extensions. Now I want to create a custom content element that displays a few products that the editor can manage in the backend. In my extension I created a simple model for the products:

namespace Something\Products\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

class Product extends AbstractEntity
{

    protected $name;

    protected $description;

    public function __construct(string $name, string $description)
    { ... }

    public function getName(): string
    { ... }

    public function setName(string $name)
    { ... }

    public function getDescription(): string
    { ... }

    public function setDescription(string $description)
    { ... }
}

I also created a ProductRepository class that simply extends \TYPO3\CMS\Extbase\Persistence\Repository.

In EXT:something/Configuration/TCA/tx_product.php

I have the following definition:

return [
    'ctrl' => [
        'title' => 'Products',
        'label' => 'name'
    ],

    'columns' => [
        'name' => [
            'label' => 'Name',
            'config' => [
                'type' => 'input',
                'eval' => 'trim,required',
            ],
        ],
        'description' => [
            'label' => 'Description',
            'config' => [
                'type' => 'text',
                'eval' => 'trim,required',
            ],
        ],
    ],

    'types' => [
        '0' => ['showitem' => 'name, description'],
    ],
];

Adding and editing products is working great in Web->List Module. I store them in a folder in the page tree called Products.

My goal is it to create a content element called Products to a page in an arbitrary column. The template in the frontend should display a list of products.

I would expect something like this in my EXT:something/Resources/Private/Template/Content/Product.html

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
    xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
    xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
    xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">

    <f:layout name="Content"/>

    <f:section name="Configuration">
        <flux:form id="newsitem" options="{group: 'Unicontrol'}">
            <flux:field.input name="settings.headline" required="true"/>
        </flux:form>
    </f:section>

    <f:section name="Main">
        <ul>
            <f:for each="{products}" as="product">
                <li>{product.name}</li>
            </f:for>
        </ul>
    </f:section>
</div>

Now I don't know how I can do that. I think I need a controller class but I can't figure out how to connect it with my Fluid powered TYPO3 Templates/Partials. Can anyone help me to find a way to realise this?

Thanks in advance and have a nice day.

EDIT:

My current CE template looks like this now:

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
    xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
    xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
    xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">

    <f:layout name="Content"/>

    <f:section name="Configuration">
        <flux:form id="products" options="{group: 'Unicontrol'}">
            <flux:field.relation name="settings.relation" table="tx_products_domain_model_product"
                                transform="TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage<Something\\Products\\Domain\\Model\\Product>"
                                multiple="true"/>
        </flux:form>
    </f:section>

    <f:section name="Main">
        <ul>
            <f:for each="{settings.relation}" as="product">
                <li>{product.name}</li>
            </f:for>
        </ul>
    </f:section>
</div>

I can now select one product of my list in the CE but in the frontend it only displays one element, the element I selected in the backend. It doesn't matter if I escape the slashes or not.

1
Just a small note: if your TCA (and SQL) schema is actually that truncated and you didn't just crop it for this question, then you should consider taking a look at other extensions, for example EXT:news, to see what a complete TCA structure should contain. There is a multitude of control fields and toggles that you probably want to support!Claus Due
@ClausDue Thank you for this tip. I try to complete my TCA configuration.René Papenfuß

1 Answers

1
votes

Normally you would prefer to have an actual plugin for this - there are several reasons why, but most importantly, it separates your content from the interactive plugins and gives each plugin a dedicated scope for arguments and such.

That said, you can achieve a product listing display as Flux-enabled element. It requires three things in combination:

  1. A Repository for your Model must exist (or it is not considered an aggregate root. A "Product" definitely sounds like an aggregate root so that fits well!
  2. In the content element template add a flux:field.relation or .select or .multiRelation depending on how you want to handle the selection. Point this to the SQL table of your domain model (and see the Flux ViewHelper docs for further arguments to specify how selection is done)
  3. Use the transform argument for that ViewHelper to declare that the final type should be TYPO3\CMS\Extbase\Persistence\ObjectStorage<Your\Model\ClassName> (note that you may need to escape the backslashes, e.g. TYPO3\\CMS\\...).

Then render the product list exactly like you already do in your Main section in the template. Internally Flux converts whichever value or relations are selected in the field, reading a list of UIDs and using the Repository you created to pick each one.