2013-05-11 20:44:25 +04:00
|
|
|
/**
|
|
|
|
* Main controller for Ghost frontend
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*global require, module */
|
|
|
|
|
2013-12-06 12:51:35 +04:00
|
|
|
var config = require('../config'),
|
2013-11-28 06:45:01 +04:00
|
|
|
api = require('../api'),
|
|
|
|
RSS = require('rss'),
|
|
|
|
_ = require('underscore'),
|
|
|
|
errors = require('../errorHandling'),
|
|
|
|
when = require('when'),
|
|
|
|
url = require('url'),
|
|
|
|
filters = require('../../server/filters'),
|
2013-12-29 04:15:14 +04:00
|
|
|
coreHelpers = require('../helpers'),
|
2013-05-11 20:44:25 +04:00
|
|
|
|
2013-06-25 15:43:15 +04:00
|
|
|
frontendControllers;
|
2013-05-11 20:44:25 +04:00
|
|
|
|
2013-06-25 15:43:15 +04:00
|
|
|
frontendControllers = {
|
2013-09-17 04:54:36 +04:00
|
|
|
'homepage': function (req, res, next) {
|
2013-12-06 12:51:35 +04:00
|
|
|
// Parse the page number
|
|
|
|
var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
|
|
|
|
postsPerPage,
|
2013-09-05 16:55:28 +04:00
|
|
|
options = {};
|
2013-08-20 06:18:39 +04:00
|
|
|
|
2013-12-06 12:51:35 +04:00
|
|
|
api.settings.read('postsPerPage').then(function (postPP) {
|
|
|
|
postsPerPage = parseInt(postPP.value, 10);
|
|
|
|
// No negative pages
|
|
|
|
if (isNaN(pageParam) || pageParam < 1) {
|
|
|
|
//redirect to 404 page?
|
|
|
|
return res.redirect('/');
|
|
|
|
}
|
|
|
|
options.page = pageParam;
|
2013-09-06 06:09:47 +04:00
|
|
|
|
2013-12-06 12:51:35 +04:00
|
|
|
// Redirect '/page/1/' to '/' for all teh good SEO
|
|
|
|
if (pageParam === 1 && req.route.path === '/page/:page/') {
|
2013-12-28 20:01:08 +04:00
|
|
|
return res.redirect(config.paths().subdir + '/');
|
2013-12-06 12:51:35 +04:00
|
|
|
}
|
2013-09-05 16:55:28 +04:00
|
|
|
|
2013-12-06 12:51:35 +04:00
|
|
|
// No negative posts per page, must be number
|
|
|
|
if (!isNaN(postsPerPage) && postsPerPage > 0) {
|
|
|
|
options.limit = postsPerPage;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}).then(function () {
|
|
|
|
return api.posts.browse(options);
|
|
|
|
}).then(function (page) {
|
2013-08-21 18:05:17 +04:00
|
|
|
var maxPage = page.pages;
|
|
|
|
|
|
|
|
// A bit of a hack for situations with no content.
|
|
|
|
if (maxPage === 0) {
|
|
|
|
maxPage = 1;
|
|
|
|
page.pages = 1;
|
|
|
|
}
|
|
|
|
|
2013-08-18 21:41:55 +04:00
|
|
|
// If page is greater than number of pages we have, redirect to last page
|
2013-08-21 18:05:17 +04:00
|
|
|
if (pageParam > maxPage) {
|
2013-12-28 20:01:08 +04:00
|
|
|
return res.redirect(maxPage === 1 ? config.paths().subdir + '/' : (config.paths().subdir + '/page/' + maxPage + '/'));
|
2013-08-18 21:41:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Render the page of posts
|
2013-11-28 06:45:01 +04:00
|
|
|
filters.doFilter('prePostsRender', page.posts).then(function (posts) {
|
2013-06-25 19:13:19 +04:00
|
|
|
res.render('index', {posts: posts, pagination: {page: page.page, prev: page.prev, next: page.next, limit: page.limit, total: page.total, pages: page.pages}});
|
2013-05-11 20:44:25 +04:00
|
|
|
});
|
2013-09-17 04:54:36 +04:00
|
|
|
}).otherwise(function (err) {
|
2013-11-15 18:27:06 +04:00
|
|
|
var e = new Error(err.message);
|
|
|
|
e.status = err.errorCode;
|
|
|
|
return next(e);
|
2013-06-25 15:43:15 +04:00
|
|
|
});
|
|
|
|
},
|
2013-09-17 04:54:36 +04:00
|
|
|
'single': function (req, res, next) {
|
2013-12-30 11:03:29 +04:00
|
|
|
// From route check if a date was parsed
|
|
|
|
// from the regex
|
2014-01-01 15:17:35 +04:00
|
|
|
var dateInSlug = req.params[0] ? true : false;
|
2013-12-30 11:03:29 +04:00
|
|
|
when.join(
|
|
|
|
api.settings.read('permalinks'),
|
|
|
|
api.posts.read({slug: req.params[1]})
|
|
|
|
).then(function (promises) {
|
|
|
|
var permalink = promises[0].value,
|
|
|
|
post = promises[1];
|
|
|
|
|
|
|
|
function render() {
|
2013-11-28 06:45:01 +04:00
|
|
|
filters.doFilter('prePostsRender', post).then(function (post) {
|
2013-12-06 12:51:35 +04:00
|
|
|
api.settings.read('activeTheme').then(function (activeTheme) {
|
2013-12-30 11:03:29 +04:00
|
|
|
var paths = config.paths().availableThemes[activeTheme.value],
|
|
|
|
view = post.page && paths.hasOwnProperty('page') ? 'page' : 'post';
|
|
|
|
res.render(view, {post: post});
|
2013-12-06 12:51:35 +04:00
|
|
|
});
|
2013-09-17 04:54:36 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-12-30 11:03:29 +04:00
|
|
|
if (!post) {
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
// depending on the permalink setting.
|
|
|
|
// For all other conditions return 404.
|
|
|
|
if (post.page === 1 && dateInSlug === false) {
|
|
|
|
return render();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (post.page === 0) {
|
|
|
|
// Handle post rendering
|
|
|
|
if ((permalink === '/:slug/' && dateInSlug === false) ||
|
|
|
|
(permalink !== '/:slug/' && dateInSlug === true)) {
|
|
|
|
return render();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
next();
|
|
|
|
|
|
|
|
|
2013-09-17 04:54:36 +04:00
|
|
|
}).otherwise(function (err) {
|
2013-11-15 18:27:06 +04:00
|
|
|
var e = new Error(err.message);
|
|
|
|
e.status = err.errorCode;
|
|
|
|
return next(e);
|
2013-06-25 15:43:15 +04:00
|
|
|
});
|
2013-08-28 02:31:43 +04:00
|
|
|
},
|
2013-09-17 04:54:36 +04:00
|
|
|
'rss': function (req, res, next) {
|
2013-08-28 02:31:43 +04:00
|
|
|
// Initialize RSS
|
2013-11-20 17:58:52 +04:00
|
|
|
var siteUrl = config().url,
|
2013-09-16 15:11:17 +04:00
|
|
|
pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
|
|
|
|
feed;
|
|
|
|
//needs refact for multi user to not use first user as default
|
2013-12-30 05:03:30 +04:00
|
|
|
when.settle([
|
2013-12-06 12:51:35 +04:00
|
|
|
api.users.read({id : 1}),
|
|
|
|
api.settings.read('title'),
|
|
|
|
api.settings.read('description')
|
2013-12-30 05:03:30 +04:00
|
|
|
]).then(function (result) {
|
|
|
|
var user = result[0].value,
|
|
|
|
title = result[1].value.value,
|
|
|
|
description = result[2].value.value;
|
|
|
|
|
2013-09-02 05:29:56 +04:00
|
|
|
feed = new RSS({
|
2013-12-06 12:51:35 +04:00
|
|
|
title: title,
|
|
|
|
description: description,
|
2013-09-14 15:12:27 +04:00
|
|
|
generator: 'Ghost v' + res.locals.version,
|
2013-10-17 19:15:25 +04:00
|
|
|
author: user ? user.name : null,
|
2013-09-26 16:52:53 +04:00
|
|
|
feed_url: url.resolve(siteUrl, '/rss/'),
|
2013-09-02 05:29:56 +04:00
|
|
|
site_url: siteUrl,
|
|
|
|
ttl: '60'
|
2013-09-16 15:11:17 +04:00
|
|
|
});
|
2013-08-28 02:31:43 +04:00
|
|
|
|
2013-09-16 15:11:17 +04:00
|
|
|
// No negative pages
|
|
|
|
if (isNaN(pageParam) || pageParam < 1) {
|
2013-12-28 20:01:08 +04:00
|
|
|
return res.redirect(config.paths().subdir + '/rss/');
|
2013-08-28 02:31:43 +04:00
|
|
|
}
|
|
|
|
|
2013-12-28 20:01:08 +04:00
|
|
|
if (pageParam === 1 && req.route.path === config.paths().subdir + '/rss/:page/') {
|
|
|
|
return res.redirect(config.paths().subdir + '/rss/');
|
2013-08-28 02:31:43 +04:00
|
|
|
}
|
|
|
|
|
2013-09-16 15:11:17 +04:00
|
|
|
api.posts.browse({page: pageParam}).then(function (page) {
|
2013-12-29 04:15:14 +04:00
|
|
|
var maxPage = page.pages,
|
|
|
|
feedItems = [];
|
2013-09-16 15:11:17 +04:00
|
|
|
|
|
|
|
// A bit of a hack for situations with no content.
|
|
|
|
if (maxPage === 0) {
|
|
|
|
maxPage = 1;
|
|
|
|
page.pages = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If page is greater than number of pages we have, redirect to last page
|
|
|
|
if (pageParam > maxPage) {
|
2013-12-28 20:01:08 +04:00
|
|
|
return res.redirect(config.paths().subdir + '/rss/' + maxPage + '/');
|
2013-09-16 15:11:17 +04:00
|
|
|
}
|
|
|
|
|
2013-11-28 06:45:01 +04:00
|
|
|
filters.doFilter('prePostsRender', page.posts).then(function (posts) {
|
2013-09-16 15:11:17 +04:00
|
|
|
posts.forEach(function (post) {
|
2013-12-29 04:15:14 +04:00
|
|
|
var deferred = when.defer();
|
|
|
|
post.url = coreHelpers.url;
|
|
|
|
post.url().then(function (postUrl) {
|
|
|
|
var item = {
|
|
|
|
title: _.escape(post.title),
|
|
|
|
guid: post.uuid,
|
|
|
|
url: siteUrl + postUrl,
|
|
|
|
date: post.published_at,
|
|
|
|
categories: _.pluck(post.tags, 'name')
|
|
|
|
},
|
|
|
|
content = post.html;
|
|
|
|
|
|
|
|
//set img src to absolute url
|
|
|
|
content = content.replace(/src=["|'|\s]?([\w\/\?\$\.\+\-;%:@&=,_]+)["|'|\s]?/gi, function (match, p1) {
|
|
|
|
/*jslint unparam:true*/
|
|
|
|
p1 = url.resolve(siteUrl, p1);
|
|
|
|
return "src='" + p1 + "' ";
|
|
|
|
});
|
|
|
|
//set a href to absolute url
|
|
|
|
content = content.replace(/href=["|'|\s]?([\w\/\?\$\.\+\-;%:@&=,_]+)["|'|\s]?/gi, function (match, p1) {
|
|
|
|
/*jslint unparam:true*/
|
|
|
|
p1 = url.resolve(siteUrl, p1);
|
|
|
|
return "href='" + p1 + "' ";
|
|
|
|
});
|
|
|
|
item.description = content;
|
|
|
|
feed.item(item);
|
|
|
|
deferred.resolve();
|
2013-09-26 16:52:53 +04:00
|
|
|
});
|
2013-12-29 04:15:14 +04:00
|
|
|
feedItems.push(deferred.promise);
|
2013-09-16 15:11:17 +04:00
|
|
|
});
|
2013-12-29 04:15:14 +04:00
|
|
|
});
|
|
|
|
when.all(feedItems).then(function () {
|
2013-09-16 15:11:17 +04:00
|
|
|
res.set('Content-Type', 'text/xml');
|
|
|
|
res.send(feed.xml());
|
2013-08-28 02:31:43 +04:00
|
|
|
});
|
|
|
|
});
|
2013-09-17 04:54:36 +04:00
|
|
|
}).otherwise(function (err) {
|
2013-11-15 18:27:06 +04:00
|
|
|
var e = new Error(err.message);
|
|
|
|
e.status = err.errorCode;
|
|
|
|
return next(e);
|
2013-08-28 02:31:43 +04:00
|
|
|
});
|
2013-06-25 15:43:15 +04:00
|
|
|
}
|
|
|
|
};
|
2013-05-11 20:44:25 +04:00
|
|
|
|
2013-10-18 21:18:49 +04:00
|
|
|
module.exports = frontendControllers;
|