Permalink
Browse files

WIP PhotosNearMe server.

  • Loading branch information...
1 parent d864758 commit cb45257e8a2ba25cacca75e094b7c9c8bda4e115 @ericf committed Apr 20, 2012
View
91 app.js
@@ -0,0 +1,91 @@
+require('./conf/config');
+
+var connect = require('connect'),
+ combo = require('combohandler'),
+ express = require('express'),
+ Y = require('yui').use('handlebars'),
+
+ app = express.createServer(),
+ pubDir = global.config.pubDir;
+
+// -- Express config -----------------------------------------------------------
+app.configure('development', function () {
+ // Gives us pretty logs in development. Must run before other middleware.
+ app.use(express.logger(
+ '[:date] :req[x-forwarded-for] ":method :url" :status [:response-time ms]'
+ ));
+});
+
+app.configure(function () {
+ // Don't ignore trailing slashes in routes.
+ app.set('strict routing', true);
+
+ // Use our custom Handlebars-based view engine as the default.
+ app.register('.handlebars', require('./lib/view'));
+ app.set('view engine', 'handlebars');
+
+ // Local values that will be shared across all views. Locals specified at
+ // render time will override these values if they share the same name.
+ app.set('view options', Y.merge(require('./conf/common'), {
+ config: global.config
+ }));
+
+ // Middleware.
+ app.use(app.router);
+ app.use(express.favicon());
+ app.use(express.static(pubDir));
+});
+
+app.configure('development', function () {
+ app.use(express.errorHandler({
+ dumpExceptions: true,
+ showStack : true
+ }));
+});
+
+app.configure('production', function () {
+ app.enable('view cache');
+ app.use(express.errorHandler());
+});
+
+// -- Routes -------------------------------------------------------------------
+
+// Root.
+app.get('/', function (req, res) {
+ res.render('index');
+});
+
+// Combo-handler for JavaScript.
+app.get('/combo', combo.combine({rootPath: pubDir + '/js'}), function (req, res) {
+ if (connect.utils.conditionalGET(req)) {
+ if (!connect.utils.modified(req, res)) {
+ return connect.utils.notModified(res);
+ }
+ }
+
+ res.send(res.body, 200);
+});
+
+// Dymanic resource for precompiled templates.
+app.get('/templates.js', (function () {
+ var precompiled = require('./lib/templates').precompiled,
+ templates = [];
+
+ Y.Object.each(precompiled, function (template, name) {
+ templates.push({
+ name : name,
+ template: template
+ });
+ });
+
+ return function (req, res) {
+ res.render('templates', {
+ layout : false,
+ templates: templates
+ }, function (err, view) {
+ res.send(view, {'Content-Type': 'application/javascript'}, 200);
+ });
+ };
+}()));
+
+module.exports = app;
View
@@ -0,0 +1,9 @@
+var config = require('./config');
+
+module.exports = {
+ env : config.env,
+ layout : config.layout,
+ min : config.env.production ? '-min' : '',
+ yui_config : JSON.stringify(config.yui.client),
+ yui_version: config.yui.version
+};
View
@@ -0,0 +1,51 @@
+var fs = require('fs'),
+ path = require('path'),
+ Y = require('yui/yui-base'),
+
+ CONFIG_FILE = 'config.json',
+ NODE_ENV = process.env.NODE_ENV,
+
+ ENV = {
+ development: NODE_ENV !== 'production',
+ production : NODE_ENV === 'production'
+ };
+
+var appRoot = process.cwd(),
+ configFile = path.join(__dirname, CONFIG_FILE),
+ config = path.existsSync(configFile) &&
+ JSON.parse(fs.readFileSync(configFile, 'utf8'));
+
+if (!config) {
+ console.error('Could not read config file: ' + configFile);
+ process.exit(1);
+}
+
+config.env = ENV;
+config.pubDir = path.join(appRoot, config.pubDir);
+config.templatesDir = path.join(appRoot, config.templatesDir);
+
+// YUI on the server.
+config.yui.server = {
+ groups: {
+ pnm: Y.merge(config.yui.pnm, {
+ base : path.join(config.pubDir, config.yui.pnm.base),
+ combine: false
+ })
+ }
+};
+
+// YUI on the client.
+config.yui.client = {
+ allowRollup: false,
+ combine : ENV.production,
+ filter : ENV.production ? 'min' : 'raw',
+ modules : config.yui.modules,
+
+ groups: {
+ pnm: Y.merge(config.yui.pnm, {
+ combine: ENV.production
+ })
+ }
+};
+
+global.config = module.exports = config;
View
@@ -0,0 +1,99 @@
+{
+ "layout" : "layouts/main",
+ "pubDir" : "public/",
+ "templatesDir": "shared/templates/",
+
+ "flickr": {
+ "api_key": "0984607e2222db7a1be6a5692741ca08"
+ },
+
+ "yui": {
+ "version": "3.5.0",
+
+ "modules": {
+ "ios-oc-fix": "/vendor/ios-orientationchange-fix.js",
+ "typekit" : "http://use.typekit.com/wkh7ffm.js"
+ },
+
+ "pnm": {
+ "base" : "/js/",
+ "comboBase": "/combo?",
+ "root" : "/",
+
+ "modules": {
+ "pnm-place": {
+ "path" : "models/place.js",
+ "requires": [
+ "cache-offline",
+ "gallery-model-sync-yql",
+ "model",
+ "yql"
+ ]
+ },
+
+ "pnm-photo": {
+ "path" : "models/photo.js",
+ "requires": [
+ "gallery-model-sync-yql",
+ "cache-offline",
+ "model",
+ "pnm-place",
+ "yql"
+ ]
+ },
+
+ "pnm-photos": {
+ "path" : "models/photos.js",
+ "requires": [
+ "cache-offline",
+ "gallery-model-sync-yql",
+ "model-list",
+ "pnm-photo",
+ "yql"
+ ]
+ },
+
+ "pnm-grid-view": {
+ "path" : "views/grid.js",
+ "requires": [
+ "handlebars",
+ "node-style",
+ "node-screen",
+ "pnm-photos",
+ "view"
+ ]
+ },
+
+ "pnm-lightbox-view": {
+ "path" : "views/lightbox.js",
+ "requires": [
+ "event-key",
+ "handlebars",
+ "pnm-photos",
+ "transition",
+ "view"
+ ]
+ },
+
+ "pnm-templates": {
+ "fullpath": "/templates.js",
+ "requires": ["handlebars-base"]
+ },
+
+ "pnm-app": {
+ "path" : "app.js",
+ "requires": [
+ "app-base",
+ "app-transitions",
+ "gallery-geo",
+ "pnm-grid-view",
+ "pnm-lightbox-view",
+ "pnm-photos",
+ "pnm-place",
+ "pnm-templates"
+ ]
+ }
+ }
+ }
+ }
+}
View
@@ -0,0 +1,26 @@
+var fs = require('fs'),
+ path = require('path'),
+ Y = require('yui/handlebars'),
+
+ config = require('../conf/config');
+
+var raw = {},
+ precompiled = {},
+ templatesDir = config.templatesDir,
+ files = path.existsSync(templatesDir) &&
+ fs.readdirSync(templatesDir, 'utf8');
+
+if (files && files.length) {
+ files.forEach(function (file) {
+ if (path.extname(file) !== '.handlebars') { return; }
+
+ var name = file.replace('.handlebars', '');
+ template = fs.readFileSync(path.join(templatesDir, file), 'utf-8');
+
+ raw[name] = template;
+ precompiled[name] = Y.Handlebars.precompile(template);
+ });
+}
+
+exports.raw = raw;
+exports.precompiled = precompiled;
View
@@ -0,0 +1,19 @@
+var Y = require('yui/handlebars'),
+
+ templates = require('./templates').raw;
+
+global.Handlebars = Y.Handlebars;
+
+// Register all templates as partials.
+Y.Object.each(templates, function (template, name) {
+ Y.Handlebars.registerPartial(name, template);
+});
+
+// Export a compile() method for Express.
+exports.compile = function (source, options) {
+ var template = Y.Handlebars.compile(source);
+
+ return function (options) {
+ return template(options, options.helpers);
+ }
+};
View
@@ -5,8 +5,9 @@
"version" : "0.4.2",
"author" : "Eric Ferraiuolo <eferraiuolo@gmail.com> (http://github.com/ericf)",
"dependencies": {
+ "combohandler": "~0.1",
"connect" : ">=1.8.0 <2.0.0",
- "express" : ">=2.4.0 <3.0.0",
- "combohandler": "~0.1"
+ "express" : ">=2.5.0 <3.0.0",
+ "yui" : "3.5.0"
}
}
View
@@ -1,42 +1,5 @@
-var connect = require('connect'),
- combo = require('combohandler'),
- express = require('express'),
-
- app = express.createServer(),
- port = process.env.PORT || 3000,
- pubDir = __dirname + '/public';
-
-app.configure(function () {
- app.use(express.favicon());
- app.use(express.staticCache());
- app.use(express.static(pubDir));
-});
-
-// Combo-handler for JavaScript.
-app.get('/js', combo.combine({rootPath: pubDir + '/js'}), function (req, res) {
- if (connect.utils.conditionalGET(req)) {
- if (!connect.utils.modified(req, res)) {
- return connect.utils.notModified(res);
- }
- }
-
- res.send(res.body, 200);
-});
-
-// The actual PNM app.
-app.get('/', function (req, res) {
- res.sendfile('index.html');
-});
-
-// Restrict to only known paths that the app can respond to:
-//
-// - "/place/:id/"
-// - "/photo/:id/"
-//
-// Redirects back to "/" with the URL as a fragment, e.g. "/#/photo/:id/"
-app.get(/^\/(?:(?:place|photo)\/\d+\/)$/, function (req, res) {
- res.redirect('/#' + req.url, 302);
-});
+var app = require('./app'),
+ port = process.env.PORT || 3000;
app.listen(port, function () {
console.log('Server listening on ' + port);
@@ -0,0 +1,7 @@
+<li class="photo" id="{{clientId}}">
+ <a href="/photo/{{id}}/">
+ {{#if thumbUrl}}
+ <img src="{{thumbUrl}}" />
+ {{/if}}
+ </a>
+</li>
@@ -0,0 +1,7 @@
+<ul class="layout">
+{{#each photos}}
+ {{> photo}}
+{{/each}}
+</ul>
+
+<p class="loading"></p>
@@ -0,0 +1,13 @@
+<h1>
+ <a href="/" id="logo">
+ <span class="pin-shadow"></span>
+ <span class="pin"></span>
+ </a>
+ {{#if place}}
+ <a href="/place/{{place.id}}/">
+ Photos Near <span id="location">{{place.text}}</span>
+ </a>
+ {{else}}
+ Photos Near <span id="location">Me</span>
+ {{/if}}
+</h1>
Oops, something went wrong.

0 comments on commit cb45257

Please sign in to comment.