Tuli pitkästä aikaa koodattua hiukan Drupalilla. Tein tänne omalle saitilleni yksinkertaisen navigointi-footerin, joka näyttää artikkelien kategoriat. Siitä tuli ihan irrallinen moduuli, joten pistän tähän jakoon, public domain. Tästä on varmasti enemmän iloa esimerkkikoodina kuin varsinaisena tuotantomoduulina. :-)

Moduuli tuottaa blokin, jossa on kaksiulotteinen taulurakenne. Taulun thead-osuudessa ovat päätason kategoriat ja tbody-osuudessa niiden alakategoriat. Monimutkaisemmat hierarkiat vaativat tuon rakenteen miettimistä vähän eri lailla, mutta omiin tarpeisiini se täsmää. Omassa teemassani olen sijoittanut blokin erilliseen fatfooter-diviin ja tyylittänyt sen sitten CSS:llä.

taxfooter.info

name = Taxonomy footer
description = Show taxonomy navigation as a fat footer
core = 6.x
dependencies[] = taxonomy

taxfooter.module

function taxfooter_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks = array(
        array('info' => t('Taxonomy footer')),
      );
      return $blocks;
    case 'configure':
      switch ($delta) {
        case 0:
          $vocs = taxonomy_get_vocabularies();
          $vocnames = array(0 => '(none)');
          foreach ($vocs as $voc) $vocnames[$voc->vid] = $voc->name;
          $form = array(
            'taxfooter_vocabulary' => array(
              '#type' => 'select',
              '#title' => t('Vocabulary to show in fat footer'),
              '#default_value' => variable_get('taxfooter_vocabulary', 0),
              '#options' => $vocnames
          ));
          break;
      }
      return $form;
    case 'save':
      switch ($delta) {
        case 0:
          variable_set('taxfooter_vocabulary', (int) $edit['taxfooter_vocabulary']);
          break;
      }
      break;
    case 'view':
      switch ($delta) {
        case 0:
          $vid = variable_get('taxfooter_vocabulary', 0);
          if ($vid <= 0) return null;
          $html = _taxfooter_render($vid);
          $block = array(
            'subject' => t('Fat Footer'),
            'content' => $html);
          break;
      }
      return $block;
  }
}

function _taxfooter_render($vid) {
  $subcolumns = 7;
  $tree = taxonomy_get_tree($vid);
  $html = '<table>';
  $html .= '<thead>';
  $html .= '<tr>';
  $count = 0;
  $toplevel = array();
  foreach ($tree as $category) if ($category->depth == 0) {
    $toplevel[] = $category->tid;
    if ($count++ > 0) $html .= '<td class="divide"></td>';
    $html .= '<td colspan="' . $subcolumns . '">';
    $html .= l($category->name . ' categories', 'taxonomy/term/' . $category->tid) . '<br/>';
    $html .= '</td>';
  }
  $html .= '</tr>';
  $html .= '</thead>';
  $html .= '<tbody>';
  $html .= '<tr>';
  $tcount = 0;
  foreach ($toplevel as $toptid) {
    $scount = 0;
    $ccount = 0;
    foreach ($tree as $subcategory) if ($subcategory->depth > 0 && in_array($toptid, $subcategory->parents)) {
      if ($tcount > 0 && $scount == 0) $html .= '<td class="divide"></td>';
      if ($scount == 0) { $html .= '<td>'; $ccount++; }
      elseif ($scount % 2 == 0) { $html .= '</td><td>'; $ccount++; }
      $html .= l($subcategory->name, 'taxonomy/term/' . $subcategory->tid) . '<br/>';
      $scount++;
    }
    while ($ccount++ < $subcolumns) {
      $html .= '</td><td>';
    }
    $html .= '</td>';
    $tcount++;
  }
  $html .= '</tr>';
  $html .= '</tbody>';
  $html .= '</table>';
  return $html;
}