mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Merge pull request #4772 from ekulabuhov/4262_NextPrevPostWIP
[API] Retrieve next and previous post
This commit is contained in:
commit
023a37b074
6 changed files with 81 additions and 9 deletions
|
@ -8,7 +8,7 @@ var Promise = require('bluebird'),
|
||||||
utils = require('./utils'),
|
utils = require('./utils'),
|
||||||
|
|
||||||
docName = 'posts',
|
docName = 'posts',
|
||||||
allowedIncludes = ['created_by', 'updated_by', 'published_by', 'author', 'tags', 'fields'],
|
allowedIncludes = ['created_by', 'updated_by', 'published_by', 'author', 'tags', 'fields', 'next', 'previous'],
|
||||||
posts;
|
posts;
|
||||||
|
|
||||||
// ## Helpers
|
// ## Helpers
|
||||||
|
|
|
@ -525,6 +525,9 @@ Post = ghostBookshelf.Model.extend({
|
||||||
findOne: function (data, options) {
|
findOne: function (data, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
|
var withNext = _.contains(options.include, 'next'),
|
||||||
|
withPrev = _.contains(options.include, 'previous');
|
||||||
|
|
||||||
data = _.extend({
|
data = _.extend({
|
||||||
status: 'published'
|
status: 'published'
|
||||||
}, data || {});
|
}, data || {});
|
||||||
|
@ -533,10 +536,50 @@ Post = ghostBookshelf.Model.extend({
|
||||||
delete data.status;
|
delete data.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add related objects
|
// Add related objects, excluding next and previous as they are not real db objects
|
||||||
options.withRelated = _.union(options.withRelated, options.include);
|
options.withRelated = _.union(options.withRelated, _.pull([].concat(options.include), 'next', 'previous'));
|
||||||
|
|
||||||
return ghostBookshelf.Model.findOne.call(this, data, options);
|
return ghostBookshelf.Model.findOne.call(this, data, options).then(function (post) {
|
||||||
|
if ((withNext || withPrev) && post && !post.page) {
|
||||||
|
var postData = post.toJSON(),
|
||||||
|
publishedAt = postData.published_at,
|
||||||
|
prev,
|
||||||
|
next;
|
||||||
|
|
||||||
|
if (withNext) {
|
||||||
|
next = Post.forge().query(function (qb) {
|
||||||
|
qb.where('status', '=', 'published')
|
||||||
|
.andWhere('page', '=', 0)
|
||||||
|
.andWhere('published_at', '>', publishedAt)
|
||||||
|
.orderBy('published_at', 'asc')
|
||||||
|
.limit(1);
|
||||||
|
}).fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withPrev) {
|
||||||
|
prev = Post.forge().query(function (qb) {
|
||||||
|
qb.where('status', '=', 'published')
|
||||||
|
.andWhere('page', '=', 0)
|
||||||
|
.andWhere('published_at', '<', publishedAt)
|
||||||
|
.orderBy('published_at', 'desc')
|
||||||
|
.limit(1);
|
||||||
|
}).fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.join(next, prev)
|
||||||
|
.then(function (nextAndPrev) {
|
||||||
|
if (nextAndPrev[0]) {
|
||||||
|
post.relations.next = nextAndPrev[0];
|
||||||
|
}
|
||||||
|
if (nextAndPrev[1]) {
|
||||||
|
post.relations.previous = nextAndPrev[1];
|
||||||
|
}
|
||||||
|
return post;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return post;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -235,6 +235,32 @@ describe('Post API', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can retrieve next and previous posts', function (done) {
|
||||||
|
request.get(testUtils.API.getApiQuery('posts/3/?include=next,previous'))
|
||||||
|
.set('Authorization', 'Bearer ' + accesstoken)
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect('Cache-Control', testUtils.cacheRules['private'])
|
||||||
|
.expect(200)
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
should.not.exist(res.headers['x-cache-invalidate']);
|
||||||
|
var jsonResponse = res.body;
|
||||||
|
jsonResponse.should.exist;
|
||||||
|
jsonResponse.posts.should.exist;
|
||||||
|
testUtils.API.checkResponse(jsonResponse.posts[0], 'post', ['next', 'previous']);
|
||||||
|
jsonResponse.posts[0].page.should.not.be.ok;
|
||||||
|
|
||||||
|
jsonResponse.posts[0].next.should.be.an.Object;
|
||||||
|
testUtils.API.checkResponse(jsonResponse.posts[0].next, 'post');
|
||||||
|
jsonResponse.posts[0].previous.should.be.an.Object;
|
||||||
|
testUtils.API.checkResponse(jsonResponse.posts[0].previous, 'post');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('can retrieve a static page', function (done) {
|
it('can retrieve a static page', function (done) {
|
||||||
request.get(testUtils.API.getApiQuery('posts/7/'))
|
request.get(testUtils.API.getApiQuery('posts/7/'))
|
||||||
.set('Authorization', 'Bearer ' + accesstoken)
|
.set('Authorization', 'Bearer ' + accesstoken)
|
||||||
|
|
|
@ -162,7 +162,7 @@ describe('Post Model', function () {
|
||||||
|
|
||||||
it('can findOne, returning a dated permalink', function (done) {
|
it('can findOne, returning a dated permalink', function (done) {
|
||||||
var firstPost = 1,
|
var firstPost = 1,
|
||||||
today = new Date(),
|
today = testUtils.DataGenerator.Content.posts[0].published_at,
|
||||||
dd = ('0' + today.getDate()).slice(-2),
|
dd = ('0' + today.getDate()).slice(-2),
|
||||||
mm = ('0' + (today.getMonth() + 1)).slice(-2),
|
mm = ('0' + (today.getMonth() + 1)).slice(-2),
|
||||||
yyyy = today.getFullYear(),
|
yyyy = today.getFullYear(),
|
||||||
|
|
|
@ -242,7 +242,7 @@ describe('Config', function () {
|
||||||
var permalinkSetting = '/:year/:month/:day/:slug/',
|
var permalinkSetting = '/:year/:month/:day/:slug/',
|
||||||
/*jshint unused:false*/
|
/*jshint unused:false*/
|
||||||
testData = testUtils.DataGenerator.Content.posts[2],
|
testData = testUtils.DataGenerator.Content.posts[2],
|
||||||
today = new Date(),
|
today = testData.published_at,
|
||||||
dd = ('0' + today.getDate()).slice(-2),
|
dd = ('0' + today.getDate()).slice(-2),
|
||||||
mm = ('0' + (today.getMonth() + 1)).slice(-2),
|
mm = ('0' + (today.getMonth() + 1)).slice(-2),
|
||||||
yyyy = today.getFullYear(),
|
yyyy = today.getFullYear(),
|
||||||
|
|
|
@ -9,18 +9,21 @@ DataGenerator.Content = {
|
||||||
{
|
{
|
||||||
title: "HTML Ipsum",
|
title: "HTML Ipsum",
|
||||||
slug: "html-ipsum",
|
slug: "html-ipsum",
|
||||||
markdown: "<h1>HTML Ipsum Presents</h1><p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=\"#\">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p><h2>Header Level 2</h2><ol><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ol><blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote><h3>Header Level 3</h3><ul><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ul><pre><code>#header h1 a{display: block;width: 300px;height: 80px;}</code></pre>"
|
markdown: "<h1>HTML Ipsum Presents</h1><p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=\"#\">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p><h2>Header Level 2</h2><ol><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ol><blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote><h3>Header Level 3</h3><ul><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ul><pre><code>#header h1 a{display: block;width: 300px;height: 80px;}</code></pre>",
|
||||||
|
published_at: new Date("2015-01-01")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Ghostly Kitchen Sink",
|
title: "Ghostly Kitchen Sink",
|
||||||
slug: "ghostly-kitchen-sink",
|
slug: "ghostly-kitchen-sink",
|
||||||
markdown: "<h1>HTML Ipsum Presents</h1><p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=\"#\">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p><h2>Header Level 2</h2><ol><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ol><blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote><h3>Header Level 3</h3><ul><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ul><pre><code>#header h1 a{display: block;width: 300px;height: 80px;}</code></pre>"
|
markdown: "<h1>HTML Ipsum Presents</h1><p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=\"#\">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p><h2>Header Level 2</h2><ol><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ol><blockquote><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus magna. Cras in mi at felis aliquet congue. Ut a est eget ligula molestie gravida. Curabitur massa. Donec eleifend, libero at sagittis mollis, tellus est malesuada tellus, at luctus turpis elit sit amet quam. Vivamus pretium ornare est.</p></blockquote><h3>Header Level 3</h3><ul><li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li><li>Aliquam tincidunt mauris eu risus.</li></ul><pre><code>#header h1 a{display: block;width: 300px;height: 80px;}</code></pre>",
|
||||||
|
published_at: new Date("2015-01-02")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Short and Sweet",
|
title: "Short and Sweet",
|
||||||
slug: "short-and-sweet",
|
slug: "short-and-sweet",
|
||||||
markdown: "## testing\n\nmctesters\n\n- test\n- line\n- items",
|
markdown: "## testing\n\nmctesters\n\n- test\n- line\n- items",
|
||||||
html: "<h2 id=\"testing\">testing</h2>\n\n<p>mctesters</p>\n\n<ul>\n<li>test</li>\n<li>line</li>\n<li>items</li>\n</ul>"
|
html: "<h2 id=\"testing\">testing</h2>\n\n<p>mctesters</p>\n\n<ul>\n<li>test</li>\n<li>line</li>\n<li>items</li>\n</ul>",
|
||||||
|
published_at: new Date("2015-01-03")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Not finished yet",
|
title: "Not finished yet",
|
||||||
|
|
Loading…
Add table
Reference in a new issue