Making MovableType’s search multiple domain savvy [updated]
It’s no secret that I like using MovableType. I’ve done quite a bit of complex templating, and always enjoy doing new things with MovableType. One of the things that has bugged me about it though is mt-search.cgi. Search is great, everyone is doing it, but in MovableType it has a nasty address:
http://www.site.com/cgi-bin/mt/mt-search.cgi
It’s fair enough to say that you don’t need /cgi-bin/ in some situations (like mine), but that’s still minimal. GET variables get added onto this address when you do a search:
http://www.site.com/cgi-bin/mt/mt-search.cgi?IncludeBlogs=1&
search=query
Ugly. It gets even worse if you operate multiple sites off a single MovableType install: they have to share a common domain name for search. Take a look at Gawker, Gizmodo, Wonkette and Fleshbot (all operated off a single MovableType install under the direction of Nick Denton). Here is the format for their search URLs:
http://www.gawker.com/moveabletype/mt-search.cgi?Template=
TEMPLATE&IncludeBlogs=ID&search=search
Not only is this ghetto, it’s insecure. By messing with the BLOG_ID, one can find interesting results (press cancel to bypass that .htaccess protection). Or you could even have a Gawker search in Gizmodo’s clothing. Top secret internal weblogs can be searched with a quick ID change in the URL. I’m sure this isn’t ideal. (Update: Looks like they have improved things and the previous links don’t work anymore. Before the change the links showed search results from Gawker Internal and Kinja’s dev blog).
Hopefully you now agree that things can be improved. I recently changed MovableType to make:
1) The URLs are nicer
2) Each site search use its own domain
3) No blogid/template ID changes take effect
It’s actually pretty simple. If all you want is to get the sites on their own domain, skip step one. It’s just for cosmetics.
1) Make sure your server has mod_rewrite turned on. Add the following to your .htacces file:
RewriteEngine On
RewriteRule ^search/(.*) /mt-search.cgi$1
Now change the search form on your website to send the info to a new address:
http://www.site.com/search/
The final project will produce search URLs like:
http://www.site.com/search/?search=query
2) Now for the clever bits. In the folder that holds MT, duplicate mt.cfg. Name it something that has to do with your second site. Open it up and look for “CGIPath” and “DataSource”. I’m assuming here that you do not use MySQL or similar, but a file-based DB.
Make the URL for CGIPath the same that you changed the search form send its data to. Change the DataSource to be relative to the second site. In my case, this was: ../site.com/mt/db.
Save it off and grab a copy of mt-search.cgi.
3) With the duplicate copy of mt-search.cgi, go back to your second site and upload it. Change the permissions to 755. Find where the BEGIN code block starts (right at the top) and place this after the if/else loop:
$MT_DIR = '../site.com/mt/';
Note, you’ll have to change the path to whatever is correct in your situation.
4) Now look where it says “mt.cgf” (you can do a search). Change that to the name of your second .cfg file.
5) Here’s the slick part, add this the next line down (just as long as it’s before $app->run) and you won’t have to worry about templates:
$app->{searchparam}{Template} = "TEMPLATE_NAME";
As long as you have a template by the same name in your second mt.cfg file, you’re good to go. No one can change your template via URL hacking.
That’s all there is to it. Pretty simple. You’re probably saying, “Hey dummy there is an easier way to prevent templates from being changed, it’s called not defining AltTemplate.” True. But there are times where you want multiple blogs searched on a single domain. A links blog for example. This opens that up. You can run another copy of mt-search.cgi and get no cross-flow and no URL hacking. Just watch your IncludeBlogs in your second mt.cfg files, and you will have no problems.
If you have any tips/questions, let me know. I’m always looking to learn. This solution works well for me, and I hope it does the same for you. Let’s hope at least Gawker Media figures it out.
HOLY CRAP.
There’s still a hack out there –
the “IncludeBlogs” variable.. it too needs to be treated like:
$app->{searchparam}{IncludeBlogs} = “BLOG_NUMBER”;
Thing is, I stink at Perl and using that structure causes an error… any clue how to fix it?
Ben Trott noted that putting “NoOverride IncludeBlogs,ExcludeBlogs” in your config file will solve that very same problem.
Hi,
Changing the comments form so that the form uses “post” rather than “get” may also help…
All the best,
—
Ian