Extending Magento With Backbone.js

Yousef Cisco | @yousefcisco

Backbone.js is a Javascript MVC library that gives structure to web applications by providing models, collections, views, routers and connects them to existing APIs.

  • A great platform to be working with.
  • Flexible, modular, has a ton of extendible functionality.
  • Holds a lot of opinions about application structure
  • Provides inconsistent APIs

onepage checkout

Block

/**
 * Payment method form html getter
 * @param Mage_Payment_Model_Method_Abstract $method
 */
public function getPaymentMethodFormHtml(
    Mage_Payment_Model_Method_Abstract $method)
{
    return $this->getChildHtml('payment.method.' .
        $method->getCode());
}
                    

onepage checkout

Controller

/**
 * Shipping method action
 */
public function shippingMethodAction()
{
    if ($this->_expireAjax()) {
        return;
    }
    $this->loadLayout(false);
    $this->renderLayout();
}
                    

Magento+Backbone.js

  • Moves some application logic to the browser
  • Utilises existing Magento functionality
  • Allows for a simpler backend implementation
  • Improves development workflows

Mini-Basket

  • Rendered client-side
  • Handles adding products to the basket
  • Small number of fast requests
  • Built on top of existing Magento functionality

mini-basket

Backbone Model

                        
Ampersand.MiniBasket.Model = Backbone.Model.extend({

    defaults: {
        items: new Ampersand.MiniBasket.Item.Collection(),
        subtotal: 0,
        grand_total: 0,
        qty:0,
        items_count:0
    },

    addItem: function(item) {
        this.get('items').create({
            product_id: item.product_id
        }, {
            data: {
                model: item,
                form_key: Mage.Cookies.get(Ampersand.DATA.MINI_BASKET_FORM_KEY_COOKIE_NAME),
                ajax_cart_config: Ampersand.MiniBasket.Config.getConfig()
            },
            success: this.onSync,
            error: this.onError,
            wait: true
        });
    }

    ...

});

                        
                    

mini-basket

Request headers:

                        
model[product_id]:90228
model[simple_product_id]:92057
model[super_attribute][185]:63
model[label]:Medium
model[id]:63
form_key:eWuwTu0J4HIVegaN
                        
                    

mini-basket

observer

                        
public function generateAddParams(Varien_Event_Observer $observer)
{
    $controllerAction = $observer->getEvent()
        ->getControllerAction();

    $model = $controllerAction->getRequest()
        ->getParam('model', null);

    if ($model) {
        foreach ($model as $_key => $_value) {
            $controllerAction->getRequest()
                ->setParam($_key, $_value);
        }
    }
}
                        
                    

mini-basket

JSON response

                        {
   "items":[
      {
         "item_id":"304",
         "product_id":"90228",
         "name":"Vintage Long Sleeve Tee",
         "url":"http:\/\/ampersandweb.co.uk\/-vintage-long-sleeve-tee",
         "qty":1,
         "price":75,
         "price_formatted":"\u00a375.00",
         "row_total":75,
         "row_total_formatted":"\u00a375.00",
         "message":"",
         "size_info":"Medium",
         "colour_description":"Cameo Blue",
         "last_added":1
      }
   ],
   "subtotal":75,
   "subtotal_formatted":"\u00a375.00",
   "subtotal_title":"Subtotal",
   "shipping":2.95,
   "shipping_formatted":"\u00a32.95",
   "shipping_title":"Shipping & Handling (Standard - DPD \u2013 Standard Standard \u2013 2 to 3 Days)",
   "tax":30,
   "tax_formatted":"\u00a330.00",
   "tax_title":"Tax",
   "giftcardaccount":0,
   "giftcardaccount_formatted":"\u00a30.00",
   "giftcardaccount_title":"Gift Cards",
   "grand_total":107.95,
   "grand_total_formatted":"\u00a3107.95",
   "grand_total_title":"Grand Total",
   "giftwrapping":null,
   "giftwrapping_formatted":"\u00a30.00",
   "giftwrapping_title":null,
   "qty":1,
   "items_count":1,
   "has_error":null,
   "tax_info":"All duties and taxes paid",
   "shipping_to":"United Kingdom"
}
                        
                    

Solving known
performance issues

  • Slow layout parsing and template rendering
  • Unmanageable number of cache entries


These issues are caused by:

  • Large number of blocks and templates
  • Personalised pages for each customer

Harvey Nichols
Shortlist

Improving the
cachability of pages

  • Rendering personalised content client-side
  • Requesting content only when necessary
  • Providing application data as JSON

Building a client-side
bundle product
configurator

Questions?

Yousef Cisco @yousefcisco

Get slides: http://amp.co/MageY