This is the last in the series where we try to get WordPress to show single-post images in the sidebar and hide them from the post content itself. In the previous two posts we saw how to write a simple WordPress plugin and sidebar widget and how to extract and display images attached to a post in the sidebar. Now, we’ll see how to hide the images from the post’s content itself so it only shows in the sidebar. After looking at jQuery Colorbox, I decided to adopt a similar approach of regex matching on the content and modifying the post’s contents.
WordPress exposes the filter the_content
that allows us to hook into the post’s content and modify it as we please. We can use the add_filter
function to add our content filter hook in our plugin. One thing to note is that you specify a priority to the filter and you’ll need to specify a high number so the filter runs as late as possible and filters out images. Here’s the code I used to filter out images from the post’s content:
function hideAllImages($content) { global $post; $imgfilter = array( 'order' => 'ASC', 'post_mime_type' => 'image', 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment',); $attachments = get_children( $imgfilter ); $images = array(); if ( $attachments ) { foreach ( $attachments as $attachment ) { $imgUrl = wp_get_attachment_url( $attachment->ID ); if ( SidebarImage_Widget::filterImageUrl($imgUrl) ) { $images[] = str_replace('.jpg', '', $imgUrl); } } } $imgPattern = "/<img([^\>]*?)>/i"; if (preg_match_all($imgPattern, $content, $imgTags)) { foreach ($imgTags[0] as $imgTag) { $imgSrcPattern = '/src="([^"]*?)"/i'; if ( preg_match($imgSrcPattern, $imgTag, $imgSources) && !preg_match('/style="display:none;"/i', $imgTag) ) { $isMatch = false; foreach ( $images as $img ) { $isMatch = strpos($imgSources[1], $img); if ( $isMatch !== false ) { break; } } if ( $isMatch !== false ) { $pattern = $imgPattern; $replacement = '<img style="display:none;" class="colorbox-none" $1>'; $replacedImgTag = preg_replace($pattern, $replacement, $imgTag); $content = str_replace($imgTag, $replacedImgTag, $content); } } } } return $content; }
We first iterate through the children of the post that are of type image to find the attached images. We strip the .jpg
part of the image URL
out and populate the array of attached image URLs
. After that find all occurrences of <img>
tags in the content and extract the src
attribute. We see if this src
is matched by any of the filtered attachment URLs
that we built and if so, we hide this image by specifying style="display:none;"
. We do a prefix match on the attachment’s URI without the extension – this is because wordpress will automatically create foo_<height>x<width>.jpg files and use them for improving performance. In addition we add class="colorbox-none"
so these images are not picked up by colorbox for its slideshow. We use filterImageUrl
to filter out emoticons and nextgen gallery thumbnails out from the attachment list so they’ll not be filtered out by this plugin. Finally, here’s the entire plugin code:
<?php /* Plugin Name: Sidebar Image Plugin URI: http://www.nramkumar.org/tech Description: Hides images from single posts and shows them in the sidebar Version: 0.5 Author: Ramkumar Natarajan Author URI: http://www.nramkumar.org/tech */ //error_reporting(E_ALL); add_action('widgets_init', array('SidebarImage_Widget', 'register')); add_filter('the_content', array('SidebarImage_Widget', 'hideAllImages'), 10); class SidebarImage_Widget extends WP_Widget { function SidebarImage_Widget() { parent::WP_Widget(false, 'Sidebar Image Widget'); } function form($instance) { } function update($new_instance, $old_instance) { return $new_instance; } function filterImageUrl($imgurl) { return (strpos($imgurl, '_thumb.jpg') === false) && (strpos($imgurl, 'Emoticon') === false); } function widget($args) { global $post; extract($args); if ( is_single() ) { echo $before_widget; echo $before_title . 'Snapshots' . $after_title; $imgfilter = array( 'order' => 'ASC', 'post_mime_type' => 'image', 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment',); $attachments = get_children( $imgfilter ); if ( $attachments ) { $images = array(); foreach ( $attachments as $attachment ) { $imgUrl = wp_get_attachment_url( $attachment->ID ); if ( SidebarImage_Widget::filterImageUrl($imgUrl) ) { $images[] = $attachment; } } foreach ( $images as $image ) { $imageSrc = wp_get_attachment_image_src( $image->ID, 'medium' ); echo '<a href="' . wp_get_attachment_url( $image->ID ) . '" class="cboxElement">' . '<img src="' . $imageSrc[0] . '" class="colorbox-' . $post->ID . '"></a>'; } } else { echo __('No Images', 'text_domain'); } echo $after_widget; } } function hideAllImages($content) { global $post; $imgfilter = array( 'order' => 'ASC', 'post_mime_type' => 'image', 'post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment',); $attachments = get_children( $imgfilter ); $images = array(); if ( $attachments ) { foreach ( $attachments as $attachment ) { $imgUrl = wp_get_attachment_url( $attachment->ID ); if ( SidebarImage_Widget::filterImageUrl($imgUrl) ) { $images[] = str_replace('.jpg', '', $imgUrl); } } } $imgPattern = "/<img([^\>]*?)>/i"; if (preg_match_all($imgPattern, $content, $imgTags)) { foreach ($imgTags[0] as $imgTag) { $imgSrcPattern = '/src="([^"]*?)"/i'; if ( preg_match($imgSrcPattern, $imgTag, $imgSources) && !preg_match('/style="display:none;"/i', $imgTag) ) { $isMatch = false; foreach ( $images as $img ) { // echo __('Pattern ' . $img, 'text_domain'); $isMatch = strpos($imgSources[1], $img); if ( $isMatch !== false ) { break; } } if ( $isMatch !== false ) { $pattern = $imgPattern; $replacement = '<img style="display:none;" class="colorbox-none" $1>'; $replacedImgTag = preg_replace($pattern, $replacement, $imgTag); $content = str_replace($imgTag, $replacedImgTag, $content); } } } } return $content; } function register(){ wp_register_sidebar_widget( 'Sidebar_Image_Widget', 'Sidebar Image Widget', array('SidebarImage_Widget', 'widget')); } } ?>