nd.module in Display Suite 6.3
Node displays.
File
modules/nd/nd.moduleView source
<?php
/**
* @file
* Node displays.
*/
/**
* Tell ctools where we keep default plugins
*/
function nd_ctools_plugin_directory($module, $plugin) {
if ($module == 'ds' && !empty($plugin)) {
return "plugins/{$plugin}";
}
}
/**
* 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) {
// Attach a display to the node object
ds_attach_display($node);
$node->ds
->prepare($node);
// Build fields and regions.
//ds_build_fields_and_regions($node, 'nd');
// 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,
));
}
}
/**
* 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;
$vars['content'] = $node->ds
->render();
}
/**
* 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();
$linked = FALSE;
$vid = end(explode('_', $field['key']));
$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
Name | 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_content_build_modes | Implementation of hook_content_build_modes(). |
nd_ctools_plugin_directory | Tell ctools where we keep default plugins |
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. |