Making the Move to Mango
As of today, my blog has made the transition from BlogCFC (I was still running 4.0) to Mango Blog. I previously reviewed Mango back when I launched the Flex Camp Boston
site so the reasons to choose Mango should be clear. However, there are
many more things to consider when migrating an existing blog. If you've
had your blog for any decent time, this migration is difficult - no
matter what engine you move from or to. It's like I read in some
ancient Chinese prophesy, "Making your way in the world today takes
everything you got..." Indeed....indeed.
Step 1 : Migrating Your Exising Posts
Included in the installer, Mango includes a tool to import posts,
comments and settings from Wordpress and BlogCFC version 5. However
there may be reasons this will not work for you, as it did not for me.
I had a large number of posts (closing in on 500) and comments (almost
1,400) to move. While there was an importer for BlogCFC 4 in the code
(it isn't implemented in the installer), I couldn't use this because of
the way the importer works. This is becuause, since each item in Mango
is an object (i.e. a post, a comment, etc.) creating instances of 2,000
objects simply brought ColdFusion to its knees (even ColdFusion 8 with
its performance improvements).
Nonetheless, the installer did lead the way to building a straight
query-based installation script in that it helped map the fields
between the two sets of database tables. Thus, I ran the installation
as normal and then ran my import script. One key in the import script
is to get your author id and blog id (probably just "default") out of
the database and make sure your posts are associated to it.
Another thing that can cause trip-ups here is the cache. If you have
run the blog or admin you may need to use the utility in the admin to
clear the cache. Additionally, many of the queries are cached as well
via standard ColdFusion query "cachedwithin." I added a means to tell
my install script to also clear the query cache otherwise things just
didn't show up correctly.
(note: if anyone is moving from BlogCFC 4.x, I would be willing to share the import script).
Step 2 : Migrating Your Design
One of the key reasons to choose Mango is its templating API.
First, you can download and share new templates via the Mango site.
Implementing a newly downloaded template is just a matter of choosing
it in the admin. Nonetheless, if you are like me, you will want to use
your own existing design.
There are only a handful of requires template files for Mango and
generally once you have migrated one they will all move along pretty
easily (since more than likely you don't have dramatically different
designs for every portion of your site). Each type of object in Mango
has a set of custom tags that allow you to do things like, for example,
loop over posts, output post properties and create conditional code
blocks. I did run into some issues in while most tags are well-documented,
some tags aren't. Still, if you simply open the tag it pretty well
documents itself. Except for once where I hit a minor bug which I was
able to fix, there were no major snags in templating.
Step 3 : Migrating Your Pages
Most sites have pages other than just the blog posts, as mine does.
Mango includes the ability to add custom pages, as my new publications
and projects pages are. However, you may have pages that require custom
ColdFusion code. My about me page actually includes code for a number
of minor things, but the primary issue was the random photo which is
drawn off my Flickr photo feed.
I am certain there is a potentially better solution for this, but what
I did was create a directory called pages and in it I put pages such as
this. Part of this was creating a layout custom tag which still uses
the Mango tags for accessing data about my Mango blog. Then I can wrap
these custom code pages in the same design as the rest of my Mango blog
and it will know about things like my pages, posts and default blog
information.
The open-source list was another story, since it is an entirely
separate application. For the moment, I simply hard coded any changes
to the underlying blog layout. Obviously, this isn't a great long term
solution, but sometimes you just need to get these things up and
running (even if imperfect)
Step 4 : Managing Old URLs
One benefit of sorts that I had was that my old blog lived in a
directory called "blog" and the new one would live in the root. This
allowed me to put scripts to redirect old post URLs and not touch the
underlying Mango code. Otherwise, you will likely need to add a call to
some custom code within Mango's application.cfc to handle redirecting
old URLs. For instance, Mango does not include the date in the URL like
BlogCFC even though the alias will remain the same. Obviously there may
be other differences when moving from other engines.
My BlogCFC install went back to 2005, when BlogCFC didn't even have
friendly URLs, so I needed to manage both. So my script handles those
old URLs, new URLs and date searches:
<!--- if the entry already defined in the URL for old non-SES URLs --->
<cfif structKeyExists(url,"entry")>
<!--- get the friendly url from the database --->
<cfquery name="getFriendlyURL" datasource="mydsn">
SELECT name
FROM mango_entry
WHERE id = <cfqueryparam cfsqltype="cf_sql_varchar" value="#url.entry#" />
</cfquery>
<cflocation url="/post.cfm/#getFriendlyURL.name#" addtoken="false" statusCode="301" />
</cfif>
<!--- if someone is coming in with a date link --->
<cfif structKeyExists(url,"month") and structKeyExists(url,"year")>
<cflocation url="/archives.cfm/date/#url.year#/#url.month#" addtoken="false" statusCode="301" />
</cfif>
<!--- Try to load my info from the URL ... --->
<cfset sesInfo = reReplaceNoCase(trim(cgi.path_info), '.+\.cfm/? *', '') />
<cfif len(sesInfo)>
<!--- skip the date portion --->
<cfif listLen(sesInfo,"/") eq 4>
<cfset sesInfo = listGetAt(sesInfo,4,"/")>
</cfif>
<cflocation url="/post.cfm/#sesInfo#" addtoken="false" statusCode="301" />
</cfif>
<cflocation url="/index.cfm" addtoken="false" statusCode="301" />
If you are moving from BlogCFC (and directories), you also need to remember the rss.cfm and print.cfm.
Step 4b : Managing Enclosures
This was something I initially overlooked because a small minority of
my posts contain enclosures but I did want to maintain access to them.
Unfortunately, at the moment Mango doesn't support enclosures which
means you can't directly import them.
In the end, I wrote a script to append an enclosure link to any post
containing an enclosure. Indirectly this fixed a problem I did not know
I had in BlogCFC. Since BlogCFC (at least my old version) stored
enclosures with the full path it meant that any enclosures added while
I was at a different host weren't working. The following script will
take existing enclosures in BlogCFC, clean up the URL and then append
them to the new posts in Mango.
<cfquery name="getEnclosures" datasource="remotesynth">
SELECT id, enclosure
FROM tblblogentries
WHERE enclosure <> '' and enclosure is not null
</cfquery>
<cfoutput>#getEnclosures.recordCount# enclosures found<br /></cfoutput>
<cfset enclosurePath = "/blog/enclosures/" />
<cfloop query="getEnclosures">
<cfset enclosureFile = listLast(getEnclosures.enclosure,'/') />
<cfset enclosureFile = listLast(enclosureFile,'\') />
<!--- get the same post from Mango --->
<cfquery name="getMangoPost" datasource="remotesynth">
SELECT id,title,content
FROM mango_entry
WHERE id = <cfqueryparam cfsqltype="cf_sql_varchar" value="#getEnclosures.id#" />
</cfquery>
<cfoutput>Modifying content of #getMangoPost.title#<br /></cfoutput>
<cfsavecontent variable="newContent">
<cfoutput><p><a href="#enclosurePath##enclosureFile#">Download the attachment.</a></p></cfoutput>
</cfsavecontent>
<cfset newContent = getMangoPost.content & newContent />
<!--- update mango post --->
<cfquery name="updateMangoPost" datasource="remotesynth">
UPDATE mango_entry
SET content = <cfqueryparam cfsqltype="cf_sql_varchar" value="#newContent#" />
WHERE id = <cfqueryparam cfsqltype="cf_sql_varchar" value="#getMangoPost.id#">
</cfquery>
post updated<br />
</cfloop>
Step 4c : Managing Code Blocks
Mango comes with a plugin that color codes code blocks
automatically for you. However, if you use the pre-installed TinyMCE
WYSIWYG editor, this can cause issues. I like having the WYSIWYG
editor; it makes copying posts (like this one) from Google Docs and
other sources easier so I didn't want to give it up. The current
suggested solution is to turn off JavaScript when working on a post
with code blocks, but that seems like it could become a major
annoyance. (Note: Mango supports several API's that allow you to post
directly from Google Docs and other editors rather than copy and paste).
After doing a bit of research I was able to find a JavaScript function
that handles turning TinyMCE off and on. I then simply added links
after the content labels allowing you to turn off the appropriate
editor and turn it back on. First, place this script at line 5 of
admin/postForm.cfm:
<script language="javascript" type="text/javascript">
function toggleEditor(id) {
if (!tinyMCE.getInstanceById(id))
tinyMCE.execCommand('mceAddControl', false, id);
else
tinyMCE.execCommand('mceRemoveControl', false, id);
}
</script>
Then after the label for content at line 92 add:
<span style="font-size:10px;">(<a href="##" title="toggle TinyMCE" onclick="toggleEditor('contentField');">Toggle TinyMCE&lt;/a>)</span>
You can also add the same code following the excerpt label at line 102, just change the id in the script call to "excerpt".
Conclusion
As you can see, even though Mango makes many migration issues
simpler, any blog migration on a longstanding existing blog is
complicated and you are likely to overlook something (as I probably
did). Nonetheless, I am excited to take advantage of the features Mango
offers like plugins, easy templating and more. Hopefully I will do a
better job keeping up to date with recent versions.
