I am trying to create two functions, one that catches the first paragraph of some content, and one that catches the rest, but I have hit a bit of a conundrum.

I have this in my single.php:

<div class='the_content'>
  <?php the_content(); ?>

which produces:

<div class="the_content">
   <p>The content .....</p>
   <p>The content .....</p>
   <p>The content .....</p>

each paragraph all nicely wrapped in a <p> tag. I assumed that I could simple break the explode() the content based on the string </p>, theoretically splitting the content into paragraphs, but all the content is in the first resulting array element. I investigated, and there are no <p> tags in either the HTML edit, or indeed the database entry. Both look like:

The Content .....
The Content .....
The Content .....

Note:Line breaks present, but not <p> tags.

Where does Wordpress add the <p> back in? How does it find the line breaks and how can I hook a function into that?


Here is the function that fails, based closely on the the_content() function:

function get_first_paragraph(){
    $content = $firstcontent = get_the_content();
    $content = str_replace(']]>', ']]&gt;', $content);
    $content = explode('</p>',$content);

    return $content[0];

The paragraphs are done by the wpautop() function, hooked to the_content, the_excerpt() & comment_text as well as 'term_description' for taxonomies.

The plugin linked by @javipas does an enormous effort to just add this, but it's a good example (+1). You can (modify it a little and) take the following part out of it:

// The init function
function wpse24553_add_p_the_content()
    add_filter( 'the_content', 'wpse24553_p_the_content' );
    add_filter( 'the_content_feed', 'wpse24553_p_the_content' );
add_action( 'init', 'wpse24553_add_p_the_content' );

// The actual modification function
function wpse24553_p_the_content( $the_content )
    global $post;

    $content_by_p = preg_split( '/<\/p>/is', $the_content );

    $i = 0;
    // Set a var to count until the targeted <p> is met - change this to your needs
    // Set to empty '' if you want to modify every paragraph
    $targeted_p = 1;

    static $new_content = '';

    foreach ( $content_by_p as $key => $p )
        // abort and return the modified content if we're beyond the targeted <p>
        if ( $i > $targeted_p )
            $new_content .= $p;

        // Remove empty space at the end of a paragraph, then remove original <p>-tag
        $p = rtrim( $p );
        $p = preg_replace( '/<p>/is', '', $p );

        // Wrap replacements in new <p>-tags, so it validates
        $new_content .= '<p class="paragraph-link"><a name="p-'.$key.'"></a>';
        // Prepend the graf with an anchor tag
        $new_content .= '<a ref="permalink" title="Permalink to this paragraph" href="'.get_permalink( $post->ID ).'#p-'.$key.'">#</a>;
        $new_content .= $p;
        $new_content .= '</p>';

    // Return the new content
    return $new_content;


  • The function needs to be placed in your functions.php
  • You need to alter the function and what gets added/removed/modified with a single paragraph by yourself (no use case in the Q).
  • The function currently is not tested.
  • 1
    This is great, I can adapt this to add the content I need where I need it – Mild Fuzz Aug 1 '11 at 10:07

If I have understand you, what you want is permalinks for each paragraph? The known blogger Dave Winer wrote about this a year ago, and there's a plugin called WinerLinks that puts a '#' after each paragraph, that makes that paragraph linkable.

I hope it works for you.

  • I am afraid not. That still simple attaches the link to the final <p> tag. I am interested in how it adds the extra ones within the content. – Mild Fuzz Jul 31 '11 at 21:05

Where does Wordpress add the <p> back in?

afaik, by applying the 'the_content' filter.

possible examples for your functions:

function get_first_paragraph() { 
    $text = apply_filters('the_content', get_the_content() );
    $paragraphs = explode('</p>', $text);
    $first_paragraph = array_shift($paragraphs).'</p>';
return $first_paragraph;


function get_last_paragraphs() { 
    $text = apply_filters('the_content', get_the_content() );
    $paragraphs = explode('</p>', $text);
    $first_paragraph = array_shift($paragraphs).'</p>';
    $rest_paragraphs = implode('</p>', $paragraphs);
return $rest_paragraphs; 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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