')); /** * Implementation of hook_help(). */ function paging_help($section) { switch ($section) { case 'admin/help#paging': return t('

Break long pages into smaller ones by means of a page tag:

First page here.
%separator
Second page here.
%separator
More pages here.
', array('%separator' => PAGING_SEPARATOR)); } } /** * Implementation of hook_menu(). */ function paging_menu($maycache) { if ($maycache) { $items[] = array( 'path' => 'admin/settings/paging', 'title' => t('Paging'), 'description' => t('Enable paging for node types and set the page break string.'), 'callback' => 'drupal_get_form', 'callback arguments' => 'paging_settings', 'access' => user_access('administer site configuration'), 'type' => MENU_NORMAL_ITEM, ); } return $items; } /** * Menu callback; display module settings form. */ function paging_settings() { $form = array(); $node_types = node_get_types('names'); $node_types_enabled = variable_get('paging_node_types_enabled', array()); unset($node_types_enabled[0]); $form['paging_config'] = array( '#type' => 'fieldset', '#title' => t('Paging settings'), ); $form['paging_config']['paging_separator'] = array( '#type' => 'textfield', '#title' => t('Separator'), '#size' => 20, '#maxlength' => 255, '#default_value' => PAGING_SEPARATOR, '#description' => t('Page separator string. You should use an HTML tag that will render reasonably when paging is not enabled, such as:
<!--pagebreak--> or <HR />.'), ); $form['paging_config']['paging_read_more_enabled'] = array( '#type' => 'checkbox', '#title' => t('Link read more to next page'), '#description' => t('If enabled, the "read more" link under teasers will link to the next content page.
Note: Only works if teaser and first page have the same content. Not recommended unless you are willing to customize it with your theme.'), '#default_value' => variable_get('paging_read_more_enabled', 0) ); $form['paging_config']['paging_node_types_enabled'] = array( '#type' => 'checkboxes', '#title' => t('Node types'), '#description' => t('Select the node types you want to enable paging for.'), '#default_value' => $node_types_enabled, '#options' => $node_types, ); $form['paging_automatic'] = array( '#type' => 'fieldset', '#title' => t('Automatic Paging settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); /*$form['paging_automatic']['paging_automatic_on'] = array( '#type' => 'checkbox', '#title' => t('Enable Automatic Paging'), '#description' => t('Enabling Automatic Paging will automatically set the page separator string at the consecutive configured number of words for the chosen node type. Content with manually inserted page separator string will not be treated.'), '#default_value' => variable_get('paging_automatic_on', 0), );*/ if (count($node_types_enabled) > 0) { foreach (array_keys($node_types_enabled, '0') as $unset) { unset($node_types_enabled[$unset]); } foreach ($node_types_enabled as $key => $nodetype) { $node_types_enabled[$key] = $node_types[$key]; } $form['paging_automatic']['paging_node_types_auto_enabled'] = array( '#type' => 'checkboxes', '#title' => t('Node types'), '#description' => t('Select the node types you want to enable automatic paging for. Only node types, for which Paging is enabled, are shown.'), '#default_value' => variable_get('paging_node_types_auto_enabled', array()), '#options' => $node_types_enabled, ); } else { $form['paging_automatic']['paging_node_types_auto_enabled'] = array( '#type' => 'checkboxes', '#title' => t('Node types'), '#description' => t('Only node types, for which Paging is enabled(above), are shown.'), '#attributes' => array('disabled' => 'disabled'), ); } $form['paging_automatic']['paging_paragraph'] = array( '#type' => 'fieldset', '#title' => t('By line break'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['paging_automatic']['paging_paragraph']['paging_automatic_chars'] = array( '#type' => 'select', '#title' => t('Length of each page'), '#options' => array(0 => t('Disable'), 200 => t('200 characters'), 400 => t('400 characters'), 600 => t('600 characters'), 800 => t('800 characters'), 1000 => t('1000 characters'), 1200 => t('1200 characters'), 1400 => t('1400 characters'), 1600 => t('1600 characters'), 1800 => t('1800 characters'), 2000 => t('2000 characters'), 2500 => t('2500 characters'), 3000 => t('3000 characters')), '#required' => TRUE, '#description' => t('Set the number of characters that should be displayed per page. This is the recommended method for automatic paging.'), '#default_value' => variable_get('paging_automatic_chars', 1000), ); $form['paging_automatic']['paging_words'] = array( '#type' => 'fieldset', '#title' => t('By words'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['paging_automatic']['paging_words']['paging_automatic_words'] = array( '#type' => 'textfield', '#title' => t('Number of words on each page'), '#size' => 5, '#maxlength' => 5, '#required' => TRUE, '#description' => t('Set the number of words that should be displayed per page. This may break your sentences at page breaks. Enter 0 to disable.'), '#default_value' => variable_get('paging_automatic_words', 0), ); return system_settings_form($form); } /** * Implementation of hook_nodeapi(). */ function paging_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { if (isset($node->field_body[0]['view'])) { // support for CCK _paging_nodeapi($node, $node->field_body[0]['view'], $node->field_teaser[0]['view'], $op, $teaser, $page); } elseif (isset($node->field_body[0]['value'])) { // support for CCK _paging_nodeapi($node, $node->field_body[0]['value'], $node->field_teaser[0]['value'], $op, $teaser, $page); } else { _paging_nodeapi($node, $node->body, $node->teaser, $op, $teaser, $page); } } /** * Helper function for paging_nodeapi(). */ function _paging_nodeapi(&$node, &$nodebody, &$nodeteaser, $op, $teaser, $page) { switch ($op) { case 'load': $custom_body = $nodebody; if (in_array($node->type, variable_get('paging_node_types_auto_enabled', array()), TRUE) && strpos($nodebody, PAGING_SEPARATOR) === false) { if (($paging_number = variable_get('paging_automatic_chars', 1000)) != 0) { $words_count = strlen($nodebody); $body = $nodebody; if ($words_count > $paging_number) { $breaks = $words_count / $paging_number; for ($i = 0; $i < $breaks; $i++) { $bodypart[$i] = paging_paragraph_split(trim($body), $paging_number); $bodycount += strlen($bodypart[$i]); $body = substr($nodebody, $bodycount); } $custom_body = implode(PAGING_SEPARATOR, $bodypart); } } elseif (($paging_number = variable_get('paging_automatic_words', 0)) != 0) { $body = explode(' ', $nodebody); $words = count($body); if ($words > $paging_number) { $breaks = $words / $paging_number; for ($i = 1; $i <= $breaks; $i++) { $index = $i * $paging_number; $para_pos = strpos($index, 'a', 1); $body[$index] .= PAGING_SEPARATOR; } } $custom_body = implode(' ', $body); } } $node->pages = explode(PAGING_SEPARATOR, $custom_body); $node->pages_count = count($node->pages); break; case 'view': $node_type = in_array($node->type, variable_get('paging_node_types_enabled', array()), TRUE); if (!$node->in_preview && $node_type && ereg('', $teaser ? $nodeteaser : $nodebody)) { $element = 1; if (!$teaser && $node->pages_count > 1 && arg(2) != 'print' && arg(2) != 'full') { global $pager_page_array, $pager_total; $page = isset($_GET['page']) ? $_GET['page'] : ''; $pager_page_array = explode(',', $page); $pager_total[$element] = $node->pages_count; $page = isset($pager_page_array[$element]) ? $pager_page_array[$element] : 0; $node->content['body']['#value'] = check_markup($node->pages[$page], $node->format, false); $node->content['body']['#value'] .= theme('pager', NULL, 1, $element); } elseif ($teaser && $node->pages_count > 1 && strlen($node->teaser) > strlen($node->pages[0])) { // check to see if the teaser is longer than our first page. $node->content['body']['#value'] = check_markup($node->pages[0], $node->format, false); $node->pagemore = true; } } break; } } function paging_paragraph_split($body, $size) { // If we have a short body, the entire body is the teaser. if (strlen($body) < $size) { return $body; } // The teaser may not be longer than maximum length specified. Initial slice. $teaser = truncate_utf8($body, $size); $position = 0; // Cache the reverse of the teaser. $reversed = strrev($teaser); // In some cases, no delimiter has been specified. In this case, we try to // split at paragraph boundaries. $breakpoints = array('

' => 0, '
' => 6, '
' => 4, "\n" => 1); // We use strpos on the reversed needle and haystack for speed. foreach ($breakpoints as $point => $offset) { $length = strpos($reversed, strrev($point)); if ($length !== FALSE) { $position = - $length - $offset; return ($position == 0) ? $teaser : substr($teaser, 0, $position); } } // When even the first paragraph is too long, we try to split at the end of // the last full sentence. $breakpoints = array('. ' => 1, '! ' => 1, '? ' => 1, '?' => 0, '? ' => 1); $min_length = strlen($reversed); foreach ($breakpoints as $point => $offset) { $length = strpos($reversed, strrev($point)); if ($length !== FALSE) { $min_length = min($length, $min_length); $position = 0 - $length - $offset; } } return ($position == 0) ? $teaser : substr($teaser, 0, $position); } /** * Implementation of hook_link(). */ function paging_link($type, $node = 0, $main = 0) { $links = array(); if ($type == 'node') { if (array_key_exists('links', $node)) { $links = $node->links; } if ($main == 1 && $node->teaser && $node->pagemore && variable_get('paging_read_more_enabled', 0)) { $links['node_read_more'] = array( 'title' => t('Read more'), 'href' => drupal_get_path_alias("node/$node->nid"), 'attributes' => array('title' => t('Read the rest of this posting.'), 'class' => 'read-more-paging'), 'query' => 'page=0,1' ); } } return $links; } /** * Implementation of hook_filter(). */ function paging_filter($in_op, $in_delta = 0, $in_format = -1, $in_text = '') { switch ($in_op) { case 'list': return array(t("Paging")); case 'description': return t('Allows content to be broken up into pages, using the %separator tag, configurable here.', array('%separator' => PAGING_SEPARATOR, '!url' => url('admin/settings/paging'))); // the filter gets called before the nodeapi 'view' so, // add a comment to the body to inform the nodapi to apply the filter case 'process': return ''. $in_text; default: return $in_text; } } /** * Implementation of hook_filter_tips(). */ function paging_filter_tips($in_delta, $in_format, $in_is_long = FALSE) { if ($in_is_long) { return '

'. t('Paging Help') .'

'. paging_help('admin/help#paging'); } else { return t('Use %separator to create page breaks.', array('%separator' => PAGING_SEPARATOR)); } }