Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

What is the best method for intercepting the_content of a post (for a single post page) and dividing the_content into sections of 500 characters (or any other number of characters), and then outputting each 500-character section wrapped in its own div container?

I understand that get_the_content() will return the post content as a string that can be stored in a variable. But, being new to PHP, I'm not sure how to go about segmenting the content based on character count. We could get the character count using:

    <?php
      $content = get_the_content();
      echo strlen($content);
    ?>

But that is as far as my knowledge goes. Can anyone help me out with this challenge?

UPDATE: With some help from Lukas Kolletzki on stackoverflow I have gotten this far:

    <?php
    $content = get_the_content();
    $chunks = str_split($content, 500);

    //Printing each chunk in a div
    foreach($chunks as $chunk_content) {
        echo "<div>";
        echo $chunk_content;
        echo "</div>";
    }
    ?>

This successfully splits the post content into 500-word sections and wraps each of them into separate containers.

Going even further, Lukas suggested using the wordwrap() and explode() functions to ensure that words weren't cut in half:

    <?php
    $content = get_the_content();
    $strings = wordwrap($content, 500, "<br />"); //Put a {BREAK} every 500 characters
    $chunks = explode("<br />", $strings); //Put each segment separated by {BREAK} into an array field

    //Printing each chunk in a div
    foreach($chunks as $chunk_content) {
        echo "<div class="post-content">";
        echo $chunk_content;
        echo "</div>";
    }
    ?>

This works quite nicely, but now I am realizing that the normal wordpress

tags are not being output. Is this because get_the_content() outputs only text, without the html?

How can I get the paragraphs back into the post content and still maintain the above functionality?

Thanks again, and please do not mark this as duplicate. It's a much different question than the excerpt_length filter question... or at least I think so.

share|improve this question
    
We already had this one once. Guess it was by @rilwis –  kaiser Aug 16 '13 at 1:56
    
possible duplicate of limit the words in the post content and add read more link –  kaiser Aug 16 '13 at 1:57
    
I mark it as duplicate as it is effectively the same from the WordPress part (filters). Just alter it a bit and you're fine. –  kaiser Aug 16 '13 at 1:58
    
@kaiser Thanks for making me aware of the other thread. Forgive me though, I do not know how to adapt that solution to my specific case. Would I use the get_the_content filter in place of the excerpt_length filter? And then would I have to set up an additional FOR loop in order to display the whole post (all the sections), rather than just the first array_splice section? Could you please provide an example of how that could be done. It would be SOOO helpful for me. Thank you! –  user2655393 Aug 16 '13 at 2:51
1  
hey is it just a typo "explore" or you are actually using it, it should be "explode" instead and that particular code would work for you. –  sven Aug 16 '13 at 5:03
show 4 more comments

3 Answers

get_the_content() return what's in the editor, but wpautop filters and such are attached to the_content (which you don't need inside your split function - just apply it later manually with

apply_filters( 'the_content', $output );

at the end.

You should as well use strip_shortcodes( get_the_content() ); before splitting it up:

$output = get_the_content();
$output = wp_trim_words( $output, 500 );

You'll need to loop through it as long as you got content and array_push() to your $output = array();.

share|improve this answer
add comment

so I really appreciate all the feedback and the answer that @kaiser and @t31os contributed. I am shaky with PHP so it was hard to put together a working block of code with kasier & t31os's answer. That's my fault for not being a very talented coder :-(

But, I wanted to post the solution that I came up with by doing my own research on PHP.net and asking a similar question on StackOverflow.

Here is the code I'm using to accomplish what I originally set out to do:

    <?php
    $content = get_the_content();
    $strings = wordwrap($content, 500, "<!--break-->"); //insert this every 500 chars, but preserve whole words.
    $chunks = explode("<!--break-->", $strings); create a new string of 500-char sections.

    ob_start(); // buffer the output of the following expressions...
    foreach($chunks as $chunk_content) {
        echo '<span>'; // use <span> instead of <div> so as to not interrupt the paragraph formatting of the content when viewed normally (graceful degradation).
        echo $chunk_content;
        echo '</span> ';
        }
    $segmented_content = ob_get_contents(); // put the results of the above expressions into a variable.
    ob_end_clean(); // discard the expressions that were buffered.
    echo nl2br($segmented_content); // put the result through a filter which replaces line-breaks with <br> tags.
    ?>

NOTES:

  • The purpose of this segmenting of the content is to create separate frames or "pages" that will be used by the BookBlock page-flip plugin (check out this codrops tutorial for more info). Each 500-character section will be treated as a "page", and the navigation controls on the page allow the user to flip through the pages with a nice CSS3 3D transform transition.

  • I used <span> containers to wrap the output because this method lends itself to graceful degradation. If the user's device does not support Javascript or some essential CSS3 properties, then Modernizer will detect that and my CSS will adapt, showing a normal page of content, not broken into separate frames, and in this case the <span> won't disrupt the normal paragraph structure of the content.

  • I used output buffering in order to compile all the 500-char sections into one variable to be passed through the nl2br(); filter for final output.

  • At first I tried using the wpautop(); filter to ensure that paragraphs were rendered properly in the output, but soon remembered that <span> and <p> tags cannot overlap :-P And if I applied the wpautop(); filter to each 500-char section individually, it would output <p> tags in the middle of sentences sometimes. The solution was to use the nl2br(); filter in order to add <br> tags at every line break in the content, which, because they don't require a closing tag, will maintain the paragraph structure without disrupting the 500-char containers.

QUESTION: This code works, and it will be used on a website that will not have heavy traffic (probably less that 50 visits per day). But, I am still concerned (because I really am not very knowledgeable about PHP) that this code may be sluggish, and not be very elegant.

Assuming I knew exactly how accomplish what kaiser and t31os are recommending in their answer, would their solution be better for computation speed (i.e. fewer server requests, db queries, less code, etc.)? Or is my solution just as good?

share|improve this answer
    
I don't see why you are using output buffering instead of just concatenating a string. The buffering looks like unnecessary overhead to me. –  s_ha_dum Aug 18 '13 at 4:20
    
@s_ha_dum Thank you for the feedback. Could you teach me how to do it without output buffering? I did it that way because I couldn't figure out how to take the result of the foreach() expression and pass it through the nl2br() filter. How would you do it? Maybe you could write a new answer to this thread with better code? That would help me so much! (sorry for my ignorance...) –  user2655393 Aug 18 '13 at 8:30
    
It is pretty simple. See my answer. –  s_ha_dum Aug 18 '13 at 15:48
add comment

Per a request from user2655393 I have written a version of his/her code that does not use output buffering, but uses string concatenation instead.

$content = get_the_content();
$strings = wordwrap($content, 500, "<!--break-->"); //insert this every 500 chars, but preserve whole words.
$chunks = explode("<!--break-->", $strings); create a new string of 500-char sections.  
$segmented_content = '';
foreach($chunks as $chunk_content) {
  $segmented_content .= '<span>'; // use <span> instead of <div> so as to not interrupt the paragraph formatting of the content when viewed normally (graceful degradation).
    $segmented_content .= $chunk_content;
  $segmented_content .= '</span> ';
}
echo nl2br($segmented_content); // put the result through a filter which replaces line-breaks with <br> tags.
share|improve this answer
    
Thank you for demonstrating this alternative method. This is very helpful to me in my php learning process! This post discusses the performance trade offs of output buffering vs concatenation, and seems to confirm that output buffering is faster/more efficient. Is that relevant to my particular situation? Will output buffering be faster than concatenation for the above code? –  user2655393 Aug 19 '13 at 20:05
    
See this too: planetozh.com/blog/2006/05/… –  s_ha_dum Aug 19 '13 at 20:40
    
According to your above linked article, it seems like output buffering is only more efficient when there a large number of strings to be concatenated. In my case (splitting a wordpress post), using concatenation seems like it will be just as good, since there won't ever be a huge number of strings (unless the post is exceptionally long). Does that seem like an accurate conclusion? Honestly, I'm still unsure which version (output buffering vs concatenation) is the better solution... (?) –  user2655393 Aug 19 '13 at 22:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.