Skip to content

Commit

Permalink
Merge branch '0.3.2-wip'
Browse files Browse the repository at this point in the history
Conflicts:
	core/test/unit/api_posts_spec.js
  • Loading branch information
ErisDS committed Oct 10, 2013
2 parents 03ee256 + a37d487 commit 9466a97
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 74 deletions.
2 changes: 1 addition & 1 deletion content/themes/casper
Submodule casper updated 3 files
+2 −2 default.hbs
+1 −1 index.hbs
+1 −1 post.hbs
2 changes: 1 addition & 1 deletion core/client/tpl/list-item.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<a class="permalink{{#if featured}} featured{{/if}}" href="#">
<h3 class="entry-title">{{title}}</h3>
<h3 class="entry-title">{{{title}}}</h3>
<section class="entry-meta">
<time datetime="2013-01-04" class="date">
{{#if published}}
Expand Down
6 changes: 6 additions & 0 deletions core/client/views/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@
this.$('#entry-title').val(this.model.get('title')).focus();
this.$('#entry-markdown').text(this.model.get('markdown'));

this.listenTo(this.model, 'change:title', this.renderTitle);

this.initMarkdown();
this.renderPreview();

Expand Down Expand Up @@ -365,6 +367,10 @@
}
},

renderTitle: function () {
this.$('#entry-title').val(this.model.get('title'));
},

// This is a hack to remove iOS6 white space on orientation change bug
// See: http://cl.ly/RGx9
orientationChange: function () {
Expand Down
21 changes: 15 additions & 6 deletions core/client/views/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

this.addSubview(this.sidebar);

this.listenTo(Ghost.router, "route:settings", this.changePane);
this.listenTo(Ghost.router, 'route:settings', this.changePane);
},

changePane: function (pane) {
Expand Down Expand Up @@ -155,7 +155,8 @@
},

saveSettings: function () {
var title = this.$('#blog-title').val(),
var self = this,
title = this.$('#blog-title').val(),
description = this.$('#blog-description').val(),
email = this.$('#email-address').val(),
postsPerPage = this.$('#postsPerPage').val();
Expand Down Expand Up @@ -186,7 +187,7 @@
}, {
success: this.saveSuccess,
error: this.saveError
});
}).then(function () { self.render(); });
}
},
showLogo: function (e) {
Expand All @@ -212,8 +213,10 @@
self.model.save(data, {
success: self.saveSuccess,
error: self.saveError
}).then(function () {
self.render();
});
self.render();

return true;
},
buttonClass: "button-save right",
Expand Down Expand Up @@ -271,8 +274,9 @@
self.model.save(data, {
success: self.saveSuccess,
error: self.saveError
}).then(function () {
self.render();
});
self.render();
return true;
},
buttonClass: "button-save right",
Expand Down Expand Up @@ -311,7 +315,8 @@
},

saveUser: function () {
var userName = this.$('#user-name').val(),
var self = this,
userName = this.$('#user-name').val(),
userEmail = this.$('#user-email').val(),
userLocation = this.$('#user-location').val(),
userWebsite = this.$('#user-website').val(),
Expand Down Expand Up @@ -350,6 +355,8 @@
}, {
success: this.saveSuccess,
error: this.saveError
}).then(function () {
self.render();
});
}
},
Expand Down Expand Up @@ -393,6 +400,8 @@
status: 'passive'
});
}
}).then(function () {
self.render();
});
}
},
Expand Down
10 changes: 8 additions & 2 deletions core/config-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ function writeConfigFile() {

function validateConfigEnvironment() {
var envVal = process.env.NODE_ENV || 'undefined',
hasHostAndPort,
hasSocket,
config,
parsedUrl;

Expand All @@ -50,6 +52,7 @@ function validateConfigEnvironment() {

}


// Check if we don't even have a config
if (!config) {
errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), "NODE_ENV=" + envVal, 'Ensure your config.js has a section for the current NODE_ENV value');
Expand All @@ -69,9 +72,12 @@ function validateConfigEnvironment() {
return when.reject();
}

hasHostAndPort = config.server && !!config.server.host && !!config.server.port;
hasSocket = config.server && !!config.server.socket;

// Check for valid server host and port values
if (!config.server || !config.server.host || !config.server.port) {
errors.logError(new Error('Your server values (host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
if (!config.server || !(hasHostAndPort || hasSocket)) {
errors.logError(new Error('Your server values (socket, or host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
return when.reject();
}

Expand Down
130 changes: 75 additions & 55 deletions core/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var express = require('express'),
_ = require('underscore'),
colors = require('colors'),
semver = require('semver'),
fs = require('fs'),
slashes = require('connect-slashes'),
errors = require('./server/errorHandling'),
admin = require('./server/controllers/admin'),
Expand Down Expand Up @@ -366,68 +367,87 @@ when(ghost.init()).then(function () {
server.get('/:slug/', frontend.single);
server.get('/', frontend.homepage);

// Are we using sockets? Custom socket or the default?
function getSocket() {
if (ghost.config().server.hasOwnProperty('socket')) {
return _.isString(ghost.config().server.socket) ? ghost.config().server.socket : path.join(__dirname, '../content/', process.env.NODE_ENV + '.socket');
}
return false;
}

function startGhost() {
// Tell users if their node version is not supported, and exit
if (!semver.satisfies(process.versions.node, packageInfo.engines.node)) {
console.log(
"\nERROR: Unsupported version of Node".red,
"\nGhost needs Node version".red,
packageInfo.engines.node.yellow,
"you are using version".red,
process.versions.node.yellow,
"\nPlease go to http://nodejs.org to get the latest version".green
);

process.exit(0);
}

// ## Start Ghost App
server.listen(
ghost.config().server.port,
ghost.config().server.host,
function () {

// Tell users if their node version is not supported, and exit
if (!semver.satisfies(process.versions.node, packageInfo.engines.node)) {
// Startup & Shutdown messages
if (process.env.NODE_ENV === 'production') {
console.log(
"Ghost is running...".green,
"\nYour blog is now available on",
ghost.config().url,
"\nCtrl+C to shut down".grey
);

// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nERROR: Unsupported version of Node".red,
"\nGhost needs Node version".red,
packageInfo.engines.node.yellow,
"you are using version".red,
process.versions.node.yellow,
"\nPlease go to http://nodejs.org to get the latest version".green
"\nGhost has shut down".red,
"\nYour blog is now offline"
);

process.exit(0);
}

// Startup & Shutdown messages
if (process.env.NODE_ENV === 'production') {
});
} else {
console.log(
"Ghost is running...".green,
"\nListening on",
getSocket() || ghost.config().server.host + ':' + ghost.config().server.port,
"\nUrl configured as:",
ghost.config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"Ghost is running...".green,
"\nYour blog is now available on",
ghost.config().url,
"\nCtrl+C to shut down".grey
"\nGhost has shutdown".red,
"\nGhost was running for",
Math.round(process.uptime()),
"seconds"
);
process.exit(0);
});
}

// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shut down".red,
"\nYour blog is now offline"
);
process.exit(0);
});
} else {
console.log(
"Ghost is running...".green,
"\nListening on",
ghost.config().server.host + ':' + ghost.config().server.port,
"\nUrl configured as:",
ghost.config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shutdown".red,
"\nGhost was running for",
Math.round(process.uptime()),
"seconds"
);
process.exit(0);
});
}
// Let everyone know we have finished loading
loading.resolve();
}

// Let everyone know we have finished loading
loading.resolve();
}
);
// ## Start Ghost App
if (getSocket()) {
// Make sure the socket is gone before trying to create another
fs.unlink(getSocket(), function (err) {
server.listen(
getSocket(),
startGhost
);
fs.chmod(getSocket(), '0744');
});

} else {
server.listen(
ghost.config().server.port,
ghost.config().server.host,
startGhost
);
}
}, errors.logAndThrowError);
15 changes: 11 additions & 4 deletions core/server/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ coreHelpers = function (ghost) {
});

ghost.registerThemeHelper('body_class', function (options) {
var classes = [];
var classes = [],
tags = this.post && this.post.tags ? this.post.tags : this.tags || [];

if (_.isString(this.path) && this.path.match(/\/page/)) {
classes.push('archive-template');
} else if (!this.path || this.path === '/' || this.path === '') {
Expand All @@ -200,17 +202,22 @@ coreHelpers = function (ghost) {
classes.push('post-template');
}

if (tags) {
classes = classes.concat(tags.map(function (tag) { return 'tag-' + tag.slug; }));
}

return ghost.doFilter('body_class', classes, function (classes) {
var classString = _.reduce(classes, function (memo, item) { return memo + ' ' + item; }, '');
return new hbs.handlebars.SafeString(classString.trim());
});
});

ghost.registerThemeHelper('post_class', function (options) {
var classes = ['post'];
var classes = ['post'],
tags = this.post && this.post.tags ? this.post.tags : this.tags || [];

if (this.tags) {
classes = classes.concat(this.tags.map(function (tag) { return 'tag-' + tag.name; }));
if (tags) {
classes = classes.concat(tags.map(function (tag) { return 'tag-' + tag.slug; }));
}

return ghost.doFilter('post_class', classes, function (classes) {
Expand Down
2 changes: 1 addition & 1 deletion core/server/helpers/tpl/nav.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<nav id="site-navigation" role="navigation">
<ul>
{{#links}}
<li class="{{#active}}current-menu-item{{/active}}"><a title="{{title}}" href="{{url}}">{{title}}</a></li>
<li class="{{#active}}current-menu-item{{/active}}"><a title="{{{title}}}" href="{{url}}">{{{title}}}</a></li>
{{/links}}
</ul>
</nav>
7 changes: 6 additions & 1 deletion core/server/models/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ var GhostBookshelf,
_ = require('underscore'),
uuid = require('node-uuid'),
config = require('../../../config'),
Validator = require('validator').Validator;
Validator = require('validator').Validator,
sanitize = require('validator').sanitize;

// Initializes Bookshelf as its own instance, so we can modify the Models and not mess up
// others' if they're using the library outside of ghost.
Expand Down Expand Up @@ -78,6 +79,10 @@ GhostBookshelf.Model = GhostBookshelf.Model.extend({
return attrs;
},

sanitize: function (attr) {
return sanitize(this.get(attr)).xss();
},

// #### generateSlug
// Create a string act as the permalink for an object.
generateSlug: function (Model, base) {
Expand Down
2 changes: 1 addition & 1 deletion core/server/models/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Post = GhostBookshelf.Model.extend({

this.set('html', converter.makeHtml(this.get('markdown')));

this.set('title', this.get('title').trim());
this.set('title', this.sanitize('title').trim());

if (this.hasChanged('status') && this.get('status') === 'published') {
if (!this.get('published_at')) {
Expand Down
12 changes: 12 additions & 0 deletions core/server/models/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,19 @@ Settings = GhostBookshelf.Model.extend({
validation[validationName].apply(validation, validationOptions);
}, this);
}
},


saving: function () {

// All blog setting keys that need their values to be escaped.
if (this.get('type') === 'blog' && _.contains(['title', 'description', 'email'], this.get('key'))) {
this.set('value', this.sanitize('value'));
}

return GhostBookshelf.Model.prototype.saving.apply(this, arguments);
}

}, {
read: function (_key) {
// Allow for just passing the key instead of attributes
Expand Down
Loading

0 comments on commit 9466a97

Please sign in to comment.