YUIConf2013: Introducing The "Modown" Project

Preview:

DESCRIPTION

The Mojito team have been working very hard on a new project under the YUI umbrella with codename "Modown", and we want to tell you more about it. Building on the success of the YUI Application Framework (YAF), plus the things we learned while creating Mojito, we decided to go back to our roots by creating a set of modular and versatile building blocks rather than trying to prescribe how to write single-page applications. In this presentation, we are going to cover the motivations, the current state of the project, how you can start using it, and how to help!

Citation preview

#yuiconf#modown@caridy

the web platform

“modown”

motivations

web applications becomingsingle-page applications

YAF success

mojito constraints

modown components

mojito-next(yui, search)

hermes(flickr)

assembler(touchdown)

Mojito

EmberJS

AngularJSRendr

BackboneMeteor

DerbyJS

YAF

React

single-page applications

users can switch betweendifferent states in no time

... and doing so without breakingany of the core features of the web

(history, url, openness, seo)

back to our roots

building blocks ratherthan prescriptions

libraries over frameworks

development on the open

goals

building blocks forSPA written in nodejs

extending express

rendering initial state on the server,then let the browser takes over

today

13 modules in NPM

https://npmjs.org/search?q=modown

Locator

locator-dust

locator-handlebars

locator-lang

locator-microlocator-

yui

expressexpress-

map

express-state

express-combo

express-yuiexpress-

annotation

express-view

modown components

express-slash

2 major customers in production(flickr and media)

all major changes in YAFare already in place

https://github.com/yui/yui3/blob/master/src/app/HISTORY.md

no docs, only component leveldocs and examples in github

examples

express-yuifor yui core modules

var express = require('express'), app = express(); 

app.get('/', function (req, res, next) { // `res.locals` holds all data // available on the template});

app.listen(3000);

var express = require('express'), expyui = require('express-yui'), app = express(); expyui.extend(app);

app.get('/', function (req, res, next) { // `res.locals` holds all data // available on the template});

app.listen(3000);

var express = require('express'), expyui = require('express-yui'), app = express(); expyui.extend(app);

app.use(expyui.expose());

app.get('/', function (req, res, next) { // `res.locals.state.toString()` will be // available on the template as a javascript blob});

app.listen(3000);

var express = require('express'), expyui = require('express-yui'), app = express(); expyui.extend(app);

app.yui.setCoreFromAppOrigin();

app.use(expyui.expose());

app.get('/', function (req, res, next) { // `res.locals.state.toString()` will be // available on the template as a javascript blob});

app.listen(3000);

var express = require('express'), expyui = require('express-yui'), app = express(); expyui.extend(app);

app.yui.setCoreFromAppOrigin();

app.use(expyui.expose());

app.yui.applyConfig({ fetchCSS: false });

app.get('/', function (req, res, next) { // `res.locals.state.toString()` will be // available on the template as a javascript blob});

app.listen(3000);

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" /> <title>usage of `express-yui`</title>

<script>{{{state}}}</script> // if using handlebars, or <script><%== state %></script> // if using micro, or <script>{state|s}</script> // if using dust

</head><body> <p>non-blocking way to inject yui seed files</p></body></html>

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" /> <title>usage of `express-yui`</title> <script>{{{state}}}</script> <script> app.yui.ready(function (err) { // `YUI().use()` and `app.yui.use()` are available }); </script>

</head><body> <p>non-blocking way to inject yui seed files</p></body></html>

express-yuifor custom yui modules

var express = require('express'), expyui = require('express-yui'), app = express(); 

expyui.extend(app);app.use(expyui.expose());

app.get('/item/:id', function (req, res, next) {

});

app.listen(3000);

var express = require('express'), expyui = require('express-yui'), app = express(); 

expyui.extend(app);app.use(expyui.expose());

app.get('/item/:id', function (req, res, next) {

});

app.yui.ready(function (err) { app.listen(3000);});

var express = require('express'), expyui = require('express-yui'), app = express(); 

expyui.extend(app);app.use(expyui.expose());

app.get('/item/:id', function (req, res, next) { app.yui.use('model-foo', function (Y) { var model = new Y.ModelFoo();

});});

app.yui.ready(function (err) { app.listen(3000);});

var express = require('express'), expyui = require('express-yui'), app = express(); 

expyui.extend(app);app.use(expyui.expose());

app.get('/item/:id', function (req, res, next) { app.yui.use('model-foo', function (Y) { var model = new Y.ModelFoo(); model.load(req.params.id, function (err) { res.render('view-name', model.toJSON()); }); });});

app.yui.ready(function (err) { app.listen(3000);});

var express = require('express'), expyui = require('express-yui'), app = express(); 

expyui.extend(app);app.use(expyui.expose());

app.get('/item/:id', function (req, res, next) { app.yui.use('model-foo', function (Y) { var model = new Y.ModelFoo(); model.load(req.params.id, function (err) { res.expose(model,'fooData'); //window.app.fooData res.render('view-name', model.toJSON()); }); });});

app.yui.ready(function (err) { app.listen(3000);});

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" /> <title>usage of `express-yui` and `locator-yui`</title> <script>{{{state}}}</script> <script> app.yui.ready(function (err) { app.yui.use('model-foo', function (Y) {

}); }); </script>

</head><body> <p>non-blocking way to inject yui seed files</p></body></html>

<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" /> <title>usage of `express-yui` and `locator-yui`</title> <script>{{{state}}}</script> <script> app.yui.ready(function (err) { app.yui.use('model-foo', function (Y) { var model = new Y.ModelFoo(app.fooData); }); }); </script>

</head><body> <p>non-blocking way to inject yui seed files</p></body></html>

filesystem abstractionwith locator

locator gives semantic meaningto files on the filesystem

filesystem analysis to understandthe capabilities of the app

on the making...

Intl

composition

ES6 modules

UI data bindings

modownization of YUI

some final notes

modown is not a framework

modown is not a product

modown is just a principle

Thanks@caridy

Recommended