mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 10:01:40 -05:00
working on search, API, RSS feeds, etc.
This commit is contained in:
parent
19b561df20
commit
5df17c6305
20 changed files with 184 additions and 258 deletions
|
@ -157,6 +157,7 @@ useraccounts:core@1.12.3
|
|||
useraccounts:flow-routing@1.12.3
|
||||
useraccounts:unstyled@1.11.1
|
||||
utilities:avatar@0.9.0
|
||||
utilities:onsubscribed@0.1.0
|
||||
webapp@1.2.0
|
||||
webapp-hashing@1.0.3
|
||||
zimme:active-route@2.3.2
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
* Removed `Telescope.utils.getCurrentTemplate()`;
|
||||
*
|
||||
|
||||
* RSS feed and API can now both accept any post query parameter (`limit`, `view`, `cat`, `before`, `after`, etc.)
|
||||
|
||||
## v0.24 “SubScope2”
|
||||
|
||||
* [BREAKING] Modules data context must now be passed on explicitely using the `moduleData` attribute.
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
serveAPI = function(limitSegment){
|
||||
serveAPI = function(terms){
|
||||
var posts = [];
|
||||
var limit = isNaN(limitSegment) ? 20 : limitSegment; // default limit: 20 posts
|
||||
|
||||
Posts.find({status: Posts.config.STATUS_APPROVED}, {sort: {postedAt: -1}, limit: limit}).forEach(function(post) {
|
||||
var parameters = Posts.parameters.get(terms);
|
||||
|
||||
Posts.find(parameters.find, parameters.options).forEach(function(post) {
|
||||
var url = Posts.getLink(post);
|
||||
var properties = {
|
||||
var postOutput = {
|
||||
title: post.title,
|
||||
headline: post.title, // for backwards compatibility
|
||||
author: post.author,
|
||||
|
@ -15,18 +16,18 @@ serveAPI = function(limitSegment){
|
|||
};
|
||||
|
||||
if(post.body)
|
||||
properties.body = post.body;
|
||||
postOutput.body = post.body;
|
||||
|
||||
if(post.url)
|
||||
properties.domain = Telescope.utils.getDomain(url);
|
||||
postOutput.domain = Telescope.utils.getDomain(url);
|
||||
|
||||
if (post.thumbnailUrl) {
|
||||
properties.thumbnailUrl = Telescope.utils.addHttp(post.thumbnailUrl);
|
||||
postOutput.thumbnailUrl = Telescope.utils.addHttp(post.thumbnailUrl);
|
||||
}
|
||||
|
||||
var twitterName = Users.getTwitterNameById(post.userId);
|
||||
if(twitterName)
|
||||
properties.twitterName = twitterName;
|
||||
postOutput.twitterName = twitterName;
|
||||
|
||||
var comments = [];
|
||||
|
||||
|
@ -60,9 +61,9 @@ serveAPI = function(limitSegment){
|
|||
comments.splice(index,1);
|
||||
});
|
||||
|
||||
properties.comments = comments;
|
||||
postOutput.comments = comments;
|
||||
|
||||
posts.push(properties);
|
||||
posts.push(postOutput);
|
||||
});
|
||||
|
||||
return JSON.stringify(posts);
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
// Meteor.startup(function () {
|
||||
|
||||
// Router.route('api', {
|
||||
// where: 'server',
|
||||
// path: '/api/:limit?',
|
||||
// action: function() {
|
||||
// var limit = parseInt(this.params.limit);
|
||||
// this.response.write(serveAPI(limit));
|
||||
// this.response.end();
|
||||
// }
|
||||
// });
|
||||
|
||||
// });
|
||||
// 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(serveAPI(params.query));
|
||||
});
|
|
@ -34,6 +34,7 @@ Package.onUse(function (api) {
|
|||
'kadira:flow-router@2.6.0',
|
||||
'kadira:blaze-layout@2.1.0',
|
||||
'arillo:flow-router-helpers@0.4.5',
|
||||
'meteorhacks:picker@1.0.3',
|
||||
'dburles:collection-helpers@1.0.3',
|
||||
// 'meteorhacks:flow-router@1.5.0',
|
||||
// 'meteorhacks:flow-layout@1.1.1',
|
||||
|
@ -64,6 +65,7 @@ Package.onUse(function (api) {
|
|||
// 'utilities:state-transitions@0.1.0',
|
||||
'tmeasday:publish-counts@0.7.1',
|
||||
// 'dburles:iron-router-query-array@1.0.1'
|
||||
'utilities:onsubscribed@0.1.0'
|
||||
];
|
||||
|
||||
api.use(packages);
|
||||
|
|
|
@ -5,13 +5,16 @@
|
|||
.top-nav{
|
||||
.desktop-nav{
|
||||
.pages-menu{
|
||||
a{
|
||||
font-weight: normal;
|
||||
.pages-menu-item{
|
||||
display: inline-block;
|
||||
margin-right: 20px;
|
||||
&:last-of-type{
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
a{
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +22,7 @@
|
|||
.side-nav{
|
||||
.pages-menu{
|
||||
order: 2;
|
||||
a{
|
||||
display: block;
|
||||
.pages-menu-item{
|
||||
margin-bottom: 10px;
|
||||
&:last-child{
|
||||
margin: 0;
|
||||
|
@ -31,7 +33,7 @@
|
|||
|
||||
.mobile-nav{
|
||||
.pages-menu{
|
||||
a{
|
||||
.pages-menu-item{
|
||||
border-bottom:1px white(0.2) solid;
|
||||
margin: 0;
|
||||
&:last-of-type{
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
{{#if hasPages}}
|
||||
<div class="pages-menu {{moduleClass}}">
|
||||
{{#each pages}}
|
||||
<div class="pages-menu-item">
|
||||
<a href="{{pathFor 'page' slug=this.slug}}">{{title}}</a>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -4,6 +4,10 @@ Template.feeds.onCreated(function () {
|
|||
template.subscribe('allUsersAdmin');
|
||||
});
|
||||
|
||||
Template.feeds.onSubscribed(function () {
|
||||
console.log("subscription done!");
|
||||
});
|
||||
|
||||
Template.feeds.helpers({
|
||||
feeds: function(){
|
||||
return Feeds.find({}, {sort: {url: 1}});
|
||||
|
|
|
@ -1,63 +1,26 @@
|
|||
// Meteor.startup(function () {
|
||||
Picker.route('/feed.xml', function(params, req, res, next) {
|
||||
if (typeof params.query.view === "undefined") {
|
||||
params.query.view = 'new';
|
||||
}
|
||||
res.end(servePostRSS(params.query, 'feed.xml'));
|
||||
});
|
||||
|
||||
// // New Post RSS
|
||||
Picker.route('/rss/posts/new.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'new'}, '/rss/posts/new.xml'));
|
||||
});
|
||||
|
||||
// Router.route('/feed.xml', function () {
|
||||
// this.response.write(servePostRSS('new', 'feed.xml'));
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'feed',
|
||||
// where: 'server'
|
||||
// });
|
||||
Picker.route('/rss/posts/top.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'top'}, '/rss/posts/top.xml'));
|
||||
});
|
||||
|
||||
// // New Post RSS
|
||||
Picker.route('/rss/posts/best.xml', function(params, req, res, next) {
|
||||
res.end(servePostRSS({view: 'best'}, '/rss/posts/best.xml'));
|
||||
});
|
||||
|
||||
// Router.route('/rss/posts/new.xml', function () {
|
||||
// this.response.write(servePostRSS('top', 'rss/posts/new.xml'));
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'rss_posts_new',
|
||||
// where: 'server'
|
||||
// });
|
||||
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'));
|
||||
});
|
||||
|
||||
// // Categories RSS
|
||||
|
||||
// Router.route('/rss/category/:slug/feed.xml', function () {
|
||||
// this.response.write(servePostRSS('new', '/rss/category/:slug/feed.xml',this.params.slug));
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'rss_posts_category',
|
||||
// where: 'server'
|
||||
// });
|
||||
|
||||
// // Top Post RSS
|
||||
|
||||
// Router.route('/rss/posts/top.xml', function () {
|
||||
// this.response.write(servePostRSS('top', 'rss/posts/top.xml'));
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'rss_posts_top',
|
||||
// where: 'server'
|
||||
// });
|
||||
|
||||
// // Best Post RSS
|
||||
|
||||
// Router.route('/rss/posts/best.xml', function () {
|
||||
// this.response.write(servePostRSS('best', 'rss/posts/best.xml'));
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'rss_posts_best',
|
||||
// where: 'server'
|
||||
// });
|
||||
|
||||
// // Comment RSS
|
||||
|
||||
// Router.route('/rss/comments.xml', function() {
|
||||
// this.response.write(serveCommentRSS());
|
||||
// this.response.end();
|
||||
// }, {
|
||||
// name: 'rss_comments',
|
||||
// where: 'server'
|
||||
// });
|
||||
|
||||
// });
|
||||
Picker.route('/rss/comments.xml', function(params, req, res, next) {
|
||||
res.end(serveCommentRSS());
|
||||
});
|
||||
|
|
|
@ -11,13 +11,9 @@ getMeta = function(url) {
|
|||
};
|
||||
};
|
||||
|
||||
servePostRSS = function(view, url, category) {
|
||||
servePostRSS = function(terms, url) {
|
||||
var feed = new RSS(getMeta(url));
|
||||
|
||||
var terms = {view: view, limit: 20};
|
||||
if (category) {
|
||||
terms.category = category;
|
||||
};
|
||||
var params = Posts.parameters.get(terms);
|
||||
delete params['options']['sort']['sticky'];
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
// Meteor.startup(function () {
|
||||
|
||||
// Posts.controllers.search = Posts.controllers.list.extend({
|
||||
|
||||
// view: 'search',
|
||||
|
||||
// showViewsNav: false,
|
||||
|
||||
// getTitle: function() {
|
||||
// return i18n.t("Search") + ' - ' + Settings.get('title', "Telescope");
|
||||
// },
|
||||
|
||||
// getDescription: function() {
|
||||
// return Settings.get('description');
|
||||
// },
|
||||
|
||||
// onBeforeAction: function() {
|
||||
// var query = this.params.query;
|
||||
// if ('q' in query) {
|
||||
// // if search box has 'empty' class, that means user just deleted last character in search keyword
|
||||
// // but router hasn't updated url, so params.query still has '?q=<LAST CHARACTER>'
|
||||
// // if we set searchQuery in this case, user will see last character pops up again unexpectedly
|
||||
// // so add this check to fix the bug. issue #825
|
||||
// if (!$('.search').hasClass('empty')) {
|
||||
// Session.set('searchQuery', query.q);
|
||||
// }
|
||||
// if (query.q) {
|
||||
// Meteor.call('logSearch', query.q);
|
||||
// }
|
||||
// }
|
||||
// this.next();
|
||||
// },
|
||||
|
||||
// data: function () {
|
||||
|
||||
// var terms = {
|
||||
// view: "search",
|
||||
// limit: this.params.query.limit || Settings.get('postsPerPage', 10),
|
||||
// query: this.params.query.q
|
||||
// };
|
||||
|
||||
// return {searchQuery: this.params.query.q, terms: terms};
|
||||
// }
|
||||
// });
|
||||
|
||||
// Router.onBeforeAction(Router._filters.isAdmin, {only: ['logs']});
|
||||
|
||||
// // Search
|
||||
|
||||
// Router.route('/search', {
|
||||
// name: 'search',
|
||||
// controller: Posts.controllers.search
|
||||
// });
|
||||
|
||||
// // Search Logs
|
||||
|
||||
// Router.route('/logs/:limit?', {
|
||||
// controller: Telescope.controllers.admin,
|
||||
// name: 'searchLogs',
|
||||
// template: 'search_logs',
|
||||
// waitOn: function () {
|
||||
// var limit = this.params.limit || 100;
|
||||
// if(Meteor.isClient) {
|
||||
// Session.set('logsLimit', limit);
|
||||
// }
|
||||
// return Meteor.subscribe('searches', limit);
|
||||
// },
|
||||
// data: function () {
|
||||
// return Searches.find({}, {sort: {timestamp: -1}});
|
||||
// },
|
||||
// fastRender: true
|
||||
// });
|
||||
|
||||
// });
|
|
@ -7,46 +7,44 @@ var delay = (function(){
|
|||
};
|
||||
})();
|
||||
|
||||
Meteor.startup(function () {
|
||||
|
||||
Template.search.helpers({
|
||||
Template.search.helpers({
|
||||
canSearch: function () {
|
||||
return Users.can.view(Meteor.user());
|
||||
},
|
||||
searchQuery: function () {
|
||||
return this.searchQuery;
|
||||
return FlowRouter.getQueryParam("query");
|
||||
},
|
||||
searchQueryEmpty: function () {
|
||||
return this.searchQuery ? "" : "empty";
|
||||
return !!FlowRouter.getQueryParam("query") ? "" : "empty";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Template.search.events({
|
||||
Template.search.events({
|
||||
'keyup .search-field': function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var val = $(e.target).val(),
|
||||
$search = $('.search');
|
||||
|
||||
// if we're not on search route, go to it
|
||||
|
||||
if (FlowRouter.getRouteName() !== "postsDefault") {
|
||||
FlowRouter.go("postsDefault");
|
||||
}
|
||||
|
||||
if (val === '') {
|
||||
// if search field is empty, just do nothing and show an empty template
|
||||
// if search field is empty
|
||||
$search.addClass('empty');
|
||||
// Router.go('search', null, {replaceState: true});
|
||||
val = null;
|
||||
} else {
|
||||
$search.removeClass('empty');
|
||||
// if search field is not empty, add a delay to avoid firing new searches for every keystroke
|
||||
}
|
||||
|
||||
delay(function(){
|
||||
|
||||
// Update the querystring.
|
||||
var opts = {query: {q: val}};
|
||||
// if we're already on the search page, do a replaceState. Otherwise,
|
||||
// just use the pushState default.
|
||||
if(Router.current().route.getName() === 'search') {
|
||||
opts.replaceState = true;
|
||||
}
|
||||
Router.go('search', null, opts);
|
||||
|
||||
FlowRouter.setQueryParams({query: val});
|
||||
}, 700 );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template name="search_logs">
|
||||
<h2>Search Logs</h2>
|
||||
{{# loader ready=Template.subscriptionsReady}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -8,7 +9,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each this}}
|
||||
{{#each searches}}
|
||||
{{#if isNewDate}}
|
||||
<tr class='search-date-header'>
|
||||
<th colspan="2">
|
||||
|
@ -24,7 +25,5 @@
|
|||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="grid more-button">
|
||||
<a class="more-link" href="{{loadMoreUrl}}">{{_ "load_more"}}</a>
|
||||
</div>
|
||||
{{/loader}}
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
Meteor.startup(function () {
|
||||
Template.search_logs.helpers({
|
||||
Template.search_logs.onCreated(function () {
|
||||
var template = this;
|
||||
template.subscribe('searches', 100);
|
||||
});
|
||||
|
||||
Template.search_logs.helpers({
|
||||
searches: function () {
|
||||
return Searches.find({}, {sort: {timestamp: -1}});
|
||||
},
|
||||
getTime: function () {
|
||||
return moment(this.timestamp).format("HH:mm:ss");
|
||||
},
|
||||
|
@ -26,5 +33,4 @@ Meteor.startup(function () {
|
|||
var count = parseInt(Session.get('logsLimit')) + 100;
|
||||
return '/logs/' + count;
|
||||
},
|
||||
});
|
||||
});
|
15
packages/telescope-search/lib/parameters.js
Normal file
15
packages/telescope-search/lib/parameters.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function addSearchQueryParameter (parameters, terms) {
|
||||
if(!!terms.query) {
|
||||
var parameters = Telescope.utils.deepExtend(true, parameters, {
|
||||
find: {
|
||||
$or: [
|
||||
{title: {$regex: terms.query, $options: 'i'}},
|
||||
{url: {$regex: terms.query, $options: 'i'}},
|
||||
{body: {$regex: terms.query, $options: 'i'}}
|
||||
]
|
||||
}
|
||||
});
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
Telescope.callbacks.add("postsParameters", addSearchQueryParameter);
|
14
packages/telescope-search/lib/routes.js
Normal file
14
packages/telescope-search/lib/routes.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
Telescope.menuItems.add("adminMenu", [
|
||||
{
|
||||
route: 'adminSearchLogs',
|
||||
label: 'searchLogs',
|
||||
description: 'telescope_settings_panel'
|
||||
}
|
||||
]);
|
||||
|
||||
Telescope.adminRoutes.route('/search-logs', {
|
||||
name: "adminSearchLogs",
|
||||
action: function(params, queryParams) {
|
||||
BlazeLayout.render("layout", {main: "admin_wrapper", admin: "search_logs"});
|
||||
}
|
||||
});
|
|
@ -13,11 +13,12 @@ Package.onUse(function (api) {
|
|||
|
||||
api.addFiles([
|
||||
'lib/search.js',
|
||||
'lib/routes.js',
|
||||
'lib/parameters.js',
|
||||
'package-tap.i18n'
|
||||
], ['client', 'server']);
|
||||
|
||||
api.addFiles([
|
||||
'lib/client/routes.js',
|
||||
'lib/client/templates/search.html',
|
||||
'lib/client/templates/search.js',
|
||||
'lib/client/templates/search_logs.html',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Telescope.menuItems.add("adminMenu", [
|
||||
{
|
||||
route: 'settings',
|
||||
route: 'adminSettings',
|
||||
label: 'settings',
|
||||
description: 'telescope_settings_panel'
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ Package.onUse(function (api) {
|
|||
'lib/categories.js',
|
||||
'lib/helpers.js',
|
||||
'lib/callbacks.js',
|
||||
'lib/views.js',
|
||||
'lib/parameters.js',
|
||||
'lib/custom_fields.js',
|
||||
'lib/methods.js',
|
||||
'lib/modules.js',
|
||||
|
|
Loading…
Add table
Reference in a new issue