Skip to Main Content
6366883475 289E4E2771 O

Migrating Content from ExpressionEngine to Craft

I've wanted to give Craft CMS a go for a while now and figured the best way to do it is with a personal project. My photo blog is in dire need or a revamp and as such I've decided to migrate to Craft. Installing Craft is dead easy and took only about 90 seconds including time to download the zip file.

I've wanted to give Craft CMS a go for a while now and figured the best way to do it is with a personal project. My photo blog is in dire need or a revamp and as such I've decided to migrate to Craft. Installing Craft is dead easy and took only about 90 seconds including time to download the zip file.

Before I started working on the design I wanted to be sure that I would be able to easily migrate four years of content so the first step was migrating my Entries. This turned out to be relatively painless with the use of this import plugin.

I first copied all photos from the live site to my upload folder of the new site. Then in the Craft CP click the gear icon on the top right, then Assets, New source and fill in the fields. both the path and url can be set to relative paths, but be sure to not use a leading slash. After saving click the gear icon again and go to the lower left and update asset indexes. A short time later all your images are in the database. You can confirm this by clicking on Assets in the nav.

The next step is to install the Import plugin by putting the files in /craft/plugins then in the CP click gear and plugins and finally install. This plugin only imports content in CSV format. This requires a new template in ExpressionEngine which will need to be set with php turned on in order to force the browser to download the file directly.

The php at the top of the template tells the browser this is an excel file and forces it to download the file on browser load

    
    
      <?php
    header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=photoblog-export.xls");
header("Pragma: no-cache");
header("Expires: 0");
?>
    
  

The next bit of code contains all our fields and how we want them named. This is important to easily map the fields using the import plugin. Line 20 has entry_date with extra spaces this is due to my blog rendering it and not displaying the code correctly - remove extra spaces for it to work. When migrating images, be sure to only include the image name. My images currently reside in a Matrix field {photos} and a file cell. In order to get just the file name it is necessary to use the file tag pair like this {image}{file_name}{/image} where the outer tag pair is the file field/cell name.

    
    
      <tr>
	<td>Title</td>
    <td>Url Title</td>
    <td>Entry Date</td>
    <td>Description</td>
    <td>Image</td>
    <td>Meta Keywords</td>
    <td>Meta Description</td>
</tr>
 
{exp:channel:entries channel='photoblog' limit='1000' disable="categories|member_data|pagination|trackbacks" status="not foo"}
    <tr>
            <td>{title}</td>
            <td>{url_title}</td>
            <td>{entry_date}</td>
            <td>{description}</td>
            <td>{photos}{image}{file_name}{/image}{/photos}</td>
            {exp:seo_lite entry_id="{entry_id}"}
    </tr>
{/exp:channel:entries}
    
  

After downloading the file open it in Excel, you may see a warning that the file format doesn't match the extension, open it anyhow. Now do a save as and choose CSV (comma delimited). My research indicated that this extra step is necessary as using the template to save as CSV with content that contains quotes may not work correctly.

CSV Creation Update July 2016

I revisited this and couldn't get Excel 2013 or Google Sheets to work with the old method. I googled and found an even easier way to do this. You'll need this TabletoCSV jQuery plugin and a slightly different template. After creating your template you can visit the page and you'll see all the data in an html table. all you need to do is click the Export button and then upload to Craft. I just successfully imported 804 entries using this. I had two entries where I expected two images to be included in the assets field, but zero were imported. For those I manually added them. If you find a solution include multiple assets let me know.

    
    
      <head>
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="/js/jquery.tabletoCSV.js"></script>
</head>
<table>
<tbody>
<tr>
	<td>Title</td>
    <td>Url Title</td>
    <td>Entry Date</td>
    <td>Description</td>
    <td>Image</td>
    <td>Meta Keywords</td>
    <td>Meta Description</td>
</tr>
{exp:channel:entries channel='photoblog' limit='1000' disable="categories|member_data|pagination|trackbacks" status="not foo"}
    <tr>
            <td>{title}</td>
            <td>{url_title}</td>
            <td>{entry_date}</td>
            <td>{description}</td>
            <td>{photos}{image}{file_name}{/image}{/photos}</td>
            {exp:seo_lite entry_id="{entry_id}"}
    </tr>
{/exp:channel:entries}
</tbody>
 
<button id="export" data-export="export">Export</button>
 
<script>
$("#export").click(function(){
  $("table").tableToCSV();
});    
</script>
    
  

Now to import, click Import in the Nav. Fill in the fields as required and upload your CSV file.

Go to the next page where we map the fields to Craft fields.

Now hit import, wait a few minutes and all of your entries will be imported. To confirm click on "Entries" in the top nav. Assuming that new content is added to the live site before this build is finished then all you need to do to update is do a new export with only the new entries since the last import and repeat the process. Super easy.

Now it's time to start templating the new site.

Comment Update

Joe sent me an email in response to his my comment below - commenting is turned off automatically after a couple of weeks for spam protection. I've copied his comment here:

Hi, just replying to my comment on your article: Migrating Content from
ExpressionEngine to Craft. I couldn't make another comment on the article
for some reason.

Anyway, I was able to import my images finally. I actually used the Feed Me
plugin (https://github.com/engram-design/FeedMe) Very similar to Import, but
it allows for XML which is super nice. And to get the images from EE Matrix
to map to Craft Assets field, I just had to separate them with a comma in
the XML. That part of the EE template looked like this:

Joe
    
    
      [CDATA[{project-images
backspace="1"}{image}{file_name},{/image}{/project-images}]]>
</images>