solving for complex ui designs
TRANSCRIPT
A FRONT-END PERSPECTIVE & APPROACH
RAMI ENBASHI . NRG-EDGE MAY 6 , 2015 . FOSTER CITY, CALIFORNIA
SOLVING FOR COMPLEX UI DESIGNS
About me
I am lazy
Work smart not hard
Work on fresh ideas not tedious tasks
Productive
Laziness
Prod
uctiv
ity
Good decision making
Decision Fatigue
A lazy team is a productive team
The machine
Automate my workflow
Magnolia
The story of Mr. X and the green bars
A lazy user is a happy user
A lazy developer is a productive developer
Magnolia Template Development
How do we get there?
UI Sandbox™
Background
UI-Focused, Content Managed,
Responsive Solutions
UI-Focused
Design first
Complex client-side functionality
Project Manager
Lead AnalystDesignerDev Lead
UI LeadMagnolia
Lead
UI Developer
UI Developer
Magnolia Developer
Magnolia Developer
Analyst/ Tester
Analyst/ Tester
Express
CSS JS HTML
The problem
The environment
Magnolia Dev
UI Dev
Magnolia Dev
UI Dev
The process
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Wireframes Color Palate Typography Style Guide
Interaction Guide High Fidelity Designs
(PSDs)
UX/Design
Mobile Strategy
Template Analysis
UI Development
UI Build / QA
UI-Magnolia Sync
Magnolia Development
Final Testing
Major/Minor Breakpoints Supported Devices
Grid System Definition Fluid/Fixed-width Layout
Responsive/Adaptive
01
02
03
04
05
06
07
08
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Content Managed Fields Templates
Areas Components Content Type
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Design Implementation Client-side Functionality
Front-end API Integration Functional Website
Template Engine
var$data$=${$
$$title:$'My$Buddies',$
$$friends:$[$
$$$$'Tyrion',$
$$$$'Arya',$
$$$$'Ygritte',$
$$$$'Drogo'$
$$]$
};
<h1>{{$title$}}</h1>$
<ul>$
{%$for$friend$in$friends$%}$
$$$$<li>{{$friend$}}</li>$
{%$endfor$%}$
</ul>
<h1>My$Buddies</h1>$
<ul>$
$$$$<li>Tyrion</li>$
$$$$<li>Arya</li>$
$$$$<li>Ygritte</li>$
$$$$<li>Drogo</li>$
</ul>
+ →
. ├── global │ ├── areas │ │ ├── footer.swig │ │ ├── htmlHeader.swig │ │ ├── logo.swig │ │ ├── mainArea.swig │ │ └── navigation.swig │ ├── components │ │ └── genericContent.swig │ └── macros │ └── calculator.swig ├── layouts │ ├── about.swig │ ├── generic.swig │ └── homepage.swig └── pages └── homepage ├── areas │ ├── callout.swig │ ├── features.swig │ ├── products.swig │ ├── welcome.swig │ └── whoWeAre.swig └── components └── featureItem.swig
<div$id="welcome">$$$<div$class="container">$$$$$<h3$$class="heading">Welcome$to$Launch</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<a$href="/login"$class=“login">Log$In</a>$$$</div>$</div>$
#welcome{$$$background:$url(../assets/images/welcomeYbg.jpg)$noYrepeat$50%$84%;$$$backgroundYsize:$cover;$$$width:$inherit;$}$
CSS
HTML
<div$id=“welcome"$style=“backgroundYimage:$url(../assets/images/welcomeYbg.jpg)”$>$$$<div$class="container">$$$$$<h3$$class="heading">Welcome$to$Launch</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<a$href="/login"$class=“login">Log$In</a>$$$</div>$</div>$
#welcome{$$$background:$noYrepeat$50%$84%;$$$backgroundYsize:$cover;$$$width:$inherit;$}$
CSS
HTML
Bower
Front-end Dependency Management
{$$$"name":$"magnoliaYdemo",$$$"version":$"1.3.0YSNAPSHOT",$$$"dependencies":${$$$$$"angular":$">=1.3.*",$$$$$"json3":$"~3.3.1",$$$$$"es5Yshim":$"~3.0.1",$$$$$"foundation":$"~5.4.3",$$$$$"angularYresource":$">=1.2.*",$$$$$"angularYcookies":$">=1.2.*",$$$$$"angularYsanitize":$">=1.2.*",$$$$$"fontYawesome":$">=4.1.0",$$$$$"lodash":$"~2.4.1",$$$$$"angularYuiYrouter":$"~0.2.10",$$$$$"ngYlodash":$"~0.0.2",$$$$$"cssYtoggleYswitch":$"~3.0.0",$$$$$"angularYplaceholderYtai":$"~1.0.1",$$$$$"angularYscroll":$"~0.6.4",$$$$$"angularjsYgeolocation":$"~0.1.1",$$$$$"mobileYdetect":$"hgoebl/mobileYdetect.js#~0.4.3"$$$},$$$"devDependencies":${$$$$$"angularYmocks":$">=1.2.*",$$$$$"angularYscenario":$">=1.2.*"$$$}$}$
bower.json
Grunt
Task Runner
Compiling
Injection
Minification
UnCSS
Watch / Live Reload
Testing
Deployment
module.exports$=$function(grunt)${$
$$grunt.initConfig({$$$$$jshint:${$$$$$$$files:$['Gruntfile.js',$'src/**/*.js',$$$$$$$$$$$'test/**/*.js'],$$$$$$$options:${$$$$$$$$$globals:${$$$$$$$$$$$jQuery:$true$$$$$$$$$}$$$$$$$}$$$$$},$$$$$watch:${$$$$$$$files:$['<%=$jshint.files$%>'],$$$$$$$tasks:$['jshint']$$$$$}$$$});$
$$grunt.loadNpmTasks('gruntYcontribYjshint');$$$grunt.loadNpmTasks('gruntYcontribYwatch');$
$$grunt.registerTask('default',$['jshint']);$
};$
{""""name":""magnolia-frontend",""""version":""1.0.1",""""dependencies":"{},""""devDependencies":"{""""""bower":""~1.3.3",""""""browserify":""~6.2.0",""""""grunt":""~0.4.2",""""""grunt-autoprefixer":""~1.0.1",""""""grunt-browserify":""~3.2.0",""""""grunt-contrib-concat":""~0.5.0",""""""grunt-contrib-cssmin":""~0.10.0",""""""grunt-contrib-htmlmin":""~0.3.0",""""""grunt-contrib-imagemin":""~0.9.1",""""""grunt-contrib-jshint":""~0.10.0",""""""grunt-contrib-less":""~0.12.0",""""""grunt-contrib-uglify":""~0.6.0",""""""grunt-contrib-watch":""~0.6.1",""""""grunt-injector":""~0.5.3",""""""grunt-karma":""~0.9.0",""""""grunt-swig-templates":""~0.1.2",""""""grunt-usemin":""2.1.1",""""""jshint-stylish":""~1.0.0",""""""karma":""~0.12.21",""""""karma-chrome-launcher":""^0.1.7",""""""karma-phantomjs-launcher":""~0.1.2",""""""kss":""~1.3.0",""""""lodash":""~2.4.1",""""""minifyify":""~5.0.0"""}"}"
Gruntfile.json package.json
Yeoman
App Scaffolding Tool
Knyle Style Sheets (KSS)
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Centralized CI Build Automated Tests Browser / Device
Compatibility Testing
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
A process to allow incremental UI changes
with minimal configuration or backend changes
{""""name":""magnolia-frontend",""""version":"“1.0.1-SNAPSHOT”,""""dependencies":"{},""""devDependencies":"{"""""...""}"}"
package.json
$$<groupId>com.project.frontend</groupId>$$$<artifactId>projectYmoduleYtheme</artifactId>$$$<version>1.0.1YSNAPSHOT</version>$$$<name>Project$Magnolia$Theme</name>$
pom.xml
<plugin>$$$<groupId>org.jasig.maven</groupId>$$$<artifactId>sassYmavenYplugin</artifactId>$</plugin>$
SASS
<plugin>$$$<groupId>pl.allegro</groupId>$$$<artifactId>gruntYmavenYplugin</artifactId>$</plugin>$
Grunt
http://addyosmani.com/blog/making-maven-grunt
<plugin>$$$<groupId>com.github.eirslett</groupId>$$$<artifactId>frontendYmavenYplugin</artifactId>$</plugin>$
NodeJS
<execution>$$$<id>npm$install</id>$</execution>$
<execution>$$$<id>bower$install</id>$</execution>$
<execution>$$$<id>grunt$build</id>$<configuration>$$$<arguments>build:magnolia</arguments>$</configuration>$
</execution>$
{$//$Environment$targets$
$$development:${$$$$$options:${$$$$$$$loginURL:$'http://localhost:9000/login'$$$$$$$herokuPath:$'[email protected]:devYproject.git',$$$$$$$endpoint:$'content/products.json',$$$$$$$googleMapsKey:$'AucmoT6cAyH9TeXeGGqsB8LIYoJhvs',$$$$$$$assetsPath:$'assets/images'$$$$$}$$$},$$$magnoliaBuild:${$$$$$options:${$$$$$$$loginURL:$'/login'$$$$$$$herokuPath:$'[email protected]:mgnlYproject.git',$$$$$$$endpoint:$'/magnoliaYinstance/.rest/products',$$$$$$$googleMapsKey:$'zciuv2aS1N04nujJw0_hZoP',$$$$$$$assetsPath:$'/.resources/projectYmoduleYtheme/assets/images'$$$$$}$$$}$}
Gruntfile.json
angular.module('app')$$$.factory('products',$function($http)${$$$$$return${$$$$$$$getProducts:$function(params)${$$$$$$$$$return$$http.get('content/products.json',${$params:$params$});$$$$$$$}$$$$$};$$$});$
products.service.js
angular.module('app')$$$.factory('products',$function($http)${$$$$$return${$$$$$$$getProducts:$function(params)${$$$$$$$$$return$$http.get(‘/magnoliaYinstance/.rest/products',${$params:$params$});$$$$$$$}$$$$$};$$$});$
angular.module('app')$$$.factory('products',$function($http,$ENV)${$$$$$return${$$$$$$$getProducts:$function(params)${$$$$$$$$$return$$http.get(ENV.endpoint,${$params:$params$});$$$$$$$}$$$$$};$$$});$
<div$id="welcome">$$$<div$class="container">$$$$$<h3$class=“heading”>{{content.headingText}}</h3>$$$$$<h4$class=“subheading”>{{content.subheadingText}}</h4>$$$</div>$</div>$
welcome.swig
<div$id="welcome">$$$<div$class="container">$$$$$<h3$class=“heading">${content.headingText}</h3>$$$$$<h4$class=“subheading">${content.subheadingText}</h4>$$$</div>$</div>$
welcome.ftl
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Template configuration
01 UX/Design
02 Mobile Strategy
03 Template Analysis
04 UI Development
05 UI Build / QA
06 UI-Magnolia Sync
07 Magnolia Development
08 Final Testing
Template Configuration
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Area Definiton
Dialog Definiton
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$$class=“heading">${content.headingText!}</h3>$$$$$<h4$class=“subheading">${content.subheadingText!}</h4>$$$$$<div$class="bodyText">$$$$$$$${cmsfn.decode(content).bodyText}$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Template Script
Pages App
Content
Configuration hell
YO DAWG, I HEARD YOU LIKE MAGNOLIA CONFIGURATION
SO I PUT CONFIGURATION IN YOUR CONFIGURATION SO YOU CAN
CONFIGURE YOUR CONFIGURATION.
Alternative configuration methods
http://kickstart.io
STK
A front-end solution
UI Sandbox™
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Area Definiton
Template Script
Dialog Definiton Content
Introduce conventions
Abstract out conventional configuration
Specify only unconventional configuration
Examples of Area Definition conventions
• Area name = HTML element ID in camelCase
• “who-we-are” => “whoWeAre”
• Area title = Area name in Title Case
• “whoWeAre” => “Who We Are”
Defaults
• type = “noComponent”
• renderType = “freemarker”
• enabled = true
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Autogenerate
Area$Definition$:{$name:$“whoWeAre",$title:$“Who$We$Are”,$enabled:$true,$type:$“noComponent”,$renderType:$“freemarker”,$templateScript:$“…”$
}$
Gain simplicity
Do we have to lose Flexibility?
Convention over Configuration (CoC)
“Convention over configuration is a software design paradigm which seeks to decrease the number of decisions that developers need to make, gaining simplicity, but not necessarily
losing flexibility.”
Conventions are subjective
Use Domain Specific Language (DSL) rules to
define conventions
Rules$:{$areaNameSuffix:$“Area”,$dialogNameSuffix:$“Dialog”,$defaultAreaType:$“noComponent”,$//$$or$“single”,$“list”$areaEnabledByDefault:$true,$defaultRenderType:$“freemarker”,$//$or$“jsp”$...$
}$
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Rules
Area$Definition$:{$name:$“whoWeAre",$title:$“Who$We$Are”,$enabled:$true,$type:$“noComponent”,$renderType:$“freemarker”,$templateScript:$“…”$
}$
Magnolia Config
+
→Autogenerate
Minimum Effective Dose of configuration (MED Config)
Implicit/Explicit Configuration
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
Rules
Area$Definition$:{$name:$“whoWeAre",$title:$“Who$We$Are”,$enabled:$true,$type:$“noComponent”,$renderType:$“freemarker”,$templateScript:$“…”$
}$
Magnolia Config
+
→Autogenerate
<div$id="whoYweYare"$areaYname="myArea">$$$<div$class="container">$$$$$<h3$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
{"areaName:"“myArea”"
}"
MED Config
Area$Definition$:{$name:$“myArea",$title:$“My$Area”,$enabled:$true,$type:$“noComponent”,$renderType:$“freemarker”,$templateScript:$“…”$
}$
Magnolia Config
+
→Autogenerate
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$class="heading">Who$We$Are</h3>$$$$$<h4$class="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>$
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$class=“heading"$field="heading">Who$We$Are</h3>$$$$$<h4$class=“subheading"$field="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class=“bodyText"$field="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>
{"content:"["{"name:"“heading”,""type:"“text”"
},"{"name:"“subheading”,""type:"“text”"
},"{"name:"“bodyText”,""type:"“richText”"
}"]"
}
MED Config
+
→
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$$class=“heading">$
${content.headingText!”Heading”}$</h3>$
$$$$<h4$class=“subheading">$${content.subheadingText!”Subheading”}$
</h4>$$$$$<div$class="bodyText">$$$$$$$${cmsfn.decode(content).bodyText!”bodytext”}$$$$$</div>$$$$$<a$href="/about"$class=“learnmore">$
Learn$More$</a>$
$$</div>$</div>
FTL Template
<div$id="whoYweYare">$$$<div$class="container">$$$$$<h3$class=“heading"$field="heading">Who$We$Are</h3>$$$$$<h4$class=“subheading"$field="subheading">We$are$a$Magnolia$CMS$Services$&$Integration$Company</h4>$$$$$<div$class=“bodyText"$field="bodyText">$$$$$$$<p>NRG$Edge$has$helped$organizations$implement$and$use$Magnolia$CMS$to$build$$$$$$$$$$and$improve$the$digital$experiences$they$provide$to$their$customers.</p>$$$$$</div>$$$$$<a$href="/about"$class="learnmore">Learn$More</a>$$$</div>$</div>
{"content:"["{"name:"“heading”,""type:"“text”"
},"{"name:"“subheading”,""type:"“text”"
},"{"name:"“bodyText”,""type:"“richText”"
}"]"
}
MED Config
+
→ Dialog/Content
What did we gain?
Demo time!
Right technology stack
Data binding
Source
Target
One-way data binding
Model
View
Two-way data binding
Template
ViewModel
Three-way data binding
UI Sandbox
DSL Rules
+MGNL Config
SlicingIn-memory NoSQL DB
NoCR
REST
MED Config
HTML
MGNL Config
Magnolia
JCR
Template
Model View
Is this for everyone?
What’s next?
Thank you