Integrate SilverStripe menu to display on Magento pages

Expose SilverStripe menu using RESTful Server

First we need to get SilverStripe to output a JSON representation of the pages in our site. I did this by creating a REST class. The idea is to have one place to put any functions for access over REST. That way you know where everything is, and can control security better.

/**
 * RESTful Server to expose certain SilverStripe data to Magento
 * e.g. menus, etc.
 *
 * @package default
 * @author Barry Keenan
 */
class REST extends DataObject {

        static $db = array(
        );

        static $api_access = true;

        // important - must explicity allow the actions we want to access over REST
        static $allowed_actions = array(
                'TopMenu'
        );

        function canEdit() { return true; }
        function canView() { return true; }
        function canCreate() { return true; }


        // return second teir navigation pages
        function TopMenu() {
                $base_url = "http://" . $_SERVER['SERVER_NAME'] . "/";
        
                $whereStatement = "ShowInMenus = 1";
                $pages = DataObject::get("Page", $whereStatement);
        
                $nav = array();
                foreach($pages as $page) {
                        $nav[] = array(
                                'menuTitle' => $page->MenuTitle,
                                'url' => $base_url . $page->URLSegment
                        );
                }
        
                echo json_encode($nav);
                die();
        }
}

You need to manually add a REST record to the database. And then you’ll be able to access it at URLs like this:

http://localhost/api/v1/REST/1/

You can see that I’m accessing my one and only REST object using the id 1. A great little tool for testing your RESTful URLs is HTTP Client. If you use HTTP CLient to POST an empty string to this address:

http://localhost/api/v1/REST/1/TopMenu

You should get the following (example) data back from SilverStripe:

[{"menuTitle":"home","url":"localhost\/home"},{"menuTitle":"store","url":"localhost\/store"},{"menuTitle":"about","url":"localhost\/about"},{"menuTitle":"faq","url":"localhost\/faq"},{"menuTitle":"contact","url":"localhost\/contact"}]

Write a Magento module to grab the SilverStripe data

So now we can get the data we need by simply posting to the above URL. Great :)

All we need to do is write a custom magento module that grabs this data. (I intend to write a guide that details how to do this fairly soon(ish) ;) )

I’ll be using Gen X Design’s excellent REST class to make my requests. I’m not completely sure if I’ve got the Magento concepts correct yet, but my ‘controller’ looks like this:

/**
* Display menu items from JSON source. In this case Silverstripe
*
* @codepool   Local
* @category   Craft
* @package    Craft_Silverstripe
* @module     Silverstripe
*/

require ('RestRequest.inc.php');

class Craft_Silverstripe_Block_Navigation extends Mage_Core_Block_Template {

        protected $base_url = 'http://localhost/api/v1/REST';

        public function menuItems() {

                $request_data = array();
                $request = new RestRequest($this->base_url . '/1/TopMenu', 'POST', $request_data);

                // Is auth required??
                // $request->setUsername ('user');
                // $request->setPassword ('pass');
                $request->execute();

                // this will be an array of stdClass Objects
                $items_json = json_decode($request->getResponseBody());

                // Mage::log($items_json);

                return $items_json;
        }

}

So we have our ‘controller’ We also need a ‘view’ to display our menu:

<ul id="nav_top">
<?php foreach($this->menuItems() as $page) { ?>
        <li><a href="<?php echo $page->url ?>"><?php echo $page->menuTitle ?></a></li>
<?php } ?>
</ul>

All you need to do now, is tell Magento about this block in your page.xml configuration using something like this:

<block type="craft_silverstripe/navigation" name="silverstripe.navigation" as="ssNav" template="silverstripe/navigation/view.phtml"/>

And then actually call the block, defined above, in your templates using this:

<?php echo $this->getChildHtml('ssNav') ?>

Hey presto! SilverStripe menu in Magento :)