TEE-09 Frontend Detailliste

Aus Contao Community Documentation

MsgError.png Unvollständiger Artikel: dieser Artikel ist noch nicht sauber bearbeitet.

Bitte erweitere ihn und entferne erst anschliessend diesen Hinweis.

Tagebuch einer Extension-Entwicklung

betrifft
TYPOlight Version ab TL 2.8
Extensions Extension Creator


Details, Details, Details

In der Listenübersicht der Turnierpaare ist als Link bereits vorgesehen, dass man beim Klick auf den "Detail"-Link eines Paares zu einer Detail-Seite kommt. Ich möchte das mit demselben Modul regeln, also ohne Weiterleitungsseite auf eine (versteckte) Seite mit einem "DetailViewer"-Modul.

Ich habe mir das schamlos beim EFG ab geguckt. Meine Turnierpaarliste liegt unter turnierpaarliste.html. Wenn man als URL z.B. turnierpaarliste/info/8.html verwendet, wird trotzdem die Seite turnierpaarliste aufgerufen, aber jetzt hat der GET-Parameter "info" den Wert 8. Sehr praktisch.

Prüft man im Modulcode auf diesen Parameter, kann man dann gegebenenfalls auf das Detail-Template wechseln und anderen Code ausführen.

Nochmal der entsprechende Abschnitt aus dem Template der /system/modules/gw_turnierpaare/templates/gw_turnierpaarliste.tpl:

  </td> 
  <td><?php echo '<a href="/turnierpaarliste/info/'.$paar['id'].'.html">Detail</a>'; ?> 
  </td>

Hier wird aus der Paar-ID der Detail-Link gebaut. Mich stört noch, dass mein Seitenname "turnierpaarliste" hardkodiert ist. Das werde ich noch ändern müssen, habe gerade aber keine Idee, wie ich an diese Information komme. Außerdem wäre es schöner, statt mit der numerischen ID mit einem alphanumerischen Alias zu arbeiten, so wie bei Seiten oder Artikeln. Das werde ich noch in einem zukünftigen Schritt implementieren.

Das Template für die Detailseite /system/modules/gw_turnierpaare/templates/gw_turnierpaarliste_detail.tpl sieht so aus:

<div class="<?php echo $this->class; ?> block paarvisitenkarte"<?php echo $this->cssID; ?> 
<?php if ($this->style): ?> style="<?php echo $this->style; ?>"<?php endif; ?>> 
<h3><?php echo $this->paar['partnernachname']; ?> 
<?php if($this->paar['partnervorname']) { echo ", ".$this->paar['partnervorname']; 
}; ?> 
<?php if($this->paar['partnerinnachname']) { echo " und ".$this->paar['partnerinnachname']; }; ?> 
<?php if($this->paar['partnerinvorname']) { echo ", ".$this->paar['partnerinvorname']; }; ?> 
</h3> 
<?php if ($this->paar['bild']): ?> 
<div class="left"> 
<?php if($this->paar['bildfullsize']): ?> 
<a href="<?php echo $this->paar['bildfullsize']; ?>" rel="lightbox[bild]"> 
<?php endif; ?> 
<img src="<?php echo $this->paar['bild']; ?>"> 
<?php if($this->paar['bildfullsize']): ?> 
</a> 
<?php endif; ?> 
</div> 
<?php endif; ?> 
<div class="right"> 
<ul> 
<?php if ($this->paar['startklassestandard'] != '-'): ?> 
<li> 
  <?php echo $this->paar['startgruppe']." ".$this->paar['startklassestandard']." Standard"; ?> 
</li> 
<?php endif; ?> 
<?php if ($this->paar['startklasselatein'] != '-'): ?> 
<li> 
  <?php echo $this->paar['startgruppe']." ".$this->paar['startklasselatein']." Latein"; ?> 
</li> 
<?php endif; ?> 
<li> 
   Aktiv: <?php echo $this->paar['aktivseit']; ?> - <?php if($this-
>paar['aktivbis']) { echo $this->paar['aktivbis']; } else { echo "heute"; }; ?> 
</li> 
<?php if ($this->paar['anschrift']): ?> 
<li> 
   <?php echo nl2br($this->paar['anschrift']); ?> 
</li> 
<?php endif; ?> 
<?php if ($this->paar['telefon']): ?> 
<li> 
   Tel.: <?php echo $this->paar['telefon']; ?> 
</li> 
<?php endif; ?> 
 
<?php if ($this->paar['fax']): ?> 
<li> 
   Fax: <?php echo $this->paar['fax']; ?> 
</li> 
<?php endif; ?> 
<?php if ($this->paar['mobil']): ?> 
<li> 
   Mob.: <?php echo $this->paar['mobil']; ?> 
</li> 
<?php endif; ?> 
<?php if ($this->paar['email']): ?> 
<li> 
   EMail: {{email::<?php echo $this->paar['email']; ?>}} 
</li> 
<?php endif; ?> 
<?php if ($this->paar['homepage']): ?> 
<li> 
   Homepage: <a href="<?php echo $this->paar['homepage']; ?>"><?php echo $this->paar['homepage']; ?></a> 
</li> 
<?php endif; ?> 
</ul> 
</div> 
<div class="twocol"> 
<?php echo nl2br($this->paar['beschreibung']); ?> 
</div> 
</div>

Im Prinzip nichts besonderes, ich bastele aus den Namen eine schöne Überschrift, Bild und die anderen Texte werden in DIVs verpackt, die ich per CSS dann "hübsch" anordne. Beim Bild wird unser Modulcode in $paar['bild'] eine verkleinerte Version (180px breit max.) zurück liefern. In $paar['bildfullsize'] befindet sich das Originalbild, das hier im Template dann über eine Lightbox zur Großansicht anklickbar ist. Das Array $paar im Template entspricht ansonsten den Datenbankfeldern in tl_gw_turnierpaare.

Die Hauptarbeit passiert nun in der Frontend-Modul-Klasse /system/modules/gw_turnierpaare/gwTurnierpaarliste.php:

class gwTurnierpaarliste extends Module 
{ 
    /** 
     * Template 
     * @var string 
     */ 
    protected $strTemplate = 'gw_turnierpaarliste'; 
  protected $strDetailKey = 'info';

Zunächst definiere ich wie üblich den "Default"-Templatenamen, das ist der für die gesamte Liste. Zusätzlich definiere ich hier das URL-Fragment, was meinen "Detail-Link" ausmachen soll.

  function obj2Arr($objPaar) 
  { 
    $newArr = array 
      ( 
        'partnernachname' => trim($objPaar->partnernachname), 
        'partnervorname' => trim($objPaar->partnervorname), 
        'partnerinnachname' => trim($objPaar->partnerinnachname), 
        'partnerinvorname' => trim($objPaar->partnerinvorname), 
        'startgruppe' => $objPaar->startgruppe, 
        'startklasselatein' => $objPaar->startklasselatein, 
        'startklassestandard' => $objPaar->startklassestandard, 
        'aktiv' => $objPaar->aktiv, 
        'aktivseit' => $objPaar->aktivseit, 
        'aktivbis' => $objPaar->aktivbis, 
        'id' => $objPaar->id, 
        'beschreibung' => $objPaar->beschreibung, 
      ); 
      if($objPaar->zeigeanschrift == '1') 
      { 
        $newArr['anschrift'] = $objPaar->anschrift; 
      } 
      if($objPaar->zeigetelefon == '1') 
      { 
        $newArr['telefon'] = $objPaar->telefon; 
      }
      if($objPaar->zeigefax == '1') 
      { 
        $newArr['fax'] = $objPaar->fax; 
      } 
      if($objPaar->zeigemobil == '1') 
      { 
        $newArr['mobil'] = $objPaar->mobil; 
      } 
      if($objPaar->zeigeemail == '1') 
      { 
        $newArr['email'] = $objPaar->email; 
      } 
      if($objPaar->zeigehomepage == '1') 
      { 
        $newArr['homepage'] = $objPaar->homepage; 
      } 
    return $newArr; 
  }

Diese Utility-Funktion füllt mir eine Zeile des Resultsets der Datenbank in ein Array. Ich brauche das an zwei Stellen, darum habe ich das hierhin ausgelagert. Hier werden auch schon die zeige-Flags berücksichtigt: Sind die nicht angehakt, landet auch nichts im Array. Damit spare ich mir die Abfragen im Template.

 
    protected function compile() 
    { 
        if ( strlen($this->Input->get($this->strDetailKey)) ) 
        { 
      // A "detail"-URL is given -> Output turnierpaarliste_detail template 
      $this->compileDetailTemplate(); 
    } 
    else 
    { 
      // Output the turnierpaarliste template 
      $this->compileListTemplate(); 
      } 
}

Die alte compile()-Funktion wurde angenehm kurz. Falls der GET-Parameter mit dem Namen info gesetzt ist (über unsere URL turnierpaarliste/info/8.html), dann wird eine Funktion zur Ausgabe des Detail-Templates aufgerufen, ansonsten eine für das Listentemplate.

  // Compiles the turnierpaarliste template 
  protected function compileListTemplate() 
  { 
        $moduleParams = $this->Database->prepare("SELECT * FROM tl_module WHERE id=?") 
                ->limit(1) 
                ->execute($this->id); 
    $whereClause = ''; 
    if($moduleParams->gw_tp_showonlyactive == 'A') 
    { 
      $whereClause = "WHERE aktiv='1'"; 
    } 
    else 
    { 
      if($moduleParams->gw_tp_showonlyactive == 'I') 
      { 
        $whereClause = "WHERE aktiv=''"; 
      } 
    } 
    $orderClause = 'partnernachname, partnerinnachname'; 
    if($moduleParams->gw_tp_couplesorting == 'C') 
    { 
      // Nach Altersgruppen sortieren 
      $fieldstartgruppe="''"; 
       foreach(array('KIN I','KIN II', 'JUN I', 'JUN II', 'JUG', 'HGR', 'HGR II', 'SEN I', 'SEN II', 'SEN III', 'SEN IV') as $gruppe) 
      { 
        $fieldstartgruppe .= ",'".$gruppe."'"; 
      } 
      $fieldstartklasse="''"; 
      foreach(array('-', 'E','D', 'C', 'B', 'A', 'S', 'PRO', 'LL', 'OL', 'RL', '2. BL', '1. BL') as $klasse) 
      { 
        $fieldstartklasse .= ",'".$klasse."'"; 
      } 
      $orderClause = "FIELD(startgruppe,".$fieldstartgruppe."), FIELD(startklassestandard,".$fieldstartklasse."), FIELD(startklasselatein,".$fieldstartklasse."), partnernachname, partnerinnachname"; 
    } 
    $arrPaare = array(); 
    $objPaare = $this->Database->execute("SELECT * FROM tl_gw_turnierpaare " . $whereClause . "ORDER BY " . $orderClause); 
    while ($objPaare->next()) 
    { 
      $newArr = $this->obj2Arr($objPaare); 
      if(strlen($objPaare->bild) == 0) 
      { 
        $newArr['bild'] = '/system/modules/gw_turnierpaare/icons/default.png'; 
      } 
      else 
      { 
        $newArr['bild'] = $this->getImage($objPaare->bild, '', '48'); 
      } 
      $arrPaare[] = $newArr; 
    } 
    $this->Template->paare = $arrPaare; 
  }

Bei der Ausgabe des Listentemplates hat sich nicht viel gegenüber dem letzten Schritt getan, nur die Utility-Funktion obj2Arr wird jetzt benutzt, um den Großteil der Felder aus der Datenbank ins Array zu packen. Als Paarbild wird ein Thumbnail von max. 48 Pixeln Höhe ausgegeben.

 
  // Compiles the data for the turnierparliste_detail template 
  protected function compileDetailTemplate() 
  { 
    $coupleRow = $this->Database->prepare("SELECT * FROM tl_gw_turnierpaare WHERE id=?") 
            ->limit(1) 
            ->execute($this->Input->get($this->strDetailKey)); 
    $this->strTemplate = 'gw_turnierpaarliste_detail'; 
    $this->Template = new FrontendTemplate($this->strTemplate); 
    $newArr = $this->obj2Arr($coupleRow); 
    if(strlen($coupleRow->bild) == 0) 
    { 
      $newArr['bild'] = '/system/modules/gw_turnierpaare/icons/default.png'; 
    } 
    else 
    { 
      $newArr['bild'] = $this->getImage($coupleRow->bild, '180', ''); 
      $newArr['bildfullsize'] = $coupleRow->bild; 
    } 
    $this->Template->paar = $newArr; 
  }

Hier die Ausgabe des Detail-Templates: Zunächst holen wir uns das Paar aus der Datenbank, dessen Detailseite ausgegeben werden soll. Hier wäre wohl zukünftig noch eine Fehlerabfrage ("ID existiert nicht") notwendig. Hüstel

Dann müssen wir das andere Template wählen. Dafür ersetze ich den Namen durch den Neuen. Das alleine reichte aber nicht: Es erschien immer noch das alte Template, weil es schon initialisiert war, als compile() aufgerufen wurde.

Eine Änderung von $strTemplate bleibt dann unbemerkt. Darum muss jetzt in der nächsten Zeile ein neues Frontendtemplate instanziert werden. Ich hätte den Namen auch direkt als Parameter bei der Instanzierung angeben können. Dann fülle ich mit obj2Arr() mein Paar-Array, und gebe (falls vorhanden) das Paarbild-Thumbnail mit maximal 180 Pixel Breite aus, und zusätzlich das Originalbild.

Das Ergebnis ist das Folgende - die Turnierpaarliste:

Datensatz Liste

Ich habe das Default-Bild noch ausgetauscht, das angezeigt wird, wenn kein Paarbild hinterlegt ist (Ich hänge es auch hier nochmal an). Das "richtige" Paarbild ist übrigens ein freies aus Wikimedia Commons.

Nach Klick auf einen Detaillink:

Datensatz Details

Ansichten
Meine Werkzeuge

Contao Community Documentation

<TheTril> Stateless Template, Stateless Elements, Stateless Renderer :)
<TheTril> everything is stateles :D
<leo-unglaub> TheTril: genau wie Ed Snowden *g*

Navigation
Verstehen
Verwenden
Entwickeln
Verschiedenes
Werkzeuge