Using WP’s “the_content” function and filter hook

Using WP's "the_content" function and filter

When the the_content() function is called in WordPress, the content of the post or page is displayed. By filtering the_content() through another function, the displayed content can be changed in various ways.

This is an ongoing post. Please suggest corrections, explanations, etc. in the comment section at the bottom of this page.

Web developers popularly need to add and/or remove things from the content before it is displayed by WordPress. In many cases, this can be achieved by adding additional functions to the WordPress the_content filter. This post will show how the WordPress the_content filter hook can be used and how to manipulate the content output of different post types.

The the_content() function

Themes and plugins can use the WordPress the_content() function in various places to show the content of a Post or Page. The the_content() function is commonly used inside the Loop. In its simplest form, the content of a post type is displayed using the following PHP:

the_content();

Even though this is the case, the content has come some way since it was stored in the WordPress database. To have a better understanding of how to add the the_content() function to a filter hook to manipulate its output, we first need to see where the content of the the_content() function comes from.

By searching for the_content() function in the WordPress.org Developer Resources, we get the following:

function the_content( $more_link_text = null, $strip_teaser = false ) {
  $content = get_the_content( $more_link_text, $strip_teaser );

  /**
   * Filters the post content.
   *
   * @since 0.71
   *
   * @param string $content Content of the current post.
   */
  $content = apply_filters( 'the_content', $content );
  $content = str_replace( ']]>', ']]>', $content );
  echo $content;
}

After doing some tidying up (and ignoring the arguments for now), the the_content() function looks likes this:

function the_content() {
  $content = get_the_content();
  $content = apply_filters( 'the_content', $content );
  $content = str_replace( ']]>', ']]>', $content );
  echo $content;
}

Here we can see that the first step in the the_content() function is to get the raw content from the WordPress database as $content — by calling the get_the_content() function. After this, the the_content filter is applied. This means that even in its simplest form, the the_content() function uses the the_content filter to change the content that is echoed to the web browser.

Note that the value of $content has only been changed programmatically. Its value has not been saved in the WordPress database again.

Using the_content() function’s parameters

Without looking like an attempt to change the subject of this post too much, let’s quickly look into the default arguments/parameters of the the_content() function. The original code above shows that there are two optional parameters that can be used to change the behaviour of the content that is displayed:

the_content( $more_link_text, $strip_teaser );

By using parameters, the WordPress the_content() function can also be used to create excerpts or ‘teasers’.

Using these parameters are only useful on ‘non-post type pages’ (i.e. non-single pages, e.g. archive pages, search page, index page, etc). Because Posts, and Pages, can have their own excerpts defined in the excerpt meta box, the the_content() function doesn’t have to be used in most cases. Because of its limitations, the the_content() function parameters will not be discussed any further.

The the_content filter

Now that we had a look at the WordPress the_content() function and how it runs its content through the the_content filter, we can have a closer look at the the_content filter itself.

The WordPress the_content filter is a filter that takes a string value (i.e. $content) and applies a series of ‘filters’ to that string value. As with other WordPress filter hooks, it takes one value and returns a modified version of that value. Each of the filtering steps is done using its own function. This series of ‘filters’ (i.e. functions) typically add paragraph tags and default rel attributes, auto-embeds videos, expand shortcodes, etc.

The filters that are referenced in the the_content() function are default functions that are automatically added by WordPress itself, but plugins and themes can also add their own filter functions to the the_content filter.

Adding additional functions to the the_content filter

Additional custom content/code filters (in the form of functions) can be added to the list of filters in the the_content filter. To register a new custom content function to be added to the the_content filter, the following PHP code is added to the plugin file or the (child) theme’s functions.php file:

add_filter( 'the_content', 'unique_function_name' );

In this case, a function called unique_function_name has been added to the the_content filter. By looking at the WordPress the_content filter’s code reference, an (optional) priority argument/parameter can also be passed:

add_filter( 'the_content', 'unique_function_name', 10 );

The priority parameter (set as an integer value) will affect the order at which a filter will be executed. In other words, it is used to prioritise additional content filters. If not set, the default value is 10. Setting a relatively low priority, i.e. a large number (e.g. 99), will already have processed all the other filters by the time the filter is executed and vice versa.

After the custom function has been added to the the_content filter, its needs to be created (see later).

The wpautop() function

Before adding any custom function to the the_content filter, some of the default WordPress content filters need to be considered. One such default filter is the famous WordPress wpautop() function.

WordPress uses its wpautop() function to add HTML <p> tags to paragraphs – in this case, to $content (including when the the_content() function was called). Depending on where the $content variable is called into a custom filter function, it might, or might not, already have passed through wpautop(). This means that the $content variable might, or might not, have paragraph tags added.

As far as I can see, and I might be wrong, the default priority (within the default the_content filters) of adding wpautop() to the the_content filter is 10:

add_filter( 'the_content', 'wpautop', 10 );

Note that it is considered bad practice to change the default priority of the default wpautop() content filter. It is an even worse practice to remove or replace it entirely. Instead, the priority of the custom content filter should be adapted accordingly. By setting a relatively high priority for the custom content filter, e.g. 0, will likely prioritise it before the default wpautop() content filter. The opposite is true by setting a relatively low priority (e.g. 99).

Creating a custom function that appends HTML to the content

After registering a new function to the the_content filter (see earlier), the function can be created and coded to do all sorts of things. To, for example, add a custom HTML segment to the top and the bottom of the current content, the following function can be used:

function bts_add_html_to_content( $content ) {
  $html_segment = '<p>Text to be added.</p>';
  $content = $html_segment . $content . $html_segment;
  return $content;
}
add_filter( 'the_content', 'bts_add_html_to_content', 99);

To get a better understanding of how things work, let’s break the function down:

function bts_add_html_to_content( $content ) {
  // do something here
  return $content;
}
add_filter( 'the_content', 'bts_add_html_to_content', 99);

In this case, the function was named bts_add_html_to_content. bts_ was added to the function name to make sure the name is unique. By using $content as the input parameter, the current content will be passed through the function and returned at the end. By using a high priority parameter (in this case 99), we attempt to call this filter after the default wpautop() content filter was called.

Next is to create the string, or strings, to be added to the beginning and/or the end of the content:

function bts_add_html_to_content( $content ) {
  $html_segment = '<p>Text to be added.</p>';
  return $content;
}
add_filter( 'the_content', 'bts_add_html_to_content', 99);

Paragraph HTML tags were added because it is assumed that paragraph tags were already added by this time.

Lastly, to append the string to the beginning and end of $content:

function bts_add_html_to_content( $content ) {
  $html_segment = '<p>Text to be added.</p>';
  $content = $html_segment . $content . $html_segment;
  return $content;
}
add_filter( 'the_content', 'bts_add_html_to_content', 99);

Remember to add a description to the function so that, in the future, you know what it does.

Creating a custom function that appends HTML inside paragraph tags

To, for example, add a custom HTML segment to the first letter of the current content (e.g. <b> or <span> tags), the following function reasoning be used.

When appending HTML (or anything else), once again, the paragraph tags added by the default wpautop() content filter needs to be considered. In this example, we will attempt to run the custom filter function with a high priority (i.e. 0) so that paragraph tags were not added yet. The final PHP code will look as follows:

function bts_change_first_char( $content ) {
  $first_char = substr( $content, 0, 1 ); // gets 1 char at position 0
  $content = substr( $content, 1 ); // trim first char
  $content = '<span class="char-one">' . $first_char . '</span>' . $content;
  return $content;
}
add_filter( 'the_content', 'bts_change_first_char', 0 );

To get a better understanding of how things work, let’s break the function down:

function bts_change_first_char( $content ) {
  // do something here
  return $content;
}
add_filter( 'the_content', 'bts_change_first_char', 0 );

In this case, the function was named bts_change_first_char. bts_ was added to the function name to make sure the name is unique. By using $content as the input parameter, the current content will be passed through the function and returned at the end.

Assuming the first paragraph starts with without a <p> tag, the function will obtain the first character, then trim the first character and append the modified version back:

function bts_change_first_char( $content ) {
  $first_char = substr( $content, 0, 1 ); // gets 1 char at position 0
  $content = substr( $content, 1 ); // trim first char
  $content = '<span class="char-one">' . $first_char . '</span>' . $content;
  return $content;
}
add_filter( 'the_content', 'bts_change_first_char', 0 );

Remember to add a description to the function so that, in the future, you know what it does.

Similar code reasoning principles can be used to add or subtract HTML in other areas of the original content.

Setting conditions for content filters

As with both examples mentioned earlier, using the the_content filter without conditions will affect the content in all the places the the_content() function is called. By adding one or more content conditional filters, only the places (e.g. on a Post, Page or custom post type, the main content area or a Loop item) can be selected for.

Useful content conditionals include the following:

  • is_single(), is_page(), is_attachment() -> Is a Post, is a Page, is an Attachment
  • is_singular() -> Is a Post, is a Page or is an Attachment
  • is_singular('product', 'custom_post_type_slug', 'ID') -> Is Product, is custom post type with custom_post_type_slug or is post type with ID
  • in_the_loop()
  • is_main_query()

Content conditionals will either return a true or a false value, so they can be used in a function as follows:

function unique_function_name( $content ) {
  if ( is_single() ) {
    // only do something if is Post, Page or Attachment
  } elseif ( is_singular('page') ) { // i.e. is page post type
    // only do something if is Page post type
  } elseif ( is_main_query() ) { // i.e. is advert post type
    // only do something is is main query
  } else {
    // do something if none of the above
  }
}

add_filter( 'the_content', 'unique_function_name' );

Other WordPress functions and conditional can also be used.

About the author
Renier busies himself with improving his English writing, creative web design and his websites, photoshopping, micro-electronics, multiple genres of music, superhero movies and badass series.
Behind the Scenes is a free, informative website. If you find value in any of our content, please consider making a donation to our cause.
Donate via PayPal

Save, share & Disqus

Use the buttons below, on the left or the bottom of this page to share this post. Your comment is important, but don't be a knob. Keep it constructive and polite.

Comment via Disqus

Disqus is a worldwide comment hosting service for web sites and online communities. This secure platform ensures a pleasant commenting environment which is manageable from one account. Use the Login button to sign up.

More website development related posts

Discover the easy way to send bulk SMS from your PC, Mac or mobile device
Discover the easy way to send bulk SMS from your PC, Mac or mobile device
19 October 2020
Ad: Using the latest in technology, WinSMS offers cost effective messaging solutions that makers and business owners can use. With their online portal and API functionality, buying SMS bundles and sending them to recipients is more cost effective and easy to do. More…
Getting started with private projects on Raspbian and Bitbucket
Getting started with private projects on Raspbian and Bitbucket
28 October 2018 | Updated 10 March 2020
Bitbucket is a great alternative to Github to start, store and track simple programming dependant project files. On a Raspberry Pi, it can be done using Raspbian. Projects uploaded to Bitbucket with less than 6 contributors can be kept private and won’t cost a cent. More…
Using Cron to schedule tasks
Using Cron for scheduling tasks
30 June 2017 | Updated 11 July 2017
Cron is an Unix-like operating system software utility used to schedule automatic time-based commands. Entered commands can be in the form of Bash or Bash scripts that are meant to be automatically executed periodically at fixed times, dates or intervals. More…