On Thursday, I posted about getting Railo 3.1 running on Aptana Cloud, specifically using the UrlRewriteFilter to create the necessary rewrite rules in place for Tomcat. With Railo deployed and ColdBox running and accepting SES URLs, I deployed the open-source, ColdFusion-powered blog software, Mango Blog.

Deploying Mango Blog onto my Cloud instance was not quite as seamless as ColdBox. To start, the Cloud is slightly limited in that you cannot create your own Virtual Host without enabling root access**. Because I don't want to do this (see note below), I am running the blog from its directory (it's at www.imageaid.net/blog instead of blog.imageaid.net).

In my previous post, I noted a couple of UrlRewriteFilter rules I put in place to handle SES URLs for my simple ColdBox application. However, one of the rules for ColdBox is going to present a problem for Mango Blog: ^/(.*)/(.*)$

This rule will match www.imageaid.net/blog/ and redirect it to the main ColdBox application, which will then throw an exception because we have no handler called blog, etc. When you go  to setup Mango Blog, you are redirected to an administration url (url.com/blog/admin). This URL also matches our rule and will redirect to ColdBox, resulting in an application exception being thrown.

We need to create a few (well, more than a few actually) Mango Blog rules.

 
^(assets|skins|feeds|api|admin|components)
^/blog/$
/blog/index.cfm


^/blog/admin/setup(.*)$
-

The first rule first checks that the Request URI does not contain one of the character sets in the parentheses but does contain '/blog/' (www.imageaid.net/blog/ will be matched but www.imageaid.net/blog/feeds/ will not), the rule processes the to element and forwards the request to /blog/index.cfm, showing our blog's home page.

The second rule checks to ensure we're not in the specific administration setup pages. This rule may not actually be necessary but as I was working through the rule setup process, I needed it and just left it in there.

While UrlRewriteFilter is an excellent tool and a solid 'replacement' for Apache's mod_rewrite, it does lacks a couple of key features, namely %{REQUEST_FILENAME}, which provides the ability to test if a URL contains a file or directory. If the requested file is neither a file nor a directory, you can (re)direct the request to an appropriate URL. This makes handling SES-style URLs quite easy in Apache but not as easy when you use UrlRewriteFilter.

Because of this, and coupled with my craptacular knowledge of regular expressions, I ended up with a larger set of rules for Mango Blog. The reason for this is that, unlike ColdBox, Mango Blog uses several CFML files to handle various requests. For example, the CFML file post.cfm handles the retrieval and display of blog posts. The post page (post.cfm) only looks for one possible URL value (entry is its name). An example would be: www.imageaid.net/blog/post.cfm/my-first-post.

On the other hand, the CFML file archive.cfm handles the retrieval and display of archive entries based on several possible variables. The archive page (archives.cfm) might get archives by month and year (www.imageaid.net/blog/archives.cfm/date/2009/4) or by an alphanumeric category (www.imageaid.net/blog/archives.cfm/category/coldfusion).

With the other relevant CFML files, I need to expand the rules for my Url rewrites. Each of these key CFML pages (post, archives, author, and page) received one or more dedicated rules.

When Apache is serving the files, we can utilize the aforementioned variable %{REQUEST_FILENAME}, coupled with the [QSA] directive (attaching to a query string) to handle all URL rewrites. Since UrlRewriteFilter lacks both the REQUEST_FILENAME and the ability to append values to a query string ([QSA]), I've had to make a larger set of rules. I'm going to continue to try and improve these rules with improved regular expression skills (suggestions welcome!). In the meantime, they work and don't seem to have a negative impact on performance.

Mango Blog rules:




^(assets|skins|feeds|api|admin|components)
^/blog/$
/blog/index.cfm




term=(\w*)
^/blog/archives.cfm/search/(.*)$
/blog/archives.cfm?archiveType=search&term=%1


^/blog/archives.cfm/category/(.*)$
/blog/archives.cfm?archiveType=category&category=$1


^/blog/archives.cfm/(date|author)/(.*)$
/blog/archives.cfm?archiveType=$1&vars=$2




^/blog/(post|page).cfm/(.*)$
/blog/$1.cfm?entry=$2




^/blog/author.cfm/(.*)$
/blog/author.cfm?alias=$1




^/blog/feeds/(rss|atom).cfm/(.*)$
/blog/feeds/$1.cfm?category=$2




^/blog/admin/setup(.*)$
-

Mango-Railo Gotcha
A reminder that when you run Mango Blog (1.3.x) on Railo (3.0 and 3.1), you need to go to the datasources section of your Railo administrator and deselect the database option to 'Preserve Single Quotes'. You can see a previous post for more (with links to other bits about it).

Notes:
**While this might not seem like a big deal (and in the big picture, it isn't), it (enabling root access) does nullify your support (well, it's not nullified but they don't have to provide support), disqualify you for managed software patches and updates, and compromise some management features (they may not work).

Comments

Craig Kaminsky
@Marty: Thanks for noting the ampersands! I actually use the HTML entities in my code but the conversion from Blogger's editor (and syntax hightlighter, I'm sure) they always get converted ... I should probably spend some time to figure that out :)!

Again, thanks for pointing that out and I'm very glad the rewrite rules are working for you.

Cheers,
Craig
Marty McGee
These rules work great!!! Thank you Craig for your time on this. However, make sure to change the ampersand & signs in the XML to their HTML equivalent & amp; (without the space) because the ampersand is a special xml character and as written will throw an error like "The reference to entity 'term' must end with the ';' delimiter".

Lines affected:
/archives.cfm?archiveType=search& amp;term=%1
/archives.cfm?archiveType=category& amp;category=$1
/archives.cfm?archiveType=$1& amp;vars=$2
Craig Kaminsky
updated the mango blog rules today to a (I think) complete set
Craig Kaminsky
@steven: I should be posting the rules later today or early tomorrow. The drawback has been that (so far as I can tell from the manual and API), UrlRewriteFilter doesn't allow conditionals in the 'to' element. But, I could be easily missing something and am still working on it. Thanks!

@sami: Thank you and I'll try :)!
Sami Hoda
Keep up these posts Craig.
Steven Parkes
I'm interested in seeing the whole set of rules. Seems like it shouldn't be necessary, so either I might be able to come up with something better or at least understand what makes it impossible.