TemplaVoila-Field in TypoScript auslesen

Montag, 27. Mai 2013

Für Suchmaschinen, Phrasen nach denen ich selbst gesucht habe: “per ts auf tv field zugreifen”, Per TypoScript auf TV Feld zugreifen, TV-Feld per TypoScript auslesen. Feldwert von TemplaVoila in HMENU verwenden. Auf ein Datenfeld in TV per TS zugreifen. Mit Typoscript auf Felder eines FCE zugreifen. Zugriff auf TV aus Typoscript.

Aufgabe: Der Redakteur soll bei den Seiteneigenschaften ein Icon auswählen können, das vor dem Menüpunkt dargestellt wird. In TemplaVoilà wurde dazu bei einem Seitentemplate ein Feld angelegt (field_navi_icon) vom Typ “Auswahlliste”. Das Feld wird nicht gemappt, sondern ist später einfach nur eine Auswahlliste unter den Seiteneigenschaften einer Seite. Die Werte dieser Liste sind z.B.

<type>select</type>
<items type="array">
  <numIndex index="0" type="array">
    <numIndex index="0">Default Icon</numIndex>
    <numIndex index="1"></numIndex>
  </numIndex>
  <numIndex index="1" type="array">
    <numIndex index="0">Palme (icon-1)</numIndex>
    <numIndex index="1">icon-1</numIndex>
  </numIndex>
  <numIndex index="2" type="array">
    <numIndex index="0">Segelboot (icon-2)</numIndex>
    <numIndex index="1">icon-2</numIndex>
  </numIndex>
  <numIndex index="3" type="array">
    <numIndex index="0">Foto (icon-3)</numIndex>
    <numIndex index="1">icon-3</numIndex>
  </numIndex>
  <!-- ... usw ... -->
  <numIndex index="10" type="array">
    <numIndex index="0">Kein Icon (no-icon)</numIndex>
    <numIndex index="1">no-icon</numIndex>
  </numIndex>
</items>
<default></default>

Da mir leider keine Möglichkeit bekannt ist, direkt per TypoScript auf ein bestimmtes Feld von TemplaVoilà zuzugreifen, schreiben wir dazu eine kleine benutzerdefinierte Funktion. Die Datei unter “fileadmin/scripts/class.userfunctions.php” speichern:

<?php
 
require_once(PATH_tslib.'class.tslib_pibase.php');
 
class user_functions extends tslib_pibase {
 
  function get_tv_field( $content, $conf ) {
    $this->pi_loadLL();
    $this->pi_setPiVarDefaults();
    $this->pi_initPIflexForm();
 
    $def = array(  'field'      => 'tx_templavoila_flex',
            'flex_data'     => 'field_content', 
            'sheet_pointer' => 'sDEF', 
            'lang'       => 'lDEF', 
            'value_def'   => 'vDEF',
            'pid'      => $GLOBALS['TSFE']->id 
          );
 
    if ($conf['pid.']) {
      $conf['pid'] = $this->cObj->cObjGetSingle($conf['pid'], $conf['pid.']);
    }
 
    foreach ($def as $k=>$v) if (!$conf[$k]) $conf[$k] = $v;
 
    if ($conf['pid']) {
      $flex_array = t3lib_div::xml2array($this->cObj->TEXT(array('data'=>'DB : pages : '.$conf['pid'].' : tx_templavoila_flex')));
    } else {
      $flex_array = t3lib_div::xml2array($this->cObj->data[''.$conf['field'].'']);
    }
    $tv_field = $this->pi_getFFvalue($flex_array, $conf['flex_data'], $conf['sheet_pointer'], $conf['lang'], $conf['value_def']);
 
    return $tv_field;
  }
 
}
?>

Die benutzerdefinierte Funktion binden wir jetzt per TypoScript-Setup ein, damit wir später darauf zugreifen können:

page {
   includeLibs.myUserFuncs = fileadmin/scripts/class.userfunctions.php
}

Per TypoScript wird ein “normales” HMENU/TMENU aufgebaut, allerdings mit dem kleinen Zusatz, das Feld in TemplaVoilà auszulesen und in das li-Tag der Navi als Klasse mit einzubauen:

lib.navi_main = HMENU
 
lib.navi_main {
 
  entryLevel = 1
 
  special = directory
  // Dieser Wert muss natürlich angepasst werden:
  special.value = 67
 
  wrap = <ul class="lv-0">|</ul>
 
  1 = TMENU
  1.expAll = 1
  1.noBlur = 1
  1.wrap = |
 
  1.NO = 1
  1.NO {
    before.cObject = LOAD_REGISTER
    before.cObject.navi_icon.cObject = USER
    before.cObject.navi_icon.cObject {
      userFunc = user_functions->get_tv_field
      flex_data = field_navi_icon
      pid = TEXT
      pid.field = uid
    }
 
    stdWrap.wrap = |
    wrapItemAndSub = <li class="lv-0 first pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 last pid-{field:uid} {register:navi_icon}">|<span></span></li>
    wrapItemAndSub.insertData = 1
    ATagParams.dataWrap = class="lv-0"
  }
 
  1.ACT < .1.NO
  1.ACT {
    stdWrap.dataWrap = |
    wrapItemAndSub = <li class="lv-0 active first pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 active pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 active last pid-{field:uid} {register:navi_icon}">|<span></span></li>
    ATagParams.dataWrap = class="lv-0 active"
  }
 
  1.CUR < .1.ACT
  1.CUR {
    stdWrap.dataWrap = |
    wrapItemAndSub = <li class="lv-0 selected first pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 selected pid-{field:uid} {register:navi_icon}">|<span></span></li>|*|<li class="lv-0 selected last pid-{field:uid} {register:navi_icon}">|<span></span></li>
    ATagParams.dataWrap = class="lv-0 selected"
  }
}

Das Ergebnis ist ein Menü, das im HTML-Quelltext z.B. so aussieht:

<ul class="lv-0">
  <li class="lv-0 selected first pid-554 icon-1">
    <a href="home.html" class="lv-0 selected">Home</a>
    <span></span>
  </li>
  <li class="lv-0 pid-1849 icon-2">
    <a href="beispiel.html" class="lv-0">Beispiel</a>
    <span></span>
  </li>
</ul>

Jeder Menüpunkt hat den Feld-Wert aus TemplaVoilà als Klasse angehängt bekommen. Die zusätzliche Angabe der Ziel-pid als Klasse “pid-{uid}” finde ich ebenfalls sehr praktisch. Alles weitere ist Sache von CSS. Dort nutze ich das span-Element z.B. zur Darstellung des Icons als Hintergrundbild.