<p>Here is how I did it on a recent project:</p>

<ol>
<li><strong>Create a temporary WP site to work in:</strong> I installed WP locally, imported the database, and downloaded the <code>wp-content/uploads</code> folder. You don't need the theme or any plugins (unless they affect the content output). In the Reading section of the WordPress settings, change "blog pages show at most" to a number higher than the number of posts in the system. You could also do this in a hidden template on the live site if you like to live on the edge. I was actually importing from a WordPress.com site, so I first had to export from that and then import into a self-hosted site.</li>
<li><strong>Migrate comments to Disqus:</strong> Create a new site in Disqus and install the Disqus plugin in your local WP installation. Let it run its import process to move all your existing comments into their system. Now the comments are their responsibility, and you only have to worry about the posts.</li>
<li><strong>Export the posts to a CSV:</strong> Paste the code below into the index.php file of WP's default twentyfifteen theme. Now when you visit the homepage of the temporary site, it will output a CSV file instead of HTML. Press cmd/alt-s to save it to a file. You may need to tweak the code a bit depending on your needs, but this should get you close. The interesting part is lines 20-23, where we apply the <code>the_content</code> filter (which replaces WP's short-tags), fix some character encoding issues, and replace image URLs with their corresponding URLs on the new site. I also set a "fullWidth" transformation on all the images, which I created in my Craft site to limit the images to the width of the page. See below for more on that. Save that resulting CSV file somewhere.</li>
</ol>

<blockquote>
<pre><code>&lt;?php

ob_start();
$df = fopen("php://output", 'w');
fputcsv($df, array(
    'Title',
    'Slug',
    'Date',
    'Author',
    'Category',
    'Tags',
    'Body'
));

global $more;
if ( have_posts() ) :
    while ( have_posts() ) : the_post();

        $more = 1;
        $content = apply_filters( 'the_content', get_the_content() );
        $content = str_replace( ']]&gt;', ']]&amp;gt;', $content );
        $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $content = preg_replace('#http://cmnh-blog.dev/wp-content/uploads/\d{4}/\d{2}/(.+?)\.(jpg|jpeg|png|gif)#', 'http://childrens-museum.s3-us-west-2.amazonaws.com/blog/_fullWidth/$1.$2', $content);
        $content = preg_replace('#https://childrensmuseumnh.files.wordpress.com/wp-content/uploads/\d{4}/\d{2}/(.+?)\.(jpg|jpeg|png|gif)#', 'http://childrens-museum.s3-us-west-2.amazonaws.com/blog/_fullWidth/$1.$2', $content);
        $cats = implode(', ', wp_get_post_categories( $post-&gt;ID, array( 'fields' =&gt; 'names' ) ));
        $tags = implode(', ', wp_get_post_tags( $post-&gt;ID, array( 'fields' =&gt; 'names' ) ));

        $row = array(
            html_entity_decode(get_the_title(), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
            $post-&gt;post_name,
            get_the_date('c'),
            get_the_author_meta('user_login'),
            $cats,
            $tags,
            $content,
        );
        fputcsv($df, $row);

    endwhile;
endif;

fclose($df);
echo ob_get_clean();
</code></pre>
</blockquote>

<ol start="4">
<li><strong>Create user accounts:</strong> If you set up user accounts before importing the posts, the authorship will be maintained. Just make sure to use the same email address for each person as in the old site.</li>
<li><strong>Import the content:</strong> I used <a href="https://github.com/boboldehampsink/import">Import</a> for this, although <a href="https://github.com/engram-design/FeedMe">FeedMe</a> might actually work better, as it will create Categories for you on the fly. </li>
<li><strong>Reconnect the comments:</strong> If you are keeping the same URL structure, you can just use Disqus's <a href="https://help.disqus.com/customer/en/portal/articles/912627-domain-migration-wizard">Domain Migration Tool</a> to update their records from the temporary WordPress site to your live domain. If you are changing the URL structure as well, you'll need to use <a href="https://help.disqus.com/customer/portal/articles/912757-url-mapper">URL Mapper</a> and somehow generate a CSV of corresponding old and new URLs for each post. Now you can add the Disqus embed code to your post template and the comments <em>should</em> appear.</li>
<li><strong>Generate image transforms:</strong> Remember how we set a transform on the images in the posts? Craft won't automatically generate those. So create the asset source and copy all the images in from your WP site. Now reindex the asset source in Craft and make sure you can see all the files in the Assets tab. Finally, create a new template with the following code. Open it in the browser and wait for all the images to appear. If you have more than 200 images, you will need to set the offset to <code>200</code> and run it again, and so on until all the transforms have been generated.

<blockquote>
<pre><code>{% set images = craft.assets.source('blogImages').limit(500).offset(0) %}
{% for image in images %}
    &lt;img src="{{ image.url('fullWidth') }}"&gt;
{% endfor %}
</code></pre>
</blockquote></li>
<li><strong>Check for broken styling:</strong> You will need to include <a href="https://codex.wordpress.org/CSS#WordPress_Generated_Classes">WordPress's default classes</a> in your new stylesheet, or you will lose image alignment and such. If there were any other markup patterns in the WP site that were generated by plugins, you will also need to accommodate those. If necessary, you can also add additional <code>preg_replace</code> lines to the export script to manipulate the markup as needed.</li>
</ol>

CC BY-SA 3.0
2015-10-01T06:14:29.577Z
I've updated index.php of my theme with the code to export a CSV, but when I visit the page in a browser, it's being printed out to the page and not saving a CSV. It's also not printing all the posts either, only about 10 of more than 100.
Tyssen
CC BY-SA 3.0
2015-10-01T22:14:35.520Z
You can just cmd-S to save the CSV as a file. And yes, you will need to set the "posts per page" in your WordPress Reading settings to a number higher than the number of posts. I will edit my answer to include that.
Eli Van Zoeren
CC BY-SA 3.0
2015-10-02T02:58:55.057Z
Great, thanks, that works fine for saving the CSV. Now I'm having trouble importing the CSV. I'm not sure whether it's the way the CSV is formatted. Would you have a small sample of one you've used you could post somewhere for comparison?
Tyssen
CC BY-SA 3.0
2015-10-01T03:48:50.180Z
2015-10-01T22:16:38.703Z
2015-10-01T22:16:38.703Z
Eli Van Zoeren
<p>If you're just trying to migrate data, the most simple method would be to use a WordPress plugin to export your posts to a CSV and import it into Craft using this <a href="http://boboldehampsink.github.io/CraftImportPlugin/" rel="noreferrer">Import Plugin by Bob Olde Hampsink</a>. This is just for posts. I'm not sure what you would do for pages, since we have a special section type for those.</p>

<p>A WordPress Import Plugin has not yet been created because many, if not most, Craft developers came from ExpressionEngine.</p>

CC BY-SA 3.0
2014-06-13T12:00:19.063Z
2014-06-13T12:00:19.063Z
Bryan Redeagle
<p>Its not a full-blown guide yet, but the <a href="https://sgroup.com.au/plugins/feedme/guides/migrating-from-wordpress" rel="nofollow noreferrer">Feed Me Guide</a> will get you off to a good start. That really deals with getting the data out of Wordpress. Handles Advanced Custom Fields, WooCommerce, Custom Taxonomies and Custom Post Types.</p>

<p>Once you've got out export file, you can following the <a href="https://sgroup.com.au/plugins/feedme/guides/importing-entries" rel="nofollow noreferrer">Importing Entries</a> guide for Feed Me.</p>

CC BY-SA 3.0
2017-02-01T13:18:08.203Z
2017-02-01T13:18:08.203Z
crawf
<p>At this point in time, you have a few options: </p>

<p><strong>Import Plugins</strong></p>

<p>As of this post, there are a few partial import plugins available and rumors that a few others might be on their way.</p>

<ul>
<li><a href="https://sprout.barrelstrengthdesign.com/craft-plugins/import" rel="nofollow noreferrer">Sprout Import</a> - Sprout Import supports over 40 data types such as Entries, Users, Assets, Products, Orders, Forms, Email, and Redirects; and more can be added as needed via plugin integrations.</li>
<li><a href="https://github.com/engram-design/FeedMe" rel="nofollow noreferrer">Feed Me</a> - Feed Me is a Craft plugin for super-simple importing of content, either once-off or at regular intervals. With support for XML, RSS, ATOM or JSON feeds, you'll be able to import your content as Entries, Categories, Craft Commerce Products (and variants), and more.</li>
<li><a href="https://github.com/boboldehampsink/CraftImportPlugin/" rel="nofollow noreferrer">Import</a> - Handles Entries and allows you to map them to fields in
your Entries Sections </li>
<li><a href="https://github.com/clearbold/craftimport/" rel="nofollow noreferrer">EE/Craft Import</a> - While this plugin has EE
in it's title, it looks like it's framed more around XML imports in
general and promotes itself as being a starting point if you have
other custom import needs. </li>
</ul>

<p><strong>Import Service</strong></p>

<p>Full disclosure, my company offers a migration service to help folks migrate to Craft.  We use a combination of a private plugin, custom scripts, and manual processes when necessary.  We find, in most cases, many things about your data architecture can be improved when migrating to Craft.  So, while an import plugin can help with some heavy lifting, being able to make architecture decisions on how to import certain types of content outside of what a plugin would allow is useful for improving user experience and getting the most of of Craft.  For example, content that fits nicely in Singles and Matrix Fields don't always have equivalents in other CMSs, yet frequently other CMSs have content that fits these use cases.</p>

<ul>
<li><a href="http://thegreatmigration.net/" rel="nofollow noreferrer">The Great Migration</a></li>
</ul>

<p><strong>Do It Yourself</strong></p>

<p>If you want to roll up your sleeves, you can create a utility plugin or script for your own needs.  If you need to go this route, you probably want to import your data using Craft's Service Layer and the <code>save</code> methods for each of the individual Elements you are importing.</p>

<p>You can see some examples of this in the plugins available on GitHub above, or read up more on the service layer in the Craft docs.  A good place to start may be the <a href="http://buildwithcraft.com/docs/templating/entrymodel" rel="nofollow noreferrer">Entries Service</a>.</p>

<p>You will need to get your data into a format that matches the <a href="http://buildwithcraft.com/docs/apis/entriesservice#saveEntry" rel="nofollow noreferrer">EntryModel</a> and then you can pass that information to the <code>saveEntry</code> method:</p>

<pre><code>craft()-&gt;entries-&gt;saveEntry($entry)
</code></pre>

<p>That's a fairly simple explanation, but the gist of where to start. All of the other Elements are going to have similar Models and save methods you can use to import your data.</p>

CC BY-SA 3.0
2014-06-13T16:07:17.157Z
2017-05-06T16:45:08.780Z
2017-05-06T16:45:08.780Z
Ben Parizek
<p>How do I migrate my Wordpress project to Craft CMS?</p>

<p>What would be the best way?</p>

CC BY-SA 3.0
2014-06-13T12:09:59.570Z
Could you tell us more about your Wordpress project? What types of posts do you have, any content-specific plugins? -- There is always another way to do sth. in Craft, that's why 'the best way' will heavily depend on your project.
Victor
CC BY-SA 3.0
2014-06-13T12:36:47.667Z
I just asked because I wanted to help you with your problem, but a generic topic is awesome as well, and will surely help a few people ;)
Victor
<migration>
How do I migrate a Wordpress project to Craft CMS?
# How do I migrate a Wordpress project to Craft CMS?

(Asked by: username_0 on 2014-06-13)

How do I migrate my Wordpress project to Craft CMS?

What would be the best way?

**Tags:** migration
> **Comments:**
> **username_1**: Could you tell us more about your Wordpress project? What types of posts do you have, any content-specific plugins? -- There is always another way to do sth. in Craft, that's why 'the best way' will heavily depend on your project.  
> **username_1**: I just asked because I wanted to help you with your problem, but a generic topic is awesome as well, and will surely help a few people ;)  

---

## 4 answers

### Answer by username_6 on 2014-06-13. Score: 17 | Accepted answer

At this point in time, you have a few options: 
Import Plugins
As of this post, there are a few partial import plugins available and rumors that a few others might be on their way.

Sprout Import - Sprout Import supports over 40 data types such as Entries, Users, Assets, Products, Orders, Forms, Email, and Redirects; and more can be added as needed via plugin integrations.
Feed Me - Feed Me is a Craft plugin for super-simple importing of content, either once-off or at regular intervals. With support for XML, RSS, ATOM or JSON feeds, you'll be able to import your content as Entries, Categories, Craft Commerce Products (and variants), and more.
Import - Handles Entries and allows you to map them to fields in
your Entries Sections 
EE/Craft Import - While this plugin has EE
in it's title, it looks like it's framed more around XML imports in
general and promotes itself as being a starting point if you have
other custom import needs. 

Import Service
Full disclosure, my company offers a migration service to help folks migrate to Craft.  We use a combination of a private plugin, custom scripts, and manual processes when necessary.  We find, in most cases, many things about your data architecture can be improved when migrating to Craft.  So, while an import plugin can help with some heavy lifting, being able to make architecture decisions on how to import certain types of content outside of what a plugin would allow is useful for improving user experience and getting the most of of Craft.  For example, content that fits nicely in Singles and Matrix Fields don't always have equivalents in other CMSs, yet frequently other CMSs have content that fits these use cases.

The Great Migration

Do It Yourself
If you want to roll up your sleeves, you can create a utility plugin or script for your own needs.  If you need to go this route, you probably want to import your data using Craft's Service Layer and the save methods for each of the individual Elements you are importing.
You can see some examples of this in the plugins available on GitHub above, or read up more on the service layer in the Craft docs.  A good place to start may be the Entries Service.
You will need to get your data into a format that matches the EntryModel and then you can pass that information to the saveEntry method:
craft()->entries->saveEntry($entry)

That's a fairly simple explanation, but the gist of where to start. All of the other Elements are going to have similar Models and save methods you can use to import your data.


---

### Answer by username_2 on 2015-10-01. Score: 13

Here is how I did it on a recent project:

Create a temporary WP site to work in: I installed WP locally, imported the database, and downloaded the wp-content/uploads folder. You don't need the theme or any plugins (unless they affect the content output). In the Reading section of the WordPress settings, change "blog pages show at most" to a number higher than the number of posts in the system. You could also do this in a hidden template on the live site if you like to live on the edge. I was actually importing from a WordPress.com site, so I first had to export from that and then import into a self-hosted site.
Migrate comments to Disqus: Create a new site in Disqus and install the Disqus plugin in your local WP installation. Let it run its import process to move all your existing comments into their system. Now the comments are their responsibility, and you only have to worry about the posts.
Export the posts to a CSV: Paste the code below into the index.php file of WP's default twentyfifteen theme. Now when you visit the homepage of the temporary site, it will output a CSV file instead of HTML. Press cmd/alt-s to save it to a file. You may need to tweak the code a bit depending on your needs, but this should get you close. The interesting part is lines 20-23, where we apply the the_content filter (which replaces WP's short-tags), fix some character encoding issues, and replace image URLs with their corresponding URLs on the new site. I also set a "fullWidth" transformation on all the images, which I created in my Craft site to limit the images to the width of the page. See below for more on that. Save that resulting CSV file somewhere.


', ']]>', $content );
        $content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
        $content = preg_replace('#http://cmnh-blog.dev/wp-content/uploads/\d{4}/\d{2}/(.+?)\.(jpg|jpeg|png|gif)#', 'http://childrens-museum.s3-us-west-2.amazonaws.com/blog/_fullWidth/$1.$2', $content);
        $content = preg_replace('#https://childrensmuseumnh.files.wordpress.com/wp-content/uploads/\d{4}/\d{2}/(.+?)\.(jpg|jpeg|png|gif)#', 'http://childrens-museum.s3-us-west-2.amazonaws.com/blog/_fullWidth/$1.$2', $content);
        $cats = implode(', ', wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) ));
        $tags = implode(', ', wp_get_post_tags( $post->ID, array( 'fields' => 'names' ) ));

        $row = array(
            html_entity_decode(get_the_title(), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
            $post->post_name,
            get_the_date('c'),
            get_the_author_meta('user_login'),
            $cats,
            $tags,
            $content,
        );
        fputcsv($df, $row);

    endwhile;
endif;

fclose($df);
echo ob_get_clean();



Create user accounts: If you set up user accounts before importing the posts, the authorship will be maintained. Just make sure to use the same email address for each person as in the old site.
Import the content: I used Import for this, although FeedMe might actually work better, as it will create Categories for you on the fly. 
Reconnect the comments: If you are keeping the same URL structure, you can just use Disqus's Domain Migration Tool to update their records from the temporary WordPress site to your live domain. If you are changing the URL structure as well, you'll need to use URL Mapper and somehow generate a CSV of corresponding old and new URLs for each post. Now you can add the Disqus embed code to your post template and the comments should appear.
Generate image transforms: Remember how we set a transform on the images in the posts? Craft won't automatically generate those. So create the asset source and copy all the images in from your WP site. Now reindex the asset source in Craft and make sure you can see all the files in the Assets tab. Finally, create a new template with the following code. Open it in the browser and wait for all the images to appear. If you have more than 200 images, you will need to set the offset to 200 and run it again, and so on until all the transforms have been generated.


{% set images = craft.assets.source('blogImages').limit(500).offset(0) %}
{% for image in images %}
    
{% endfor %}


Check for broken styling: You will need to include WordPress's default classes in your new stylesheet, or you will lose image alignment and such. If there were any other markup patterns in the WP site that were generated by plugins, you will also need to accommodate those. If necessary, you can also add additional preg_replace lines to the export script to manipulate the markup as needed.

> **Comments:**
> **username_3**: I've updated index.php of my theme with the code to export a CSV, but when I visit the page in a browser, it's being printed out to the page and not saving a CSV. It's also not printing all the posts either, only about 10 of more than 100.  
> **username_2**: You can just cmd-S to save the CSV as a file. And yes, you will need to set the "posts per page" in your WordPress Reading settings to a number higher than the number of posts. I will edit my answer to include that.  
> **username_3**: Great, thanks, that works fine for saving the CSV. Now I'm having trouble importing the CSV. I'm not sure whether it's the way the CSV is formatted. Would you have a small sample of one you've used you could post somewhere for comparison?  

---

### Answer by username_4 on 2014-06-13. Score: 5

If you're just trying to migrate data, the most simple method would be to use a WordPress plugin to export your posts to a CSV and import it into Craft using this [Import Plugin by Bob Olde Hampsink](http://boboldehampsink.github.io/CraftImportPlugin/). This is just for posts. I'm not sure what you would do for pages, since we have a special section type for those.

A WordPress Import Plugin has not yet been created because many, if not most, Craft developers came from ExpressionEngine.


---

### Answer by username_5 on 2017-02-01. Score: 1

Its not a full-blown guide yet, but the [Feed Me Guide](https://sgroup.com.au/plugins/feedme/guides/migrating-from-wordpress) will get you off to a good start. That really deals with getting the data out of Wordpress. Handles Advanced Custom Fields, WooCommerce, Custom Taxonomies and Custom Post Types.

Once you've got out export file, you can following the [Importing Entries](https://sgroup.com.au/plugins/feedme/guides/importing-entries) guide for Feed Me.


---

