4.6. Dividing a Text Block into Multiple Pages

Problem

You want to display long articles stored in a database over multiple pages.

Solution

Add logic to your web page code that breaks text into chunks based on word count or some other parameter.

Discussion

Woe is the modern-day Melville or Proust trying to hone their craft online at 72 dots per inch. Nothing turns off an online audience faster than an eye-glazing block of text that scrolls on and on and on (see Figure 4-4). The conventional wisdom of online publishing contends that no one reads web pages. Web surfers browse, scan, and pick through online content—so the thinking goes—and then print what they want to give it their full attention in a more comfortable reading environment.

Sometimes, though, long articles are not only central to your web site's mission, they're what your visitors are seeking. Everything from essays to technical white papers require every last word to serve their readers. And breaking up articles over multiple pages offers the bottom-line benefit of increasing advertising impressions for sites that generate revenue in that way. Remember, it was newspapers—not web sites—that first came up with the idea of giving readers a taste of many articles on the front page, and then forcing them to flip inside to the conclusion displayed alongside the lingerie ads. Let's look at some ways to add one or more "jump pages" to your online articles by automatically breaking up long articles into two or more linked pages.

This Recipe makes a couple of assumptions. Since it uses PHP scripting to manipulate the text, you'll need some familiarity with the use of variables and functions in that language. Also, the solution described below assumes that you don't need to exercise any fine-grained editorial measures to keep lines or words together on the same page that might otherwise be separated automatically by the scripting logic.

First, you will need to load all the text from long article into a PHP variable. The text can come from a record in an articles table in your web database or from a static file on your web server (that, in turn, might be opened and read into the variable by PHP's built-in file-handling functions). Call the variable with the article $text.

Then you'll need to add a function for performing a variety of formatting routines on the text. For now, you'll limit this function's action to replacing line breaks in the $text variable with opening and closing <p> tags. In Recipe 4.7, you'll learn ways to expand this function to handle other inline HTML code in your stored text.

Assuming each paragraph of stored text is separated by two line breaks—each represented by \n—the basic text-processing function looks like this:

	function processText( $texttoProcess )
	{
       $texttoProcess = str_replace("\n\n"," </p>\n<p> ",$texttoProcess);
       return $texttoProcess;
   }

You may need to tweak this function, depending on how paragraphs in your stored text are separated. For the function to work reliably, though, the separating characters should be consistent between all blocks of text.

Long articles can be divided into multiple pages for easier reading

Figure 4-4. Long articles can be divided into multiple pages for easier reading

Now define a new variable to tell PHP how many words of the article to display on each page:

	$text_limit = 275;

Now, you need to add the logic to count the number of words in the article and load that value into a new variable, keep track of the start and end of each article chunk, and add links to the top and bottom of the page to navigate forward and backward among the pages.

First, use PHP's built-in explode( ) and count( ) functions to create an array of individual words in the article and tally the total number of words:

	$text_array = explode(" ",$text);
	$text_total_words = count($text_array);

Next, you'll introduce the variables needed to keep track of the currently displayed article section: $start and $step. Eventually, the previous and next links on the page will pass these variables as arguments back to the PHP script to display other sections. If no arguments are passed, then this part of the script instructs PHP to display the first section of the article, up to the limit you defined above as the variable $text_limit:

	if (!isset($step)) {
	 $start = 0;
	 $step = $text_limit;
	}

Now, add a for loop to the script by using the $start and $step variables to create a new variable—$text_display—that contains just the number of words you want to display per page:

	for ($x=$start;$x<$step;$x++) {
	 $text_display .= $text_array[$x]." ";
	}

And pass the $text_display variable to the function you defined at the top of the script to swap line feeds with paragraph tags:

	$text_display = processText($text_display);

For the previous and next page links, you'll need to add a couple of conditional statements to the script that prepend or append the previous and next page links—if they're needed—to the text block to be displayed. Because you're using the $start variable as a marker to define where an article section should start, the page will need a previous or back link if $start's value is greater than zero, like this:

	if ($start > 0) {
	 $pstart = $start - $text_limit;
	 $pstep = $step - $text_limit;
	 $text_display = "<a href = \"article.php?start=".$pstart."&step=".$pstep."\">&#60;
	Prev page</a>&nbsp;…&nbsp;".$text_display;
	}

The conditional statement uses two new variables—$pstart and $pstep—to deduct the word limit value from the current values of $start and $step and build a link to the previous block of article text.

The next page link operates in a similar fashion, with new variables $nstart and $nstep defined as additions to the current text block markers. Here, the condition compares the total word count of the article—$text_total_words—to the end-point marker of the currently displayed block—$step. If the former is greater than the latter, there's more text to show and a next page link is needed:

	if ($text_total_words > $step) { //still more text to read
	 $nstart = $start + $text_limit;
	 $nstep = $step + $text_limit;
	 $text_display = $text_display."…&nbsp;<a href =
	\"word_break.php?start=".$nstart."&step=".$nstep."\">Next page &#62;</a>";
	}

Finally, print the text block on the page wrapped in paragraph tags to ensure the proper display of the first and last paragraphs not formatted by the function.

The full script is shown in Example 4-1.

Example 4-1. This script splits lengthy text over multiple pages and creates links between the pages

<?
$text = "Some long-article text gets loaded from a database record or file into this
variable.";

function processText( $texttoProcess )
{
 $texttoProcess = str_replace("\n\n","\n</p>\n<p>\n",$texttoProcess);
 return $texttoProcess;
}

$text_limit = 275;

$text_array = explode(" ",$text);
$text_total_words = count($text_array);

if (!isset($step)) {
 $start = 0;
 $step = $text_limit;
}

for ($x=$start;$x<$step;$x++) {
 $text_display .= $text_array[$x]." ";
}
$text_display = processText($text_display);

if ($start > 0) { //we're beyond the first page
 $pstart = $start - $text_limit;
 $pstep = $step - $text_limit;
 $text_display = "<a href = \"word_break.php?start=".$pstart."&step=".$pstep."\">&#60;
Prev page</a>&nbsp;…&nbsp;".$text_display;
}
if ($text_total_words > $step) { //still more text to read
 $nstart = $start + $text_limit;
 $nstep = $step + $text_limit;
 $text_display = $text_display."…&nbsp;<a href = \"word_break.php?start=".$nstart.
"&step=".$nstep."\">Next page &#62;</a>";
}
 echo "<p>\n".$text_display."\n</p>";
?>

The displayed text looks like Figure 4-5.

The segmented article has previous and next links to lead the reader through the article over multiple pages

Figure 4-5. The segmented article has previous and next links to lead the reader through the article over multiple pages

You can alter this Recipe to divide articles by paragraph, rather than by word, if you like. Using word count offers a more consistently sized chunk of text per page, but the page breaks will fall arbitrarily in the middle of sentences. On the other hand, a newspaper editor will tell you that mid-sentence page breaks are good for maintaining reader interest and preventing readers from thinking an article has ended before it actually has. Pages of paragraph-based chunks will vary more in length, but the breaks will be neater.

To split the text by paragraph, change the explode( ) statement near the top of the script to build your article array out of paragraphs, rather than words (splitting on line endings, rather than spaces between words):

	$text_array = explode("\n\n",$text);

And reduce the value of the block limit to a much lower number:

	$text_limit = 3;

Get Web Site Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.