Moving from ExpressionEngine to WordPress in 64 easy steps.

I’ve had a lot of requests for a post on how I moved my ExpressionEngine blogs over to WordPress so here it, finally, is. And, no, it doesn’t really take 64 steps.

The problem with moving from EE to WordPress is that while WP has an impressive selection of importing tools for various platforms built into it, ExpressionEngine isn’t one of the supported platforms. This means we have to do it ourselves and so that’s what I set out to do. You will find in the ExpressionEngine Wiki some information on how to export to the MovableType Format, but this has a couple of limitations that made it less than ideal. For example, I used the SolSpace Tags module in ExpressionEngine and wanted to move all the tags over to WordPress, but the MT format has no facility to do that. A much better  solution would be to export to WordPress’s native WXR format which does support tags, but finding info on how the WXR format is defined (it’s an extension of XML) was more difficult than I thought it would be. It doesn’t appear anyone has sat down and specifically posted what WordPress looks for and accepts in an WXR file.

Eventually I set up a test blog in WP, put in some content that hit all the features I wanted to support, and then did an WXR export to see how the file was set up. I’m far from an expert on the WXR format, but I managed to figure out enough of it to get things to work. My method is similar to the aforementioned MT export templates except that it outputs WXR formatted data instead. You can download the templates by clicking here.

To use them you’ll want to create a new template group called “export” in ExpressionEngine. Then create two RSS templates in that group to hold the templates themselves. I called the first one “export” and the second one “comments.” It doesn’t really matter what you call the first one, but the second one must be named comments so it’ll be embedded properly. If you change the name then be sure to change it in the first template file. Both templates should be set in EE as RSS pages and you should set Allow PHP to “Yes” and “On Input” on the comments template. In the first template on the very first line is the global variable {assign_variable:master_weblog_name=”yourblogshortname”} which you should change to the short name for your blog in EE.

Once you’ve done all of that you’re almost ready to start exporting data. I use the word almost because there’s one thing that I can’t account for ahead of time and that’s the amount of data you are exporting and what RAM limits your server has. There’s also the fact that these templates do not save out to a file. Instead you have to right click on the “view” link in EE’s template listing and select “open in a new tab/window” then click on that new tab and select “show page source” which will open another new window, and then save that new window’s output to an XML file.

Doesn’t matter what you call the files (I named mine SEB1.xml, SEB2.xml, etc.), but if you try to output all of your data at once and you have a crap load of it then your browser will probably crash before you can save the file. On top of all of that, WordPress has a import size limit of 10MBs per file. In the case of SEB, at the time I made the move, I transferred some 6,500+ entries and 75,000+ comments and there was no way in hell it was all going to come out as one great big file so I ended up having to do multiple exports.

Here’s how you do that: In the first template file there’s a line that reads as follows:

{exp:weblog:entries weblog="{master_weblog_name}" dynamic_start="on" limit="9999" offset="0" sort="asc" rdf="off"}

The two key parameters are the limit and offset. The limit sets the total number of entries that’ll be included an in export and the offset tells it at what entry to start at. If you have a very small blog (couple of hundred entries with less than a dozen comments each) then you might be able to get away with a single export using those settings, but if not then here’s where you will have to experiment to find out what you can get away with and it will depend on how many entries you have as well as how many comments on those entries. There is a similar line in the comments template which limits how many comments to include that is set to 1,000 comments. None of the entries on SEB ever hit 1,000 comments so that worked just fine for me, but if you have entries with more than 1,000 comments you may need to edit that template as well. Due to memory limitations on my server I found that I could only export between 100 and 300 entries at a time before EE would abort with an out of memory error. This meant that I ended up exporting some 32 files total to get everything moved over. If I got an out of memory error then I’d go in and change the limit to a smaller number (usually decrementing by 50 each time) until I got a successful export. Once it was successful I’d go back in and change the limit back to 300 and increase the offset by however much the last export put out. Do that as many times as you need to to export all your data.

If that sounds like a pain in the ass, well, it is, but there’s still more that can go wrong. Because you’re generating an XML file your browser can be pretty fucking picky about any weird or garbled characters that might happen to be in your code. SEB was originally on MovableType and in the move from that to ExpressionEngine there were a few entries that ended up with some non-standard characters in them. Whenever an export hit one of those garbled characters it would cause an XML error and I’d have to try and figure out which entry was causing the problem, edit it in EE to fix the garbled characters, and then retry that particular export. I’d say there was about a dozen entries or so that caused me fits, but if you’ve been running on EE all along then this probably won’t be a problem for you.

Now for some good news: WordPress is impressively good at importing those WXR files. If you screw up and forget to change the offset number and end up with a duplicate file (or just one that has a handful of duplicates) WordPress will NOT create duplicate entries in your database. It’ll report those as duplicate entries and reject them. WordPress will also ask you how to handle entries written by people other than the account you are logged in as when doing the importing. You can either reassign those entries to an existing WP user or you can have WP create accounts for those users when doing the import. WordPress is also just fine with importing one file after another to build up your database back to normal.

Some other things to keep in mind with these templates: They make the assumption you’re using the default field names of {body} and {extended} for your blog entries. I also didn’t include {summary} as I never used it myself so you’ll need to add that in if you want it. The code I used for exporting Tags is not included because not everyone uses that module, but I can supply it if you want it. One other thing I should have done and didn’t think of until after I was finished was adding in code to check if the {extended} field existed and if it did to put in the WP code for a Read More link. So for SEB, all the entries where I had a body and extended section became one big posting under WP. If you’re at all comfortable with making EE templates then you should be able to look at these, see how I did things, and tweak them according to your needs.

That’s pretty much the process in a nutshell. Hopefully this isn’t too confusing. If nothing else it should give you a starting point if you want to make the transition yourself. Perhaps someone else will come up with an even better way to do it. Feel free to ask me any questions you have in the comments.

63 thoughts on “Moving from ExpressionEngine to WordPress in 64 easy steps.

  1. Thanks for posting this.

    There’s also the fact that these templates do not save out to a file. Instead you have to right click on the “view” link in EE’s template listing and select “open in a new tab/window” then click on that new tab and select “show page source” which will open another new window, and then save that new window’s output to an XML file.

    Better use wget or curl from the Linux/cygwin command line instead of a browser.

  2. If you opt to go this route let me know and I’ll lend a hand. It turns out there are things about WP I like and some I don’t, but it’s headed more in the direction I want to go than EE these days.

  3. Thank you – I will see if I can make this work for me. I’ve been looking years—YEARS—for something like this because I can’t get the EE export to work with the Multi Site Manager. At least I think that’s what it is because I was able to make that old script work with a single site three years ago when I exported everything to write a book, but something’s different now and I can’t even get it to do that. When I click View Template the redirect always sends me to a 404 page where there should be the export data, where I could view source, if the damn thing worked.
    Any ideas on the MSM?

  4. Mindy, I never bought the MSM module. While I did run multiple blogs from my install of EE, it was done on the standard version without MSM. I’m not sure what changes the MSM module makes, but I would hazard a guess that you should still be able to make things work with these templates.

  5. The only conceivable difference that MSM makes is that you’d have to add a site_id parameter to certain tags if you’re accessing things from a different site (say templates and weblogs).

    Mindy, have you tried to get help on the EE forums?

  6. elwedriddsche , yep, I’ve tried the forums and they are awfully fond of their own template, the one they’ve had there forever. I’ll try again with the MSM site parameter angle, though. Thank you both!

  7. Well, their own template works on MSM. What I’ve done in the past is to create a new template group and stick the two templates in there; this approach doesn’t require any MSM jiggery-pokery at all.

  8. In that case I think it must have something to do with the redirects/paths the person who put the sites together specified. For example, when I click on a quicklink at the top of the control panel, I go to a redirect page and have to click the link again to move on. I get that with the templates I created too, but it always goes to a 404. But since the redirect works with every other link, I don’t know that that’s it. I’ll have to comb through the code again to be sure I’m doing it right.

  9. Hi Les, I really would appreciate if you publish the Tag Module code.

    Onether question, what about custom fields? I was using some of them and I would need to import them to WP. Any suggestion?

    Thank you

  10. Hi, I imported the cudtom fields succefully copying the same structure than the WP Export Tool XML. Tomorrow I will try the same with the Tags. Thank you, your guide has been very useful.

  11. Sounds like you managed to work it out on your own. It’s not too tough once you get your head around it. Glad my guide was useful to you.

  12. Hi,

    thank you for your efforts to write down this tutorial.

    I tried your scripts and it worked quite well. As like you, before I run the script, I noticed the lack of check for {extended}.

    I’m not really familiar this WordPress and it’s tag & commands and php yet. I don’t have any clue how to insert categories and tags (I used solspaces’ Tags module as well). Would you mind to help me on this?

    Greetings,
    Stefan

  13. nevermind with categories. I used the “WordPress” Import feature (not via RSS) and it saved the categories and author as well.
    Now only the solspace Tags need to be done

    Greetings,
    Stefan

  14. Stefan, I got your email and sent you a reply with the necessary code. Let me know if you have any trouble with it.

  15. I’d really appreciate the solspace tags code as well. This was EXTREMELY helpful. I had been looking around google in a dozen ways to see if anyone had done this successfully. Finally used “moving” in the search string and found this. Yes!

  16. Terrific post (and blog!), thank you for sharing. I’m also moving from EE to WordPress and this was exactly what I needed. I’m also using the Solspace Tag module, and would like to check out your export code for that. Since EE generally seems to push the Solspace Tag module when new licenses are purchased, there are probably quite a good many of us using it. Might be easiest to just post it here in the comments?

  17. Vlad, you’re right. I should probably just post the code here. I’ll give it a shot and see what happens:

    Here's the relevant section of code that I used to export the tags:

    {exp:tag:tags entry_id="{entry_id}" }

    <category domain="tag">< ![CDATA[{tag}]]></category>

    <category domain="tag" nicename="{websafe_tag}">< ![CDATA[{tag}]]></category>

    {/exp:tag:tags}

    That's all it takes. Put that into the export template right after the categories section and before the line that starts with: . This will include any tags on the entries as they are exported and WordPress will build the tags database as it imports them. Afterward, if you're felling ambitious, you can go through the tags in WP and edit the display name to use upper case letters and remove any \'s that were put in to escape characters such as the ' symbol.

  18. Where it says in the post that you have to right click on the “view” link in EE’s template, what happened was that it only showed the template again in a new window.

  19. Minic, I just tested it and you’re right. It does appear to just open the template view in a new window. Instead just click on “View” and it should open a new tab or window with the RSS page it creates. Then right click on that tab/window and select View Source and that should give you yet another window with everything you need to save to a file.

  20. REALLY helpful – thanks for posting this, saved me having to do this work from scratch.
    As a side note – you should be able to just hit file -> save page as… to save the xml file from Firefox. I imagine something similar exists in Chrome and IE as well (although I don’t trust IE anyway)

  21. you need to click the view rendered template button, when you are looking at template. I think that will get what you want. The view link from the list did not do anything for me.
    I wonder if that is a bug in EE?

    also, the tag that asks for the feed blog_name should really ask for the weblog (at least in 1.6.x which is what I was using)

    anyway, yes, thanks for posting this. I am an EE fan, but some people are better off with wordpress.

  22. Thanks. This worked quite well on a couple of sites without comments. On a site with comments, only 1 comment would show up per entry.

  23. Hi Les,

    Thank you so much for this. I know you’re probably sick of questions, but I have 3 weblogs set up on an EE (www.bookbloggerappreciationweek.com) and I get the error “This feed contains no entries” when I try to view the RSS page.

    Any suggestions?

    Thanks!

  24. I finally got this to work perfectly in EE 1.7 by adding the comment_id in the Comments RSS template. However, that doesn’t work in moving EE 2.x content to WP (even changed all the weblogs to channels).

    Any ideas?

  25. Ron McElfresh: Add the comment_id to the comment template. I had the same problem and this helped for me!

  26. JP, that’s how I got it to work on EE 1.7 to WP. But the same code (changed weblog to channel) doesn’t work on EE 2.x to WP. Did yours work in EE 2.x?

  27. Monica, I’d suggest double checking that you put the short blog name that you want to export into the variable at the top of the export template. You can also double check the tags that make use of the short blog name to see if I perhaps forgot to include the variable (I just hardcoded my blog’s name in each tag myself).

    Ron, I’ve not tried these templates on EE 2.0 as I was only a beta tester and never converted my blogs to it. I’m afraid I don’t have enough experience with 2.0 to offer much in the way of advice.

  28. Thanks, Les. Is it possible to move what’s in Comments template into the Export template? I’m trying that now but not with success. The trick appears to be matching up the comments with the entry so WP knows to keep them all together.

    Love your hat, BTW.

  29. Ron, as I recall the reason for the separate template is because EE normally doesn’t have the ability to display comments on multi-entry pages, which is what we’re building here. Having the comments in a separate template with that bit of PHP parsing is a work around that makes it possible. There may be newer ways of doing it that I’m not aware of, though, so be sure to check the EE Wiki.

    And if you like the hat, then you’d probably love the coat that goes with it.

  30. Hey Les,

    I’m trying to export my entries to WP format. I started my efforts with a similar way to yours ( uses XML templates, almost identical, based on the EE Wiki to export entries ) but i get the same “strange” thing with both your templates and the other ones.

    Comments are… crazy! Especially with your templates comments appear to random entries.

    With the other set of export/comments XML templates comments appear inside the previous ( entry ) instead of the one there were written for!

    Any ideas? I’m trying to find out if i have something weird with my EE setup, but nothing… I was so lazy installing it that i didn’t event changed the short name :)

  31. Double check your templates and make sure that all the shortnames are correct. Beyond that you might try running the Comment Recount tool in ExpressionEngine to ensure the database has an accurate record. Also you could try checking the database for corruption using the tools in EE as well.

  32. @netfreak

    Are you converting from EE 1.x to WP? I wonder if the offset=”” would work on Comments?

  33. Yey. I fixed it!

    Thanks for quick reply Les, and a huge thanks for Ron. His comment made me check the Documentation for exp:comment:entries ( yes i’m exporting from 1.6.8 ) and i got an idea.

    That tag doesn’t support offset, but it supports the parameter entry_id. So i added the:
    entry_id="{embed:the_entry_id}"
    inside the {exp:comment:entries } and comments seem in place!

    PS: Some hints for anyone want to export:
    If you have the “go to last comment” plugin, disable it prior to export, cause it will add a Javascript file request to every entry with comments causing the XML/RSS to be corrupted.

    Also, check your entries & comments for emails written inside them. I think ExpressionEngine ( and not a plugin ) converts emails to encoded JS code to protect them. Personally i just wrote them again like user(at)domain.com.

    Thanks again :)

  34. Glad to hear that worked out. I’m trying to move a couple of sites from EE 2.x to WP and have trouble with the comments. I’ll give that a try. All worked fine from EE 1.7x to WP, comments included.

  35. Thanks for the post, it is exactly what I was looking for. I have one problem though. I have one field that is an ID field for another weblog called “park names” within the site, but I don’t want the ID, just the name. Below is my working code. The field that is giving me the ID number is park_name and it’s way down in the post meta data at the bottom of the code.

    I am new to expression engine, so I don’t know how to get that value or even find out what the “Park Name” field is named within the “park names” weblog. Any guidance would be appreciated. thanks!

    {exp:weblog:entries weblog="{master_weblog_name}" dynamic_start="on" limit="100" offset="0" sort="asc" rdf="off"}
    		
    {exp:xml_encode}{title}{/exp:xml_encode}
    
    {entry_date format="%r"}
    connectwithtn
    {categories}
    
    		
    
    {/categories}
    
    
    
    
    
    
    {entry_date format="%Y-%m-%d %H:%i:%s"}
    {gmt_date format="%Y-%m-%d %H:%i:%s"}
    closed
    open
    {url_title}
    publish
    0
    0
    trail
    
    0
    
    
    	_edit_last
    	
    
    
    	_ct_text_4e9300562e1ca
    	
    
    
    	_ct_text_4e9300f716921
    	
    
    
    	_ct_selectbox_4e93013605fca
    	
    
    
    	_ct_selectbox_4e93017ccfcef
    	
    
    
    	_ct_text_4e9301949ca3e
    	
    
    
    	
    {/exp:weblog:entries}	
    
  36. For some reason I just posted this message and the site hid everything inside tag marks, so I put spaces in to make it show.

    Original Post:

    Thanks for the post, it is exactly what I was looking for. I have one problem though. I have one field that is an ID field for another weblog called “park names” within the site, but I don’t want the ID, just the name from within the park names list based on the ID. Below is my working code. The field that is giving me the ID number is park_name.

    I am new to expression engine, so I don’t know how to get that value or even find out what the “Park Name” field is named within the “park names” weblog. Any guidance would be appreciated. thanks!

    _ct_text_4e9300562e1ca

  37. Looks like WordPress may be eating some of the code. Drop me an email with your sample and I’ll take a look at it.

  38. I got this to work, but had to change the second line of export.rss from:
    {exp:rss:feed blog_name=”{master_weblog_name}”}
    to:
    {exp:rss:feed weblog=”{master_weblog_name}”}

    I was using EE 1.6.7.

    Thanks so much for posting this, worked like a charm!

  39. something crook in the comment by mike copied below . the feed downloaded a whole lot of online-pharmacy kind of posts. i am lost and i am using ee1.6.3 and the script won’t work for me
    Mike wrote:

    I got this to work, but had to change the second line of export.rss from:
    {exp:rss:feed blog_name=”{master_weblog_name}”}
    to:
    {exp:rss:feed weblog=”{master_weblog_name}”}

    I was using EE 1.6.7.

    Thanks so much for posting this, worked like a charm!

  40. On the admin page of my EE (v1.7.1) site, rather than having a Weblog Administration option I have Channel Administration. I stuck the in short name of the channel containing the blog I want to export the content from, but that didn’t seem to work. Is the another part I need to edit since it’s set up as channels? Currently I get the same “This feed contains no entries” error Monica had mentioned.

  41. Thanks for this guide. I’m a WP guy and know nothing about EE. I created the template group and templates. Then I uploaded the rss files into the template group folder. When I click on “view”, I get a blank xml file.

    Retracing my steps:

    I’m in 1.6.8.

    The “templates” folder was empty and I found under Template Preferences, “Allow Templates to be Saved as Files”, checked “Yes” and entered the path to the templates directory. I still didn’t see anything in the templates directory.

    So I clicked on each template in the template group, checked a box I saw “Save Template as File”, updated and then saw where the a folder appeared for the template group, along with two php files for the templates (although these were blank.)

    Since I could see the template group folder name, I uploaded your rss files into the template group folder.

    I read through all the comments above, realized I’m just plain ignorant and decided to post this to see if I could get some help :)

    ****UPDATE****
    I finally recognized that by clicking on the template names, I could paste in the code from your files, which is what I should have done in the first place. Things are clicking now – thanks!

  42. I’m following these directions precisely, but for some reason it’s not working at all. On EE 1.6.8, and when I right click to view the template rss files it just shows me the site index page. WTF am I doing wrong?

  43. Holy hell, that might have done it. I had an .htaccess issue, for starters, having to do with my custom URLs. And then I had to use the index file in the export template group to view the comments template, instead of viewing it directly. I took the code for the index directly from EE’s entry on exporting comments, if anyone else runs into that.

  44. Hi Les,

    I get this error:

    “Error

    The weblog specified in your RSS feed does not exist.”

    I tried changing the template as commented above:

    {exp:rss:feed blog_name=”{master_weblog_name}”}
    to:
    {exp:rss:feed weblog=”{master_weblog_name}”}

    Still no go. Using EE 1.61.

    Does anyone have an idea what could cause that? Appreciate any pointers!

  45. Christine, are you using the correct short-name for the blog you want to export? What I mean to ask is did you change “master_weblog_name” to whatever your blog’s short-name is? I hope it doesn’t seem like too simple a question. There’s a thread that addresses this on the EE forums you can find here.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>