Movable Type Full Word Search

Prior to its integration into Movable Type, the MT-Search module allowed the ability to toggle between full-word and partial-word searches. For instance, if you searched on full words for out, you would get out in the results. But not outdoors, outliner or even outrageous. Unfortunately, that functionality isn’t currently available in Movable Type. This describes how to add it back.

Because this is a Movable Type module covered by copyright laws, I cannot distribute the module itself. You’ll have to do the work on your end.

I used PartialWords as the name of my form field. There is nothing magical about this field name. Use whatever you like, but keep in mind that when you see this value here, you’ll want to replace it with what you’re going to use on your end.

Step 1: Backup your Search.pm module and default.tmpl template so you can put them back if something goes wrong (or if you just want to go back to the default way of doing things). Search.pm can be found in lib/MT/App, underneath your main MT folder. Default.tmpl can be found in search_templates, also underneath your main MT folder.

Step 2: Make sure that the value of the parameter is being evaluated and set correctly, otherwise none of the other stuff will work. Look for the first batch of code, replace it with the second. The code is found about halfway through sub init in the Search.pm module. Changes are highlighted in bold.

  for my $key (qw( RegexSearch CaseSearch ResultDisplay SearchCutoff
  CommentSearchCutoff ExcerptWords SearchElement
  Type MaxResults SearchSortBy )) {
  for my $key (qw( RegexSearch CaseSearch ResultDisplay SearchCutoff
  CommentSearchCutoff ExcerptWords SearchElement
  Type MaxResults SearchSortBy PartialWords )) {

Step 3: Add the approprite code to the actual search function so that when a match is looked for, it will react appropriately. Again, search for the first batch of code, replace it with the second. This code makes up the majority of sub is_a_match, also found in the search.pm module.

  my $casemod = $app->{searchparam}{CaseSearch} ? '' : '(?i)';
  for (@{$app->{searchparam}{search_keys}{AND}}) {
   return unless $txt =~ /$casemod$_/;
  }
  for (@{$app->{searchparam}{search_keys}{NOT}}) {
   return if $txt =~ /$casemod$_/;
  }
  my $casemod = $app->{searchparam}{CaseSearch} ? '' : '(?i)';
  my $wordmod = $app->{searchparam}{PartialWords} ? '' : '(\b)';
  for (@{$app->{searchparam}{search_keys}{AND}}) {
   return unless $txt =~ /$wordmod$casemod$_$wordmod/;
  }
  for (@{$app->{searchparam}{search_keys}{NOT}}) {
   return if $txt =~ /$wordmod$casemod$_$wordmod/;
}

Step 4: (Optional) If you want to have the checkbox set on your form after the results are returned (that is, if you want the results form to show a checked box for partial searches after performing a partial search), here’s how to do it. If you don’t care if that box remains checked, then you can ignore this step. Add this code to sub set_form_elements within the else for ‘newcomments’ (right under similar entries for CaseSearch and RegexSearch is a good place). Also in the Search.pm module.

  if ($app->{searchparam}{CaseSearch}) {
     $tmpl =~ s/(<input type="checkbox"[^>]+name="CaseSearch")/$1 checked="checked"/g;
  }
  if ($app->{searchparam}{RegexSearch}) {
     $tmpl =~ s/(<input type="checkbox"[^>]+name="RegexSearch")/$1 checked="checked"/g;
  }
  if ($app->{searchparam}{PartialWords}) {
     $tmpl =~ s/(<input type="checkbox"[^>]+name="PartialWords")/$1 checked="checked"/g;
  }

Step 5: Add the appropriate checkbox to your form. I like the default of full word searches, so I didn’t add it to my initial search form, but I did add it to the template for the search results so that the box is set appropriately when results are displayed. This change is made to the default.tmpl template. The text after the checkbox is up to you. The only important part is the name. It needs to match the value we’ve been using thus far. If you use XHTML, you may want to use the ID attribute instead.

  <input type="checkbox" name="PartialWords" /> Partial words

This method defaults to performing full-word searches rather than partial-word searches. If you can understand what’s going on here, you should be able to flip that around the other way if you like. You could also add the above checkbox to your main search form and allow the user to set it as needed.

Finally, there is an area of the mt.cfg file (found in your primary MT directory) that refers to searches. Search for RegexSearch or CaseSearch to find it. If you’d like to set your default here, entering an uncommented line of PartialWords X ought to do it. Replace X with 0 or 1, depending on if you want the partial word search on. If the partial word search is on (1), it will search on partial words. If off (0), then the search will default to full words only.


Posted

in