Strukturierte URLs

Aus Contao Community Documentation

Strukturierte URLs

In diesem Artikel geht es darum, wie man aus den klassischen Contao URLs /reader/items/alias.html z.B. URLs dieser Form macht /reader/2011/Feb/alias.html. Dies lässt sich sowohl für News, Events und andere Reader basierte Extensions machen.

Zunächst gehe ich davon aus, dass die Reader Page ID 5 und dem Alias leser ist. Außerdem geht es um die Domain blog.example.com, auf der News angezeigt werden (das Prinzip lässt sich einfach auf andere Module adaptieren).

Zuerst muss eine kleine Erweiterung erstellt werden:

system/modules/customurls/config/config.php

<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
 
/**
 * Hooks
 */
$GLOBALS['TL_HOOKS']['generateFrontendUrl'][] = array('CustomURLs', 'hookGenerateFrontendUrl');
$GLOBALS['TL_HOOKS']['getPageIdFromUrl'][]    = array('CustomURLs', 'hookGetPageIdFromUrl');

system/modules/customurls/CustomURLs.php

<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
 
class CustomURLs extends Frontend
{
  /**
   * @var Database;
  */
  protected $Database;
 
  /**
   * @param array $arrRow
   * @param string $strParams
   * @param string $strUrl
   * @return string
   */
  public function hookGenerateFrontendUrl($arrRow, $strParams, $strUrl)
  {
    ...
  }
 
  /**
   * @param array $arrFragments
   * @return array
   */
  public function hookGetPageIdFromUrl($arrFragments)
  {
    ...
  }
}

Bisher haben wir eine Klasse CustomURLs erstellt, welche auf die beiden HOOKs generateFrontendUrl und getPageIdFromUrl registriert ist. Mit generateFrontendUrl werden wir die URL umschreiben, während getPageIdFromUrl die URL zurück transformieren wird.

In meinem Fall soll die URL von leser/items/alias.html auf jahr/alias.html umgeschrieben werden. Also z.B. leser/items/mein_erster_blog_post.html zu 2011/mein_erster_blog_post.html.

Als erstes muss die generierte URL umgeschrieben werden:

system/modules/customurls/CustomURLs.php

...
  /**
   * @param array $arrRow
   * @param string $strParams
   * @param string $strUrl
   * @return string
   */
  public function hookGenerateFrontendUrl($arrRow, $strParams, $strUrl)
  {
    if (   $GLOBALS['objPage']->id == 5 // Page ID 5 ist die Reader Page
        && preg_match('#/items/([^/]+)#', $strParams, $arrMatch)) // extrahiere den Alias aus den Parametern
    {
      $this->import('Database');
 
      // Den News aus der DB laden um an das Datum zu kommen
      $objNews = $this->Database
        ->prepare("SELECT * FROM tl_news WHERE id=? OR alias=?")
        ->execute($arrMatch[1], $arrMatch[1]);
      if ($objNews->next())
      {
        // Die URL umschreiben
        $strUrl = str_replace('leser/items/', date('Y', $objNews->date) . '/', $strUrl);
 
        // Alternatives Format jahr/monat/alias.html
        // Verwende beim 2. mal parseDate, um lokalisierte Monatsnamen zu erhalten. (z.B. Mai anstatt May)
        // $strUrl = str_replace('leser/items/', date('Y', $objNews->date) . '/' . $this->parseDate('M', $objNews->date) . '/', $strUrl);
      }
    }
 
    return $strUrl;
  }
...

Jetzt werden alle URLs die generiert werden umgeschrieben, aber Contao weiß zur Zeit noch nichts mit diesen anzufangen, deshalb müssen wir dieses URL Format selbst verarbeiten.


system/modules/customurls/CustomURLs.php

...
  /**
   * @param array $arrFragments
   * @return array
   */
  public function hookGetPageIdFromUrl($arrFragments)
  {
    if (   $this->Environment->httpHost == 'blog.example.com'
        && count($arrFragments) >= 1
        && preg_match('#^\d\d\d\d/(.*)#', $arrFragments[0], $arrMatch) // Alias extrahieren; Format: Jahreszahl (4 Zahlen) gefolgt vom Alias
    //  && preg_match('#^\d\d\d\d/\w\w\w/(.*)#', $arrFragments[0], $arrMatch) // Alias extrahieren; Alternatives Format: Jahreszahl (4 Zahlen) mit Monat (3 Buchstaben) gefolgt vom Alias
    )
    {
      // Splitte das Fragment in die 3 Contao Fragmente
      //   1. Page Alias/ID
      //   2. Parameter Identifier
      //   3. Item Alias/ID
      $arrTemp = array('leser', 'items', $arrMatch[1]);
      // ersetze das erste Fragment mit den neuen Fragmenten und hänge den Rest hinten dran
      return array_merge
      (
        $arrTemp,
        array_slice($arrFragments, 1)
      );
    }
    return $arrFragments;
  }
...

Fertig, jetzt werden die URLs entsprechend umgeschrieben.

Ansichten
Meine Werkzeuge

Contao Community Documentation

Nur weil es bei Nachbarseite XYZ was gibt, wird automatisch oft davon ausgegangen, dass das fertige Bauteil einsatzbereit auf der Straße liegt.

Marie Dietz
Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge