mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
Merging RSS and API packages into example-forum (make them collection-agnostic later)
This commit is contained in:
parent
545bba9fd1
commit
32e90e1b9a
6 changed files with 204 additions and 4 deletions
9
packages/example-forum/lib/modules/headtags.js
Normal file
9
packages/example-forum/lib/modules/headtags.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { Head, Utils } from 'meteor/vulcan:core';
|
||||
|
||||
// add permanent <link /> markup
|
||||
Head.link.push({
|
||||
name: 'rss',
|
||||
rel: 'alternate',
|
||||
type: 'application/rss+xml',
|
||||
href: `${Utils.getSiteUrl()}feed.xml`
|
||||
});
|
|
@ -3,6 +3,7 @@ import './fragments.js';
|
|||
import './components.js';
|
||||
import './config.js';
|
||||
import './routes.js';
|
||||
import './headtags.js';
|
||||
|
||||
export * from './categories/index.js';
|
||||
export * from './comments/index.js';
|
||||
|
|
90
packages/example-forum/lib/server/api.js
Normal file
90
packages/example-forum/lib/server/api.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
import Posts from '../modules/posts/index.js';
|
||||
import Comments from '../modules/comments/index.js';
|
||||
import Users from 'meteor/vulcan:users';
|
||||
import { Utils } from 'meteor/vulcan:core';
|
||||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
|
||||
export const servePostsApi = (terms) => {
|
||||
var posts = [];
|
||||
|
||||
if (!terms.limit) {
|
||||
terms.limit = 50;
|
||||
}
|
||||
|
||||
var parameters = Posts.getParameters(terms);
|
||||
|
||||
const postsCursor = Posts.find(parameters.selector, parameters.options);
|
||||
|
||||
postsCursor.forEach(function(post) {
|
||||
var url = Posts.getLink(post);
|
||||
var postOutput = {
|
||||
title: post.title,
|
||||
headline: post.title, // for backwards compatibility
|
||||
author: post.author,
|
||||
date: post.postedAt,
|
||||
url: url,
|
||||
pageUrl: Posts.getPageUrl(post, true),
|
||||
guid: post._id
|
||||
};
|
||||
|
||||
if(post.body)
|
||||
postOutput.body = post.body;
|
||||
|
||||
if(post.url)
|
||||
postOutput.domain = Utils.getDomain(url);
|
||||
|
||||
if (post.thumbnailUrl) {
|
||||
postOutput.thumbnailUrl = Utils.addHttp(post.thumbnailUrl);
|
||||
}
|
||||
|
||||
var twitterName = Users.getTwitterNameById(post.userId);
|
||||
if(twitterName)
|
||||
postOutput.twitterName = twitterName;
|
||||
|
||||
var comments = [];
|
||||
|
||||
Comments.find({postId: post._id}, {sort: {postedAt: -1}, limit: 50}).forEach(function(comment) {
|
||||
var commentProperties = {
|
||||
body: comment.body,
|
||||
author: comment.author,
|
||||
date: comment.postedAt,
|
||||
guid: comment._id,
|
||||
parentCommentId: comment.parentCommentId
|
||||
};
|
||||
comments.push(commentProperties);
|
||||
});
|
||||
|
||||
var commentsToDelete = [];
|
||||
|
||||
comments.forEach(function(comment, index) {
|
||||
if (comment.parentCommentId) {
|
||||
var parent = comments.filter(function(obj) {
|
||||
return obj.guid === comment.parentCommentId;
|
||||
})[0];
|
||||
if (parent) {
|
||||
parent.replies = parent.replies || [];
|
||||
parent.replies.push(JSON.parse(JSON.stringify(comment)));
|
||||
commentsToDelete.push(index);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
commentsToDelete.reverse().forEach(function(index) {
|
||||
comments.splice(index,1);
|
||||
});
|
||||
|
||||
postOutput.comments = comments;
|
||||
|
||||
posts.push(postOutput);
|
||||
});
|
||||
|
||||
return JSON.stringify(posts);
|
||||
};
|
||||
|
||||
// for backwards compatibility's sake, accept a "limit" segment
|
||||
Picker.route('/api/:limit?', function(params, req, res, next) {
|
||||
if (typeof params.limit !== "undefined") {
|
||||
params.query.limit = params.limit;
|
||||
}
|
||||
res.end(servePostsApi(params.query));
|
||||
});
|
|
@ -14,3 +14,6 @@ import './categories/indexes.js';
|
|||
import './posts/cron.js';
|
||||
import './posts/out.js';
|
||||
import './posts/indexes.js';
|
||||
|
||||
import './api.js';
|
||||
import './rss.js';
|
101
packages/example-forum/lib/server/rss.js
Normal file
101
packages/example-forum/lib/server/rss.js
Normal file
|
@ -0,0 +1,101 @@
|
|||
import RSS from 'rss';
|
||||
import Posts from '../modules/posts/index.js';
|
||||
import Comments from '../modules/comments/index.js';
|
||||
import { Utils, getSetting } from 'meteor/vulcan:core';
|
||||
import { Picker } from 'meteor/meteorhacks:picker';
|
||||
|
||||
Posts.addView('rss', Posts.views.new); // default to 'new' view for RSS feed
|
||||
|
||||
const getMeta = (url) => {
|
||||
const siteUrl = getSetting('siteUrl', Meteor.absoluteUrl());
|
||||
|
||||
return {
|
||||
title: getSetting('title'),
|
||||
description: getSetting('tagline'),
|
||||
feed_url: siteUrl+url,
|
||||
site_url: siteUrl,
|
||||
image_url: siteUrl+'img/favicon.png'
|
||||
};
|
||||
};
|
||||
|
||||
export const servePostRSS = (terms, url) => {
|
||||
const feed = new RSS(getMeta(url));
|
||||
|
||||
let parameters = Posts.getParameters(terms);
|
||||
delete parameters['options']['sort']['sticky'];
|
||||
|
||||
parameters.options.limit = 50;
|
||||
|
||||
const postsCursor = Posts.find(parameters.selector, parameters.options);
|
||||
|
||||
postsCursor.forEach((post) => {
|
||||
|
||||
const description = !!post.body ? post.body+'</br></br>' : '';
|
||||
const feedItem = {
|
||||
title: post.title,
|
||||
description: description + `<a href="${Posts.getPageUrl(post, true)}">Discuss</a>`,
|
||||
author: post.author,
|
||||
date: post.postedAt,
|
||||
guid: post._id,
|
||||
url: (getSetting('RSSLinksPointTo', 'link') === 'link') ? Posts.getLink(post) : Posts.getPageUrl(post, true)
|
||||
};
|
||||
|
||||
if (post.thumbnailUrl) {
|
||||
const url = Utils.addHttp(post.thumbnailUrl);
|
||||
feedItem.custom_elements = [{'imageUrl':url}, {'content': url}];
|
||||
}
|
||||
|
||||
feed.item(feedItem);
|
||||
});
|
||||
|
||||
return feed.xml();
|
||||
};
|
||||
|
||||
export const serveCommentRSS = (terms, url) => {
|
||||
const feed = new RSS(getMeta(url));
|
||||
|
||||
const commentsCursor = Comments.find({isDeleted: {$ne: true}}, {sort: {postedAt: -1}, limit: 20});
|
||||
|
||||
commentsCursor.forEach(function(comment) {
|
||||
const post = Posts.findOne(comment.postId);
|
||||
|
||||
feed.item({
|
||||
title: 'Comment on ' + post.title,
|
||||
description: `${comment.body}</br></br><a href='${Comments.getPageUrl(comment, true)}'>Discuss</a>`,
|
||||
author: comment.author,
|
||||
date: comment.postedAt,
|
||||
url: Comments.getPageUrl(comment, true),
|
||||
guid: comment._id
|
||||
});
|
||||
});
|
||||
|
||||
return feed.xml();
|
||||
};
|
||||
|
||||
|
||||
Picker.route('/feed.xml', function(params, req, res, next) {
|
||||
if (typeof params.query.view === 'undefined') {
|
||||
params.query.view = 'rss';
|
||||
}
|
||||
res.end(servePostRSS(params.query, 'feed.xml'));
|
||||
});
|
||||
|
||||
Picker.route('/rss/posts/new.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'new'}, '/rss/posts/new.xml'));
|
||||
});
|
||||
|
||||
Picker.route('/rss/posts/top.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'top'}, '/rss/posts/top.xml'));
|
||||
});
|
||||
|
||||
Picker.route('/rss/posts/best.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'best'}, '/rss/posts/best.xml'));
|
||||
});
|
||||
|
||||
Picker.route('/rss/category/:slug/feed.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'new', cat: params.slug}, '/rss/category/:slug/feed.xml'));
|
||||
});
|
||||
|
||||
Picker.route('/rss/comments.xml', function(params, req, res, next) {
|
||||
res.end(serveCommentRSS({}, '/rss/comments.xml'));
|
||||
});
|
|
@ -25,10 +25,6 @@ Package.onUse(function (api) {
|
|||
'vulcan:events',
|
||||
'vulcan:embedly',
|
||||
|
||||
// 'vulcan:api',
|
||||
// 'vulcan:rss',
|
||||
// 'vulcan:subscribe',
|
||||
|
||||
]);
|
||||
|
||||
api.addAssets([
|
||||
|
|
Loading…
Add table
Reference in a new issue