You are here

nd.module in Node displays 6.2

Same filename and directory in other branches
  1. 6.3 nd.module
  2. 6 nd.module
  3. 7 nd.module

Node displays.

File

nd.module
View source
<?php

/**
 * @file
 * Node displays.
 */

/**
 * Implementation of hook_ds_api().
 */
function nd_ds_api() {
  $help = array(
    '<p>This module comes with a nd.tpl.php, available in the templates folder, which is optimized for use with Node Displays. You can copy the file to your themes folder to use your own version if you want. Copying the file to your theme folder will only work if node.tpl.php is in the theme folder.</p>
    <p>You can create a file called <strong>nd-<em>node_type</em>.tpl.php</strong>, <strong>nd-<em>node_type</em>-<em>build_mode</em>.tpl.php</strong> or <strong>nd-<em>node_type</em>-<em>build_mode</em>-<em>nid</em>.tpl.php</strong> for even more fine-grained theming.</p>
    <p>If you exclude the RSS build mode, the default node feed is generated, but might render strange content. Make sure you do not choose the "Titles only" as your feed content setting, otherwhise, this screen will not have any effect. Choosing either "Full text" or "Titles + teaser" does not matter, this screen will have effect on both settings, apart from the read more link and the format of the body (full/teaser). Remember that some fields like upload and terms are added automatically to the feed and that this build mode manipulates the $description variable, it does not add extra keys to the feed.</p>
    <p>If you have a problem with the content not being rendered through DS, please read <a href="http://drupal.org/node/572614">http://drupal.org/node/572614</a>.',
  );
  return array(
    'title' => 'Node displays',
    'module' => 'nd',
    'object' => 'node',
    'views_base' => array(
      'node',
      'apachesolr',
      'apachesolr_node',
    ),
    'types' => 'node_get_types',
    'extra' => array(
      'has_body',
    ),
    'plugins_exclude' => array(
      NODE_BUILD_RSS,
    ),
    'regions_single' => array(
      NODE_BUILD_RSS,
    ),
    'help' => $help,
  );
}

/**
 * Implementation of hook_init().
 */
function nd_init() {
  drupal_add_css(drupal_get_path('module', 'nd') . '/css/nd_regions.css');
}

/**
 * Implementation of hook_rules_event_info().
 */
function nd_rules_event_info() {
  return array(
    'nd_node_is_build' => array(
      'label' => t('DS has built the node display'),
      'module' => 'nd',
      'arguments' => array(
        'node' => array(
          'type' => 'node',
          'label' => t('Content'),
        ),
      ),
    ),
  );
}

/**
 * Implementation of hook_rules_action_info().
 */
function nd_rules_action_info() {
  return array(
    'nd_rules_disable_fields' => array(
      'label' => t('Do not show a ND field'),
      'arguments' => array(
        'node' => array(
          'type' => 'node',
          'label' => t('Content'),
        ),
      ),
      'module' => 'nd',
    ),
  );
}

/**
 * Implementation of hook_content_build_modes().
 */
function nd_content_build_modes() {
  $build_modes = array(
    'nd' => array(
      'title' => t('Node displays'),
      'build modes' => array(
        'full' => array(
          'title' => t('Full node'),
          'weight' => -1,
        ),
        'teaser' => array(
          'title' => t('Teaser'),
          'weight' => 1,
        ),
        'sticky' => array(
          'title' => t('Sticky'),
          'weight' => 2,
          'views style' => TRUE,
        ),
        NODE_BUILD_RSS => array(
          'title' => t('RSS'),
          'weight' => 3,
        ),
      ),
    ),
  );

  // Also add this here, so other modules (like views_attach)
  // can profit from custom build modes from the UI.
  $db_build_modes = variable_get('nd_build_modes', array());
  foreach ($db_build_modes as $key => $build_mode) {
    $build_modes[$key] = array(
      'title' => $build_mode,
      'build modes' => array(
        $key => array(
          'title' => $build_mode,
          'views style' => TRUE,
        ),
      ),
    );
  }
  return $build_modes;
}

/**
 * Implementation of hook_registry_alter().
 */
function nd_theme_registry_alter(&$registry) {
  $path = drupal_get_path('module', 'nd') . '/templates';
  array_unshift($registry['node']['theme paths'], $path);
}

/**
 * Implementation of hook_nodeapi().
 */
function nd_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {

    // Add has body property.
    case 'load':
      $node->has_body = node_get_types('type', $node->type)->has_body;
      break;

    // Determine build mode.
    case 'view':
      if ($node->build_mode == NODE_BUILD_RSS) {

        // For the RSS build mode, we need to manipulate right now.
        _nd_nodeapi($node);
      }
      elseif ($node->build_mode == NODE_BUILD_PREVIEW) {
        $node->build_mode = $teaser ? 'teaser' : 'full';

        // Prepare taxonomy
        if (isset($node->taxonomy)) {
          foreach ($node->taxonomy as $tid => $term) {
            if (is_int($tid)) {
              $node->taxonomy[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
            }
          }
        }
      }
      elseif ($node->build_mode === NODE_BUILD_NORMAL) {
        $build_mode = $teaser ? 'teaser' : 'full';
        $node->build_mode = $build_mode;
      }
      $node->has_body = node_get_types('type', $node->type)->has_body;
      if ($node->has_body == 1 && strlen($node->body) == 0) {
        $node->has_empty_body = 1;
      }
      drupal_alter('nd_build', $node);
      break;

    // Alter the node object for viewing.
    case 'alter':

      // We ignore the RSS build mode, which is handled in the view operation.
      if ($node->build_mode == NODE_BUILD_RSS) {
        return;
      }
      _nd_nodeapi($node);
      break;
  }
}

/**
 *  Implements hook_nd_build_alter
 */
function nd_nd_build_alter(&$node) {

  /**
   * Stickied Teasers
   *
   * Use of sticky as a stand-alone buildmode will be deprecated in 3.x,
   * where it will be replaced with custom variant selection.
   * For the time being, sticky can be ignored by setting
   * $conf['ds_ignore_sticky'] = TRUE
   * in settings.php
   */
  if (variable_get('ds_ignore_sticky', FALSE) != TRUE) {
    if ($node->build_mode == 'teaser' && $node->sticky == 1) {
      $node->build_mode = 'sticky';
    }
  }

  /**
   * Switch buildmode based on query string
   *
   * Build modes can be changed by setting ?build_mode=name in the query
   * string. Becuase this is potentially insecure, developers must enable
   * this for specific build modes by setting which modes allow switching
   * in a variable 'nd_parameter_switch_bm'.
   */
  $parameter_build_modes = variable_get('nd_parameter_switch_bm', array());
  if (isset($_GET['build_mode'])) {
    $switch = check_plain($_GET['build_mode']);
    if (in_array($switch, $parameter_build_modes)) {
      $node->build_mode = $switch;
    }
  }
}

/**
 * Implements hook_preprocess_page()
 */
function nd_preprocess_page(&$vars) {

  /**
   * Unset the node title
   *
   * Display Suite can display the node title where required. The default is to
   * use Drupal's default behaviour, however you may wish to hide the title and
   * let Display Suite take over.
   */
  if (isset($vars['node']) && variable_get('nd_ignore_title_' . $vars['node']->type, FALSE) == TRUE) {
    $vars['title'] = '';
  }
}

/**
 * Helper function to alter node properties
 *
 * @param stdClass $node The complete node object.
 */
function _nd_nodeapi(&$node) {

  // Build fields and regions.
  nd_build_fields_and_regions($node);

  // Special support for RSS.
  if ($node->build_mode == NODE_BUILD_RSS && $node->render_by_ds == TRUE) {
    foreach (element_children($node->content) as $key => $field) {
      if (!isset($node->ds_fields[$field])) {
        $node->content[$field]['#access'] = FALSE;
      }
      $node->content[$field]['#weight'] = $node->ds_fields[$field]['weight'];
      unset($node->ds_fields[$field]);
    }
    foreach ($node->ds_fields as $key => $field) {
      $render_key = $key . '_rendered';
      $node->content[$key]['#value'] = theme('ds_field', $node->{$render_key}, $node->ds_fields[$key]);
      $node->content['#content_extra_fields'][$key]['weight'] = $node->ds_fields[$key]['weight'];
    }

    // Body and title are tricky ones since their weights are set
    // in #content_extra_fields, so update the value there!
    $node->content['#content_extra_fields']['body_field']['weight'] = $node->content['body']['#weight'];
    $node->content['#content_extra_fields']['title']['weight'] = $node->content['title']['#weight'];
  }
  if (function_exists('rules_invoke_event')) {
    rules_invoke_event('nd_node_is_build', array(
      'node' => &$node,
    ));
  }
}

/**
 * Statically cached version of ds_build_fields and regions
 */
function nd_build_fields_and_regions(&$node) {
  static $displays = array();
  if (isset($displays[$node->nid][$node->build_mode])) {
    $node = $displays[$node->nid][$node->build_mode];
  }
  else {
    ds_build_fields_and_regions($node, 'nd');
    $displays[$node->nid][$node->build_mode] = $node;
  }
}

/**
 * Implementation of moduleName_preprocess_hook().
 * The node data will be rendered in regions. This uses a helper function
 * so themers/developers can call that helper function from within
 * their preprocess_hooks if they are fiddling with some data. For information
 * about this decision see http://drupal.org/node/570592 (issue) and
 * http://drupal.org/node/572614 for information on howto implement.
 */
function nd_preprocess_node(&$vars, $hook) {
  if (!variable_get('nd_preprocess_override', FALSE)) {
    _nd_preprocess_node($vars, $hook);
  }
}

/**
 * Helper function used in either nd_preprocess_node or other preprocess function.
 */
function _nd_preprocess_node(&$vars, $hook) {
  $node = $vars['node'];

  // Break all the rendering if needed.
  if (!$node->render_by_ds) {
    return;
  }

  // Add nd-content_type-build_mode(-nid) template suggestion.
  $vars['template_files'][] = 'nd';
  $vars['template_files'][] = 'nd-' . $node->type;
  $vars['template_files'][] = 'nd-' . $node->type . '-' . $node->build_mode;
  $vars['template_files'][] = 'nd-' . $node->type . '-' . $node->build_mode . '-' . $node->nid;

  // Dont completely break things for users of 1.x
  if (function_exists('ds_render')) {
    $vars['content'] = ds_render($node->nid, $node, 'nd', $vars);
  }
  else {
    drupal_set_message('You are using incompatible versions of Display Suite and Node Displays. Please downgrade Node Displays to 2.6, or upgrade Display Suite to the 2.x branch.', 'warning');
    $vars['content'] = ds_render_content($node, 'nd', $vars);
  }
}

/**
 * Render the node object through the DS views plugin.
 *
 * @param array $vars The variables to manipulate.
 * @param string $build_mode The build mode to use on this object.
 */
function ds_views_row_node(&$vars, $build_mode) {
  nd_views_node_helper($vars, $build_mode);
}

/**
 * Render the apachesolr object through the DS views plugin.
 *
 * @param array $vars The variables to manipulate.
 * @param string $build_mode The build mode to use on this object.
 */
function ds_views_row_apachesolr(&$vars, $build_mode) {
  nd_views_node_helper($vars, $build_mode);
}

/**
 * Render the apachesolr node object through the DS views plugin.
 *
 * @param array $vars The variables to manipulate.
 * @param string $build_mode The build mode to use on this object.
 */
function ds_views_row_apachesolr_node(&$vars, $build_mode) {
  nd_views_node_helper($vars, $build_mode);
}

/**
 * Helper function for views node plugin.
 */
function nd_views_node_helper(&$vars, $build_mode) {
  $nid = $vars['row']->nid;
  if (!is_numeric($nid)) {
    return;
  }
  if (module_exists('object_cache')) {
    $node = object_cache_get('node', $nid);
  }
  else {
    $node = node_load($nid);
  }
  if (empty($node)) {
    return;
  }
  $node->build_mode = $build_mode;

  // Check the teaser flag and show_links flag.
  $teaser = $node->build_mode != 'full' ? TRUE : FALSE;
  $show_links = ds_show_field('nd', $node->type, $build_mode, 'links');

  // Build object.
  $vars['object'] = node_view($node, $teaser, FALSE, $show_links);
}

/**
 * Implementation of hook_theme().
 */
function nd_theme() {
  $theme_functions = array();

  // Single theming functions.
  $formatters = array(
    'nd_bodyfield',
    'nd_title_h1_nolink',
    'nd_title_h1_link',
    'nd_title_h2_nolink',
    'nd_title_h2_link',
    'nd_title_h2_block_nolink',
    'nd_title_h2_block_link',
    'nd_title_p_nolink',
    'nd_title_p_link',
    'nd_book_add_new_child',
    'nd_book_printer_version',
  );
  foreach ($formatters as $formatter) {
    $theme_functions[$formatter] = array(
      'arguments' => array(
        'node' => NULL,
      ),
    );
  }

  // Post date with Date API.
  if (variable_get('nd_use_date_api', TRUE)) {
    if (module_exists('date_api')) {
      $date_formats = date_get_format_types('', TRUE);
    }
    else {
      $date_formats = array(
        'small' => array(
          'title' => 'Small',
          'type' => 'small',
        ),
        'medium' => array(
          'title' => 'Medium',
          'type' => 'medium',
        ),
        'large' => array(
          'title' => 'Large',
          'type' => 'large',
        ),
      );
    }
    foreach ($date_formats as $formatter) {
      $theme_functions['nd_post_date_' . $formatter['type']] = array(
        'arguments' => array(
          'node' => NULL,
        ),
        'function' => 'theme_nd_post_date',
      );
    }
  }

  // Vocabulary.
  $vocab_formatters = array(
    'nd_terms_per_vocabulary_space',
    'nd_terms_per_vocabulary_linked_space',
    'nd_terms_per_vocabulary_comma',
    'nd_terms_per_vocabulary_linked_comma',
    'nd_terms_per_vocabulary_list',
    'nd_terms_per_vocabulary_linked_list',
  );
  foreach ($vocab_formatters as $formatter) {
    $theme_functions[$formatter] = array(
      'arguments' => array(
        'node' => NULL,
      ),
      'function' => 'nd_terms_per_vocabulary',
    );
  }
  return $theme_functions;
}

/**
 * Implementation of hook_ds_fields().
 */
function nd_ds_fields($type_name, $build_mode, $extra) {
  $fields = array(
    'title' => array(
      'title' => t('Title'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'allow_formatters' => TRUE,
      'properties' => array(
        'formatters' => array(
          'nd_title_h1_nolink' => t('H1 title'),
          'nd_title_h1_link' => t('H1 title, linked to node'),
          'nd_title_h2_nolink' => t('H2 title'),
          'nd_title_h2_link' => t('H2 title, linked to node'),
          'nd_title_h2_block_nolink' => t('H2 block title'),
          'nd_title_h2_block_link' => t('H2 block title, linked to node'),
          'nd_title_p_nolink' => t('Paragraph title'),
          'nd_title_p_link' => t('Paragraph title, linked to node'),
        ),
      ),
    ),
    'author' => array(
      'title' => t('Author'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'properties' => array(
        'formatters' => array(
          'ds_author_nolink' => t('Author'),
          'ds_author_link' => t('Author linked to profile'),
        ),
      ),
    ),
    'links' => array(
      'title' => t('Links'),
      'type' => DS_FIELD_TYPE_PREPROCESS,
      'status' => DS_FIELD_STATUS_STATIC,
    ),
    'read_more' => array(
      'title' => t('Read more'),
      'type' => DS_FIELD_TYPE_CODE,
      'status' => DS_FIELD_STATUS_DEFAULT,
      'properties' => array(
        'formatters' => array(
          'ds_eval_code' => t('Default'),
        ),
        'code' => '<?php echo l(t("Read more"), "node/$object->nid"); ?>',
      ),
    ),
  );

  // Updated and posted date formatters
  if (module_exists('date_api')) {
    $date_formats = date_get_format_types('', FALSE);
  }
  else {
    $date_formats = array(
      'small' => array(
        'title' => 'Small',
        'type' => 'small',
      ),
      'medium' => array(
        'title' => 'Medium',
        'type' => 'medium',
      ),
      'large' => array(
        'title' => 'Large',
        'type' => 'large',
      ),
    );
  }
  $date_formatters = array();
  foreach ($date_formats as $formatter) {
    $date_formatters['nd_post_date_' . $formatter['type']] = t($formatter['title']);
  }

  // Regression. People upgrading from 6.x-2.2 to 6.x-2.3 will lose
  // the post date PHP code field, we can't do that by default. The
  // update_2 will make the nd_use_date_api variable false, and
  // developers can set this variable to 1 in the variable table.
  if (variable_get('nd_use_date_api', TRUE)) {
    $fields['post_date'] = array(
      'title' => t('Post date'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'properties' => array(
        'formatters' => $date_formatters,
      ),
    );
  }
  else {
    $fields['post_date'] = array(
      'title' => t('Post date'),
      'type' => DS_FIELD_TYPE_CODE,
      'status' => DS_FIELD_STATUS_DEFAULT,
      'properties' => array(
        'formatters' => array(
          'ds_eval_code' => t('Default'),
        ),
        'code' => '<?php echo format_date($object->created, "custom", "d/m/Y"); ?>',
      ),
    );
  }
  $fields['updated_date'] = array(
    'title' => t('Last updated date'),
    'type' => DS_FIELD_TYPE_THEME,
    'status' => DS_FIELD_STATUS_STATIC,
    'properties' => array(
      'formatters' => $date_formatters,
    ),
  );

  // Check for body.
  if (isset($extra['has_body']) && $extra['has_body'] == TRUE) {
    $fields['body'] = array(
      'title' => t('Body'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'allow_formatters' => TRUE,
      'properties' => array(
        'formatters' => array(
          'nd_bodyfield' => t('Default'),
        ),
      ),
    );
  }

  // Taxonomy support.
  if (module_exists('taxonomy')) {
    $all = FALSE;

    // All vocabularies per content type.
    // We can't use taxonomy_get_vocabularies() here, see http://drupal.org/node/810352.
    $result = db_query("SELECT v.vid, v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", $type_name);
    while ($vocabulary = db_fetch_object($result)) {
      $all = TRUE;
      $fields['terms_' . $vocabulary->vid] = array(
        'title' => t('Taxonomy: @vocab', array(
          '@vocab' => $vocabulary->name,
        )),
        'type' => DS_FIELD_TYPE_THEME,
        'status' => DS_FIELD_STATUS_STATIC,
        'properties' => array(
          'css-class' => 'field-terms field-terms-' . $vocabulary->vid,
          'formatters' => array(
            'nd_terms_per_vocabulary_space' => t('Separated by space'),
            'nd_terms_per_vocabulary_linked_space' => t('Separated by space, linked to term'),
            'nd_terms_per_vocabulary_comma' => t('Separated by comma'),
            'nd_terms_per_vocabulary_linked_comma' => t('Separated by comma, linked to term'),
            'nd_terms_per_vocabulary_list' => t('Unordered list'),
            'nd_terms_per_vocabulary_linked_list' => t('Unordered list, linked to term'),
          ),
        ),
      );
    }
    if ($all) {

      // All terms.
      $fields['terms'] = array(
        'title' => t('Taxonomy: all terms'),
        'type' => DS_FIELD_TYPE_PREPROCESS,
        'status' => DS_FIELD_STATUS_STATIC,
      );
    }
  }

  // Upload support.
  if (module_exists('upload') && $build_mode != 'teaser' && variable_get("upload_{$type_name}", 1)) {
    $fields['files'] = array(
      'title' => t('Core upload'),
      'type' => DS_FIELD_TYPE_IGNORE,
      'status' => DS_FIELD_STATUS_STATIC,
    );
  }

  // Book support.
  if (module_exists('book') && book_type_is_allowed($type_name)) {
    $fields['book_navigation'] = array(
      'title' => t('Book navigation'),
      'type' => DS_FIELD_TYPE_FUNCTION,
      'status' => DS_FIELD_STATUS_STATIC,
      'properties' => array(
        'formatters' => array(
          'nd_book_navigation' => t('Book navigation'),
        ),
      ),
    );
    $fields['book_add_new_child'] = array(
      'title' => t('Book: add new child'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'properties' => array(
        'formatters' => array(
          'nd_book_add_new_child' => t('Add new child'),
        ),
      ),
    );
    $fields['book_printer_version'] = array(
      'title' => t('Book: printer version'),
      'type' => DS_FIELD_TYPE_THEME,
      'status' => DS_FIELD_STATUS_STATIC,
      'properties' => array(
        'formatters' => array(
          'nd_book_printer_version' => t('Printer version'),
        ),
      ),
    );
  }
  return array(
    'nd' => $fields,
  );
}

/**
 * ND theming functions.
 */
function theme_nd_bodyfield($field) {
  return $field['object']->content['body']['#value'];
}
function theme_nd_title_h1_nolink($field) {
  return '<h1>' . check_plain($field['object']->title) . '</h1>';
}
function theme_nd_title_h1_link($field) {
  return '<h1>' . l($field['object']->title, 'node/' . $field['object']->nid) . '</h1>';
}
function theme_nd_title_h2_nolink($field) {
  return '<h2>' . check_plain($field['object']->title) . '</h2>';
}
function theme_nd_title_h2_link($field) {
  return '<h2>' . l($field['object']->title, 'node/' . $field['object']->nid) . '</h2>';
}
function theme_nd_title_h2_block_nolink($field) {
  return '<h2 class="block-title">' . check_plain($field['object']->title) . '</h2>';
}
function theme_nd_title_h2_block_link($field) {
  return '<h2 class="block-title">' . l($field['object']->title, 'node/' . $field['object']->nid) . '</h2>';
}
function theme_nd_title_p_nolink($field) {
  return '<p>' . check_plain($field['object']->title) . '</p>';
}
function theme_nd_title_p_link($field) {
  return '<p>' . l($field['object']->title, 'node/' . $field['object']->nid) . '</p>';
}

/**
 *  Post date formatter.
 */
function theme_nd_post_date($field) {
  $date_format = str_replace('nd_post_date_', '', $field['formatter']);
  if (module_exists('date_api')) {
    $datetime = date_make_date($field['object']->created, NULL, DATE_UNIX);
    $format = variable_get('date_format_' . $date_format, 'd/m/Y');
    return date_format_date($datetime, 'custom', $format);
  }
  else {
    return format_date($field['object']->created, $date_format);
  }
}

/**
 * Terms per vocabulary.
 */
function nd_terms_per_vocabulary($field) {
  $content = '';
  if (isset($field['object']->taxonomy) && !empty($field['object']->taxonomy)) {
    $terms = array();
    $key_elements = explode('_', $field['key']);
    $vid = end($key_elements);
    $formatter_explode = explode('_', $field['formatter']);
    $separators = array(
      'space' => ' ',
      'comma' => ', ',
    );
    $separator = $separators[end($formatter_explode)];
    $list = end($formatter_explode) == 'list' ? TRUE : FALSE;
    $linked = prev($formatter_explode);
    foreach ($field['object']->taxonomy as $tid => $term) {
      if ($term->vid == $vid) {
        $terms[] = $linked == 'linked' ? l($term->name, taxonomy_term_path($term)) : check_plain($term->name);
      }
    }
    if (!empty($terms)) {
      if ($separator) {
        $content = implode($separator, $terms);
      }
      elseif ($list) {
        $content = theme('item_list', $terms);
      }
    }
  }
  return $content;
}

/**
 * Book navigation theming.
 */
function nd_book_navigation($field) {
  $content = '';
  if (isset($field['object']->content['book_navigation'])) {
    if (isset($field['object']->content['book_navigation']['#value'])) {
      $content = $field['object']->content['book_navigation']['#value'];
    }
    elseif (isset($field['object']->book['bid']) && !empty($field['object']->book['bid'])) {
      $content = theme('book_navigation', $field['object']->book);
    }
  }
  else {
    if (isset($field['object']->book['bid']) && !empty($field['object']->book['bid'])) {
      $content = theme('book_navigation', $field['object']->book);
    }
  }
  return $content;
}

/**
 * Add new child for book.
 */
function theme_nd_book_add_new_child($field) {
  if (user_access('add content to books')) {
    $child = str_replace('_', '-', variable_get('book_child_type', 'book'));
    return l(t('Add child page'), 'node/add/' . $child, array(
      'query' => array(
        'parent' => $field['object']->book['mlid'],
      ),
    ));
  }
}

/**
 * Printer friendly version
 */
function theme_nd_book_printer_version($field) {
  return l(t('Printer-friendly version'), 'book/export/html/' . $field['object']->nid);
}

Functions

Namesort descending Description
ds_views_row_apachesolr Render the apachesolr object through the DS views plugin.
ds_views_row_apachesolr_node Render the apachesolr node object through the DS views plugin.
ds_views_row_node Render the node object through the DS views plugin.
nd_book_navigation Book navigation theming.
nd_build_fields_and_regions Statically cached version of ds_build_fields and regions
nd_content_build_modes Implementation of hook_content_build_modes().
nd_ds_api Implementation of hook_ds_api().
nd_ds_fields Implementation of hook_ds_fields().
nd_init Implementation of hook_init().
nd_nd_build_alter Implements hook_nd_build_alter
nd_nodeapi Implementation of hook_nodeapi().
nd_preprocess_node Implementation of moduleName_preprocess_hook(). The node data will be rendered in regions. This uses a helper function so themers/developers can call that helper function from within their preprocess_hooks if they are fiddling with some data. For…
nd_preprocess_page Implements hook_preprocess_page()
nd_rules_action_info Implementation of hook_rules_action_info().
nd_rules_event_info Implementation of hook_rules_event_info().
nd_terms_per_vocabulary Terms per vocabulary.
nd_theme Implementation of hook_theme().
nd_theme_registry_alter Implementation of hook_registry_alter().
nd_views_node_helper Helper function for views node plugin.
theme_nd_bodyfield ND theming functions.
theme_nd_book_add_new_child Add new child for book.
theme_nd_book_printer_version Printer friendly version
theme_nd_post_date Post date formatter.
theme_nd_title_h1_link
theme_nd_title_h1_nolink
theme_nd_title_h2_block_link
theme_nd_title_h2_block_nolink
theme_nd_title_h2_link
theme_nd_title_h2_nolink
theme_nd_title_p_link
theme_nd_title_p_nolink
_nd_nodeapi Helper function to alter node properties
_nd_preprocess_node Helper function used in either nd_preprocess_node or other preprocess function.