Search code examples
typo3categoriesrecordtyposcriptteaser

How to put out a record with all categorie-titles connected to it


On a website, various records are to be output as teasers. Each record is assigned to one or more categories. In the teasers, the titles of all categories assigned to the respective record should be displayed.

I tried this with a Typoscript (see below), in which I linked the database query of tt_content via a JOIN with sys_category and sys_category_record_mm.

But now for records that have multiple categories assigned to them, the corresponding teasers are output multiple times, i.e. once per category.

Fluid:

<f:if condition="{data.tx_mask_cnt_mag_teaser_records}">
    <f:for each="{data.tx_mask_cnt_mag_teaser_records}" as="data_item">
        <f:cObject typoscriptObjectPath="lib.magteaser" data="{dsuid: data_item.uid, recid: data_item.records, reclimit: 2, tstype: 1, syscats: data.tx_mask_cnt_mag_teaser_cats}" />
    </f:for>
</f:if>

Typoscript:

lib.magteaser = COA
lib.magteaser {

    wrap = |

    5 = LOAD_REGISTER
    5 {
        dTstype.data = field:tstype  // Different Teaser-Types
        dSyscats.data = field:syscats  // List of all categories to consider
    }

    10 = CONTENT
    10 {
        table = tt_content
        select {
            pidInList = 13  // Folder in which the records are stored
            uidInList.data = field:recid
            recursive = 2

            selectFields.dataWrap = *, FIND_IN_SET(`tt_content`.`uid`,'{field:recid}') AS reclist_sortby
            join = sys_category_record_mm ON (sys_category_record_mm.uid_foreign = tt_content.uid) JOIN sys_category ON (sys_category_record_mm.uid_local = sys_category.uid)

            where = tt_content.hidden=0
            where = tt_content.CType='mask_cnt_textpic_uni'

            where.data = field:syscats
            # where.intval = 1
            where.wrap = sys_category_record_mm.uid_local IN (|)

            orderBy = reclist_sortby
        }

        renderObj = COA
        renderObj {

            5 = LOAD_REGISTER
            5 {
                # Count variable for a CASE (see below) to format the first data record differently from the remaining data records.
                dsCounter.stdWrap.dataWrap = {register:dsCounter} + 1
                dsCounter.prioriCalc = intval
            }

            10 = CASE
            10 {
                key.data = register:dTstype

                default = COA
                default {
                    wrap = <div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 magteaser-std">|</div>
                    [...]
                }

                # 1 Titelbild und 2 Standard-Teaser
                1 = COA
                1 {
                    wrap = <div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 magteaser-std">|</div>
                    [...]
                }

                # 1 Top-Teaser und 2 Standard-Teaser
                2 = COA
                2 {

                    10 = CASE
                    10 {
                        key.data = register:dsCounter

                        # Standard-Teaser
                        default = COA
                        default {
                            wrap = <div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 magteaser-std">|</div>

                            10 = TEXT
                            10 {
                                wrap = Kategorie (def): |
                                value.dataWrap = {field:title}
                            }

                            [...]

                        }

                        # Top-Teaser
                        1 = COA
                        1 {
                            wrap = <div class="col-12 magteaser-top">|</div>

                            10 = TEXT
                            10 {
                                wrap = Kategorie (1): |
                                value.dataWrap = {field:title}
                            }

                            [...]

                        }

                    }

                }

            }

        }

    }

}

Does anyone have a tip for me on how to solve the problem? Many thanks in advance for your help!

Typo3 V.9.5.8


Solution

  • With the join you generate a matrix, with a 'record' for each combination.

    The correct handling would be to handle the mutiple categories in the renderObj:
    build a part where all categories for this tt_content record are printed.

    conceptual structure:

    10 = CONTENT
    10 {
        table = tt_content
        select {
              :
              // without JOIn
              :
        }
    
        renderObj = COA
        renderObj {
    
            :
    
            50 = CONTENT
            50 {
                table = sys_categories
                SELECT {
                    join = sys_category_record_mm ON (sys_category_record_mm.uid_foreign = ###CONTENT_UID###) AND (sys_category_record_mm.uid_local = sys_category.uid)
    
                    markers {
                        // context is current tt_content record:  
                        CONTENT_UID.field = uid
                    }
                }
                renderObj = TEXT
                renderObj.field = title
                renderObj.wrap =  || ,|
            }
        }
    }