-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
route context example #22
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
var path = require('path'); | ||
|
||
var stylesheetsDir = 'assets/stylesheets'; | ||
var rendrDir = 'node_modules/rendr'; | ||
var rendrHandlebarsDir = 'node_modules/rendr-handlebars'; | ||
var rendrModulesDir = rendrDir + '/node_modules'; | ||
|
||
module.exports = function(grunt) { | ||
// Project configuration. | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
|
||
stylus: { | ||
compile: { | ||
options: { | ||
paths: [stylesheetsDir], | ||
'include css': true | ||
}, | ||
files: { | ||
'public/styles.css': stylesheetsDir + '/index.styl' | ||
} | ||
} | ||
}, | ||
|
||
handlebars: { | ||
compile: { | ||
options: { | ||
namespace: false, | ||
commonjs: true, | ||
processName: function(filename) { | ||
return filename.replace('app/templates/', '').replace('.hbs', ''); | ||
} | ||
}, | ||
src: "app/templates/**/*.hbs", | ||
dest: "app/templates/compiledTemplates.js", | ||
filter: function(filepath) { | ||
var filename = path.basename(filepath); | ||
// Exclude files that begin with '__' from being sent to the client, | ||
// i.e. __layout.hbs. | ||
return filename.slice(0, 2) !== '__'; | ||
} | ||
} | ||
}, | ||
|
||
watch: { | ||
scripts: { | ||
files: 'app/**/*.js', | ||
tasks: ['browserify'], | ||
options: { | ||
interrupt: true | ||
} | ||
}, | ||
templates: { | ||
files: 'app/**/*.hbs', | ||
tasks: ['handlebars'], | ||
options: { | ||
interrupt: true | ||
} | ||
}, | ||
stylesheets: { | ||
files: [stylesheetsDir + '/**/*.styl', stylesheetsDir + '/**/*.css'], | ||
tasks: ['stylus'], | ||
options: { | ||
interrupt: true | ||
} | ||
} | ||
}, | ||
|
||
browserify: { | ||
basic: { | ||
src: [ | ||
'app/**/*.js', | ||
], | ||
dest: 'public/mergedAssets.js', | ||
options: { | ||
debug: true, | ||
alias: [ | ||
'node_modules/handlebars/lib/index.js:handlebars', | ||
'node_modules/rendr-handlebars/index.js:rendr-handlebars', | ||
], | ||
aliasMappings: [ | ||
{ | ||
cwd: 'app/', | ||
src: ['**/*.js'], | ||
dest: 'app/' | ||
}, | ||
], | ||
shim: { | ||
jquery: { | ||
path: 'assets/vendor/jquery-1.9.1.min.js', | ||
exports: '$', | ||
}, | ||
}, | ||
} | ||
} | ||
} | ||
}); | ||
|
||
grunt.loadNpmTasks('grunt-browserify'); | ||
grunt.loadNpmTasks('grunt-contrib-handlebars'); | ||
grunt.loadNpmTasks('grunt-contrib-stylus'); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
|
||
grunt.registerTask('runNode', function () { | ||
grunt.util.spawn({ | ||
cmd: 'node', | ||
args: ['./node_modules/nodemon/nodemon.js', 'index.js'], | ||
opts: { | ||
stdio: 'inherit' | ||
} | ||
}, function () { | ||
grunt.fail.fatal(new Error("nodemon quit")); | ||
}); | ||
}); | ||
|
||
|
||
grunt.registerTask('compile', ['handlebars', 'browserify', 'stylus']); | ||
|
||
// Run the server and watch for file changes | ||
grunt.registerTask('server', ['compile', 'runNode', 'watch']); | ||
|
||
// Default task(s). | ||
grunt.registerTask('default', ['compile']); | ||
|
||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Rendr App Template | ||
## GitHub Browser | ||
|
||
The purpose of this little app is to demonstrate one way of using Rendr to build a web app that runs on both the client and the server. | ||
|
||
![Screenshot](http://cl.ly/image/062d3S2D1Y38/Screen%20Shot%202013-04-09%20at%203.14.31%20PM.png) | ||
|
||
## Running the example | ||
|
||
First, make sure to have Node >= 0.8.0 [installed on your system](http://nodejs.org/). Also, make sure to have `grunt-cli` installed globally. | ||
|
||
$ npm install -g grunt-cli | ||
|
||
If you see an error on startup that looks [like this](https://github.com/rendrjs/rendr-app-template/issues/2), then you may need to un-install a global copy of `grunt`: | ||
|
||
$ npm uninstall -g grunt | ||
|
||
Run `npm install` to install dependencies: | ||
|
||
$ npm install | ||
|
||
Then, use `grunt server` to start up the web server. Grunt will recompile and restart the server when files change. | ||
|
||
$ grunt server | ||
|
||
Running "runNode" task | ||
|
||
Running "handlebars:compile" (handlebars) task | ||
11 Dec 17:40:30 - [nodemon] v0.7.10 | ||
11 Dec 17:40:30 - [nodemon] to restart at any time, enter `rs` | ||
11 Dec 17:40:30 - [nodemon] watching: /Users/spike/code/rendr/examples/00_simple | ||
File "app/templates/compiledTemplates.js" created. | ||
|
||
Running "browserify:basic" (browserify) task | ||
11 Dec 17:40:30 - [nodemon] starting `node index.js` | ||
connect.multipart() will be removed in connect 3.0 | ||
visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives | ||
connect.limit() will be removed in connect 3.0 | ||
server pid 86724 listening on port 3030 in development mode | ||
>> Bundled public/mergedAssets.js | ||
|
||
Running "stylus:compile" (stylus) task | ||
File public/styles.css created. | ||
|
||
Running "watch" task | ||
Waiting... | ||
|
||
11 Dec 17:40:32 - [nodemon] starting `node index.js` | ||
server pid 86728 listening on port 3030 in development mode | ||
|
||
Now, pull up the app in your web browser. It defaults to port `3030`. | ||
|
||
$ open http://localhost:3030 | ||
|
||
You can choose a different port by passing the `PORT` environment variable: | ||
|
||
$ PORT=80 grunt server | ||
|
||
### GitHub API rate limit | ||
|
||
GitHub [rate limits](http://developer.github.com/v3/#rate-limiting) unauthenticated requests to its public API to 60 requests per hour per IP. This should be enough for just playing with the sample app, but if you pull it down and start developing off it you may run up against the rate limit. | ||
|
||
**You've been warned.** Your best bet may be to alter the project to read from your favorite RESTful API. | ||
|
||
## Overview | ||
|
||
At times, it's useful to have certain contextual data checked on each route request (traditional page request) to determine access to that page or to determine what to show on that page. This example shows one way of accomplishing this in Rendr. | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
var BaseApp = require('rendr/shared/app'), | ||
Session = require('./models/session'), | ||
handlebarsHelpers = require('./lib/handlebarsHelpers'); | ||
|
||
/** | ||
* Extend the `BaseApp` class, adding any custom methods or overrides. | ||
*/ | ||
module.exports = BaseApp.extend({ | ||
|
||
/** | ||
* Client and server. | ||
* | ||
* `initialize` is called on app initialize, both on the client and server. | ||
* On the server, an app is instantiated once for each request, and in the | ||
* client, it's instantiated once on page load. | ||
* | ||
* This is a good place to initialize any code that needs to be available to | ||
* app on both client and server. | ||
*/ | ||
initialize: function() { | ||
/** | ||
* Register our Handlebars helpers. | ||
* | ||
* `this.templateAdapter` is, by default, the `rendr-handlebars` module. | ||
* It has a `registerHelpers` method, which allows us to register helper | ||
* modules that can be used on both client & server. | ||
*/ | ||
this.templateAdapter.registerHelpers(handlebarsHelpers); | ||
}, | ||
|
||
/** | ||
* Client-side only. | ||
* | ||
* `start` is called at the bottom of `__layout.hbs`. Calling this kicks off | ||
* the router and initializes the application. | ||
* | ||
* Override this method (remembering to call the superclass' `start` method!) | ||
* in order to do things like bind events to the router, as shown below. | ||
*/ | ||
start: function() { | ||
// Show a loading indicator when the app is fetching. | ||
this.router.on('action:start', function() { this.set({loading: true}); }, this); | ||
this.router.on('action:end', function() { this.set({loading: false}); }, this); | ||
|
||
// Call 'super'. | ||
BaseApp.prototype.start.call(this); | ||
}, | ||
|
||
getSessionModel: function() { | ||
var cachedSessionModel = this.fetcher.modelStore.get('Session', 1); | ||
if (cachedSessionModel) { | ||
return cachedSessionModel; | ||
} else { | ||
// Then, let's pull the bootstrapped version from the middleware | ||
var session = this.get('session'); | ||
session = session || {}; | ||
session.id = 1; // make the id 1 for now. | ||
// Then, we convert it to model before we set it. | ||
var sessionModel = new Session(session, { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the ideal case is to use https://github.com/expressjs/session and do sessions in middleware instead. Maybe we can change this example to use those things? |
||
app: this | ||
}); | ||
return sessionModel; | ||
} | ||
}, | ||
|
||
refreshSessionModel: function(callback) { | ||
// if this is server side, just run callback | ||
if (this.req) { | ||
callback(); | ||
// if this is client side, fetch fresh session model first | ||
} else { | ||
this.getSessionModel().fetch({ | ||
success: function(model) { | ||
model.store(); | ||
|
||
if (callback) { | ||
callback(); | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
|
||
getTimeLoaded: function() { | ||
return this.getSessionModel().get('time'); | ||
}, | ||
|
||
getMinuteLoaded: function() { | ||
return this.getSessionModel().get('minute'); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
var RendrBase = require('rendr/shared/base/collection'); | ||
|
||
module.exports = RendrBase.extend({}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
var ContextUtils = require('../lib/contextUtils'); | ||
|
||
module.exports = { | ||
index: ContextUtils.loadBaseData(function(params, callback) { | ||
callback(null, params); | ||
}), | ||
|
||
only_even_minute: ContextUtils.ensureOnlyEvenMinute(function(params, callback) { | ||
callback(null, params); | ||
}), | ||
|
||
only_odd_minute: ContextUtils.ensureOnlyOddMinute(function(params, callback) { | ||
callback(null, params); | ||
}) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
var ContextUtils = function() {}; | ||
|
||
ContextUtils = { | ||
|
||
loadBaseData: function(actionHandler) { | ||
return function() { | ||
var _arguments = arguments; | ||
this.app.refreshSessionModel(function() { | ||
actionHandler.apply(this, _arguments); | ||
}.bind(this)); | ||
}; | ||
}, | ||
|
||
/** | ||
* An example to show how to limit access based on data stored in our | ||
* app. In this case we only allow access on odd minutes. | ||
* but it could be when we have a user token. | ||
*/ | ||
ensureOnlyOddMinute: function(actionHandler) { | ||
return function() { | ||
var _arguments = arguments; | ||
|
||
this.app.refreshSessionModel(function() { | ||
var minute = this.app.getMinuteLoaded(); | ||
if ((minute % 2) === 1) { | ||
actionHandler.apply(this, _arguments); | ||
} else { | ||
this.redirectTo('/?message=odd+page+is+not+available'); | ||
} | ||
}.bind(this)); | ||
}; | ||
}, | ||
|
||
/** | ||
* An example to show how to limit access based on data stored in our | ||
* app. In this case we only allow access on even minutes. | ||
* but it could be when we have a user token. | ||
*/ | ||
ensureOnlyEvenMinute: function(actionHandler) { | ||
return function() { | ||
var _arguments = arguments; | ||
|
||
this.app.refreshSessionModel(function() { | ||
var minute = this.app.getMinuteLoaded(); | ||
if ((minute % 2) === 0) { | ||
actionHandler.apply(this, _arguments); | ||
} else { | ||
this.redirectTo('/?message=even+page+is+not+available'); | ||
} | ||
}.bind(this)); | ||
}; | ||
} | ||
}; | ||
|
||
module.exports = ContextUtils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* We inject the Handlebars instance, because this module doesn't know where | ||
* the actual Handlebars instance will come from. | ||
*/ | ||
module.exports = function(Handlebars) { | ||
return { | ||
copyright: function(year) { | ||
return new Handlebars.SafeString("©" + year); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
var RendrBase = require('rendr/shared/base/model'); | ||
|
||
module.exports = RendrBase.extend({}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var Base = require('./base'); | ||
|
||
module.exports = Base.extend({ | ||
url: '/sessions/:id', | ||
api: 'local' | ||
}); | ||
module.exports.id = 'Session'; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be a bad practice to directly access the
modelStore
not sure what anyone elses thoughts are around that though.