Web Design Blog

How to Integrate (Import) WordPress Content into Magento Blocks

04.26.2009 10:10PM by Evan Johnson

This is the technique I use to integrate WordPress content into Magento. This can be useful for bringing in posts related to a product, or having recent blog posts on the Magento home page… whatever you can dream up. No modules, plugins or extensions are needed for this technique – just a good grasp of PHP and the Magento and WordPress theming/templating systems. There are probably many other ways to do this, but this is an easy way that I figured out which works well for my purposes so far.

First, the WordPress side of the process.

Step #1 is to create a wordpress page which will have the content we want to show in Magento. The trick is that we don’t want the WordPress header or footer – we just want the content. To do this we will create a new page template. In your WordPress theme directory, copy a file with a Loop in it (index.php or page.php are a good ones to start with) and rename the new file something like MagentoContent.php. Edit this new file, and place at the top something like:

<?php
/*
Template Name: MagentoContent
*/
?>

This declares MagentoContent.php as a page template file. Then remove the function calls that pull in the Header, Footer and Sidebar. They usually look like this:

<?php get_header(); ?>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

And finally customize the Loop so it retrieves just the content you want. For instance, if you want to get the three most recent posts tagged “Magento” and show the title and excerpt it would look something like this:

<?php query_posts('tag=Magento&limit=3'); ?>
<?php if (have_posts()) : ?>
	<?php while (have_posts()) : the_post(); ?>
		<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
			<?php the_title(); ?>
		</a>
		<p><?php the_excerpt(); ?></p>
		<p><a href="<?php the_permalink(); ?>">Read more...</a></p>
	<?php endwhile; ?>
<?php else : ?>
	<p>Sorry no content found.</p>
<?php endif; ?>

Do whatever you want here though. Get to know your way around query_posts and go to town.

The final step on the WordPress side is to login to the backend and create a Page. Select the MagentoContent page template we created and Publish the page. If you used a custom post query it doesn’t matter what it’s called or what the content is. (If you actually want to bring the page’s content in to Magento, instead of the custom query, then it does of course.) Make a note of the URL of this page. If you have nice Permalinks set up and called the page Mage_content it will probably be something like this: http://example.com/wordpress/Mage_content. Visit the URL to make sure it’s returning the content you want. It will be an ugly page without the Header and Footer, but the content is what’s important. When this content is in Magento the Magento stylesheets can be used to style it.

Now let’s do the Magento side of things.

Create a new Magento template file. For this example, we’ll create one called wordpress_block.phtml and put it in the /cms folder of our theme directory. The file will just contain a short snippit of PHP code that uses the CURL library to get the contents of the WordPress page we just created (You can do this other ways, but Magneto already requires the CURL library so we know it’s at our disposal).

Technically code like this should be in a Controller function in a custom Magento extension, but it’s way faster to just throw it in the .phtml file. Here’s the code, using the WordPress page URL from our example:

<?php 
$content = '';
$url = "http://example.com/wordpress/Mage_content";
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_HEADER, 0);
ob_start();
curl_exec ($ch);
curl_close ($ch);
$content = ob_get_contents();
ob_end_clean();
echo $content; 
?>

Now that we have our block, just add it to a Layout file in your Magento theme (or to the Custom Layout options on an individual CMS or Category page):

<block type="core/template" name="wordpress_block" template="cms/wordpress_block.phtml" />

And voila – we are now pulling WordPress content into Magento. It is probably a good idea to install a wordpress caching plugin like WP Super Cache to speed up requests for Mage_content. In fact, the proper way to do this would be to also create a Magento module which caches it… but that’s beyond the scope of this little tutorial. This is a barebones proof of concept which can be adapted to specific needs.

Happy coding!

Comment

Gravatar Image
On May 21, 09:57 AM, (Link)
Jimmy said:

Where do you put the phtml file? I end up getting this:

Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 301: parser error : error parsing attribute name in /var/www/vhosts/example.com/store/httpdocs/app/code/core/Mage/Core/ Model/Layout/Update.php on line 235
Trace: #0 [internal function]: mageCoreErrorHandler(2, ‘simplexml_load_…’, ‘/var/www/vhosts…’, 235, Array) #1 /var/www/vhosts/example.com/httpdocs/app/code/core/Mage/ Core/Model/Layout/Update.php(235): simplexml_load_string(’

Gravatar Image
On Jun 2, 12:17 AM, (Link)
Evan Johnson said:

I put the phtml file in:
app/design/frontend/default/my_theme/layout/cms/wordpress_block.phtml.

You can put it other places, just make sure those places are in the active theme (“my_theme”) or the default theme, and make sure the path in the Layout XML matches.

I’m not sure what’s causing your error, but Layout/Update.php has to do with which layout template (i.e. 2columns-left.phtml) the Magento page is using (and what the title is, etc). Perhaps when you added the <block> tag to page.xml (or cusomter.xml, etc) you accidentally changed something else in the Layout XML which broke things?

Test the wordpress_block without calling curl (just echo “block test” or something) to see if the block is working.

Gravatar Image
On Jun 23, 04:43 PM, (Link)
Nick Johnson said:

Evan,

The problem described by the the previous commenter is here:

<block type=“core/template” name=“wordpress_block” template=“cms/wordpress_block.phtml” /”>

should be:

<block type=“core/template” name=“wordpress_block” template=“cms/wordpress_block.phtml” />

You’ve got extra quotes.

In other news, how’s it going?

Gravatar Image
On Jun 24, 09:18 AM, (Link)
Evan Johnson said:

Indeed I did have extra quotes snuck in there on the end. Thanks for the pointing that out! It has been fixed in the main article now.

In other news, it’s going well! Is the Montana Gift Corral on Magento your handy work then? :)

Gravatar Image
On Jul 22, 10:09 AM, (Link)
matt said:

thanks for this method! however, nothing is showing up on my page not even echo ‘test’ —

on the magento end, i inserted <block> code in custom layout xml on a cms page (only need it for one page)—do i also have to insert

{{block type=“core/template” block_id=“wordpress_block”}}

code in the general content area?

Gravatar Image
On Jul 22, 09:53 PM, (Link)
Evan Johnson said:

@matt

Without looking into it too closely, I wonder if you have the right attributes for the Block?

In addition to the “type” attribute you need the set the “template” attribute to the .phtml file you created. In my example it is template=“cms/wordpress_block.phtml”.

Also, I think the attribute “block_id” you have in your comment should be “name”.

Once you have the correct attributes, you should be able to include a Block either via the {{block}} tag in the main content OR with custom Layout XML (using the custom Layout XML is more flexible, letting you add blocks to the sidebars and such).

Gravatar Image
On Aug 12, 11:15 AM, (Link)
Michael said:

Thank you for a concise & clear tutorial!

First a couple notes, then a question…

NOTES:
It probably does without saying for most coders, but it might be helpful for others to note that…
1) Using
<block type=“core/template” name=“wordpress_block” template=“cms/wordpress_block.phtml” />
within a CMS page’s “Layout Update XML”, requires something like an opening
“<reference name=“content”>” and closing
“</reference>” for it to work (and be properly called by the page).

2) The PHP code supplied for the “wordpress_block.phtml” file requires an opening “<?php” and closing “?>” to properly work (otherwise it just pastes the code into the page).

QUESTION:
If I wanted to use this method for ALL of my Magento site’s CMS pages (so that they can be controlled by WordPress’s superior admin interface), is there a way to make a generic version of the “wordpress_block.phtml” file?

As it stands, the version in this example calls the specific URL of a single WordPress page (http://example.com/wordpress/Mage_content); but I would want something that can call a large number of pages.

Or, must I create a separate version of a “wordpress_block.phtml”-like file for each & every CMS page?

Thanks again!

Gravatar Image
On Aug 12, 11:26 PM, (Link)
Evan Johnson said:

@Michael

Thanks for pointing out the “notes”, I did add <?php tags to help make things a little more clear.

As for your question, yes I think you could do this. It would just a take some clever variable passing via the urls…

If all of your WordPress page templates are stripped of their Headers and Footers, then you don’t need to call a specific page like “http://example.com/wordpress/Mage_content”. You could just ask for ANY Wordpress page from your Magento block – “wordpress/about”, “wordpress/somecategory”, etc.

The trick then, in order to save yourself having to create a bunch of different blocks in Magento, would be to build the Wordpress URL dynamically in the Magento block. Maybe you could use PHP’s $_SERVER[‘REQUEST_URI’] to make the block on the “http://example.com/somepage/” Magento page request “http://example.com/wordpress/somepage”. See where I am going with this? It would just take a little string parsing, and you would have to make sure the Magento and Wordpress slugs matched.

If you want to override ALL Magento CMS content another approach is detailed here: http://www.magentocommerce.com/blog/tutorial-integrating-3rd-party-cms-content-within-magento/
The idea is if Magento can’t find a URL, instead of returning the 404 page it looks to see if there is a Wordpress page of the same name and displays it if there is. Cool, but it has it’s challenges as well.

Good luck!

Gravatar Image
On Nov 6, 02:22 PM, (Link)
Daniel Porter said:

Hello, this solution looks to be exactly what i am looking for.
I have everything set up exactly how the tutorial instructed.

The wp test page works fine when i test the url.

the code i inserted to the "homepage" content area is
{{block type="core/template" name="wordpress_block" template="cms/wordpress_block.phtml"}}

i also tried to put it in the content update xml with reference tags and such, to no avail….

in fact i tried using it on a test cms page as well, not the homepage

i have the wordpress_block.phtml file in correct location.

im using wordpress 2.8.4, and magento 1.3.2.3

its seems like such a simple solution, and i cant understand what i am missing,

please any help would be soo appreciated.
Thanks

Gravatar Image
On Nov 17, 11:55 PM, (Link)
Evan Johnson said:

@Daniel

Hmmm… well, the one suggestion that I can think of off the top of my head is that there have been some problems with using "_" underscores in block names. Try using a block name without underscores ("wordpress-block" instead of "wordpress_block") and see how it works. Let me know if that fixes it, and I’ll be sure to change my example code that no one else runs in to this problem!

  Subscribe to article comments