Migrating from Pivot 1.x to WordPress

Since 2004 I’d been running the “Blog” section of this website on the Pivot 1.x platform, while the rest of my website used simple HTML pages. Over the years I’d regularly updated with each release – till the last available version Pivot – 1.40.6: ‘Dreadwind’. After that they moved to their next generation called PivotX. It’s a great little platform, running off ‘flatfiles’ (no need for a database back-end), fast rendering, etc. BUT I felt I’d be better off shifting the entire website on to a slightly better featured CMS and eventually zeroed in on WordPress.

The following is the process of how it got done, posted here in the hope that it would help out others.


Soon after I started out “the move” I came up against a problem – there was no direct or simple way to import my content from Pivot in to WordPress. I could of course use the RSS feed generated by Pivot and import directly from that, but I would loose the comments as well as the main body of large posts. I looked around and found a PHP script on Sourceforge.net which seemed like it would do the trick! The script was meant to export Pivot 1.x blog contents to a Movable Type readable format (for which a WordPress importer was available). I tried it, and it did export all content of the blog into Movable Type (export/ import) format BUT without any comments! 🙁

Then I came across this page. Now this seemed like just the ticket! There were a couple of hiccups though, so I thought it maybe worthwhile to put up a combination of the advice from that page, from the official Movable Type website as well as some of my own (hit & trial) learnings.

From Mr Miata’s Blog

Sign it to your Pivot weblog. On the left hand menu, under Administration, click on Weblogs, then click “your weblog name.”

On Step 1 of 3 under “archive settings,” change your Archive Type to: Yearly Archives. Under “templates,” note what is listed under Archive Template, because we will be changing the contents of this latter, the default is archivepage_template.html.

On Step 2 of 3 under “standard” note what is listed under Shortentry Template, we will be changing the contents of this later, the default is _sub_entry_standard.html.

On Step 3 of 3 under Various Settings change Encode Email Addresses to: No. Display Date Settings change the full date format, entry date and diff date to %month%/%day%/%year% %hour24%:%minute%:00 (this is the format MT wants of it’s imported dates, the :00 on the end is important because MT wants seconds) Under Comment Settings change all the labels for ‘no comments’, ‘one comment’ and ‘X comments’ to something unique, I used Talk To Me you will be eliminating this line later and this will help you find it. Change the contents of the Format of Comments block to:

COMMENT:<BR>
AUTHOR: %name%<BR>
EMAIL: %email%<BR>
URL: %url%<BR>
DATE: %date%<BR>
%comment%<BR>
-----<BR>

Please NOTE: The last line (before the <BR>) is FIVE simple ‘dashes’ (a single dash is ‘-‘) with no spaces in between! I mention this as I got some grief over this, due to the fact that a straight copy paste from the above mentioned website caused the simple dashes to be replaced by some other characters and caused all sorts of problems. Refer to https://movabletype.org/documentation/appendices/import-export-format.html . In brief, each part/ section of a post as well as each comment MUST be separated by FIVE dashes, while EIGHT dashes indicate the end of post/ beginning of a fresh post.

From Mr Miata’s Blog

On the left hand menu, under Administration, click on Templates. Then open the _sub_entry_standard.html template (or whatever you are using for the Shortentry Template.) Select everything in the template and save it to a file on your PC. Now replace everything in the file with the following:

AUTHOR: [[user:nick]]<BR>
TITLE: [[title]]<BR>
DATE: [[date]]<BR>
CATEGORY: [[category:inthisweblog]]<BR>
STATUS: draft <BR>
ALLOW COMMENTS: 1 <BR>
CONVERT BREAKS: 1 <BR>
-----
<BR>
BODY:<BR>
[[introduction]]<BR>
-----<BR>
EXTENDED BODY:<BR>
[[body]]<BR>
-----<BR>
[[comments]]<BR>
--------<BR>
<BR>

Please NOTE: Once again (for the reasons outlined above), FIVE ‘dashes’ separate each section, while at the end we use EIGHT simple ‘dashes’.

From Mr Miata’s Blog

Now open the archivepage_template.html file (or whatever you are using for the Archive Template.) Select everything in the template and save it to a file on your PC. Now replace everything in the file with the following:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=‘[[charset]]’” />
<script language=“JavaScript” src=“[[pivot_dir]]includes/js/dyna_content.js” type=“text/javascript”></script>
</head>

<body>

[[subweblog:standard]]

</body>
</html>

On the left hand menu, under Administration, click on Maintenance, then Rebuild All Files. When this is finished, click on the Rebuild the Frontpage(s) link at the top of the page.

Once this above is done. Go to your Blog’s main page and click on the link for the yearly archive, I started with the last year and worked backwards chronologically. You can do it either way. For this operation I’d suggest using Chromium/ Chrome browser, as Firefox seems to encode the e-mail ID’s in the comments when you do a “view source” (Ctrl+U) and that will cause “pain” when you import comments into your new WordPress blog! When you click on the yearly archive link you’ll see a very plain looking page (sans all style/ formatting/ theme). This Page will have your entries/ posts listed out, with each entry followed by all comments on that entry. Now either right click and choose “view source” or simply use Ctrl+U to see the page source. Copy/ Paste this source into a text file and save it to your hard drive. The method I’d followed was to save each year in individual files and then consolidate all of them into a file called mt-export.txt , but my total entries/ posts were less than 50 in number. If you have a large number of posts, it may be better to keep each year separate and import these files individually.

However, before be begin the import process – we need to further “CLEAN UP” these files and remove some “excess material”. Your txt file will look something like the following:-

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=‘utf-8’” />
<script language=“JavaScript” src=“/blog/pivot/includes/js/dyna_content.js” type=“text/javascript”></script>
</head>

<body>

<span id="e21"></span>AUTHOR: Monkey<BR>
TITLE: Foobar 1<BR>
DATE: 07/02/2005 14:32:00<BR>
CATEGORY: humour<BR>
STATUS: draft <BR>
ALLOW COMMENTS: 1 <BR>
CONVERT BREAKS: 1 <BR>
-----
<BR>
BODY:<BR>
Foobar 1 testout
-----<BR>
EXTENDED BODY:<BR>
<a id="body"></a><BR>
-----<BR>
<a id="comm"></a>
<a id="lastcomment"></a>COMMENT:<BR>
AUTHOR: jackie<BR>
EMAIL: (<a href='mailto:jackie@Foobar 1' title='Email jackie'>Email</a>)<BR>
URL: (<a href='http://jackie.foobar' rel="nofollow" title='jackie.foobar'>URL</a>)<BR>
DATE: 09/03/2011 12:11:00 <BR>
Foobar 1 is great<br />
Foobar 1 helped me a lot<BR>
-----<BR>
<BR>
--------<BR>
<BR><span id="e19"></span>AUTHOR: Monkey<BR>
TITLE: Foobar 2<BR>
DATE: 04/13/2005 14:15:00<BR>
CATEGORY: default, crazy<BR>
STATUS: draft <BR>
ALLOW COMMENTS: 1 <BR>
CONVERT BREAKS: 1 <BR>
-----
<BR>
BODY:<BR>
Foobar 2 is running wild<br />
<br />
Read more about Foobar 2 <a href="http://Foobar 2">here</a>.<BR>
-----<BR>
EXTENDED BODY:<BR>
<a id="body"></a><BR>
-----<BR>
<a id="comm"></a>
<BR>
--------<BR>
<BR>
<script type="text/javascript">
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l=document.getElementsByTagName("a"),t=document.createElement("textarea");for(i=0;l.length-i;i++){try{a=l[i].getAttribute("href");if(a&&a.indexOf("/cdn-cgi/l/email-protection") > -1 && (a.length > 28)){s='';j=27+ 1 + a.indexOf("/cdn-cgi/l/email-protection");if (a.length > j) {r=parseInt(a.substr(j,2),16);for(j+=2;a.length>j&&a.substr(j,1)!='X';j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}j+=1;s+=a.substr(j,a.length-j);}t.innerHTML=s.replace(/</g,"<").replace(/>/g,">");l[i].setAttribute("href","mailto:"+t.value);}}catch(e){}}}catch(e){}})();
/* ]]> */
</script>
</body>
</html>

Since I use Linux almost exclusively at home, I used gedit to edit the saved files. Please adapt the following advice based on which text editor you use.

1) Before every entry is it’s identifier and it looks like this:

<span id=‘e1011’></span>

So I set the search with wildcards for

<span id=‘e....’></span>

and replaced it with nothing. I then subtracted a dot, one at a time, until every identifier was gone. If you are using M$ WORD, you should use question mark ‘?’ in stead of the dot/ period mark ‘.’

For gedit, to achieve this (using wild cards in find & replace) you will need to enable and use the python console (edit -> preferences -> Plugins, enable python console and then use Ctrl+F9 to open the console).

Please paste the following into the python console and hit enter

#function to replace stuff
import re
def replace(re1,re2):
doc = window.get_active_document()
start, end = doc.get_bounds()
txt = start.get_slice(end)
newtxt = re.sub(re1,re2,txt)
doc.set_text(newtxt)

Now type the following and hit enter

replace(r'<span id=‘e....’></span>',r'')

This will work for entries with 4 numbers after the ‘e’ for three use

replace(r'<span id=‘e...’></span>',r'')

And so on and so forth till all have been replaced/ removed.

2) Replace every <BR> using match case with nothing. For gedit and most other programs you use the shortcut Ctrl+H for the “Find and replace” function. Pivot seems to use <br /> or <br/> as its line break, so that is why <BR> was used in the templates.

3) Replace every

<p><b>Talk to Me</b></p><a id=“comm”></a><br>

with nothing. This is the comment header that Pivot places in their pages. I noticed that (through multiple trial & errors) initially the
<a id=“comm”></a>
AND
<a id=“last comments”></a>

tags would appear with the phrase “Talk to me” inserted within the tags, but later on this phrase simply would not show up. Either way, you need to get rid of
<a id=“comm”></a>
AND
<a id=“last comments”></a>

tags and whatever appears between them.

4) If you have a lot of comments this will be the most time consuming part. In the above example you will notice that the commenter’s email and URL come out in html like this:


EMAIL: (<a href='mailto:jackie@Foobar' title='Email jackie'>Email</a>)<BR>
URL: (<a href='http://jackie.foobar'  rel="nofollow"  title='jackie.foobar'>URL</a>)<BR>

It is advised to replace these to the plain email address and URL:

EMAIL: jackie@Foobar
URL: http://jackie.foobar

5) Furthermore, you will may have multiple comments where one/ more of these is missing. I somehow had comments with both e-mail and URL missing, some with either missing, etc. In such cases I removed the entries altogether. So the comment looked something like this:

COMMENT:
AUTHOR: jackie
DATE: 09/03/2011 12:11:00
Foobar 1 is great
Foobar 1 helped me a lot

6) Lastly you need to remove the HTML header, etc so that the final text from the above example looks like this:

AUTHOR: Monkey
TITLE: Foobar 1
DATE: 07/02/2005 14:32:00
CATEGORY: humour
STATUS: draft
ALLOW COMMENTS: 1
CONVERT BREAKS: 1
-----
BODY:
Foobar 1 testout
-----
EXTENDED BODY:
-----
COMMENT:
AUTHOR: jackie
EMAIL: jackie@Foobar 1
URL: http://jackie.foobar
DATE: 09/03/2011 12:11:00
Foobar 1 is great
Foobar 1 helped me a lot
-----
--------
AUTHOR: Monkey
TITLE: Foobar 2
DATE: 04/13/2005 14:15:00
CATEGORY: default, crazy
STATUS: draft
ALLOW COMMENTS: 1
CONVERT BREAKS: 1
-----
BODY:
Foobar 2 is running wild

Read more about Foobar 2