CCK formatters - 1

Mikor CCK mezők sminkeléséről beszélünk leggyakrabban a content-field.tpl.php fájl valamilyen átalakításáról esik szó. De ezt megelőzően van még egy fázis, ami a $items[$delta]['view'] értéket előállítja. Egy tartalom típus szerkesztésénél a Mezők megjelenítése fülön lehet választani a lehetőségek közül, melyek nem biztos, hogy megfelelnek a céljainknak, de szerencsére bővíthető a lista.

Mikor, miért

Nodereference típusú mező esetében az alábbi lehetőségek közül lehet választani:

  • Cím (hivatkozással)
  • Cím (hivatkozás nélkül)
  • Teljes tartalom
  • Bevezető
  • < rejtett >

Elég gyakori igény, hogy a hivatkozott tartalomnak ne csak a címe legyen megjelenítve, hanem a hozzátartozó kép is, amit egy CCK mező tárol. Első lépés az, hogy be kell kerülni a fenti listába. Ezt egy smink nem tudja megtenni. Kell hozzá egy aprócska modul. Miért? Azért, hogy a megoldás smink független, és több mezőnél is felhasználható legyen, vagy akár mezőket megjelenítő views listáknál is (amelyek nem biztos hogy a content-field.tpl.php-t használják).

A példa modulnak a fantázia dús myftr1 nevet választottam, mely a My Foramtter 1 rövidítése, és nem nyújt általános megoldást, mert néhány dolgot erősen feltételez. Például az imagecache modul létezését (egy small nevű presettel), és azt is, hogy az a tartalom típus melyre a nodreference mezőből hivatkozni lehet az rendelkezik egy imagefield típusú CCK mezővel, mely a field_img névre hallgat.

A listába kerüléshez szükséges függvény

A függvénynek egy tömböt kell visszaadni, melynek tartalmaznia kell a modul által megvalósított formázók leírását. Ez a függvény 1db formázó leírását adja vissza, melynek azonosítója a tömb kulcsa (field_img). Ez az azonosító bármi lehet, az csupán a véletlen műve, hogy megegyezik egy CCK mező nevével. Viszont ez az azonosító része lesz a smink függvény nevének.

/**
 * Implementation of hook_field_formatter_info().
 */
function myftr1_field_formatter_info() {
  return array(
    //Egyedi azonosító
    'field_img' => array(
      //Ez a név jelenik meg a select listában
      'label' => t('Image (!field)', array('!field' => 'field_img')),
      //Ezt a formázót ezeknél a típusú CCK mezőknél lehet használni
      'field types' => array('nodereference'),
      //A CCK mező értékeinek kezelése egyenként vagy egyszerre.
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}

Formázóhoz tartozó smink függvény

Definiálni kell a formázóhoz tartozó smink függvényt, melynek neve automatikusan generálódik a modul nevéből és a formázó azonosítójából.
<modulename>_formatter_<id>

/**
 * Implementation of hook_theme().
 */
function myftr1_theme() {
  return array(
    'myftr1_formatter_field_img' => array(
      'arguments' => array('element' => NULL),
    ),
  );
}

Smink függvény

Végül szükség van egy smink függvényre is ami a HTML kimenetet produkálja. A függvénynek átadott $element paraméter struktúrája függ a hook_field_formatter_info()-ban meghatározott 'multiple values' értéktől. Jelen beállítás szerint ez a smink függvény az adott CCK mező értékeire egyenként lesz meghívva.
Mivel a nodereference mező csak az azonosítóját tárolja a hivatkozott tartalomnak, ezért szükség van egy SQL lekérdezésre, ami előkaparja a tartalom címét, és a field_img mezőbe feltöltött kép adatait.

/**
 * @ingroup themeable
 */
function theme_myftr1_formatter_field_img($element) {
  $output = '';
 
  if (empty($element['#item']['nid']) OR !is_numeric($element['#item']['nid'])) {
    return $output;
  }
 
  $row = myftr1_get_node_info($element['#item']['nid']);
 
  if ($row) {
    $html = FALSE;
    $text = '';
    if ($row->filepath) {
      $text .= theme('imagecache', 'small', $row->filepath, $row->data['alt'], $row->data['title']);
      $html = TRUE;
    }
    $text .= $row->title;
    $output = l($text, "node/{$element['#item']['nid']}", array('html' => $html));
  }
 
  return $output;
}
 
function myftr1_get_node_info($nid) {
  $field = content_fields('field_img');
  $db = content_database_info($field);
 
  $sql = '
    SELECT
      n.title,
      f.filepath,
      fimg.field_img_data AS data
    FROM
      {node}               AS n                        LEFT JOIN
      {'. $db['table'] .'} AS fimg ON n.vid = fimg.vid LEFT JOIN
      {files}              AS f    ON fimg.field_img_fid = f.fid
    WHERE
      n.nid = %d
  ';
 
  if ($field['multiple']) {
    $sql .= ' ORDER BY fimg.field_img_list DESC, fimg.delta ASC';
  }
 
  $row = db_fetch_object(db_query($sql, $nid));
  if ($row) {
    $row->data = unserialize($row->data);
  }
 
  return $row;
}