Magento & WordPress Multisite: a challenging marriage

Advertisement:

For the relaunch of a project’s website, we chose to use two CMSes: Magento for managing products and being able to actually sell products online and WordPress for good old content such as news around products and company, information about the products’ designers and other similar stuff. But we were also having “satellite sites” / microsites around specific products or brands that were managed in different content management systems on different servers. This made publishing content to those different websites challenging and confusing for the editors as well as maintaining the sites for me as developer.

So I decided that we should merge those microsites into one CMS with the goal to reducing friction and overhead-work for the editors and myself. Sticking to WordPress made the most sense to us, since it is very easy to handle once you get used to it. But using a simple single WordPress installation was not enough, since those multiple sites must be maintained seperately and their content should be managed seperately. Therefor only WordPress’ multisite feature could solve the problem of bringing all sites together and making life easier for our editors and developers.

Marrying Magento to a single WordPress-site was easy in the first place. But as it turned out, it is not that easy when Magento has to get married to a WordPress MultiSite.

The initial setup of Magento and WordPress (single site)

In the project’s initial installation, Magento was the main CMS (if you’d call it that) and resides in the root-folder of the website. WordPress was installed in a subfolder named cms within that Magento installation.

To make use of WordPress inside Magento, you’d simply have to add some code to Magento’s index.php:

1
2
$wp_load_file = $_SERVER['DOCUMENT_ROOT'] . '/cms/wp-load.php';
define('WP_USE_THEMES', false);

This initiates loading the wp-load.php from the WordPress installation’s subfolder and basically running WordPress in the background. With this little snippet, you could use literally any WordPress function in your Magento theme or templates. We did so and “produce” the website’s footer on every page with the get_footer()-function. This way, we only have to maintain the footer-area in a single CMS – WordPress.

To display Magento-content in WordPress, we are using the MWI Plugin which is fairly simple to integrate and use. With the help of this plugin, we are displaying the header / navigation bar on every page and within the whole WordPress site and are managing it as a Magento static CMS block.

Activating WordPress Multi-Site

Activation of the multi-site feature is actually not a really big deal. It is very well documented in the WordPress Codex.

With creating the network, I decided to go for the subdomain-case in favour of the subfolder-version. Keeping the original URL-structure and permalinks is very important nowadays, once the search index bots have crawled and indexed a website. I didn’t want to have to manage thousands of 404s or write a bunch of Rewrite Rule in the .htaccess, which I already had when relaunching the website earlier and moving it from TYPO3 to Magento/WordPress.

The problem with activating WordPress’ multi-site feature

After I initiated WP multi-site in the wp-config.php and set up the WordPress network through the backend, I tried acessing the site. But that didn’t work as expected. Trying to access the main site failed grandiously and returned an HTTP 500-error with an infinite redirection loop. Just accessing the WordPress part of the website went fine and withou any problems or errors, though.

Finding the error

It took a while for me to find out what was causing the redirection-loop and making the site basically inaccessible – except for the WordPress part. A quick guess led me to deactivate the loading of WordPress from Magento’s index.php and I found out that when Magento was not loading WordPress, it was working fine for itself, too. Except that it didn’t have a footer of course.

So i came to the idea, that it must have something to do with how the webserver handled the redirection, since the site got stuck in a “302 – Moved temporarily”-loop which i found out using Rex Swain’s HTTP Viewer. I’m using this tool for every HTTP-error debugging action as a starting point since it shows the real responses the webserver gives and does not cache them.

It told me, that the page had been temporarily moved (HTTP 302), but was missing a Location:-information on where it had moved. So I got an empty page when accessing the website.

So I tried changing redirection rules in .htaccess but didn’t get lucky. So I figured that .htaccess must be the wrong place for the error.

My second approach was finding the error somewhere in the WordPress configuration file. Since the wp-config.php is not really complex, I was quickly done at this place. There’s not much to do essentially wrong, so I could skip this and dig into the way WordPress was being loaded from Magento.

At first, I tried to load the configuration file directly, instead of using wp-load.php – since this is, what wp-load basically does. But it didn’t help either. Rex Swain’s HTTP Viewer still told me that the page had moved temporarily without its new location.

Eventually, I began looking into the wp-includes-folder and found some files beginning with ms-: ms-settings.php, ms-functions.php, ms-load.php and such. I correctly guessed that those files are actually used over WordPress’ default configuration files when Multi-site is active.

Inside the ms-settings.php I found a line that said

183
header( 'Location: ' . $destination );

So I thought: ok, let’s give it a try. I commented out that line, tested the site with Rex Swain’s viewer and voilà: The site returned HTTP status 200 (OK). But still without any content.

So I went up the whole file to understand in which case this statement is actually used. The condition that had to be met to process the redirection was

29
if ( !isset( $current_site ) || !isset( $current_blog ) ) {

Now I knew: Either the current site or the current blog that WordPress was supposed to use is not correctly defined.

Developing the solution to load WordPress multi site outside WordPress

I tried to define the current_blog and current_site variables before loading the wp-load.php – without success. I tried to set them as PHP-variables and defining the blog and site ID this way around, but that threw an error.

I switched back to the ms-settings.php and figured out that current_blog had to be defined as an object. But even that did not make the Magento site using WordPress multi-site installation run as it should. Well, actually, I hadn’t got any further yet.

## The final solution to load a WordPress mult-site installation outside WordPress and marry it to Magento
Eventually I skipped this approach and defined the whole current_site and current_blog as object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$wp_load_file = $_SERVER['DOCUMENT_ROOT'] . '/cms/wp-load.php';
define('WP_USE_THEMES', false);
 
/* Manually defining variables hard-coded style to
 * populate them outside of WP, which we are since
 * this file is Magento's "property".
 */
 
$current_site = new stdClass;
$current_blog = new stdClass;
 
$current_site->id = 1;
$current_site->domain = 'www.example.com';
$current_site->path = '/cms/';
 
$current_blog->blog_id = 1;
$current_blog->site_id = 1;
 
require_once $wp_load_file;

Taadaa! Works. Fine. And even the second blog I originally set up in WordPress’ multi site worked without any further complications.

Like this post? Share it!
Advertisement:

14 thoughts on “Magento & WordPress Multisite: a challenging marriage

      • Hi robst and sorry for my english… :-)

        I entered the code you suggested in the index.php file of Magento. How should I set the “wp url” and “wp home” for each of the networks wordpress site?
        Thank you for your support

        • Hey Sandro,
          first make sure, that there are some &’gt; in the code (as I saw now) that should simply be >‘s.
          Not sure what you mean by wp url and wp home. In my wp-config I have those settings:

          define('DOMAIN_CURRENT_SITE', '[the actual domain with no paths]');
          define('MULTISITE', true);
          define('SUBDOMAIN_INSTALL', true);
          define('SITE_ID_CURRENT_SITE', 1);
          define('BLOG_ID_CURRENT_SITE', 1);
          define('NOBLOGREDIRECT', '');
          define('COOKIE_DOMAIN', '' );
          define('ADMIN_COOKIE_PATH','/');

      • thi is my configuration…
        i have 2 store view with code ‘it’ and ‘en’ (in my local machine).
        i have two blog in my wp network.
        magento ‘it’ home has url “www.testshopping.com/it/” and magento ‘en’ home has url “www.testshopping.com/en/”.
        wp “it” blog has following settings:
        site_url = http://www.testshopping.com/wp
        home = http://www.testshopping.com/it/corporate

        wp “en” blog has following settings:
        site_url = http://www.testshopping.com/wp/en
        home = http://www.testshopping.com/en/corporate

        finally, at the end of index.php file of magento i have:

        $wp_load_file = $_SERVER[‘DOCUMENT_ROOT’] . ‘wp/wp-load.php’;
        define(‘WP_USE_THEMES’, false);

        $current_site = new stdClass;
        $current_blog = new stdClass;

        $current_site->id = 1;
        $current_site->domain = ‘www.testshopping.com’;
        $current_site->path = ‘/wp/’;

        $current_blog->blog_id = 1;
        $current_blog->site_id = 1;

        require_once $wp_load_file;

  1. I need to add WP functions to old osCommerce website to help bridge the transition from osC to WooCommerce.
    Searched for hours before I found this.
    Thank you for posting this!

  2. Hello! (and sorry for my english)
    I write here my variation of code because your intervention in this article was fundamental to solve my problem.
    I ask your opinion to check if my variation is correct.

    I do not use subdomains and, using your code, I noticed a small problem:

    I have two magento stores:
    https://www.mage-wp.com (italian local) e
    https://www.mage-wp.com/en/ (local english)

    and two wordpress blogs:
    https://www.mage-wp.com/corporate/ (italian local) e
    https://www.mage-wp.com/en/corporate/ (local english)

    If in the magento homepage, insert the wordpress function , the result was always ‘1’, even if I was on the English site.

    I managed to solve with this little variation.
    Do you think it’s correct?

    /* WP inclusion 	--------------------------------------------------------------*/
    $wp_load_file = $_SERVER['DOCUMENT_ROOT'] . '/corporate/wp-load.php';
    define('WP_USE_THEMES', false);
    $current_site = new stdClass;
    $current_blog = new stdClass;
    
    $current_site->id = 1;
    $current_site->domain = 'www.mage-wp.com';
    $current_site->path = '/corporate/';
    
    $current_blog_id = 1;
    if( strpos( $_SERVER['REQUEST_URI'], '/en/') !== false ){
    	$current_blog_id = 2;
    }
    $current_blog->blog_id = $current_blog_id;
    $current_blog->site_id = $current_blog_id;
     
    require_once $wp_load_file;
    if( $current_blog_id !== $current_site->id ){
    	switch_to_blog($current_blog_id);
    }
    /* end WP inclusion	------------------------------------------------------------- */
    

    Thank’s a lot!

    Sandro

    • Hi Sandro, thanks for asking. Your solution seems legit at a first glance. But I’m not sure, if a multisite-environment is a good solution for serving two languages. Did you ever think about using a multi-language plugin such as WPML? It has the benefit, that it kinda “connects” posts and pages between the languges which makes the workflow a little bit easier when content in both languages is very similar.

      • Hi Robst,
        to get the same result obtained with WPML, I use the Multisite Language Switcher plugin which ‘connects’ posts as WPML does.

        Thanks for your feedback

Leave a Reply to robst Cancel 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=""> <s> <strike> <strong>