How to use Thematic and the wpSearchMu Plugin to Display Sitewide Search Results

A long title perhaps, but it could have read like this…

“What I Learned About Using WordPress Multi-Site (WMPU), Multiple Thematic Child Themes, Thematic Functions and CSS Body Class Styling and the wpSearchMu Plugin, to Accomplish a Sitewide Search and Get the Results Displayed How I Needed.”

Whew!

In other words…

My client had a need for several distinct sites for each of their product offerings, all related and interconnected, but needing to have individual plugins and themes managed separately. I needed six sites, all with the same branding, but all with slightly different layout and functional changes. I should also point out that this is a page heavy implementation of WordPress. Across all six sites there are only three actual blog posts and roughly 700 pages, give or take. Yes. You read that correctly…over 700 pages in total.

The Network of Sites

As I stated above there are six sites. The main site and five subdomain sites. Three of these sites are actually duplicates of the main site and two subdomain sites that have been translated into another language, so for the purposes of this article, I’ll be referring to just three sites. We’ll call them Main Portal, Residential, and Commercial.

Each of these sites had to have the same theme applied, but each site’s theme needed to have a slightly different look and functionality. By that I mean, the contents of the style.css and the functions.php files needed to be different for each theme. My solution was to use the Thematic Framework and create a custom Child Theme for each site and this has worked great, but when I needed a sitewide search solution, things got a bit dicey and I needed to do a lot of research, forum reading, trial and error, and reach out for assistance from a WPMU and Thematic guru in order to find the solution.

The Initial Solution

The sitewide WordPress Multi-Site search solution I chose to implement was the wpSearchMu plugin by Adam Wulf and Kenny Katzgrau. I’ll let you read the instructions for setting up this plugin on your own, but when you get to the part about making a small edit to your theme’s search.php file, be sure to read below if you’re using Thematic and a child theme. That’s what this post is all about…

The theme edit that the plugin requires is to add some code to the beginning and the end of the Loop in your search.php file.

At the beginning of the Loop:

switch_to_blog($post->blog_id);

At the end of the Loop:

restore_current_blog();

It’s not quite that simple when using Thematic and child themes, instead of editing the main Thematic search.php file (and having it overwritten each time you upgrade the Thematic core), you would instead create a function in each child theme to filter the main Thematic search. In this search filter function you would add the extra bit of code that the plugin requires. Here’s that function with those two lines added to the beginning and end of the search loop:

//**********  FILTER SEARCH LOOP TO ADD WPSEARCHMU PLUGIN CODE  ***********
function remove_searchloop() {
    remove_action('thematic_searchloop', 'thematic_search_loop');
}
add_action('init', 'remove_searchloop');

function my_wpsearchmu_loop() {
	global $post;
	while ( have_posts() ) : the_post();
		switch_to_blog($post->blog_id); ?>
		<div id="post-<?php the_ID() ?>" class="<?php thematic_post_class() ?>">
			<?php thematic_postheader(); ?>
			<div class="entry-content">
				<?php thematic_content(); ?>
			</div>
			<?php thematic_postfooter(); ?>
		</div><!-- .post -->
		<?php restore_current_blog();
      endwhile;
}
add_action('thematic_searchloop', 'my_wpsearchmu_loop');

//***************************************************************

Ok, so now that I had the necessary code from the wpSearchMu plugin added to the search loop, I went through the rest of the instructions including creating an index of the blogs I wanted search results from. And I did this on each of the blogs. Now it was time to test my search results…

The Problem

I tested the search from the main blog using the search term of “radon” because I knew that this term existed on the three blogs I wanted results from: Main Portal, Residential, and Commercial. This worked perfectly and exactly as expected, as seen in the image below.

The blue text you see in the image above are the page title links. Mission accomplished right? Not quite. Next I checked the search from one of the subdomain blogs and check out the search results now…where did the page titles go!?

Well, obviously those aren’t very useful results as they don’t lead the user anywhere! This was only also happening on Commercial site. So I started troubleshooting to find out what was going on. As I had been working on this project for a long time, and knowing it (and it’s stylesheets and functions files) had been changed, tweaked, and edited many times, I assumed the trouble was with one of two things. Either I was hiding those page titles with a function or within the stylesheet of that particular child theme.

The Final Solution

After many hours and days of frustration searching through and comparing these files over and over again, I finally reached out to the aforementioned guru, a.k.a. Ron Rennick and asked him to have a look with fresh eyes, which he graciously did and this was his response:

Found it- In Thematic

function thematic_postheader() {
  global $id, $post, $authordata;
  <snip>
    if (is_single() || is_page()) {
      $posttitle = '<h1 class="entry-title">' . get_the_title() . "</h1>n";
  } elseif (is_404()) {          $posttitle = '<h1 class="entry-title">' . __('Not Found', 'thematic') . "</h1>n";
  } else {
      $posttitle = '<h2 class="entry-title"><a href="';
      $posttitle .= get_permalink();
      $posttitle .= '" title="';
      $posttitle .= __('Permalink to ', 'thematic') . the_title_attribute('echo=0');
      $posttitle .= '" rel="bookmark">';
      $posttitle .= get_the_title();        $posttitle .= "</a></h2>n";
  }

<...>

In the main blog, the url for radon is being treated as a post. On the residential blog, it’s being treated as a page. Your search loop calls the thematic_postheader function.

Now I still don’t really understand why the thematic_postheader function would treat one blog’s content as a page and the other as a post, but I took the guru’s advice and created separate thematic_postheader functions for each child theme and placed it in their respective functions.php files. My child theme postheader function looks like this:

/*********** Filtering thematic_postheader Function to Display Post Title Links in Search Results **************/
// Information in Post Header
function childtheme_thematic_postheader() {
    global $id, $post, $authordata;

    // Create $posteditlink
    $posteditlink .= '<a href="' . get_bloginfo('wpurl') . '/wp-admin/post.php?action=edit&amp;post=' . $id;
    $posteditlink .= '" title="' . __('Edit post', 'thematic') .'">';
    $posteditlink .= __('Edit', 'thematic') . '</a>';
    $posteditlink = apply_filters('thematic_postheader_posteditlink',$posteditlink);

    if (is_single() || is_page()) {
        $posttitle = '<h1 class="entry-title">' . get_the_title() . "</h1>n";
    } elseif (is_404()) {
        $posttitle = '<h1 class="entry-title">' . __('Not Found', 'thematic') . "</h1>n";
    } else {
        $posttitle = '<h2 class="entry-title"><a href="';
        $posttitle .= get_permalink();
        $posttitle .= '" title="';
        $posttitle .= __('Permalink to ', 'thematic') . the_title_attribute('echo=0');
        $posttitle .= '" rel="bookmark">';
        $posttitle .= get_the_title();
        $posttitle .= "</a></h2>n";
    }
    $posttitle = apply_filters('thematic_postheader_posttitle',$posttitle);

    $postmeta = '<div class="entry-meta">';
    $postmeta .= '<span class="meta-prep meta-prep-author">' . __('By ', 'thematic') . '</span>';
    $postmeta .= '<span class="author vcard">'. '<a class="url fn n" href="';
    $postmeta .= get_author_link(false, $authordata->ID, $authordata->user_nicename);
    $postmeta .= '" title="' . __('View all posts by ', 'thematic') . get_the_author() . '">';
    $postmeta .= get_the_author();
    $postmeta .= '</a></span><span class="meta-sep meta-sep-entry-date"> | </span>';
    $postmeta .= '<span class="meta-prep meta-prep-entry-date">' . __('Published: ', 'thematic') . '</span>';
    $postmeta .= '<span class="entry-date"><abbr class="published" title="';
    $postmeta .= get_the_time(thematic_time_title()) . '">';
    $postmeta .= get_the_time(thematic_time_display());
    $postmeta .= '</abbr></span>';
    // Display edit link
    if (current_user_can('edit_posts')) {
        $postmeta .= ' <span class="meta-sep meta-sep-edit">|</span> ' . '<span class="edit">' . $posteditlink . '</span>';
    }
    $postmeta .= "</div><!-- .entry-meta -->n";
    $postmeta = apply_filters('thematic_postheader_postmeta',$postmeta);

    if ($post->post_type == 'page' || is_404()) {
        $postheader = $posttitle;
    } else {
        $postheader = $posttitle . $postmeta;
    }

    echo apply_filters( 'childtheme_thematic_postheader', $postheader ); // Filter to override default post header
} // end thematic_postheader
add_filter('thematic_postheader','childtheme_thematic_postheader');
/************ END Filtering Thematic Post Header ********************

Thank you Thematic Forum community for providing the basis for the above.

So now I had relevant sitewide search results that users could actually use, and they worked on each of the three sites, but there was one more thing to change per my client’s request.

Instead of the results being listed in the standard content area that is roughly 620px wide, they wanted these results to use the full width of the page. There are many ways to do this, but I had already created a function that removed the sidebar from specified pages and css declarations to change the width of these pages using the Thematic-added body class, so I went ahead and added the search page to my code.

//REMOVES SIDEBAR ON SPECIFIED PAGES - ALSO CHANGES TO CSS
function remove_sidebar() {
	// We test if we are on the pages "Test One, Test Two, Test Three, and Search Results"
if (is_page('test-one') || is_page('test-two') || is_page('test-three') || is_search()) {
// Yes, we are .. now we switch off the sidebar
		return FALSE;
	} else {
		// we are not .. we leave the switch on
		return TRUE;
	}
}
// Connect the filter to thematic_sidebar()
add_filter('thematic_sidebar', 'remove_sidebar');

This removed the sidebar, but the content still didn’t use the full width yet. I had to target the body css class on each page in order to make the width extend the full width of the page. That looked like this:

body.slug-test-one #container {
	width: 940px;
}

body.slug-test-two #content {
	width: 940px;
	/*border: 1px solid;*/
}

body.slug-test-three #content {
	width: 940px;
	/*border: 1px solid;*/
}

/* Styling the Search Results Page */
body.search-results #content {
	width: 940px;
	color:#666666;
	font-family:verdana;
	font-size:12px;
	line-height:15px;
	margin-bottom:10px;
	margin-left:10px;
	/*border: 1px solid;*/
}

I hope this helps someone. Please feel free to leave comments to help me (and others) understand further. I also would like to give a big thanks to everyone on the Thematic forums, the creators of wpSearchMu, and Ron Rennick for your code and assistance:)

[AppAd]