Ergebnis 1 bis 6 von 6

Thema: 2 Tabellen mit gemischter Reihenfolge

  1. #1
    Contao-Fan Avatar von jenda
    Registriert seit
    20.06.2009.
    Ort
    Berlin
    Beiträge
    521

    Standard 2 Tabellen mit gemischter Reihenfolge

    Hallo,

    ich möchte 2 Tabellen und deren Einträge als Liste ausgeben, dabei sollen diese nach folgender Reihenfolge ausgegeben werden.

    Jeweils 3 aus der 1. Tabelle, dann eine aus der 2. Tabelle, bis es in der 2 Tabelle nicht mehr geht, werden danach einfach nur die Einträge aus der 1. Tabelle ausgegeben.

    Momentan habe ich 2 ce-Listen dort, die allerdings die Einträge für jede Tabelle separat ausgeben - allerdings stehen sie im DOM alle in einem DIV.

    Meine Frage ist: soll ich alles nur über eine ce-Liste ausgeben und die PHP-Abfrage direkt im Template machen oder gibt es noch eine andere Vorgehensweise, wie ich es erreichen kann, zum Beispiel durch einen speziellen Filter oder ein spezielles Feld, wo man eine Nummer eintragen würde, die die Reihenfolge bestimmen würde, wobei ich dieses dann in der ce-Liste abfragen könnte?

  2. #2
    Wandelndes Contao-Lexikon Avatar von zonky
    Registriert seit
    19.03.2010.
    Ort
    Berlin, Rdf
    Beiträge
    10.181
    User beschenken
    Wunschliste

    Standard

    Ich habe die Beschreibung nicht ganz verstanden - insbesondere den Teil:

    Zitat Zitat von jenda Beitrag anzeigen
    dann eine aus der 2. Tabelle, bis es in der 2 Tabelle nicht mehr geht, werden danach einfach nur die Einträge aus der 1. Tabelle ausgegeben.
    Meine "Interpretation" ist, du hast zwei MModels und willst die gemischt ausgeben als

    * mm_aepfel: gib die ersten drei Items aus
    * mm_birnen: gib ein Item aus
    * mm_aepfel: gib ab Item 4 alle aus

    wenn dem so ist, würde ich drei CE-MM-Liste anlegen - das erste und dritte auf mm_aepfel und das zweite auf mm_birnen. Über die Einstellungen in "Offset und Limit für die Auflistung verwenden" kann man genau diese Ausgaben erreichen

    * mm_aepfel: Listen-Offset: 0 / Maximale Anzahl an Items: 3
    * mm_birnen: Listen-Offset: 0 / Maximale Anzahl an Items: 1
    * mm_aepfel: Listen-Offset: 3 / Maximale Anzahl an Items: 0

    Bei den beiden "mm_aepfel" muss natürlich die selbe Einstellung bei Filterung und Sortierung vorhanden sein.

    Zwei oder mehr Models kann man auch nicht mit einem Spezialfilter mischen.

  3. #3
    Wandelndes Contao-Lexikon Avatar von zonky
    Registriert seit
    19.03.2010.
    Ort
    Berlin, Rdf
    Beiträge
    10.181
    User beschenken
    Wunschliste

    Standard

    @jenda: ist Deine Frage damit beantwortet?

  4. #4
    Contao-Fan Avatar von jenda
    Registriert seit
    20.06.2009.
    Ort
    Berlin
    Beiträge
    521

    Standard

    Es sollen nicht nur drei und dann Schluss ausgegeben werden, sondern jeweils 3 Einträge aus der 1. Tabelle, dann einer aus der 2. Tabelle und so weiter, bis es einfach nur geht. Dabei hat die erste Tabelle mehr Einträge. Momentan habe ich folgende Lösung mit einem ce_Modul und einem Template für alle Einträgen aus beiden Tabellen. Dabei habe ich mir meinen Helper um eine Funktion für die Ausgabe der 2. Tabelle erweitert. Meine Frage ist, ob es die beste Lösung ist? Momentan gehe ich davon aus.

    Hier ist meine Lösung, die funktioniert.

    PHP-Code:
    <?php
    use App\Helper\MetaModelsTemplateHelper;
    use 
    MetaModels\Filter\Rules\SearchAttribute;

    // Get helper.
    $templateHelper = \Contao\System::getContainer()->get(MetaModelsTemplateHelper::class);

    if (
    $this->data) {
        
    $persons $this->data;

        
    // Abrufen der Artikel aus der zweiten Tabelle mit Filterung
        
    $articles $templateHelper->getFilteredArticles('mm_person_topics_objects'6);

        
    $personCount 0;
        
    $articleCount 0;
        
    $totalItems count($persons) + count($articles);

        for (
    $i 0$i $totalItems$i++):
            if (
    $i && $personCount count($persons)):
                
    $arrItem $persons[$personCount++];
                
    $itemType 'person';
            elseif (
    $articleCount count($articles)):
                
    $arrItem $articles[$articleCount++];
                
    $itemType 'article';
            elseif (
    $personCount count($persons)):
                
    $arrItem $persons[$personCount++];
                
    $itemType 'person';
            else:
                continue;
            endif;

            
    $itemId $arrItem['raw']['id'];
            
    $category = ($itemType == 'person') ? 'person' strtolower($arrItem['text']['category']);

            
    $published = ($arrItem['text']['published'] === '1') ? 'published' 'unpublished';
            
    ?>
            
            <div class="item <?= $itemType ?> <?= $arrItem['class'?> <?= $published ?>" id="<?= $itemType ?>_<?= $itemId ?>" data-id="<?= $itemId ?>" data-modal="modal_<?= $itemType ?>_<?= $itemId ?>" data-category="<?= $category ?>">
                <div class="item-inner">
                    <div class="picture-index-main">
                        <div class="picture-index-main_inner">
                            <div class="picture-index-first">
                            <?php if ($arrItem['text']['index_picture_main'] || $arrItem['text']['main_catalog_picture']): ?>
                                <?php if ($itemType === 'person'): ?>
                                <?= $arrItem['html5']['index_picture_main'?>
                                <?php else: ?>
                                <?= $arrItem['html5']['main_catalog_picture'?>
                                <?php endif ?>
                            <?php else: ?>
                                <?php if ($itemType === 'person'): ?>
                                    {{picture::68cf5035-0da4-11f0-9ef5-9e914297a1db?size=7&template=picture_default}}
                                     <?php else: ?>
                                {{picture::a8303e98-0568-11f0-af09-0fd5a88a267d?size=7&template=picture_default}}
                                <?php endif ?>
                            <?php endif ?>
                            </div>
                           
                            <div class="picture-index-hover">
                                 <?php if ($arrItem['text']['index_picture_hover'] || $arrItem['text']['hover_catalog_picture']): ?>
                                    <?php if ($itemType === 'person'): ?>
                                <?= $arrItem['html5']['index_picture_hover'?>
                                <?php else: ?>
                                    <?= $arrItem['html5']['hover_catalog_picture'?>
                                <?php endif ?>
                                <?php else: ?>
                                    <?php if ($itemType === 'person'): ?>
                                {{picture::68cb48a4-0da4-11f0-9ef5-9e914297a1db?size=7&template=picture_default}}
                                 <?php else: ?>
                                {{picture::a8303e7a-0568-11f0-81d0-0fd5a88a267d?size=7&template=picture_default}}
                                <?php endif ?>
                            <?php endif ?>
                            </div>
                        </div>
                    </div>
                    
                <div class="overlay-wrapper">
                    {{file::modals-reading-finished.html5}}
                    <?= $arrItem['html5']['name'] ?? $arrItem['html5']['personName'?>
                    <?= $arrItem['html5']['title'?>
                    <button class="button modal-trigger"></button>
                </div>
            </div>
        </div>
        <?php endfor; ?>

        <div class="modals-wrapper">
            <?php
            $combinedItems 
    = [];
            
    $personCount 0;
            
    $articleCount 0;

            for (
    $i 0$i $totalItems$i++) {
                if (
    $i && $personCount count($persons)) {
                    
    // Überprüfen, ob die Person veröffentlicht ist
                    
    while ($personCount count($persons) && $persons[$personCount]['text']['published'] !== '1') {
                        
    $personCount++;
                    }
                    if (
    $personCount count($persons)) {
                        
    $combinedItems[] = ['type' => 'person''data' => $persons[$personCount++]];
                    }
                } elseif (
    $articleCount count($articles)) {
                    
    $combinedItems[] = ['type' => 'article''data' => $articles[$articleCount++]];
                } elseif (
    $personCount count($persons)) {
                    
    // Überprüfen, ob die Person veröffentlicht ist
                    
    while ($personCount count($persons) && $persons[$personCount]['text']['published'] !== '1') {
                        
    $personCount++;
                    }
                    if (
    $personCount count($persons)) {
                        
    $combinedItems[] = ['type' => 'person''data' => $persons[$personCount++]];
                    }
                }
            }

            foreach (
    $combinedItems as $item):
                
    $arrItem $item['data'];
                
    $itemType $item['type'];
                
    ?>
        <div class="modal" id="modal_<?= $itemType ?>_<?= $arrItem['raw']['id'?>">
            <div class="modal-inner">
                {{file::modals-buttons.html5}}
                <div class="modal-content">
                    <?php if ($itemType === 'person'): ?>
                        <?= $arrItem['html5']['name'] ?? $arrItem['html5']['personName'?>
                        <div class="picture">
                            <?= $arrItem['html5']['index_picture_main'?>
                        </div>
                        <?= $arrItem['html5']['intro'?>
                        <?= $arrItem['html5']['longtext'?>
                    <?php else: ?>
                        <?= $arrItem['html5']['title'?>
                        <?= $arrItem['html5']['intro'?>
                        <?= $arrItem['html5']['longtext'?>
                        <?= $arrItem['html5']['article'?>
                        <?php if ($arrItem['raw']['related_articles']): ?>
                            <div class="related-articles-wrapper">
                                <?= $arrItem['html5']['related_articles'?>
                            </div>
                        <?php endif ?>
                    <?php endif ?>
                </div>
            </div>
        </div>

        <?php
                
    // Wenn es sich um eine Person handelt, geben wir die zugehörigen Artikel als separate Modals aus
                
    if ($itemType === 'person' && $arrItem['text']['published'] === '1'):
                    
    $personArticles $templateHelper->getPersonArticles($arrItem['raw']['id']);
                    foreach (
    $personArticles as $article):
                        
    ?>
                <div class="modal" id="modal_article_person_<?= $article['raw']['id'?>">
                    <div class="modal-inner">
                        {{file::modals-buttons.html5}}
                        <div class="modal-content">
                            <?= $article['html5']['title'?>
                            <?= $article['html5']['intro'?>
                            <?= $article['html5']['longtext'?>
                            <?= $article['html5']['article'?>
                        </div>
                    </div>
                </div>
                <?php
                        
    // Wenn der Artikel verwandte Artikel hat, geben wir diese ebenfalls aus
                        
    if ($article['raw']['related_articles']):
                            foreach (
    $article['raw']['related_articles'] as $relatedArticle):
                                
    ?>
                        <div class="modal" id="modal_related_article_<?= $relatedArticle['__TAGS_RAW__']['id'?>">
                            <div class="modal-inner">
                                {{file::modals-buttons.html5}}
                                <div class="modal-content">
                                    <h2 class="headline"><?= $relatedArticle['title'?></h2>
                                    <div class="intro a-text"><?= $relatedArticle['value']['intro']['value'?></div>
                                    <div class="longtext b-text"><?= $relatedArticle['__TAGS_RAW__']['longtext']['value'?></div>
                                    <?php if ($relatedArticle['article']): ?>
                                        <div class="more-articles">
                                            <?php foreach ($relatedArticle['__TAGS_RAW__']['article']['value'] as $moreArticle): ?>
                                                <?= $moreArticle ?>
                                            <?php endforeach ?>
                                        </div>
                                    <?php endif ?>
                                </div>
                            </div>
                        </div>
                    <?php
                            
    endforeach;
                        endif;
                    endforeach;
                endif;
            endforeach;
            
    ?>
        </div>
    <?php } else { ?>
        <p class="info"><?= $this->noItemsMsg ?></p>
    <?php ?>
    Hier mein Helper

    PHP-Code:
    <?php

    namespace App\Helper;

    use 
    MetaModels\Filter\Setting\IFilterSettingFactory;
    use 
    MetaModels\Render\Setting\IRenderSettingFactory;
    use 
    MetaModels\IFactory;
    use 
    MetaModels\IMetaModel;

    class 
    MetaModelsTemplateHelper
    {
        
    /**
         * The factory.
         *
         * @var IFactory
         */
        
    private IFactory $factory;

        
    /**
         * Filter setting factory.
         *
         * @var IFilterSettingFactory
         */
        
    private IFilterSettingFactory $filterFactory;

        
    /**
         * Render setting factory.
         *
         * @var IRenderSettingFactory
         */
        
    private IRenderSettingFactory $renderFactory;

        
    /**
         * MetaModelsTemplateHelper constructor.
         *
         * @param IFactory              $factory
         * @param IFilterSettingFactory $filterFactory
         * @param IRenderSettingFactory $renderFactory
         */
        
    public function __construct(
            
    IFactory $factory,
            
    IFilterSettingFactory $filterFactory,
            
    IRenderSettingFactory $renderFactory
        
    ) {
            
    $this->factory $factory;
            
    $this->filterFactory $filterFactory;
            
    $this->renderFactory $renderFactory;
        }

        
    /**
         * Retrieve all staff members of a given division.
         *
         * @param string $divisionAlias The alias of division.
         *
         * @return array
         */
        
    public function getPersonArticles(string $personId): array
        {
            
    $modelName 'mm_person_articles';
            
    $renderId 3;
            
    $parentId = (int) $personId;
            
    $model $this->factory->getMetaModel($modelName);
            if (!
    $model) {
                throw new \
    RuntimeException("MetaModel '$modelName' not found.");
            }
            
    $filter $model->getEmptyFilter();
            
    $filterRule = new \MetaModels\Filter\Rules\SimpleQuery('SELECT id FROM mm_person_articles WHERE pid = ?', [$parentId]);
            
    $filter->addFilterRule($filterRule);
            
    $items $model->findByFilter($filter);
            
    $articleItems $items->parseAll('html5'$this->renderFactory->createCollection($model$renderId));
            return 
    $articleItems;
        }

        public function 
    getTopicObjectArticles(string $articleId): array
        {
            
    $modelName 'mm_person_topics_objects';
            
    $renderId 3;
            
    $model $this->factory->getMetaModel($modelName);
            if (!
    $model) {
                throw new \
    RuntimeException("MetaModel '$modelName' not found.");
            }
            
    $filter $model->getEmptyFilter();
            
    $filterRule = new \MetaModels\Filter\Rules\SimpleQuery('SELECT id FROM mm_person_topics_objects WHERE id = ?', [$articleId]);
            
    $filter->addFilterRule($filterRule);
            
    $items $model->findByFilter($filter);
            
    $articleItems $items->parseAll('html5'$this->renderFactory->createCollection($model$renderId));
            return 
    $articleItems;
        }

        public function 
    getFilteredArticles(string $modelNameint $filterId): array
        {
            
    $model $this->factory->getMetaModel($modelName);
            
    $renderId 13;
            if (!
    $model) {
                throw new \
    RuntimeException("MetaModel '$modelName' not found.");
            }

            
    $filter $model->getEmptyFilter();

            
    // Abrufen der Filtereinstellungen
            
    $filterSettings $this->filterFactory->createCollection($filterId);

            
    // Anwenden der Filtereinstellungen auf den Filter
            // Wir fügen ein leeres Array als zweites Argument hinzu
            
    $filterSettings->addRules($filter, []);

            
    $items $model->findByFilter($filter);
            return 
    $items->parseAll('html5'$this->renderFactory->createCollection($model$renderId));
        }
    }
    Geändert von jenda (24.04.2025 um 10:45 Uhr)

  5. #5
    Wandelndes Contao-Lexikon Avatar von zonky
    Registriert seit
    19.03.2010.
    Ort
    Berlin, Rdf
    Beiträge
    10.181
    User beschenken
    Wunschliste

    Standard

    Zitat Zitat von jenda Beitrag anzeigen
    Es sollen nicht nur drei und dann Schluss ausgegeben werden, sondern jeweils 3 Einträge aus der 1. Tabelle, dann einer aus der 2. Tabelle und so weiter, bis es einfach nur geht. ...
    o.k. also "Äpfel" und "Birnen" alternierend in Verhältnis 3:1

    ... wofür auch immer man das benötigt

    Ich glaube, eine richtig elegante Lösung gibt es nicht - ggf. würde die Anzeige ein CSS-Profi auch so hin bekommen.

    Da Paginierung dann eh nicht geht, würde ich wahrscheinlich zwei API Abfragen machen - eine zu Äpfel und eine zu Birnen und mir mit den zwei Arrays ein Ergebnisarray "Obst" mit dem 3:1-Verhältnis gebaut und das dann in einer Schleife ausgegeben. Das könnte mit der Trennung von "Logik" zu "Ausgabe" übersichtlicher sein als die foreach-if-enforeach-endif-Würmer...

  6. #6
    Wandelndes Contao-Lexikon Avatar von zonky
    Registriert seit
    19.03.2010.
    Ort
    Berlin, Rdf
    Beiträge
    10.181
    User beschenken
    Wunschliste

    Standard

    ChatGPT:

    per CSS

    Code:
    <div class="grid-wrapper">
      <ul class="list1">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
      </ul>
      <ul class="list2">
        <li>Item A</li>
        <li>Item B</li>
      </ul>
    </div>
    Code:
    .grid-wrapper {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-auto-rows: auto;
    }
    
    .list1 li,
    .list2 li {
      list-style: none;
    }
    
    .list1 li:nth-child(1) { grid-column: 1; grid-row: 1; }
    .list1 li:nth-child(2) { grid-column: 2; grid-row: 1; }
    .list1 li:nth-child(3) { grid-column: 3; grid-row: 1; }
    .list2 li:nth-child(1) { grid-column: 4; grid-row: 1; }
    
    .list1 li:nth-child(4) { grid-column: 1; grid-row: 2; }
    .list1 li:nth-child(5) { grid-column: 2; grid-row: 2; }
    .list1 li:nth-child(6) { grid-column: 3; grid-row: 2; }
    .list2 li:nth-child(2) { grid-column: 4; grid-row: 2; }
    oder per JS

    Code:
    <ul id="list1">
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
      <li>Item 6</li>
    </ul>
    
    <ul id="list2">
      <li>Item A</li>
      <li>Item B</li>
    </ul>
    
    <ul id="combinedList"></ul>
    Code:
    const list1 = Array.from(document.querySelectorAll('#list1 li'));
    const list2 = Array.from(document.querySelectorAll('#list2 li'));
    const combined = document.getElementById('combinedList');
    
    let i = 0, j = 0;
    while (i < list1.length || j < list2.length) {
      // Add 3 items from list1
      for (let k = 0; k < 3 && i < list1.length; k++, i++) {
        combined.appendChild(list1[i].cloneNode(true));
      }
      // Add 1 item from list2
      if (j < list2.length) {
        combined.appendChild(list2[j].cloneNode(true));
        j++;
      }
    }
    Code:
    #list1, #list2 {
      display: none;
    }

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •