Responsive Layouts With Stylus Jeet And Rupture

Develop for mobile first is a common theme you hear today. I use three libraries for preprocessing css to help with this process. They make it easy to get a responsive site running fairly quick.

  1. Stylus - CSS pre-processor.
  2. Jeet - Flexible ratio grid system for stylus.
  3. Rupture - Simple media queries in stylus.

Below is a sample design I’ll be working with. There is a sidebar and a content area. I’ve decided to make a breakpoint at 600 pixels. Once the browser screen size is below 600 pixels the layout will change.

alt text

This is how the screen will display once the size is below 600 pixels. I’ve stacked the sidebar and content area. I also display the links horizontally instead of vertically.

alt text

I’ll use the following stylus code to accomplish the above:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@import 'jeet'
#root
center(960px)
.sidebar
col(1/3)
background-color: #FFFFCC
ul
list-style: none
li
display: none
margin: 0 0 10px 0
+below(600px)
stack()
ul
center(200px)
li
display: inline
margin: 0 15px 0 0
.main
col(2/3)
background-color: #CCCCCC
+below(600px)
stack()

To summarize what I’m doing:

  • Center the document within 960 pixels.
  • Set the .sidebar element to take up 1/3 of the screen size.
  • Each .sidebar > ul > li will be displayed vertically and have a bottom margin of 15 pixels.
  • Set the .main element to take up 2/3 of the screen size.

When the screen size is below 600 pixles:

  • Stack the .sidebar and .main elements vertically.
  • Center the .sidebar > ul within 200 pixels.
  • Each .sidebar > ul > li will be displayed horizontally and have a right margin of 15 pixels.

For under 30 lines of code I accomplished a lot and set a good foundation for a responsive design. I’ll need to create a build step for the above code to be processed into css. That’s pretty easy too:

1
$ stylus -u jeet -u rupture css/*.styl --out static/bundle.css

That one liner takes the stylus file and creates a css file, bundle.css, in the directory static. I can then include the bundle.css in my html.

I created a github repo, responsive-layout for this example.

Questions? Comments? Tweet me @schempy or email schempysays@gmail.com

Async Tasks With ES6 Generators

ES6 generators seem to be a very good fit for handling asynchronous actions. I’ve been using a library, generator-runner, which uses ES6 generators for running async tasks. To use the library you create a runner that takes two parameters:

  1. A generator function. Within this function you yield to a async task. The async task is invoked with a callback to continue the generator (calling next). The callback returns the value for the yield expression. The runner then takes the value for yield expression and returns it.
  2. A callback to handle the return of the generator. The return value from the previous step is handled here.

The syntax for the above is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var task = require('generator-runner');
// Define the runner.
task(
function* () {
// Yield to some async task and set the value for async_result.
let async_result = yield function (next) {
// Some async task goes here
return next(null, 'result'); // Return if success OR
return next(err, undefined); // Return error
};
// Return the value from the async task.
return async_result;
},
// Callback to handle the return from generator.
function (err, ret) {
if (err) {} else {}
}
);

As an example I want to get the contents of a JSON file from a http request and display the results. The generator function will make the http request using hyperquest. The result from the http request is a readable stream. I’ll pipe the readable stream into concat-stream which fires a callback with all the data from our readable stream. Then I’ll call the callback to continue the generator (calling next) with the results from the http request.

Here’s the example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
var task = require('generator-runner');
var hyperquest = require('hyperquest');
var concat = require('concat-stream');
// Set URL that we want to get the contents.
let url = 'https://iojs.org/dist/index.json';
// Define our runner.
task(
function* () {
// use hyperquest to get the contents of the URL.
let stream = hyperquest(url);
// Yield to async action.
let async_result = yield function (next) {
// Pipe the readable stream, from hyperquest, into
// concat-stream and call the continuation callback
// with the results from concat-stream.
stream.pipe(concat(
function (body) {
next(null, body.toString());
}
))
// Error! Call continuation callback with error.
.on('error', function (err) {
next(err, undefined);
});
};
// Return value from async task.
return async_result;
},
// Callback to handle the return from generator.
function (err, ret) {
if (err) {
console.error(err);
} else {
console.log(ret);
}
});

I created a github repo, async-tasks-with-es6-generators for this example.
To run the example do the following:

1
2
3
$ npm install
$ npm run prepublish
$ npm start

Note:
I use babel, turns ES6 code into ES5, in the example files.

Questions? Comments? Tweet me @schempy or email schempysays@gmail.com

Streaming File Uploads With Node.js

I’ve been experimenting with Node.js to build a http server for handling POST requests. Particularly for uploading files. I would send a multipart-form/data POST request containing one or more files. The route handler would parse and stream any file to a destination. That destination could be a directory on the server or a storage service like Amazon S3.

I used routes for handling routing and busboy for parsing HTML form data. Busyboy is a perfect module for this application. It emits a file event for incoming files and a field event for each non-file field. If a file is found Busboy will emit a data event when streaming and an end event when the streaming is complete.

Here’s an example of the http server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
var http = require('http');
var router = require('routes')();
var Busboy = require('busboy');
var port = 5000;
// Define our route for uploading files
router.addRoute('/images', function (req, res, params) {
if (req.method === 'POST') {
// Create an Busyboy instance passing the HTTP Request headers.
var busboy = new Busboy({ headers: req.headers });
// Listen for event when Busboy finds a file to stream.
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
// We are streaming! Handle chunks
file.on('data', function (data) {
// Here we can act on the data chunks streamed.
});
// Completed streaming the file.
file.on('end', function () {
console.log('Finished with ' + fieldname);
});
});
// Listen for event when Busboy finds a non-file field.
busboy.on('field', function (fieldname, val) {
// Do something with non-file field.
});
// Listen for event when Busboy is finished parsing the form.
busboy.on('finish', function () {
res.statusCode = 200;
res.end();
});
// Pipe the HTTP Request into Busboy.
req.pipe(busboy);
}
});
var server = http.createServer(function (req, res) {
// Check if the HTTP Request URL matches on of our routes.
var match = router.match(req.url);
// We have a match!
if (match) match.fn(req, res, match.params);
});
server.listen(port, function () {
console.log('Listening on port ' + port);
});

This was a fun experiment. Handling multipart/form-data was pretty easy and the ability to stream file uploads is awesome!

I created a gist for this example stream-file-uploads-nodejs.js.

Questions? Comments? Tweet me @schempy or email schempysays@gmail.com

Where To Have API Calls In React Flux

Working with React/Flux the last three months I couldn’t decide where to make asynchronous calls. Should they be made in the component, store or action creators? I chose the action creators since dispatching of all actions come from them. A module could abstract the actual asynchronous call and return a promise. The promise would resolve with the result of the call or be rejected if there was an error.

Here’s an example of the module to make the asynchronous call. I used superagent to make the request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Api = {
get: function (url) {
return new Promise(function (resolve, reject) {
request
.get(url)
.end(function (res) {
if (res.status === 404) {
reject();
} else {
resolve(JSON.parse(res.text));
}
});
});
}
};

The action creator would use this module. When the promise is returned dispatch an action containing the result.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Api = require('./Api');
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
// Define the ActionCreator.
var ActionCreator = {
getCategories: function () {
Api
.get('/api/categories')
.then(function (categories) {
// Dispatch an action containing the categories.
Dispatcher.handleViewAction({
actionType: ActionConstants.RECEIVE_CATEGORIES,
categories: categories
});
});
};
};

The store would register with the dispatcher and provide a callback to handle the response from the action. It would also emit a change event so components would be notified that values have changed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
var Dispatcher = require('./Dispatcher');
var ActionConstants = require('./ActionConstants');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');
var CHANGE_EVENT = 'change';
var _categories = [];
function setCategories (categories) {
_categories = categories;
}
// Define the Store.
var Store = assign({}, EventEmitter.prototype, {
emitChange: function () {
this.emit(CHANGE_EVENT);
},
addChangeListener: function (callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getCategories: function () {
return _categories;
}
});
// Store registers with dispatcher to handle actions.
Store.dispatchToken = Dispatcher.register(function (payload) {
var action = payload.action;
switch (action.actionType) {
case ActionConstants.RECEIVE_CATEGORIES:
// Callback to handle the response from the action.
setCategories();
break;
default:
return true;
break;
}
Store.emitChange();
return true;
});

Finally our components would use the store to register change listeners and the action creator for getting our categories!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
var Store = require('./Store');
var ActionCreator = require('./ActionCreator');
// Define the Category component.
var Category = React.createClass({
getInitialState: function () {
return {
categories: []
};
},
componentWillMount: function () {
Store.addChangeListener(this._onChange);
},
// Use the ActionCreator to get the categories.
componentDidMount: function () {
ActionCreator.getCategories();
},
componentWillUnmount: function () {
Store.removeChangeListener(this._onChange);
},
/**
* Update the state of categories for this component.
* This will get called when our store handles the response
* from the action.
*/
_onChange: function () {
this.setState({
categories: Store.getCategories()
});
},
// Display a drop-down containg the categories.
render: function () {
var categories;
if (this.state.categories) {
categories = this.state.categories.map(function (category) {
return <option key={ category.id }
value={ category.name }>
{ category.name }</option>;
});
}
return (
<div>
<select name="category">
<option value="">Select a Category</option>
{ categories }
</select>
</div>
);
}
});

final thoughts

The result from an asynchronous call should create an action. This keeps the data flowing through the application the flux way (Actions -> Dispatcher -> Stores -> Views).

One issue having the category component make a Api call once it’s mounted is it will be rendered twice. Having components get their data from props is better but sometimes the data has to be from an external service.

Check out the repo on github: react-flux-api-calls

Questions? Comments? Tweet me @schempy or email schempysays@gmail.com

React Flux and Routing For Seo

Single page web applications are awesome. Recently I used React/Flux to build a simple application to test if I can get SEO working without being a real pain. The application would display products based on a category. The user would select a category from a drop-down. Once a category has been selected a list of products in that category would display.

I wanted to have a client-side router. I chose react-router. Selecting a category would push a url to the browser history. The user would be able to refresh the browser with the new url and have the contents of the page be SEO friendly.

the challenge

On the server-side I needed the following:

  1. Initialize the React application.
  2. Set the state for the React components.
  3. Render the React components to html.
  4. Return the page that will be SEO friendly. Passing the initial state of the components.

On the client-side I needed the following:

  1. Initialize the React application.
  2. Set the state for the React components using the initial state passed from the server.
  3. Render the React components. If the components contain the same initial state from the server, React is smart enough to know not to re-render the components.

The initial state passed from the server would be JSON stored in a javascript variable.

1
2
3
<script type="text/javascript">
window.App={"products:[{"id": 1, "name":"Led Zeppelin"},{"id": 2, "name":"Bob Marley"}]};
</script>

Read More