Compare commits
3 commits
master
...
no-js-rend
Author | SHA1 | Date | |
---|---|---|---|
|
a93aadf0fa | ||
|
f7f20edb70 | ||
|
d8733f0add |
7 changed files with 300 additions and 25 deletions
87
app/templates/main.jade
Normal file
87
app/templates/main.jade
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
doctype html
|
||||||
|
//[if lt IE 7]> <html class="lt-ie10 lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]
|
||||||
|
//[if IE 7]> <html class="lt-ie10 lt-ie9 lt-ie8" lang="en"> <![endif]
|
||||||
|
//[if IE 8]> <html class="lt-ie10 lt-ie9" lang="en"> <![endif]
|
||||||
|
//[if IE 9]> <html class="lt-ie10" lang="en"> <![endif]
|
||||||
|
//[if !IE] <!
|
||||||
|
html(lang='en')
|
||||||
|
// <![endif]
|
||||||
|
head
|
||||||
|
meta(charset='utf-8')
|
||||||
|
meta(name='viewport', content='width=1024')
|
||||||
|
title CodeCombat - Learn how to code by playing a game
|
||||||
|
meta(name='description', content='Learn programming with a multiplayer live coding strategy game for beginners. Learn Python or JavaScript as you defeat ogres, solve mazes, and level up. Open source HTML5 game!')
|
||||||
|
meta(property='og:title', content='CodeCombat: Learn to Code by Playing a Game')
|
||||||
|
meta(property='og:url', content='http://codecombat.com')
|
||||||
|
meta(property='og:type', content='game')
|
||||||
|
meta(property='og:image', content='http://codecombat.com/images/pages/home/play_img.png')
|
||||||
|
meta(property='og:site_name', content='CodeCombat')
|
||||||
|
meta(name='twitter:card', content='summary')
|
||||||
|
meta(name='twitter:title', content='CodeCombat: Learn to Code by Playing a Game')
|
||||||
|
meta(name='twitter:url', content='http://codecombat.com')
|
||||||
|
meta(name='twitter:site', content='CodeCombat')
|
||||||
|
meta(name='twitter:image:src', content='http://codecombat.com/images/pages/base/logo_square_250.png')
|
||||||
|
meta(name='twitter:description', content='Learn programming with a multiplayer live coding strategy game for beginners. Learn Python or JavaScript as you defeat ogres, solve mazes, and level up. Open source HTML5 game!')
|
||||||
|
link(href='https://plus.google.com/115285980638641924488', rel='publisher')
|
||||||
|
link(rel='shortcut icon', href='/images/favicon.ico')
|
||||||
|
link(rel='stylesheet', href='/stylesheets/app.css')
|
||||||
|
link(href='//fonts.googleapis.com/css?family=Merriweather', rel='stylesheet', type='text/css')
|
||||||
|
// Google Analytics
|
||||||
|
script.
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
ga('create', 'UA-39724129-1', 'auto');
|
||||||
|
// Mixpanel
|
||||||
|
script(type='text/javascript').
|
||||||
|
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"===e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f)}})(document,window.mixpanel||[]);
|
||||||
|
mixpanel.init("e71a4e60db7e1dc5e685be96776280f9");
|
||||||
|
script(src='https://checkout.stripe.com/checkout.js')
|
||||||
|
// IE9 doesn't support defer attribute: https://github.com/h5bp/lazyweb-requests/issues/42
|
||||||
|
//[if IE 9]>
|
||||||
|
script(src='/lib/ace/ace.js')
|
||||||
|
script(src='/javascripts/box2d.js')
|
||||||
|
script(src='/javascripts/vendor.js')
|
||||||
|
script(src='/javascripts/aether.js')
|
||||||
|
script(src='/javascripts/app.js')
|
||||||
|
<![endif]
|
||||||
|
|
||||||
|
// IE9 cors support breaks analytics logging: http://caniuse.com/#feat=cors
|
||||||
|
//[if IE 9]>
|
||||||
|
script(type='text/javascript', src='http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.2/jquery.xdomainrequest.min.js')
|
||||||
|
<![endif]
|
||||||
|
script(src='/lib/ace/ace.js', defer='')
|
||||||
|
script(src='/javascripts/vendor.js', defer='')
|
||||||
|
script(src='/javascripts/aether.js', defer='')
|
||||||
|
script(src='/javascripts/app.js', defer='')
|
||||||
|
script.
|
||||||
|
// IMPORTANT: If you edit here, make sure app/assets/javascripts/run-tests.js puts in placeholders for
|
||||||
|
// running client tests on Travis.
|
||||||
|
// Placeholder for iPad, which inspects the user object at the bottom of an injected page.
|
||||||
|
window.serverConfig = !{JSON.stringify(serverConfig)};
|
||||||
|
window.userObject = !{userObjectTag};
|
||||||
|
window.amActually = !{amActually ? JSON.stringify(amActually) : 'undefined'};
|
||||||
|
window.me = {
|
||||||
|
get: function(attribute) { return window.userObject[attribute]; }
|
||||||
|
}
|
||||||
|
onLoad = function() {
|
||||||
|
try {
|
||||||
|
// IE10 warning
|
||||||
|
var htmlElement = document.querySelector("html");
|
||||||
|
if (htmlElement) {
|
||||||
|
if ($.browser.msie && $.browser.versionNumber < 11) {
|
||||||
|
alert("CodeCombat does not run in Internet Explorer 11 or older. Sorry!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// IE8 can't handle this
|
||||||
|
FastClick.attach(document.body);
|
||||||
|
require('core/initialize');
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
body.clearfix(onload='onLoad();')
|
||||||
|
#fb-root
|
||||||
|
#page-container !{pageContent}
|
||||||
|
#modal-wrapper.modal-content.hide
|
||||||
|
#module-load-progress.progress
|
||||||
|
.progress-bar
|
|
@ -26,7 +26,7 @@ if view.showAds()
|
||||||
img(src="/images/pages/base/logo.png", title="Powered by CodeCombat - Learn how to code by playing a game ", alt="Powered by CodeCombat")
|
img(src="/images/pages/base/logo.png", title="Powered by CodeCombat - Learn how to code by playing a game ", alt="Powered by CodeCombat")
|
||||||
|
|
||||||
if campaign
|
if campaign
|
||||||
.map
|
.map(style="width: 800px; height: 600px")
|
||||||
.gradient.horizontal-gradient.top-gradient
|
.gradient.horizontal-gradient.top-gradient
|
||||||
.gradient.vertical-gradient.right-gradient
|
.gradient.vertical-gradient.right-gradient
|
||||||
.gradient.horizontal-gradient.bottom-gradient
|
.gradient.horizontal-gradient.bottom-gradient
|
||||||
|
@ -118,7 +118,7 @@ if view.showAds()
|
||||||
if campaign && campaign.locked && !godmode
|
if campaign && campaign.locked && !godmode
|
||||||
h3.campaign-locked(data-i18n="play.locked") Locked
|
h3.campaign-locked(data-i18n="play.locked") Locked
|
||||||
else if campaign
|
else if campaign
|
||||||
btn(data-i18n="common.play").btn.btn-illustrated.btn-lg.btn-success.play-button
|
a(data-i18n="common.play", href="/play/#{campaignSlug}").btn.btn-illustrated.btn-lg.btn-success.play-button
|
||||||
if campaign && campaign.get('description')
|
if campaign && campaign.get('description')
|
||||||
p.campaign-description
|
p.campaign-description
|
||||||
span= i18n(campaign.attributes, 'description')
|
span= i18n(campaign.attributes, 'description')
|
||||||
|
|
|
@ -663,6 +663,8 @@ module.exports = class CampaignView extends RootView
|
||||||
console.error "CampaignView hero update couldn't find hero slug for original:", hero
|
console.error "CampaignView hero update couldn't find hero slug for original:", hero
|
||||||
|
|
||||||
onClickPortalCampaign: (e) ->
|
onClickPortalCampaign: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
campaign = $(e.target).closest('.campaign')
|
campaign = $(e.target).closest('.campaign')
|
||||||
return if campaign.is('.locked') or campaign.is('.silhouette')
|
return if campaign.is('.locked') or campaign.is('.silhouette')
|
||||||
campaignSlug = campaign.data('campaign-slug')
|
campaignSlug = campaign.data('campaign-slug')
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
"bluebird": "^3.2.1",
|
"bluebird": "^3.2.1",
|
||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"co": "^4.6.0",
|
"co": "^4.6.0",
|
||||||
|
"cheerio": "^0.20.0",
|
||||||
"co-express": "^1.2.1",
|
"co-express": "^1.2.1",
|
||||||
"coffee-script": "1.9.x",
|
"coffee-script": "1.9.x",
|
||||||
"connect": "2.7.x",
|
"connect": "2.7.x",
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
"geoip-lite": "^1.1.6",
|
"geoip-lite": "^1.1.6",
|
||||||
"graceful-fs": "~2.0.1",
|
"graceful-fs": "~2.0.1",
|
||||||
"gridfs-stream": "~1.1.1",
|
"gridfs-stream": "~1.1.1",
|
||||||
|
"jade": "^1.11.0",
|
||||||
"jsondiffpatch": "0.1.17",
|
"jsondiffpatch": "0.1.17",
|
||||||
"lodash": "~2.4.1",
|
"lodash": "~2.4.1",
|
||||||
"lz-string": "^1.3.3",
|
"lz-string": "^1.3.3",
|
||||||
|
|
|
@ -56,7 +56,8 @@ module.exports.routes =
|
||||||
'routes/sprites'
|
'routes/sprites'
|
||||||
'routes/queue'
|
'routes/queue'
|
||||||
'routes/stacklead'
|
'routes/stacklead'
|
||||||
'routes/stripe'
|
'routes/stripe',
|
||||||
|
'routes/html'
|
||||||
]
|
]
|
||||||
|
|
||||||
mongoose = require 'mongoose'
|
mongoose = require 'mongoose'
|
||||||
|
|
199
server/routes/html.coffee
Normal file
199
server/routes/html.coffee
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
User = require '../models/User'
|
||||||
|
UserHandler = require '../handlers/user_handler'
|
||||||
|
LevelSession = require '../models/LevelSession'
|
||||||
|
Campaign = require '../models/Campaign'
|
||||||
|
Level = require '../models/Level'
|
||||||
|
config = require '../../server_config'
|
||||||
|
log = require 'winston'
|
||||||
|
Mandate = require '../models/Mandate'
|
||||||
|
utils = require '../lib/utils'
|
||||||
|
cheerio = require 'cheerio'
|
||||||
|
en = require '../../app/locale/en'
|
||||||
|
_ = require 'lodash'
|
||||||
|
|
||||||
|
translate = (key) ->
|
||||||
|
html = /^\[html\]/.test(key)
|
||||||
|
key = key.substring(6) if html
|
||||||
|
|
||||||
|
t = en.translation
|
||||||
|
#TODO: Replace with _.property when we get modern lodash
|
||||||
|
path = key.split(/[.]/)
|
||||||
|
while path.length > 0
|
||||||
|
k = path.shift()
|
||||||
|
t = t[k]
|
||||||
|
return key unless t?
|
||||||
|
|
||||||
|
return out =
|
||||||
|
text: t
|
||||||
|
html: html
|
||||||
|
|
||||||
|
|
||||||
|
makeContext = (req) ->
|
||||||
|
view =
|
||||||
|
isIPadBrowser: -> false
|
||||||
|
isMobile: -> false
|
||||||
|
isOldBrowser: -> false
|
||||||
|
forumLink: -> 'http://discourse.codecombat.com/'
|
||||||
|
showAds: -> true
|
||||||
|
|
||||||
|
me =
|
||||||
|
getPhotoURL: -> ''
|
||||||
|
isAnonymous: -> true
|
||||||
|
get: (what) -> ''
|
||||||
|
level: -> ''
|
||||||
|
displayName: -> ''
|
||||||
|
isTeacher: -> false
|
||||||
|
isOnPremiumServer: -> false
|
||||||
|
isAdmin: -> false
|
||||||
|
gems: -> 0
|
||||||
|
isPremium: -> false
|
||||||
|
|
||||||
|
opts =
|
||||||
|
view: view
|
||||||
|
me: me
|
||||||
|
i18n: (a, b) ->
|
||||||
|
return a.i18n.en[a] if 'i18n' in a
|
||||||
|
a[b]
|
||||||
|
|
||||||
|
injectView = (res, view, opts, next) ->
|
||||||
|
res.render (view + '.jade'), opts, (err, data) ->
|
||||||
|
if err
|
||||||
|
if config.isProduction
|
||||||
|
res.locals.pageContent = ''
|
||||||
|
else
|
||||||
|
res.locals.pageContent = ('<pre>' + err + '</pre>')
|
||||||
|
return next()
|
||||||
|
|
||||||
|
c = cheerio.load(data)
|
||||||
|
name = view.split(/\//).pop()
|
||||||
|
name += '-view' unless /-view$/.test(name)
|
||||||
|
roots = c.root().children()
|
||||||
|
elms = c('[data-i18n]')
|
||||||
|
elms.each (i, e) ->
|
||||||
|
i = c(this)
|
||||||
|
t = translate(i.data('i18n'))
|
||||||
|
if t.html
|
||||||
|
i.html(t.text)
|
||||||
|
else
|
||||||
|
i.text(t.text);
|
||||||
|
|
||||||
|
o = cheerio.load("<div>")
|
||||||
|
container = o('div')
|
||||||
|
container.attr('id', name)
|
||||||
|
container.html(c.html())
|
||||||
|
|
||||||
|
unless o('.style-flat').length > 0
|
||||||
|
container.addClass('site-chrome')
|
||||||
|
container.addClass('show-background') unless opts.showBackground is false
|
||||||
|
container.attr('style', 'display: none') if opts.dontActuallyShow
|
||||||
|
|
||||||
|
res.locals.pageContent = o.html()
|
||||||
|
next()
|
||||||
|
|
||||||
|
exports.setup = (app) ->
|
||||||
|
handle = (route, view, next) ->
|
||||||
|
app.get route, (req, res) ->
|
||||||
|
try
|
||||||
|
next req, res, (opts) ->
|
||||||
|
injectView res, view, opts, ->
|
||||||
|
renderMain req, res
|
||||||
|
catch e
|
||||||
|
renderMain req, res
|
||||||
|
|
||||||
|
handleSimply = (route, view, extra) ->
|
||||||
|
handle route, view, (req, res, next) ->
|
||||||
|
opts = makeContext req
|
||||||
|
_.extend opts.view, extra(req, res) if extra
|
||||||
|
next(opts)
|
||||||
|
|
||||||
|
handleSimply '/', 'new-home-view', ->
|
||||||
|
justPlaysCourses: -> false
|
||||||
|
courses: {models: []}
|
||||||
|
|
||||||
|
handleSimply '/about', 'about'
|
||||||
|
handleSimply '/community', 'community-view'
|
||||||
|
handleSimply '/contribute', 'contribute/contribute'
|
||||||
|
handleSimply '/teachers/quote', 'request-quote-view', ->
|
||||||
|
trialRequest:
|
||||||
|
isNew: -> true
|
||||||
|
handleSimply '/courses/teachers', 'courses/teacher-courses-view', ->
|
||||||
|
classrooms:
|
||||||
|
models: []
|
||||||
|
courses:
|
||||||
|
models: []
|
||||||
|
handleSimply '/legal', 'legal'
|
||||||
|
handleSimply '/privacy', 'privacy'
|
||||||
|
|
||||||
|
handle '/play', 'play/campaign-view', (req, res, next) ->
|
||||||
|
opts = makeConext req
|
||||||
|
Campaign.find({type: 'hero'}).exec (err, docs) ->
|
||||||
|
levels = {}
|
||||||
|
docs.forEach (m,k) ->
|
||||||
|
v = m.toObject()
|
||||||
|
levels[v.slug] =
|
||||||
|
attributes:
|
||||||
|
fullName: v.name
|
||||||
|
name: v.name
|
||||||
|
slug: v.slug
|
||||||
|
description: v.description
|
||||||
|
i18n: v.i18n
|
||||||
|
get: (name) -> v[name]
|
||||||
|
|
||||||
|
res.locals.campaigns = levels
|
||||||
|
res.locals.adjacentCampaigns = []
|
||||||
|
res.locals.levels = []
|
||||||
|
opts.showBackground = false
|
||||||
|
next opts
|
||||||
|
|
||||||
|
handle '/play/:campaign', 'play/campaign-view', (req, res, next) ->
|
||||||
|
opts = makeContext req
|
||||||
|
Campaign.findOne({type: 'hero', slug: req.params.campaign}).exec (err, doc) ->
|
||||||
|
levels = {}
|
||||||
|
v = doc.toObject()
|
||||||
|
|
||||||
|
res.locals.campaign =
|
||||||
|
attributes:
|
||||||
|
fullName: v.name
|
||||||
|
name: v.name
|
||||||
|
slug: v.slug
|
||||||
|
description: v.description
|
||||||
|
i18n: v.i18n
|
||||||
|
get: (name) -> v[name]
|
||||||
|
res.locals.adjacentCampaigns = []
|
||||||
|
res.locals.levelStatusMap = {}
|
||||||
|
res.locals.levelDifficultyMap = {}
|
||||||
|
res.locals.levelPlayCountMap = {}
|
||||||
|
res.locals.marked = (o) -> o
|
||||||
|
res.locals.levels = v.levels
|
||||||
|
opts.dontActuallyShow = true
|
||||||
|
opts.showBackground = false
|
||||||
|
next opts
|
||||||
|
|
||||||
|
handle '/play/level/:level', 'play/level', (req, res, next) ->
|
||||||
|
opts = makeContext req
|
||||||
|
Level.findOne({slug: req.params.level}).exec (err, doc) ->
|
||||||
|
opts.showBackground = false
|
||||||
|
opts.dontActuallyShow = true
|
||||||
|
next opts
|
||||||
|
|
||||||
|
|
||||||
|
exports.renderMain = renderMain = (req,res) ->
|
||||||
|
user = if req.user then JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') else '{}'
|
||||||
|
res.locals.pageContent = res.locals.pageContent || '!'
|
||||||
|
Mandate.findOne({}).cache(5 * 60 * 1000).exec (err, mandate) ->
|
||||||
|
if err
|
||||||
|
log.error "Error getting mandate config: #{err}"
|
||||||
|
configData = {}
|
||||||
|
else
|
||||||
|
configData = _.omit mandate?.toObject() or {}, '_id'
|
||||||
|
configData.picoCTF = config.picoCTF
|
||||||
|
configData.production = config.isProduction
|
||||||
|
|
||||||
|
res.locals.serverConfig = configData
|
||||||
|
res.locals.userObjectTag = user
|
||||||
|
res.locals.amActually = req.session.amActually
|
||||||
|
|
||||||
|
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
|
||||||
|
res.header 'Pragma', 'no-cache'
|
||||||
|
res.header 'Expires', 0
|
||||||
|
res.render 'main.jade'
|
|
@ -16,6 +16,7 @@ config = require './server_config'
|
||||||
auth = require './server/commons/auth'
|
auth = require './server/commons/auth'
|
||||||
routes = require './server/routes'
|
routes = require './server/routes'
|
||||||
UserHandler = require './server/handlers/user_handler'
|
UserHandler = require './server/handlers/user_handler'
|
||||||
|
html = require './server/routes/html'
|
||||||
slack = require './server/slack'
|
slack = require './server/slack'
|
||||||
Mandate = require './server/models/Mandate'
|
Mandate = require './server/models/Mandate'
|
||||||
global.tv4 = require 'tv4' # required for TreemaUtils to work
|
global.tv4 = require 'tv4' # required for TreemaUtils to work
|
||||||
|
@ -193,26 +194,7 @@ setupJavascript404s = (app) ->
|
||||||
|
|
||||||
setupFallbackRouteToIndex = (app) ->
|
setupFallbackRouteToIndex = (app) ->
|
||||||
app.all '*', (req, res) ->
|
app.all '*', (req, res) ->
|
||||||
fs.readFile path.join(__dirname, 'public', 'main.html'), 'utf8', (err, data) ->
|
html.renderMain(req, res)
|
||||||
log.error "Error modifying main.html: #{err}" if err
|
|
||||||
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
|
||||||
user = if req.user then JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/') else '{}'
|
|
||||||
|
|
||||||
Mandate.findOne({}).cache(5 * 60 * 1000).exec (err, mandate) ->
|
|
||||||
if err
|
|
||||||
log.error "Error getting mandate config: #{err}"
|
|
||||||
configData = {}
|
|
||||||
else
|
|
||||||
configData = _.omit mandate?.toObject() or {}, '_id'
|
|
||||||
configData.picoCTF = config.picoCTF
|
|
||||||
configData.production = config.isProduction
|
|
||||||
data = data.replace '"serverConfigTag"', JSON.stringify configData
|
|
||||||
data = data.replace('"userObjectTag"', user)
|
|
||||||
data = data.replace('"amActuallyTag"', JSON.stringify(req.session.amActually))
|
|
||||||
res.header 'Cache-Control', 'no-cache, no-store, must-revalidate'
|
|
||||||
res.header 'Pragma', 'no-cache'
|
|
||||||
res.header 'Expires', 0
|
|
||||||
res.send 200, data
|
|
||||||
|
|
||||||
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
||||||
app.get '/channel.html', (req, res) ->
|
app.get '/channel.html', (req, res) ->
|
||||||
|
@ -242,9 +224,11 @@ exports.setupMailchimp = ->
|
||||||
|
|
||||||
exports.setExpressConfigurationOptions = (app) ->
|
exports.setExpressConfigurationOptions = (app) ->
|
||||||
app.set('port', config.port)
|
app.set('port', config.port)
|
||||||
app.set('views', __dirname + '/app/views')
|
app.set('views', __dirname + '/app/templates')
|
||||||
app.set('view engine', 'jade')
|
app.set('view engine', 'jade')
|
||||||
app.set('view options', { layout: false })
|
app.set('view options', { layout: false, pretty: true })
|
||||||
|
app.locals.basedir = __dirname + '/app'
|
||||||
|
app.locals.pretty = true
|
||||||
app.set('env', if config.isProduction then 'production' else 'development')
|
app.set('env', if config.isProduction then 'production' else 'development')
|
||||||
app.set('json spaces', 0) if config.isProduction
|
app.set('json spaces', 0) if config.isProduction
|
||||||
|
|
||||||
|
|
Reference in a new issue