Hacking Magento: Creating an HTML5 Canvas Customizer on Magento - - PowerPoint PPT Presentation
Hacking Magento: Creating an HTML5 Canvas Customizer on Magento - - PowerPoint PPT Presentation
Hacking Magento: Creating an HTML5 Canvas Customizer on Magento Bundles Phillip Jackson @philwinkle Lead Magento Architect Something Digital NEW Hacking Magento Hacker: 1. who makes innovative customizations or combinations of
Hacking Magento:
Creating an HTML5 Canvas Customizer
- n Magento Bundles
Phillip Jackson
@philwinkle
Lead Magento Architect Something Digital
NEW
“Hacking” Magento
- 1. who makes innovative customizations or
combinations of computer equipment
- 2. who combines excellence, playfulness,
cleverness and exploration in performed activities
Hacker:
The Client
The Client
- Custom Printing
- Upscale Products
- Wedding, Bar/Bat Mitzvah, Holiday
- Seasonal Business
The Requirements
The Requirements: Feature List
RTL Language Drag and Drop Content Filtering Font Library SVG Motif Library Project Save Edit from Admin Edit from Cart Constrain Movement Blocking Zone Global Font Change Physical Elements Photo Upload SVG Clip Login AJAX RWD Scale Canvas Font Pick List Spot Colors CMYK Conversion PDF Output IE9 Support Realtime Price Estimate Tier Price by Element Skip Steps Global Color Change Special Characters Hebrew Text Panel Arrange Movement Undo / Redo Retina Support Tooltips / Walkthrough Event Wizard iPad Support
The Requirements: Feature List
RTL Language Drag and Drop Content Filtering Font Library SVG Motif Library Project Save Edit from Admin Edit from Cart Constrain Movement Blocking Zone Global Font Change Physical Elements Photo Upload SVG Clip Login AJAX RWD Scale Canvas Font Pick List Spot Colors CMYK Conversion PDF Output IE9 Support Realtime Price Estimate Tier Price by Element Skip Steps Global Color Change Special Characters Hebrew Text Panel Arrange Movement Undo / Redo Retina Support Tooltips / Walkthrough Event Wizard iPad Support
Why Bundles?
Why Bundles?
- Tier Pricing Support
- Flexibility Across Product Models
- Default Quantities and Selections
- Additive/Subtractive Pricing Model
Additive Pricing Model
Beautiful Product Feather Ribbon Add’l Color $0.75 $1.00 $0.35
$7.60
$5.50
Subtractive Pricing Model
Beautiful Product Feather Ribbon $0.75 $1.00
$3.40
$5.50 Layer $0.35
Why Bundles?
Why Bundles?
Bundle Simple Simple Simple Simple Related Related Related Related Related Related Related Related Related Related Related Related
Why Canvas?
Why Canvas?
- Library Quality
- Library Support
- Hardware Acceleration
- Render Time Benchmarks
- Export to PNG (previews)
HTML5 Canvas
SVG
Raphael vs Fabric.js
Raphael API Purpose Support Active Development Resources / Learning Community Fabric.js Good Charting Good Poor Poor Poor Great Canvas Great Excellent Great Great
Raphael
Fabric.js
Why Backbone?
Why Backbone
- Shared Knowledge
- Previous Experience
- Candidate Pool
- Tooling
- Ember, Angular were too new
The Build
Delegation
Phillip
The Build: Delagation
Jon Daniel
Anna
edit
bundles
pdf gen
frontend
pricing undo rtl api
clip
admin
logic
photos
layers
menus
events
Resources
The Build: Resources
Waterfall
The Build: Waterfall
- 2-week sprints
- Fixed cost
- Tight deployment window
Tech Stack
The Build: Tech Stack
The Code
The Code
- Prototype.js is not AMD compatible
- Prototype is necessary for bundle.js,
product.js, validation
- jQuery Promises
- Underscore.js gives us ES6 map, apply, FP
MV-Whatever
The Code: MV-Whatever
- Global Application for defining regions
- Models and views are obvious
- “Controllers” are basically logic centers
- We have 6 distinct controllers
- Single router for the app
The Code: MV-Whatever Application
var Customizer = new Marionette.Application();
- Customizer.on('start', function(options){
- Customizer.addRegions({
lightbox : LightBox, // can be a region object dialog : '#dialogContainer' // or it can be a dom node });
- });
- //-------------------------------
// FIRE UP YOUR ENGINES //------------------------------- Customizer.start();
The Code: MV-Whatever
A typical controller
var AdminController = Backbone.Marionette.Controller.extend({ initialize: function(){ //create new project model appRepository.project.set({ 'url' : window._adminSaveUrl, 'params' : window._adminUrlParams, 'adminMode' : true });
- //replace default saveProject action on the customizerController
customizerController.saveProject = function(){ appRepository.project.saveData(); } } });
- return new AdminController();
Dependency Management
The Code: Dependency Management
- Git submodules
- NPM / Node
- Require.js
The Code: Dependency Management
;define ([ 'app', 'jquery', 'backbone', 'collections/canvas/sides', 'collections/interface/envelope-styles', 'fabric', 'logic/fontcontroller' , 'models/apprepository', 'models/customizer-repository' ],function( Customizer, $, Backbone, stepsCollection, envStylesCollection, Fabric, fontController, appRepository, customizerRepository ){
Good
The Code: Dependency Management
;define (['app'],function(Customizer){
- var InvitationController = Backbone.Marionette.Controller.extend({
- getSides: {
require(['collections/canvas/sides'],function(sides){ //.. }); }, getStyles: { require(['collections/interface/envelope-styles'],function(styles){ //.. }); }
Better
Sensible Structure
The Code: Sensible Structure
📂 📂 📂 📂 📂
js/lib/customizer collections plugins models templates
📂 views 📂 logic
The Code: Sensible Structure
📂 📂 📂
js/lib/customizer/collections canvas cart
📂 interface
📅 designs.js 📅 sides.js
The Challenges
The Challenges
- Multi-bundles
- Tier pricing
- Async
- Responsive-ish
- No round-tripping
bundle.js
The Challenges: bundle.js
- ptions
The Challenges: bundle.js selections
The Challenges: bundle.js
var colorSelections = _.chain(bundle.config.options) .map(function(a) { if(a.title=='Ink Color Count'){ return _.values(a.selections); } }) .filter() .map(function(b) { var tmp = []; _.each(b,function(c){ if(c.name.charAt(0)==colorCount){ tmp.push(c); } }); //workaround because we can't return from the //`each` so we fetch it out of the array return tmp[0]; },context) .value();
The Challenges: bundle.js
Bundle Simple Group (fixed) Group (tier) Simple Simple Simple Simple