Listenview and detailview with typoscript

Communication of a fictitious project:

Customer: " ... and then we would like to display a few more products here on the page as a list and when you click on them, a detailed view should appear ..."

Developer: "Oh, no problem. Let's create an extra table, create a repository with models and a controller with listaction and detailaction. Then we create a page with the list view and one with the detail view".

Customer: "Okay. I don't understand a word - I trust you - go on".

A little later ...

Editor: "I don't understand why I have to create an extra sys_folder for my products. And why is there such a strange plugin on the page with the list view? Why do I need an extra page for the details?"

Everyone has probably had these or similar discussions and hopefully learned from them.

In the following, I will show you how to solve these problems with simple means. I am aware that an extbase solution is much more powerful. Nevertheless, I find the simplicity of this solution impressive and it shows once again the strengths of typoscript.

What exactly should happen?

The goal is a page with simple content elements for products. To do this, we create a simple tt_content element with a field for the teaser, a field for the detailed information and an image. In addition, the element should have a slug field to create a readable detailed URL.

The whole thing is placed on a normal page.

If you click on an element in the frontend, the detailed view is displayed.

There should also be a backlink.

First the backend

Since I find it easier and clearer, I use mst_yaml2tca to create the content element in the backend.

I hope the code speaks for itself.

Since I have created two new columns in tt_content, the database must be adapted:

ddev typo3 database:updateschema

columns:
  tt_content:
    slug:
      label: 'Slug'
      config:
        type: slug
        generatorOptions:
          fields:
            - header
          fieldSeparator: '/'
          prefixParentPageSlug: true


    description:
      label: 'Description'
      config:
        type: text
        enableRichtext: true


contentElements:
  new_mst_site_basic_elements:
    title: "New Basic elements yaml"
    elements:
      product:
        title: "Product"
        description: "Product"
        icon: "content-extension"

        config:
          columnsOverrides:
            bodytext:
              config:
                type: text
                enableRichtext: true

          showitem:
            - 
              title: "LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general"
              fields:
              - "--palette--;;general"
              - "--palette--;;header"
              - "slug"
              - "description"
              - "bodytext"
              - "media"
            -
              title: "LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance"
              fields:
                - "--palette--;;frames"
            -
              title: "LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access"
              fields:
                - "--palette--;;hidden"
                - "--palette--;;access"



        

This looks something like this when baked

typoscript, HTML & route enhancer

To make something appear in the frontend, we need a few lines of typoscript and a Fluid template. Also a route enhancer that makes the URL nice.

Since I'm not a fan of a lot of text - here's some code:

tt_content {
    product =< lib.contentElement
    product {
        layoutRootPaths.20 =   EXT:mst_site/Resources/Private/Components/Layouts/
        partialRootPaths.20 =  EXT:mst_site/Resources/Private/Components/Partials/
        templateRootPaths.20 = EXT:mst_site/Resources/Private/Components/Templates/

        templateName = Product
        dataProcessing {
            10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
            10 {
                references.fieldName = media
                as = media
            }
        }

        variables {
            display = TEXT
            display{
                value = teaser

                override.cObject = TEXT
                override.cObject {
                    value = false
                    if.isTrue.data = GP:product|detail
                    
                    override.cObject = TEXT
                    override.cObject {
                        value = detail
                        if.equals.data = GP:product|detail
                        if.value.field = uid
                    }
                }
            }
        }
    }
}
<html xlmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:switch expression="{display}">
    <f:case value="detail">
        <div class="mstitb_col mstitb_col--100">
            <f:link.page>zurück</f:link.page>
            <div class="mstitb_product">
                <h4>{data.header}</h4>
                <f:if condition="{media.0}">
                    <f:image image="{media.0}" alt="{media.0.alternative}" width="800px" />
                </f:if>
                <f:format.html>{data.bodytext}</f:format.html>
            </div>
        </div>
    </f:case>
    <f:case value="teaser">
        <div class="mstitb_col mstitb_col--33">
            <div class="mstitb_product">
                <f:link.typolink parameter="{data.pid}" additionalParams="&product[detail]={data.uid}">
                    <h4>{data.header}</h4>
                    <f:if condition="{media.0}">
                        <f:image image="{media.0}" alt="{media.0.alternative}" width="300px" />
                    </f:if>
                    <f:format.html>{data.description}</f:format.html>
                </f:link.typolink>
            </div>
        </div>
    </f:case>
</f:switch>
</html>
routeEnhancers:
  Products:
    type: Plugin
    namespace: 'product'
    routePath: '/{product_detail}'
    _arguments:
      product_detail: 'detail'

    aspects:
      product_detail:
        type: PersistedAliasMapper
        tableName: tt_content
        routeFieldName: slug

Summary

Of course, you could also do the whole thing without an additional line by placing the detail view in the page tree and placing a menu element with subpages on the list view.
But perhaps this is not possible in a grown project because it would change the entire navigation.
However, I doubt that this suggestion will ever be implemented productively. If it is, I would be pleased to hear from you.

Comments

No Comments

Write comment

* These fields are required