How to add shortcodes dynamically to a WordPress Post or Page

Here is a code example of how to add shortcodes dynamically to a WordPress Post or Page. Why do you want to do this? It happened that I had a request from a client to only show an introduction part of the description section and hide the rest with a “read more” feature.

I found this plugin called “WP show more” on the WordPress repository that is able to hide certain parts of content if the content is wrapped inside the plugin’s shortcodes.

For example, to hide the second paragraph to conserve space you need to add the shortcodes before and after the second paragraph.:

Pellentesque elementum interdum nibh blandit scelerisque. Praesent in nibh eu odio finibus ultricies. Sed sit amet placerat justo. Quisque nec diam ultrices, molestie felis ac, convallis augue. Pellentesque euismod mauris at leo feugiat interdum. Praesent tempor lorem eget erat vulputate varius. Aliquam eget cursus nulla. Suspendisse potenti. Integer placerat augue magna, ac pellentesque ante finibus non. Sed vitae eros convallis, imperdiet massa ultrices, placerat nisi.


Vivamus orci erat, dictum vitae ultrices at, interdum tempus ex. Proin varius sodales vestibulum. Etiam pulvinar tristique lectus. Mauris rutrum nisi maximus tortor vestibulum auctor. Maecenas rhoncus iaculis luctus. Aliquam at enim libero. Donec vitae libero ut nisi vehicula aliquet sed eget enim. Praesent ac odio tortor.


Now to do this with every post is time-consuming, especially if the site contains 500+ posts and you want this feature to be applied to all of them. So I wrote this WordPress hook that hooks into the content of each post just before WordPress renders it on the page. In this example, you will notice the feature is applied to WooCommerce’s Product description content only.


 *	Adding the readmore shortcodes to the content area.
 *	@param 		$content 	Existing WordPress content passed to this callback function.
 *	@return 	$content 	Returnes the original content or the processed content if condition is true.
function content_add_shortcode($content) {

    // make sure we only apply this to a product post type.
	if (is_product()) {

        // Split the content string after each paragraph.
		$content_array = explode("<p>", $content);

		$content_maker = array();

		$i = 0;

        // Process each paragraph in the array and only add the shortcode before the second paragraph.
		foreach ($content_array as $content_string) {
			$content_maker[] = '<p>' . $content_string . '</p>';
            // paragraph selector.
			if ( $i == 1 ) {
				$content_maker[] = '<p>[show_more more="READ MORE" less="READ LESS"]</p>';
        // Coverting the array back into a string.
		$content = implode('', $content_maker);
		$suf_content = '[/show_more]';
        // append the closing shortcode to the end of the content string.
		$content = $content . $suf_content;


	return $content;
add_filter('the_content', 'content_add_shortcode');


The nice thing about splitting the paragraphs in the string into array values is that you have nice clean breaks of the content. Where with the substrate() function substr (string,$string int $start [, int $length ] ) or similar you end up with broken words. To prevent that you need to implement a complex regular expression clause. So the easy way is to just break each paragraph clean.