Contao-Camp 2024
Ergebnis 1 bis 1 von 1

Thema: Tipp: Horizontale Navigation durch News-Beiträge

  1. #1
    Contao-Nutzer Avatar von syntaxys
    Registriert seit
    05.05.2011.
    Ort
    Rheinzabern
    Beiträge
    82

    Standard Tipp: Horizontale Navigation durch News-Beiträge

    Zum Bloggen mit Contao verwende ich das News-Modul. Bei kleineren Beiträgen stelle ich als Weiterleitungsziel "Standard" ein und pflege die Inhalte direkt in der Nachricht, während ich größere Beiträge als eigenständige Seiten aufbaue und im Weiterleitungsziel als "Seite" einstelle.
    Eine konsistente horizontale historische Vor-/Zurück-Navigation durch alle Beiträge ist so leider dann nicht möglich, auch nicht mit den Erweiterungen „Sibling Navigation“ oder „oneup/contao-sibling-navigation“. Man kommt damit entweder durch alle News-Beiträge mit Standard-Weiterleitungsziel ODER durch alle Seiten. Wenn die Seiten auch noch mit „Folder page“ strukturiert sind, klappt auch letzteres nicht mehr.

    Ich habe mir ein kleines Script geschrieben, das auf Basis der aktuellen News-ID oder Page-ID die richtigen Links zum nächsten, bzw. vorherigen Beitrag generiert – unabhängig vom eingestellten Weiterleitungsziel.

    Schritt 1:
    Im Template „news_full.html5“, das der Newsreader verwendet, muss die aktuelle News-ID in eine globale Variable gesetzt werden:
    PHP-Code:
    <?php
    $GLOBALS
    ['meinkrempel']['newsId'] = $this->id;
    ?>
    Schritt 2:
    Erstelle ein Template „navHorizontal.html5“, das kann z. B. so aussehen:
    PHP-Code:
    <?php
    $timestamp 
    time();

    $selectClause "`id`,`alias`,`headline`,`time`,`source`,`jumpTo`";

    $archiveIds = array(1,5,8);
    $numItems count($archiveIds);
    $a 0;
    $whereClauseArchive "AND (";
    foreach (
    $archiveIds as &$value) {
        if(++
    $a === $numItems) {
            
    $whereClauseArchive .= "pid = ".$value.")";
            }
        else {
            
    $whereClauseArchive .= "pid = ".$value." OR ";
            }
        }

    if (!empty(
    $GLOBALS['meinkrempel']['newsId']))
        {
        
    $whereClauseId "id = ".$GLOBALS['meinkrempel']['newsId'];
        unset(
    $GLOBALS['meinkrempel']['newsId']);
        }
    else
        {
        global 
    $objPage;
        
    $whereClauseId "jumpTo = ".$objPage->id;
        }

    $queryPrev "WITH nav_desc AS (SELECT ".$selectClause." FROM `tl_news` WHERE
        published = 1 "
    .$whereClauseArchive."
        AND ((start <= "
    .$timestamp." OR start = '') AND (stop >= ".$timestamp." OR stop = ''))
        ORDER BY `time` DESC), nav_r AS (SELECT "
    .$selectClause." FROM `tl_news` WHERE ".$whereClauseId.")
        SELECT `id` AS prev_id, `alias` AS prev_alias, `headline` AS prev_headline, `time` AS prev_time, `source` AS prev_source, `jumpTo` AS prev_jumpTo
        FROM nav_desc
        WHERE `time` < (SELECT `time` FROM nav_r)
           OR `time` = (SELECT `time` FROM nav_r) AND id < (SELECT id FROM nav_r)
        LIMIT 1;"
    ;

    $queryNext "WITH nav_asc AS (SELECT ".$selectClause." FROM `tl_news` WHERE
        published = 1 "
    .$whereClauseArchive."
        AND ((start <= "
    .$timestamp." OR start = '') AND (stop >= ".$timestamp." OR stop = ''))
        ORDER BY `time` ASC), nav_r AS (SELECT "
    .$selectClause." FROM `tl_news` WHERE ".$whereClauseId.")
        SELECT `id` AS next_id, `alias` AS next_alias, `headline` AS next_headline, `time` AS next_time, `source` AS next_source, `jumpTo` AS next_jumpTo
        FROM nav_asc
        WHERE `time` > (SELECT `time` FROM nav_r)
           OR `time` = (SELECT `time` FROM nav_r) AND id > (SELECT id FROM nav_r)
        LIMIT 1;"
    ;

    $this->import('Database');

    $getPrev $this->Database->prepare($queryPrev);
    $resultPrev $getPrev->execute();
    $resultSetPrev $resultPrev->fetchAllAssoc();
    $resultSetRowsPrev count($resultSetPrev);

    $getNext $this->Database->prepare($queryNext);
    $resultNext $getNext->execute();
    $resultSetNext $resultNext->fetchAllAssoc();
    $resultSetRowsNext count($resultSetNext);

    if (!empty(
    $resultSetPrev) || !empty($resultSetNext))
        {
    ?>
    <div class="mod_article block" id="horizontalNav">
    <div class="inside">
    <div class="ce_text block">
    <section class="ce_cp_grid_start block">
    <div class="grid_desktop_50_50 grid_tablet_50_50 grid_mobile_100 grid_start block">

    <div class="left">
    <?php
    if (!empty($resultSetPrev))
        {
        if (
    $resultSetPrev[0]['prev_source'] == 'internal')
            {
    ?>
    <a href="{{link_url::<?php echo $resultSetPrev[0]['prev_jumpTo']; ?>}}" class="hyperlink_txt prev" title="Zum Beitrag vom <?php echo strftime('%d.%m.%Y',$resultSetPrev[0]['prev_time']); ?>"><span class="icon">&lt</span> <?php echo $resultSetPrev[0]['prev_headline']; ?></a>
    <?php
            
    }
        else
            {
    ?>
    <a href="/newsreader/<?php echo $resultSetPrev[0]['prev_alias']; ?>.html" class="hyperlink_txt prev" title="Zum Beitrag vom <?php echo strftime('%d.%m.%Y',$resultSetPrev[0]['prev_time']); ?>"><span class="icon">&lt</span> <?php echo $resultSetPrev[0]['prev_headline']; ?></a>
    <?php
            
    }
        }
    ?>
    </div>
    <div class="right">
    <?php
    if (!empty($resultSetNext))
        {
        if (
    $resultSetNext[0]['next_source'] == 'internal')
            {
    ?>
    <a href="{{link_url::<?php echo $resultSetNext[0]['next_jumpTo']; ?>}}" class="hyperlink_txt next" title="Zum Beitrag vom <?php echo strftime('%d.%m.%Y',$resultSetNext[0]['next_time']); ?>"><?php echo $resultSetNext[0]['next_headline']; ?> <span class="icon">&gt</span></a>
    <?php
            
    }
        else
            {
    ?>
    <a href="/newsreader/<?php echo $resultSetNext[0]['next_alias']; ?>.html" class="hyperlink_txt next" title="Zum Beitrag vom <?php echo strftime('%d.%m.%Y',$resultSetNext[0]['next_time']); ?>"><?php echo $resultSetNext[0]['next_headline']; ?> <span class="icon">&gt</span></a>
    <?php
            
    }
        }
    ?>
    </div>

    </div>
    </section>
    </div>
    </div>
    </div>
    <?php
        
    }
    ?>
    Das HTML und die Pfade im Template müsst Ihr natürlich an Euren Bedarf anpassen.

    Schritt 3:
    Erstelle Dir ein Modul „Navigation History“ vom Typ „Eigener HTML-Code“ und binde das Template ein:
    PHP-Code:
    {{file::pfad/zum/template/navHorizontal.html5}} 
    Schritt 4:
    Binde das Modul in den Seitenlayouts von Newsreader und den relevanten Nachrichtenseiten ein.

    Et Voilà: Du hast eine konsistente horizontale Navigation durch alle News unabhängig vom Weiterleitungsziel. Bei mir funktioniert das prima.

    Bitte beachte:
    • Die SQL-Queries funktionieren nur mit MySQL-Server ab 8.0, es klappt nicht mit MariaDB.
    • Die Weiterleitungsziele „Artikel“ und „Individuelle URL“ sind nicht berücksichtigt.
    • Es klappt nicht, wenn 2 oder mehr News auf die selbe Seite weiterleiten
    • Die Navigation wird aktuell aus allen Nachrichten der abgefragten Archive zusammengebaut,
      unabhängig davon ob die Beiträge geschützt sind oder nicht. Hierfür sind weitere Anpassungen am Code nötig.


    Ich habe das so gestrickt, wie es mir ausreicht. Sicher kann man da noch etwas verbessern, ich freue mich auf Euer Feedback.

    Viel Spaß damit!
    LG/A

    EDIT 1: SQL-Queries bzgl. publishing angepasst.
    EDIT 2: Hinweise zu Einschränkungen ergänzt.
    EDIT 3: SQL-Queries bzgl. Archiv-Auswahl angepasst.
    Geändert von syntaxys (19.09.2022 um 06:51 Uhr) Grund: SQL angepasst, Code strukturiert
    „Arabica“ – ein One-Pager Theme für Contao 4.9: https://arabica.syntaxys.com/

Aktive Benutzer

Aktive Benutzer

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

Lesezeichen

Lesezeichen

Berechtigungen

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