'select', '#title' => t('Select the vocabulary to list'), '#default_value' => variable_get('jquery_drawer', '1'), // TODO: won't work with taxonomy_get_vocabularies() '#options' => menu_parent_options(taxonomy_get_vocabularies(), 0), ); return $form; case 'save': variable_set('jquery_drawer', $edit['jquery_drawer']); break; case 'view': $menu = explode(':', variable_get('jquery_drawer', '1')); $block['content'] = theme('jquery_drawer', $menu[0], $menu[1]); return $block; } } /** * Implementation of hook_menu(); */ function jquery_drawer_menu() { $items['jquery_drawer'] = array( 'title' => 'jQuery Drawer', 'description' => 'Displays content inside a jQuery Drawer.', 'page callback' => 'jquery_drawer_page', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * Implementation of hook_theme(); */ function jquery_drawer_theme() { return array( 'jquery_drawer' => array( 'arguments' => array( 'menu' => NULL, 'parent' => NULL, ), ), 'jquery_drawer_javascript' => array( 'arguments' => array(), ), 'jquery_drawer_css' => array( 'arguments' => array(), ), 'jquery_drawer_link' => array( 'arguments' => array(), ), ); } /** * Drawer logic. */ function theme_jquery_drawer() { // Get all terms from a given vocabulary $vocabulary = variable_get('jquery_drawer', '1'); $terms = jquery_drawer_taxonomy_get_tree($vocabulary); foreach ($terms as $term) { // Just show parent terms if (taxonomy_get_parents($term->tid) == array()) { $menu[] = $term; } } // Build the drawer $output = jquery_drawer_build($menu); return $output; } /** * Drawer rendering. * * @ingroup themeable */ function jquery_drawer_build($menu) { $output = ''; $output .= '
'; $output .= '
'; return $output; } /** * Menu callback. */ function jquery_drawer_page($tid = null) { // First render all nodes whose parent is $term $output = ''; $nodes = taxonomy_select_nodes(array($tid)); while ($node = db_fetch_object($nodes)) { $link['title'] = $node->title; $link['href'] = 'node/' . $node->nid; $output .= theme('jquery_drawer_link', $link); } // Then render all nodes whose terms are children of $term $vocabulary = variable_get('jquery_drawer', '1'); $terms = jquery_drawer_taxonomy_get_tree($vocabulary, $tid); foreach ($terms as $term) { $filter[] = $term->tid; } $query = 'SELECT node.nid, node.title, term_node.tid FROM {node} LEFT JOIN {term_node} ON term_node.nid = node.nid WHERE term_node.tid IN (%s) AND node.status = "1"'; $result = db_query(db_rewrite_sql($query), implode(',', $filter)); $tree = taxonomy_node_tree_build($result, $terms); // format output $output .= ''; // Display output echo($output); // We need to exit here to avoid themeable output exit(); } /** * Recursively build the menu. * * @ingroup themeable */ function jquery_drawer_menu_build($term) { global $jquery_drawer_id; if ($jquery_drawer_id == null) { $jquery_drawer_id = 0; } $jquery_drawer_id++; if (isset($term->tid)) { $output .= '
  • '; $output .= $term->name; if (isset($term->below)) { $output .= ''; } else if (isset($term->nodes)) { $output .= ''; $output .= '
  • '; } $output .= ''; } return $output; } /** * jQuery Drawer Javascript theme function. * * @ingroup themeable */ function theme_jquery_drawer_javascript() { drupal_add_js(drupal_get_path('module', 'jquery_drawer') .'/jquery_drawer/drw/scripts.js'); } /** * jQuery Drawer CSS theme function. * * @ingroup themeable */ function theme_jquery_drawer_css() { drupal_add_css(drupal_get_path('module', 'jquery_drawer') .'/jquery_drawer/drw/styles.css'); drupal_add_css(drupal_get_path('module', 'jquery_drawer') .'/jquery_drawer.css'); } /** * jQuery Drawer Link theme function. * * @ingroup themeable */ function theme_jquery_drawer_link($link) { if (empty($link['localized_options'])) { $link['localized_options'] = array(); } $link['attributes']['rel'] = 'drw'; $output = '
  • '; $output .= l($link['title'], $link['href'], array('attributes' => array('rel' => 'drw'))); $output .= '
  • '; return $output; } /** * Version of taxonomy_get_tree() without caching. */ function jquery_drawer_taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $cache = FALSE) { static $children, $parents, $terms; $depth++; // We can cache trees, so it's not CPU-intensive to call get_tree() on a term // and its children, too. if (!$cache && !isset($children[$vid])) { $children[$vid] = array(); $result = db_query(db_rewrite_sql('SELECT t.tid, t.*, parent FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $vid); while ($term = db_fetch_object($result)) { $children[$vid][$term->parent][] = $term->tid; $parents[$vid][$term->tid][] = $term->parent; $terms[$vid][$term->tid] = $term; } } $max_depth = (is_null($max_depth)) ? count($children[$vid]) : $max_depth; $tree = array(); if ($max_depth > $depth && !empty($children[$vid][$parent])) { foreach ($children[$vid][$parent] as $child) { $term = drupal_clone($terms[$vid][$child]); $term->depth = $depth; // The "parent" attribute is not useful, as it would show one parent only. unset($term->parent); $term->parents = $parents[$vid][$child]; $tree[] = $term; if (!empty($children[$vid][$child])) { $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth)); } } } return $tree; }