You are here

nd.module in Node displays 7

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

Node displays.

File

nd.module
View source
<?php

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

/**
 * Implements hook_ds_api().
 */
function nd_ds_api() {
  $help = array(
    t('<h3>Node displays</h3>
      <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.</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. Remember that some fields like upload and terms are added automatically to the feed and that this 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',
    ),
    'types' => 'node_type_get_types',
    'extra' => array(
      'has_body',
    ),
    'plugins_exclude' => array(
      'rss',
    ),
    'regions_single' => array(
      'rss',
    ),
    'help' => $help,
  );
}

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

/**
 * Implements 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,
        ),
        'rss' => array(
          'title' => t('RSS'),
          'weight' => 3,
        ),
      ),
    ),
  );
  return $build_modes;
}

/**
 * Implements hook_node_load().
 */
function nd_node_load($nodes, $types) {
  $node_types = node_type_get_types();
  foreach ($nodes as $nid => $node) {
    $node->has_body = $node_types[$node->type]->has_body;
  }
}

/**
 * Implements hook_node_view().
 */
function nd_node_view($node, $view_mode) {

  // Recheck this later with views, adding the build
  // mode probably isn't necessary at all.
  if (!isset($node->build_mode)) {
    $node->build_mode = $view_mode;
  }
  _nd_nodeapi($node);
}

/**
 * Implements hook_node_view_alter().
 */
function nd_node_view_alter(&$build) {

  //dsm($build);
}

/**
 * Implementation of hook_form_alter().
 */
function nd_form_alter(&$form, $form_state, $form_id) {

  // Add build modes on the node content form of ctools.
  if ($form_id == 'ctools_node_content_type_edit_form') {
    $form['identifier']['#type'] = 'select';
    $form['identifier']['#description'] = t('Node displays has taken over the identifier textfield and is now a select box with the available build modes. The template suggestion will now be node-panel-BUILDMODE.tpl.php.');
    $build_modes = array();
    $all_build_modes = ds_get_build_modes('nd');
    foreach ($all_build_modes as $key => $build_mode) {
      $build_modes[$key] = $build_mode['title'];
    }
    $form['identifier']['#options'] = $build_modes;
  }
}

//, $op, $teaser = NULL, $page = NULL) {

/*function blah() {
  switch ($op) {

    // 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 == TRUE ? 'teaser' : 'full';
        $node->has_body = node_get_types('type', $node->type)->has_body;
      }
      elseif ($node->build_mode === NODE_BUILD_NORMAL) {
        $build_mode = ($page) ? 'full' : 'teaser';
        $node->build_mode = $build_mode;
      }

      // Sticky.
      if ($node->build_mode == 'teaser' && $node->sticky == 1) {
        $node->build_mode = 'sticky';
      }

      // Panels support.
      if (isset($node->panel_identifier)) {
        $node->build_mode = $node->panel_identifier;
      }

      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 == 'rss') {
        return;
      }
      _nd_nodeapi($node);
      break;
  }
}*/

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

  // Build fields and regions.
  ds_build_fields_and_regions($node, 'nd');
  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;
      }
      elseif (isset($node->ds_fields[$field]) && $node->ds_fields[$field]['type'] == 'ds') {
        $key = $field . '_rendered';
        $node->content[$field]['#value'] = theme('ds_field', $node->{$key}, $node->ds_fields[$field]);
      }
    }

    // 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'];
  }
}

/**
 * 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) {

  //dsm($vars);

  // @todo : revise al this stuff, the nd template is found, but
  // let's find out the other suggestions and rollback to node template file.
  $node = $vars['node'];

  //dsm($vars['theme_hook_suggestions']);
  array_unshift($vars['theme_hook_suggestions'], 'nd');

  // Add nd-content_type-build_mode(-nid) template suggestion.

  /*$vars['theme_hook_suggestions'][] = 'nd';
    $vars['theme_hook_suggestions'][] = 'nd-' . $node->type;
    $vars['theme_hook_suggestions'][] = 'nd-' . $node->type . '-' . $node->build_mode;
    $vars['theme_hook_suggestions'][] = 'nd-' . $node->type . '-' . $node->build_mode . '-' . $node->nid;*/

  //dsm($vars['theme_hook_suggestions']);

  // Break all the rendering if needed.
  if (!$node->render_by_ds) {
    $vars['template_files'][] = 'node';
    return;
  }
  $content = ds_render_content($node, 'nd', $vars);
  $vars['content'] = $content;
}

/**
 * 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) {
  $nid = $vars['row']->nid;
  if (!is_numeric($nid)) {
    return;
  }
  $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);
}

/**
 * Implements hook_theme().
 */
function nd_theme() {
  $theme_functions = array();
  $path = drupal_get_path('module', 'nd');

  // 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',
  );
  foreach ($formatters as $formatter) {
    $theme_functions[$formatter] = array(
      'variables' => array(
        'field' => NULL,
      ),
    );
  }

  // 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',
  );
  foreach ($vocab_formatters as $formatter) {
    $theme_functions[$formatter] = array(
      'variables' => array(
        'field' => NULL,
      ),
      'function' => 'nd_terms_per_vocabulary',
    );
  }
  $theme_functions['nd'] = array(
    'render element' => 'elements',
    'template' => 'nd',
    'path' => $path . '/templates',
  );
  return $theme_functions;
}

/**
 * Implements 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,
      '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"); ?>',
      ),
    ),
    '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"); ?>',
      ),
    ),
  );

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

  // Taxonomy support.
  if (module_exists('taxonomy')) {

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

    // All vocabularies per content type.
    $vocabularies = taxonomy_get_vocabularies($type_name);
    if (count($vocabularies) > 0) {
      foreach ($vocabularies as $key => $vocabulary) {
        $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'),
            ),
          ),
        );
      }
    }
  }

  // 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') && $type_name == 'book') {
    $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'),
        ),
      ),
    );
  }

  // Comment support (count and add new comment link)
  return array(
    'nd' => $fields,
  );
}

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

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

/**
 * Book navigation.
 */
function nd_book_navigation($field) {
  $field = $field['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;
}

Functions

Namesort descending Description
ds_views_row_node Render the node object through the DS views plugin.
nd_book_navigation Book navigation.
nd_content_build_modes Implements hook_content_build_modes().
nd_ds_api Implements hook_ds_api().
nd_ds_fields Implements hook_ds_fields().
nd_form_alter Implementation of hook_form_alter().
nd_init Implementation of hook_init().
nd_node_load Implements hook_node_load().
nd_node_view Implements hook_node_view().
nd_node_view_alter Implements hook_node_view_alter().
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_terms_per_vocabulary Terms per vocabulary.
nd_theme Implements hook_theme().
theme_nd_bodyfield ND theming functions.
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.