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

\n" . "
\n" .
               "first page here.\n" .
               "%separator\n" .
               "second page here.\n" .
               "%separator\n" .
               "more pages here.\n", array('%separator' => PAGING_SEPARATOR));
  }
}

function paging_menu($maycache) {

  if ($maycache) {
    $items[] = array(
      'path' => 'admin/settings/paging',
      'title' => t('Paging'),
      'description' => t('Choose what node types to enable paging for & change the page breaking string'),
      'callback' => 'drupal_get_form',
      'callback arguments' => 'paging_settings',
      'access' => user_access('administer site configuration'),
      'type' => MENU_NORMAL_ITEM,
    );
  }

  return $items;
}

/*
 * Implementation of hook_settings()
 */
function paging_settings() {
  $form = array();

  $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_SEP_STRING,
    '#description' => t('Paging separator string. Enter the part between [ and ]. e.g. Put "pagebreak" for [pagebreak].'), //old text: 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, "read more" link under teasers will link to the next content page. Note: Only works if teaser and first page have the same content. Usage 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_pagelist_enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable pages listing'),
    '#description' => t('When enabled, a titled list of pages is shown below the content. Use the following syntax to give titles to each page:
[!separator title=Lorem Ipsum...].
Use the following for the first page\'s title:
[first!separator title=Lorem Ipsum...].
Default titles are "Page 1, Page 2" and so on.', array('!separator' => PAGING_SEP_STRING)), '#default_value' => variable_get('paging_pagelist_enabled', 1), ); $form['paging_config']['paging_node_types_enabled'] = array( '#type' => 'checkboxes', '#title' => t('Node Types'), '#description' => t('Set the node types you want to enable Paging for.'), '#default_value' => variable_get('paging_node_types_enabled', array()), '#options' => node_get_types('names'), ); 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': $node->pages = preg_split('/\['. PAGING_SEP_STRING .'(|\s+|\s+[^][=]+=([^][]+))\]/', $nodebody); //$node->pages = explode(PAGING_SEPARATOR, $nodebody); $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; preg_match_all('/\['. PAGING_SEP_STRING .'(|\s+|\s+title=([^][]+))\]/', $nodebody, $pagenames); //'/\[pagebreak(|\s+|\s+[^][=]+=([^][]+))\]/' foreach ($pagenames[2] as $key => $pagename) { $sitename = $pagename ? $pagename : 'Page '. ($key + 2); if ($key == 0) { preg_match('/\[(first|FIRST)'. PAGING_SEP_STRING .'\s+title=([^][]+)\]/', $nodebody, $first); $first_name = $first[2] ? $first[2] : 'Page 1'; //$links[] = array('title' => $first_name, 'href' => drupal_get_path_alias('node/'. $node->nid), 'query' => 'page=0,0'); $links[] = l($first_name, drupal_get_path_alias('node/'. $node->nid), array(), 'page=0,0'); if ($page == 0) $node->pages[$page] = str_replace($first[0], '', $node->pages[$page]); } //$links[] = array('title' => $sitename, 'href' => drupal_get_path_alias('node/'. $node->nid), 'query' => 'page=0,'. ($key + 1)); $links[] = l($sitename, drupal_get_path_alias('node/'. $node->nid), array(), 'page=0,'. ($key + 1)); } $node->content['body']['#value'] = check_markup($node->pages[$page], $node->format, false); if (variable_get('paging_pagelist_enabled', 1)) { $node->content['body']['#value'] .= theme('item_list', $links); } $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; } } /** * 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 ' . l('here', 'admin/settings/paging') . '.', array('%separator' => PAGING_SEPARATOR)); // 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)); } }