Using PHP Includes for MT Search Results

By Deane Barker on July 4, 2004

A lot of people want to roll their own search with Movable Type. Us, for instance — Gadgetopia has a two-tiered search system based on whether the search term appears in the title, keywords, or body of the entry (see this post for more information).

Our search is done in with SQL and PHP, abandoning the MT search system completely. The problem with this method is rendering the search results. If you don’t use MT, then you lose two things:

  1. Auto-creation of the permalink.
    The URL isn’t stored anywhere in the database, so you have to recreate it. If your URLs are just based on the entry ID, then it’s not hard. However, look at our URLs — they’re a conglomoration of the date and the entry title. We’d have to create a PHP function to recreate this scheme — and if we ever changed the URL structure from within MT, we’d have to change the PHP function separately.

  2. Text filters.
    If you’re just converting line breaks, the text filter is not so hard to re-produce. However, if you’re using Textile or some other plug-in to filter your text, you’re going to have to reproduce that in PHP as well so the previews render correctly.

You can avoid all this, however, by simply using PHP includes and an extra Individual Entry Archive. The result is an elegant solution that blends PHP and MT to eliminate the tedium of recreating MT functionality in PHP.

To do this, create a new Individual Entry Archive in MT called “search_fragment.” This template should contain just the HTML to present a single search result. Like this:







Configure this template to generate a file in a “search_fragments” directory named for the entry ID only. You don’t even have to add an extention, though you can if you like (if so, you’ll need the change the PHP code listed below). So the entry in the archiving configuration would be something like:


Now when an entry rebuilds, it will create two files: (1) its normal archive file, and (2) a search result fragment file called “1”, “2”, “348”, etc. in the search_fragments directory. Notice that since we’re using standard MT templates to create the fragment, the permalink will be created by MT, and the excerpt text will be formatted according to the text filter the entry is using.

Now, when you use your SQL to get your search results, just SELECT the entry ID, then spin through those and use PHP to include the matching search fragment file. Like this:

      while ($r = mysqlfetchassoc($results)) {
      @include "searchfragments/" . $r['entryid'];

This will dump the contents of each search fragment file in the table. Since each file contained two rows, the resulting table will be valid HTML. Notice we’re surpressing any errors on the inclusion line just in case a file is missing for some reason.

We’ve be using this system here for months, and it works great.