Solving for complex UI designs

Post on 09-Aug-2015

617 views 2 download

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:$'git@heroku.com:devYproject.git',$$$$$$$endpoint:$'content/products.json',$$$$$$$googleMapsKey:$'AucmoT6cAyH9TeXeGGqsB8LIYoJhvs',$$$$$$$assetsPath:$'assets/images'$$$$$}$$$},$$$magnoliaBuild:${$$$$$options:${$$$$$$$loginURL:$'/login'$$$$$$$herokuPath:$'git@heroku.com: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?

rami.enbashi@nrg-edge.com

Thank you