Browse Source

added newsroom search

develop
Rob Colbert 5 months ago
parent
commit
8b04feb962
  1. 27
      app/controllers/newsroom.js
  2. 11
      app/models/feed-entry.js
  3. 20
      app/services/feed.js
  4. 7
      app/views/newsroom/components/search-form.pug
  5. 9
      app/views/newsroom/feed-view.pug
  6. 4
      app/views/newsroom/index.pug
  7. 48
      app/views/newsroom/search.pug
  8. 1
      app/views/newsroom/unified-feed.pug
  9. 5
      config/limiter.js

27
app/controllers/newsroom.js

@ -29,17 +29,26 @@ class NewsroomController extends SiteController {
router.param('feedId', this.populateFeedId.bind(this));
router.get('/feed',
router.get(
'/search',
limiterService.createMiddleware(limiterConfig.getSearch),
this.getSearch.bind(this),
);
router.get(
'/feed',
limiterService.createMiddleware(limiterConfig.getUnifiedFeed),
this.getUnifiedFeed.bind(this),
);
router.get('/:feedId',
router.get(
'/:feedId',
limiterService.createMiddleware(limiterConfig.getFeedView),
this.getFeedView.bind(this),
);
router.get('/',
router.get(
'/',
limiterService.createMiddleware(limiterConfig.getIndex),
this.getHome.bind(this),
);
@ -67,6 +76,18 @@ class NewsroomController extends SiteController {
}
}
async getSearch (req, res, next) {
const { feed: feedService } = this.dtp.services;
try {
res.locals.pagination = this.getPaginationParameters(req, 20);
res.locals.newsroom = await feedService.search(req.query.q, res.locals.pagination);
res.render('newsroom/search');
} catch (error) {
this.log.error('failed to search the newsfeed', { error });
return next(error);
}
}
async getUnifiedFeed (req, res) {
const {
feed: feedService,

11
app/models/feed-entry.js

@ -23,6 +23,17 @@ FeedEntrySchema.index({
name: 'feed_entry_by_feed_idx',
});
FeedEntrySchema.index({
title: 'text',
description: 'text',
}, {
weights: {
title: 5,
description: 1,
},
name: 'feed-entry-text-idx',
});
module.exports = (conn) => {
return conn.model('FeedEntry', FeedEntrySchema);
};

20
app/services/feed.js

@ -293,6 +293,26 @@ class FeedService extends SiteService {
});
});
}
async search (query, pagination) {
const search = {
$text: { $search: query },
};
const entries = await FeedEntry
.find(search, { score: { $meta: "textScore" } })
.sort({
score: { $meta: "textScore" },
published: -1,
})
.skip(pagination.skip)
.limit(pagination.cpp)
.populate(this.populateFeedEntry)
.lean();
const totalFeedEntryCount = await FeedEntry.countDocuments(search);
return { entries, totalFeedEntryCount };
}
}
module.exports = {

7
app/views/newsroom/components/search-form.pug

@ -0,0 +1,7 @@
form(method="GET", action="/newsroom/search").uk-form.uk-margin-small
div(uk-grid).uk-grid-small
.uk-width-expand
input(id="search", name="q", type="text", placeholder="Enter search", value= query.q || undefined).uk-input
.uk-width-auto
button(type="submit").uk-button.dtp-button-secondary.uk-border-rounded
i.fas.fa-search

9
app/views/newsroom/feed-view.pug

@ -3,13 +3,18 @@ block content
include ../components/pagination-bar
section.uk-section.uk-section-default.uk-section-small
section.uk-section.uk-section-default
.uk-container
article.uk-article
.uk-margin-large
.uk-margin
h1.uk-article-title.uk-margin-remove.no-select= feed.title
div(uk-grid)
.uk-width-expand
h1.uk-article-title.uk-margin-remove.no-select= feed.title
.uk-width-auto
a(href="/newsroom", uk-tooltip={ title: 'Return to Newsroom' }).uk-link-reset
i.fas.fa-newspaper
.uk-article-meta
div(uk-grid)

4
app/views/newsroom/index.pug

@ -3,7 +3,7 @@ block content
include ../components/pagination-bar
section.uk-section.uk-section-default.uk-section-small
section.uk-section.uk-section-default
.uk-container
.uk-margin
@ -14,6 +14,8 @@ block content
a(href="/newsroom/feed").uk-button.dtp-button-primary.uk-button-small.uk-border-rounded
span View All
include components/search-form
if Array.isArray(newsroom.feeds) && (newsroom.feeds.length > 0)
div(uk-grid).uk-grid-match
each feed in newsroom.feeds

48
app/views/newsroom/search.pug

@ -0,0 +1,48 @@
extends ../layouts/main
block content
include ../components/pagination-bar
section.uk-section.uk-section-secondary
.uk-container
.some-kinda-header.uk-margin-medium
div(uk-grid)
.uk-width-expand
h1.uk-article-title.uk-margin-remove #{site.name} Newsroom Search
.uk-width-auto
a(href="/newsroom", uk-tooltip={ title: 'Return to Newsroom' })
i.fas.fa-newspaper
include components/search-form
.uk-text-bold #{formatCount(newsroom.totalFeedEntryCount)} articles matching #[code= query.q] at #{site.name}.
section.uk-section.uk-section-default
.uk-container
article.uk-article
.uk-margin
if Array.isArray(newsroom.entries) && (newsroom.entries.length > 0)
ul.uk-list.uk-list-divider
each entry in newsroom.entries
li(data-entry-id= entry._id)
.uk-text-large.uk-text-bold.uk-margin-small
a(href= entry.link, target="shing_reader")= entry.title
.uk-margin-small= entry.description
div(uk-grid).uk-text-small
.uk-width-auto
span.uk-text-muted date:
span.uk-margin-small-left #{moment(entry.published).format('MMM DD, YYYY')}
.uk-width-auto
span.uk-text-muted time:
span.uk-margin-small-left #{moment(entry.published).format('h:mm a')}
.uk-width-expand
span.uk-text-muted source:
span.uk-margin-small-left #[a(href= entry.feed.link, target="_blank")= entry.feed.title]
.uk-width-auto
span.uk-text-muted score:
span.uk-margin-small-left #{numeral(entry.score).format('0,0.00')}
else
div There are no matching feed entries.
.uk-margin
+renderPaginationBar(`/newsroom/search`, newsroom.totalFeedEntryCount, `&q=${query.q}`)

1
app/views/newsroom/unified-feed.pug

@ -9,6 +9,7 @@ block content
article.uk-article
.uk-margin
h1.uk-article-title.uk-margin-remove #{site.name} News Feed
include components/search-form
.uk-text-bold #{formatCount(newsroom.totalFeedEntryCount)} articles indexed by #{site.name} in one chronological feed.
.uk-margin

5
config/limiter.js

@ -293,6 +293,11 @@ module.exports = {
* NewsroomController
*/
newsroom: {
getSearch: {
total: 15,
expire: ONE_MINUTE,
message: 'You are searching the newsroom too quickly',
},
getUnifiedFeed: {
total: 15,
expire: ONE_MINUTE,

Loading…
Cancel
Save