Skip to content

Instantly share code, notes, and snippets.

@jkrems
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkrems/14cfa172918ef4832669 to your computer and use it in GitHub Desktop.
Save jkrems/14cfa172918ef4832669 to your computer and use it in GitHub Desktop.
Example of responding with an html page / fragment in quinn
/**
* @jsx React.DOM
*/
'use strict';
import {resolve} from 'bluebird';
import React from 'react';
import {getParam} from 'quinn'; // actually should be 'quinn-router'
import respond from 'quinn-respond';
import {BufferBody} from 'quinn-respond';
function loadPost(postId) {
return resolve({
title: '10 reasons to use quinn that will blow your mind',
postId: postId
});
}
var PostView = React.createClass({
render: function() {
var post = this.props.model;
return React.DOM.div(null, [
React.DOM.h1(null, 'Post Viewer v3.7.9'),
React.DOM.h2(null, post.title)
]);
}
});
function HTML5Header(options) {
return new BufferBody( // Terrible pseudo code below:
'<!DOCTYPE html><html><head>' +
'<!-- ' + options.styles + ' -->' +
'<!-- ' + options.meta + ' -->' +
'</head><body class="body-classes-from-options">'
);
}
function toHtmlBodyStream(body) {
// If it's a react component: render; then just normal respond logic
return new BufferBody(String(body));
}
function HTML5Footer(options) {
return new BufferBody( // Terrible pseudo code below:
'<!-- ' + options.scripts + ' -->' +
'</body>'
);
}
function combinedStream(streams) {
// ~= combined-stream
return new BufferBody('many streams: ' + streams.length);
}
function HTML5Layout(body, options) {
// Knows how to render an html5 page
// Perfect case:
// * toBuffer() on the returned stream should only return the inner component
// * toJSON() should return the page model
// Terrible pseudo code below:
return respond(combinedStream([
HTML5Header(options),
toHtmlBodyStream(body),
HTML5Footer(options)
]))
.header('Content-Type', 'text/html; charset=utf-8');
}
function MyFancyLayout(body, options) {
// Apply some defaults to options, wrap the body, then call the layout.
// We could also fetch something from the interwebz and return a promise
// here, rendering the body later on.
return HTML5Layout(body, options);
}
export function showPost() {
return MyFancyLayout(
// First argument: the body; component or string or stream
loadPost(getParam('postId')).then(
post => PostView({ model: post })
),
// Second argument: options for the layout (and the responder)
{
// bufferBody tells the renderer that we want to wait until the body is
// fully available before we render the head.
// Otherwise we might start sending a response (headers/statusCode)
// without knowing that the page is likely to be renderable.
// One alternative is to do the promise resolution at the top level and
// just use a plain old value as the body.
bufferBody: true,
scripts: [ /* ... */ ],
styles: [ /* ... */ ],
meta: { /* ... */ }
}
).status(418);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment