2
1
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2023-12-13 21:00:40 +01:00

Merge pull request #2617 from sebgie/issue#2604

Post response move pagination -> meta
This commit is contained in:
Hannah Wolfe 2014-04-20 23:33:51 +02:00
commit 0ac9c5037f
10 changed files with 101 additions and 92 deletions

View file

@ -67,12 +67,12 @@
parse: function (resp) {
if (_.isArray(resp.posts)) {
this.limit = resp.limit;
this.currentPage = resp.page;
this.totalPages = resp.pages;
this.totalPosts = resp.total;
this.nextPage = resp.next;
this.prevPage = resp.prev;
this.limit = resp.meta.pagination.limit;
this.currentPage = resp.meta.pagination.page;
this.totalPages = resp.meta.pagination.pages;
this.totalPosts = resp.meta.pagination.total;
this.nextPage = resp.meta.pagination.next;
this.prevPage = resp.meta.pagination.prev;
return resp.posts;
}
return resp;

View file

@ -19,7 +19,8 @@ posts = {
// **takes:** filter / pagination parameters
browse: function browse(options) {
options = options || {};
// only published posts if no user is present
if (!this.user) {
options.status = 'published';
}
@ -39,8 +40,9 @@ posts = {
// **takes:** an identifier (id or slug?)
read: function read(options) {
options = options || {};
// only published posts if no user is present
if (!this.user) {
// only published posts for
options.status = 'published';
}

View file

@ -33,8 +33,8 @@ function getPostPage(options) {
}).then(function (page) {
// A bit of a hack for situations with no content.
if (page.pages === 0) {
page.pages = 1;
if (page.meta.pagination.pages === 0) {
page.meta.pagination.pages = 1;
}
return page;
@ -44,14 +44,7 @@ function getPostPage(options) {
function formatPageResponse(posts, page) {
return {
posts: posts,
pagination: {
page: page.page,
prev: page.prev,
next: page.next,
limit: page.limit,
total: page.total,
pages: page.pages
}
pagination: page.meta.pagination
};
}
@ -79,8 +72,8 @@ frontendControllers = {
return getPostPage(options).then(function (page) {
// If page is greater than number of pages we have, redirect to last page
if (pageParam > page.pages) {
return res.redirect(page.pages === 1 ? config().paths.subdir + '/' : (config().paths.subdir + '/page/' + page.pages + '/'));
if (pageParam > page.meta.pagination.pages) {
return res.redirect(page.meta.pagination.pages === 1 ? config().paths.subdir + '/' : (config().paths.subdir + '/page/' + page.meta.pagination.pages + '/'));
}
// Render the page of posts
@ -116,8 +109,8 @@ frontendControllers = {
return getPostPage(options).then(function (page) {
// If page is greater than number of pages we have, redirect to last page
if (pageParam > page.pages) {
return res.redirect(tagUrl(options.tag, page.pages));
if (pageParam > page.meta.pagination.pages) {
return res.redirect(tagUrl(options.tag, page.meta.pagination.pages));
}
// Render the page of posts
@ -264,9 +257,7 @@ frontendControllers = {
}
}
// TODO: needs refactor for multi user to not use first user as default
return when.settle([
api.users.read.call({user : 'internal'}, {id : 1}),
api.settings.read('title'),
api.settings.read('description'),
api.settings.read('permalinks')
@ -278,13 +269,12 @@ frontendControllers = {
return api.posts.browse(options).then(function (page) {
var user = result[0].value,
title = result[1].value.value,
description = result[2].value.value,
permalinks = result[3].value,
var title = result[0].value.value,
description = result[1].value.value,
permalinks = result[2].value,
siteUrl = config.urlFor('home', null, true),
feedUrl = config.urlFor('rss', null, true),
maxPage = page.pages,
maxPage = page.meta.pagination.pages,
feedItems = [],
feed;
@ -306,7 +296,7 @@ frontendControllers = {
// A bit of a hack for situations with no content.
if (maxPage === 0) {
maxPage = 1;
page.pages = 1;
page.meta.pagination.pages = 1;
}
// If page is greater than number of pages we have, redirect to last page
@ -327,7 +317,7 @@ frontendControllers = {
url: config.urlFor('post', {post: post, permalinks: permalinks}, true),
date: post.published_at,
categories: _.pluck(post.tags, 'name'),
author: user ? user.name : null
author: post.author ? post.author.name : null
},
content = post.html;

View file

@ -656,8 +656,8 @@ coreHelpers.pagination = function (options) {
errors.logAndThrowError('All values must be defined for page, pages, limit and total');
return;
}
if ((!_.isUndefined(this.pagination.next) && !_.isNumber(this.pagination.next))
|| (!_.isUndefined(this.pagination.prev) && !_.isNumber(this.pagination.prev))) {
if ((!_.isNull(this.pagination.next) && !_.isNumber(this.pagination.next))
|| (!_.isNull(this.pagination.prev) && !_.isNumber(this.pagination.prev))) {
errors.logAndThrowError('Invalid value, Next/Prev must be a number');
return;
}

View file

@ -364,22 +364,29 @@ Post = ghostBookshelf.Model.extend({
// Format response of data
.then(function (resp) {
var totalPosts = parseInt(resp[0].aggregate, 10),
data = {
posts: postCollection.toJSON(),
page: parseInt(opts.page, 10),
limit: opts.limit,
pages: Math.ceil(totalPosts / opts.limit),
total: totalPosts
};
pagination = {},
meta = {},
data = {};
if (data.pages > 1) {
if (data.page === 1) {
data.next = data.page + 1;
} else if (data.page === data.pages) {
data.prev = data.page - 1;
pagination['page'] = parseInt(opts.page, 10);
pagination['limit'] = opts.limit;
pagination['pages'] = Math.ceil(totalPosts / opts.limit);
pagination['total'] = totalPosts;
pagination['next'] = null;
pagination['prev'] = null;
data['posts'] = postCollection.toJSON();
data['meta'] = meta;
meta['pagination'] = pagination;
if (pagination.pages > 1) {
if (pagination.page === 1) {
pagination.next = pagination.page + 1;
} else if (pagination.page === pagination.pages) {
pagination.prev = pagination.page - 1;
} else {
data.next = data.page + 1;
data.prev = data.page - 1;
pagination.next = pagination.page + 1;
pagination.prev = pagination.page - 1;
}
}

View file

@ -99,6 +99,7 @@ describe('Post API', function () {
testUtils.API.checkResponse(jsonResponse, 'posts');
jsonResponse.posts.should.have.length(5);
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
testUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
done();
});
});
@ -118,6 +119,7 @@ describe('Post API', function () {
testUtils.API.checkResponse(jsonResponse, 'posts');
jsonResponse.posts.should.have.length(6);
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
testUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
done();
});
@ -140,6 +142,7 @@ describe('Post API', function () {
testUtils.API.checkResponse(jsonResponse, 'posts');
jsonResponse.posts.should.have.length(8);
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
testUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
done();
});
});
@ -159,6 +162,7 @@ describe('Post API', function () {
testUtils.API.checkResponse(jsonResponse, 'posts');
jsonResponse.posts.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
testUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
done();
});
});
@ -178,6 +182,7 @@ describe('Post API', function () {
testUtils.API.checkResponse(jsonResponse, 'posts');
jsonResponse.posts.should.have.length(1);
testUtils.API.checkResponse(jsonResponse.posts[0], 'post');
testUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
done();
});
});

View file

@ -356,72 +356,72 @@ describe('Post Model', function () {
}).then(function () {
return PostModel.findPage({page: 2});
}).then(function (paginationResult) {
paginationResult.page.should.equal(2);
paginationResult.limit.should.equal(15);
paginationResult.meta.pagination.page.should.equal(2);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(4);
paginationResult.posts.length.should.equal(15);
paginationResult.pages.should.equal(4);
return PostModel.findPage({page: 5});
}).then(function (paginationResult) {
paginationResult.page.should.equal(5);
paginationResult.limit.should.equal(15);
paginationResult.meta.pagination.page.should.equal(5);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(4);
paginationResult.posts.length.should.equal(0);
paginationResult.pages.should.equal(4);
return PostModel.findPage({limit: 30});
}).then(function (paginationResult) {
paginationResult.page.should.equal(1);
paginationResult.limit.should.equal(30);
paginationResult.meta.pagination.page.should.equal(1);
paginationResult.meta.pagination.limit.should.equal(30);
paginationResult.meta.pagination.pages.should.equal(2);
paginationResult.posts.length.should.equal(30);
paginationResult.pages.should.equal(2);
return PostModel.findPage({limit: 10, staticPages: true});
}).then(function (paginationResult) {
paginationResult.page.should.equal(1);
paginationResult.limit.should.equal(10);
paginationResult.meta.pagination.page.should.equal(1);
paginationResult.meta.pagination.limit.should.equal(10);
paginationResult.meta.pagination.pages.should.equal(1);
paginationResult.posts.length.should.equal(1);
paginationResult.pages.should.equal(1);
return PostModel.findPage({limit: 10, page: 2, status: 'all'});
}).then(function (paginationResult) {
paginationResult.pages.should.equal(11);
paginationResult.meta.pagination.pages.should.equal(11);
// Test tag filter
return PostModel.findPage({page: 1, tag: 'bacon'});
}).then(function (paginationResult) {
paginationResult.page.should.equal(1);
paginationResult.limit.should.equal(15);
paginationResult.posts.length.should.equal(2);
paginationResult.pages.should.equal(1);
paginationResult.meta.pagination.page.should.equal(1);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(1);
paginationResult.aspect.tag.name.should.equal('bacon');
paginationResult.aspect.tag.slug.should.equal('bacon');
paginationResult.posts.length.should.equal(2);
return PostModel.findPage({page: 1, tag: 'kitchen-sink'});
}).then(function (paginationResult) {
paginationResult.page.should.equal(1);
paginationResult.limit.should.equal(15);
paginationResult.posts.length.should.equal(2);
paginationResult.pages.should.equal(1);
paginationResult.meta.pagination.page.should.equal(1);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(1);
paginationResult.aspect.tag.name.should.equal('kitchen sink');
paginationResult.aspect.tag.slug.should.equal('kitchen-sink');
paginationResult.posts.length.should.equal(2);
return PostModel.findPage({page: 1, tag: 'injection'});
}).then(function (paginationResult) {
paginationResult.page.should.equal(1);
paginationResult.limit.should.equal(15);
paginationResult.posts.length.should.equal(15);
paginationResult.pages.should.equal(2);
paginationResult.meta.pagination.page.should.equal(1);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(2);
paginationResult.aspect.tag.name.should.equal('injection');
paginationResult.aspect.tag.slug.should.equal('injection');
paginationResult.posts.length.should.equal(15);
return PostModel.findPage({page: 2, tag: 'injection'});
}).then(function (paginationResult) {
paginationResult.page.should.equal(2);
paginationResult.limit.should.equal(15);
paginationResult.posts.length.should.equal(11);
paginationResult.pages.should.equal(2);
paginationResult.meta.pagination.page.should.equal(2);
paginationResult.meta.pagination.limit.should.equal(15);
paginationResult.meta.pagination.pages.should.equal(2);
paginationResult.aspect.tag.name.should.equal('injection');
paginationResult.aspect.tag.slug.should.equal('injection');
paginationResult.posts.length.should.equal(11);
done();
}).then(null, done);

View file

@ -40,7 +40,7 @@ describe('Frontend Controller', function () {
};
sandbox.stub(api.posts, 'browse', function () {
return when({posts: {}, pages: 3});
return when({posts: {}, meta: {pagination: { pages: 3}}});
});
apiSettingsStub = sandbox.stub(api.settings, 'read');
@ -183,10 +183,14 @@ describe('Frontend Controller', function () {
beforeEach(function () {
sandbox.stub(api.posts, 'browse', function (args) {
return when({
posts: mockPosts,
page: 1,
pages: 1,
aspect: {tag: mockTags[0]}
posts: mockPosts,
meta: {
pagination: {
page: 1,
pages: 1,
},
},
aspect: {tag: mockTags[0]}
});
});
@ -254,7 +258,7 @@ describe('Frontend Controller', function () {
};
sandbox.stub(api.posts, 'browse', function () {
return when({posts: {}, pages: 3});
return when({posts: {}, meta: {pagination: { pages: 3}}});
});
apiSettingsStub = sandbox.stub(api.settings, 'read');
@ -878,7 +882,7 @@ describe('Frontend Controller', function () {
};
sandbox.stub(api.posts, 'browse', function () {
return when({posts: {}, pages: 3});
return when({posts: {}, meta: {pagination: { pages: 3}}});
});
apiUsersStub = sandbox.stub(api.users, 'read').returns(when({}));

View file

@ -682,7 +682,7 @@ describe('Core Helpers', function () {
});
it('can render single page with no pagination necessary', function () {
var rendered = helpers.pagination.call({pagination: {page: 1, prev: undefined, next: undefined, limit: 15, total: 8, pages: 1}});
var rendered = helpers.pagination.call({pagination: {page: 1, prev: null, next: null, limit: 15, total: 8, pages: 1}});
should.exist(rendered);
// strip out carriage returns and compare.
rendered.string.should.match(paginationRegex);
@ -693,7 +693,7 @@ describe('Core Helpers', function () {
});
it('can render first page of many with older posts link', function () {
var rendered = helpers.pagination.call({pagination: {page: 1, prev: undefined, next: 2, limit: 15, total: 8, pages: 3}});
var rendered = helpers.pagination.call({pagination: {page: 1, prev: null, next: 2, limit: 15, total: 8, pages: 3}});
should.exist(rendered);
rendered.string.should.match(paginationRegex);
@ -715,7 +715,7 @@ describe('Core Helpers', function () {
});
it('can render last page of many with newer posts link', function () {
var rendered = helpers.pagination.call({pagination: {page: 3, prev: 2, next: undefined, limit: 15, total: 8, pages: 3}});
var rendered = helpers.pagination.call({pagination: {page: 3, prev: 2, next: null, limit: 15, total: 8, pages: 3}});
should.exist(rendered);
rendered.string.should.match(paginationRegex);
@ -733,7 +733,7 @@ describe('Core Helpers', function () {
};
};
runErrorTest({pagination: {page: 3, prev: true, next: undefined, limit: 15, total: 8, pages: 3}})
runErrorTest({pagination: {page: 3, prev: true, next: null, limit: 15, total: 8, pages: 3}})
.should.throwError('Invalid value, Next/Prev must be a number');
runErrorTest({pagination: {page: 3, prev: 2, next: true, limit: 15, total: 8, pages: 3}})
.should.throwError('Invalid value, Next/Prev must be a number');
@ -747,13 +747,13 @@ describe('Core Helpers', function () {
runErrorTest({pagination: {page: 3, limit: 15, total: 8}})
.should.throwError('All values must be defined for page, pages, limit and total');
runErrorTest({pagination: {page: null, limit: 15, total: 8, pages: 3}})
runErrorTest({pagination: {page: null, prev: null, next: null, limit: 15, total: 8, pages: 3}})
.should.throwError('Invalid value, check page, pages, limit and total are numbers');
runErrorTest({pagination: {page: 1, limit: null, total: 8, pages: 3}})
runErrorTest({pagination: {page: 1, prev: null, next: null, limit: null, total: 8, pages: 3}})
.should.throwError('Invalid value, check page, pages, limit and total are numbers');
runErrorTest({pagination: {page: 1, limit: 15, total: null, pages: 3}})
runErrorTest({pagination: {page: 1, prev: null, next: null, limit: 15, total: null, pages: 3}})
.should.throwError('Invalid value, check page, pages, limit and total are numbers');
runErrorTest({pagination: {page: 1, limit: 15, total: 8, pages: null}})
runErrorTest({pagination: {page: 1, prev: null, next: null, limit: 15, total: 8, pages: null}})
.should.throwError('Invalid value, check page, pages, limit and total are numbers');
});
});

View file

@ -5,7 +5,8 @@ var _ = require('lodash'),
port = '2369';
schema = "http://",
expectedProperties = {
posts: ['posts', 'page', 'limit', 'pages', 'total'],
posts: ['posts', 'meta'],
pagination: ['page', 'limit', 'pages', 'total', 'next', 'prev'],
post: ['id', 'uuid', 'title', 'slug', 'markdown', 'html', 'meta_title', 'meta_description',
'featured', 'image', 'status', 'language', 'author_id', 'created_at', 'created_by', 'updated_at',
'updated_by', 'published_at', 'published_by', 'page', 'author', 'tags', 'fields'],