0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-17 23:44:39 -05:00

Merge pull request #1804 from ErisDS/issue-1803

Date permalinks use published date
This commit is contained in:
Hannah Wolfe 2014-01-01 08:13:32 -08:00
commit 7ff191c661
4 changed files with 136 additions and 123 deletions

View file

@ -4,14 +4,16 @@
/*global require, module */ /*global require, module */
var config = require('../config'), var moment = require('moment'),
api = require('../api'), RSS = require('rss'),
RSS = require('rss'), _ = require('underscore'),
_ = require('underscore'), url = require('url'),
errors = require('../errorHandling'), when = require('when'),
when = require('when'),
url = require('url'), api = require('../api'),
filters = require('../../server/filters'), config = require('../config'),
errors = require('../errorHandling'),
filters = require('../../server/filters'),
coreHelpers = require('../helpers'), coreHelpers = require('../helpers'),
frontendControllers; frontendControllers;
@ -93,6 +95,11 @@ frontendControllers = {
return next(); return next();
} }
// Check that the date in the URL matches the published date of the post, else 404
if (dateInSlug && req.params[0] !== moment(post.published_at).format('YYYY/MM/DD/')) {
return next();
}
// A page can only be rendered when there is no date in the url. // A page can only be rendered when there is no date in the url.
// A post can either be rendered with a date in the url // A post can either be rendered with a date in the url
// depending on the permalink setting. // depending on the permalink setting.

View file

@ -94,9 +94,9 @@ coreHelpers.url = function (options) {
var output = '', var output = '',
self = this, self = this,
tags = { tags = {
year: function () { return moment(self.created_at).format('YYYY'); }, year: function () { return moment(self.published_at).format('YYYY'); },
month: function () { return moment(self.created_at).format('MM'); }, month: function () { return moment(self.published_at).format('MM'); },
day: function () { return moment(self.created_at).format('DD'); }, day: function () { return moment(self.published_at).format('DD'); },
slug: function () { return self.slug; }, slug: function () { return self.slug; },
id: function () { return self.id; } id: function () { return self.id; }
}, },

View file

@ -12,7 +12,7 @@ module.exports = function (server) {
// one for date, and one for the slug. // one for date, and one for the slug.
// Examples: // Examples:
// Given `/plain-slug/` the req.params would be [undefined, 'plain-slug'] // Given `/plain-slug/` the req.params would be [undefined, 'plain-slug']
// Given `/2012/12/24/plain-slug/` the req.params would be ['2012/12/24', 'plain-slug'] // Given `/2012/12/24/plain-slug/` the req.params would be ['2012/12/24/', 'plain-slug']
server.get(/^\/([0-9]{4}\/[0-9]{2}\/[0-9]{2}\/)?([^\/.]*)\/$/, frontend.single); server.get(/^\/([0-9]{4}\/[0-9]{2}\/[0-9]{2}\/)?([^\/.]*)\/$/, frontend.single);
server.get('/', frontend.homepage); server.get('/', frontend.homepage);
}; };

View file

@ -1,11 +1,12 @@
/*globals describe, beforeEach, afterEach, it*/ /*globals describe, beforeEach, afterEach, it*/
var assert = require('assert'), var assert = require('assert'),
should = require('should'), moment = require('moment'),
sinon = require('sinon'), should = require('should'),
when = require('when'), sinon = require('sinon'),
when = require('when'),
// Stuff we are testing // Stuff we are testing
config = require('../../server/config'), config = require('../../server/config'),
api = require('../../server/api'), api = require('../../server/api'),
frontend = require('../../server/controllers/frontend'); frontend = require('../../server/controllers/frontend');
@ -28,38 +29,37 @@ describe('Frontend Controller', function () {
// No tests yet, shows up in coverage report // No tests yet, shows up in coverage report
}); });
describe('single', function() { describe('single', function () {
var mockStaticPost = { var mockStaticPost = {
'status': 'published', 'status': 'published',
'id': 1, 'id': 1,
'title': 'Test static page', 'title': 'Test static page',
'slug': 'test-static-page', 'slug': 'test-static-page',
'markdown': 'Test static page content', 'markdown': 'Test static page content',
'page': 1 'page': 1
}; },
mockPost = {
var mockPost = { 'status': 'published',
'status': 'published', 'id': 2,
'id': 2, 'title': 'Test normal post',
'title': 'Test normal post', 'slug': 'test-normal-post',
'slug': 'test-normal-post', 'markdown': 'The test normal post content',
'markdown': 'The test normal post content', 'page': 0
'page': 0 };
};
beforeEach(function () { beforeEach(function () {
sandbox.stub(api.posts , 'read', function (args) { sandbox.stub(api.posts, 'read', function (args) {
return when(args.slug === mockStaticPost.slug ? mockStaticPost : mockPost); return when(args.slug === mockStaticPost.slug ? mockStaticPost : mockPost);
}); });
apiSettingsStub = sandbox.stub(api.settings , 'read'); apiSettingsStub = sandbox.stub(api.settings, 'read');
apiSettingsStub.withArgs('activeTheme').returns(when({ apiSettingsStub.withArgs('activeTheme').returns(when({
'key': 'activeTheme', 'key': 'activeTheme',
'value': 'casper' 'value': 'casper'
})); }));
sandbox.stub(config , 'paths', function () { sandbox.stub(config, 'paths', function () {
return { return {
'availableThemes': { 'availableThemes': {
'casper': { 'casper': {
@ -74,148 +74,154 @@ describe('Frontend Controller', function () {
}); });
}); });
describe('permalink set to slug', function() { describe('permalink set to slug', function () {
beforeEach(function() { beforeEach(function () {
apiSettingsStub.withArgs('permalinks').returns(when({ apiSettingsStub.withArgs('permalinks').returns(when({
value: '/:slug/' value: '/:slug/'
})); }));
}); });
it('can render a static page', function(done) { it('can render a static page', function (done) {
var req = { var req = {
params: ['', 'test-static-page'] params: [undefined, 'test-static-page']
}; },
res = {
var res = { render: function (view, context) {
render: function(view, context) { assert.equal(view, 'page');
assert.equal(view, 'page'); assert.equal(context.post, mockStaticPost);
assert.equal(context.post, mockStaticPost); done();
done(); }
} };
};
frontend.single(req, res, null); frontend.single(req, res, null);
}); });
it('won\'t render a static page accessed as a date url', function(done) { it('will NOT render a static page accessed as a date url', function (done) {
var req = { var req = {
params: ['2012/12/30', 'test-static-page'] params: ['2012/12/30/', 'test-static-page']
}; },
res = {
render: sinon.spy()
};
var res = { frontend.single(req, res, function () {
render: sinon.spy()
};
frontend.single(req, res, function() {
res.render.called.should.be.false; res.render.called.should.be.false;
done(); done();
}); });
}); });
it('can render a normal post', function(done) { it('can render a normal post', function (done) {
var req = { var req = {
params: ['', 'test-normal-post'] params: [undefined, 'test-normal-post']
}; },
res = {
var res = { render: function (view, context) {
render: function(view, context) { assert.equal(view, 'post');
assert.equal(view, 'post'); assert(context.post, 'Context object has post attribute');
assert(context.post, 'Context object has post attribute'); assert.equal(context.post, mockPost);
assert.equal(context.post, mockPost); done();
done(); }
} };
};
frontend.single(req, res, null); frontend.single(req, res, null);
}); });
it('won\'t render a normal post accessed as a date url', function(done) { it('will NOT render a normal post accessed as a date url', function (done) {
var req = { var req = {
params: ['2012/12/30', 'test-normal-post'] params: ['2012/12/30/', 'test-normal-post']
}; },
res = {
render: sinon.spy()
};
var res = { frontend.single(req, res, function () {
render: sinon.spy()
};
frontend.single(req, res, function() {
res.render.called.should.be.false; res.render.called.should.be.false;
done(); done();
}); });
}); });
}); });
describe('permalink set to date', function() { describe('permalink set to date', function () {
beforeEach(function() { beforeEach(function () {
apiSettingsStub.withArgs('permalinks').returns(when({ apiSettingsStub.withArgs('permalinks').returns(when({
value: '/:year/:month/:day/:slug/' value: '/:year/:month/:day/:slug/'
})); }));
}); });
it('can render a static page', function(done) { it('can render a static page', function (done) {
var req = { var req = {
params: ['', 'test-static-page'] params: [undefined, 'test-static-page']
}; },
res = {
var res = { render: function (view, context) {
render: function(view, context) { assert.equal(view, 'page');
assert.equal(view, 'page'); assert.equal(context.post, mockStaticPost);
assert.equal(context.post, mockStaticPost); done();
done(); }
} };
};
frontend.single(req, res, null); frontend.single(req, res, null);
}); });
it('won\'t render a static page accessed as a date url', function(done) { it('will NOT render a static page accessed as a date url', function (done) {
var req = { var req = {
params: ['2012/12/30', 'test-static-page'] params: ['2012/12/30/', 'test-static-page']
}; },
res = {
render: sinon.spy()
};
var res = { frontend.single(req, res, function () {
render: sinon.spy()
};
frontend.single(req, res, function() {
res.render.called.should.be.false; res.render.called.should.be.false;
done(); done();
}); });
}); });
it('can render a normal post', function(done) { it('can render a normal post', function (done) {
var req = { var date = moment().format('YYYY/MM/DD/'),
params: ['2012/12/30', 'test-normal-post'] req = {
}; params: [date, 'test-normal-post']
},
var res = { res = {
render: function(view, context) { render: function (view, context) {
assert.equal(view, 'post'); assert.equal(view, 'post');
assert(context.post, 'Context object has post attribute'); assert(context.post, 'Context object has post attribute');
assert.equal(context.post, mockPost); assert.equal(context.post, mockPost);
done(); done();
} }
}; };
frontend.single(req, res, null); frontend.single(req, res, null);
}); });
it('won\'t render a normal post accessed as a slug url', function(done) { it('will NOT render a normal post with the wrong date', function (done) {
var date = moment().subtract('days', 1).format('YYYY/MM/DD/'),
req = {
params: [date, 'test-normal-post']
},
res = {
render: sinon.spy()
};
frontend.single(req, res, function () {
res.render.called.should.be.false;
done();
});
});
it('will NOT render a normal post accessed as a slug url', function (done) {
var req = { var req = {
params: ['', 'test-normal-post'] params: [undefined, 'test-normal-post']
}; },
res = {
render: sinon.spy()
};
var res = { frontend.single(req, res, function () {
render: sinon.spy()
};
frontend.single(req, res, function() {
res.render.called.should.be.false; res.render.called.should.be.false;
done(); done();
}); });
}); });
}); });
}); });
}); });