Display article.tags
This commit is contained in:
@@ -329,6 +329,7 @@ async function getArticleCounts(db, year) {
|
||||
async function getArticlesByYearMonth(db, year, month) {
|
||||
const articles = db.prepare(`
|
||||
SELECT
|
||||
id,
|
||||
printf('%d-%02d', year, month) AS year_month,
|
||||
author, title, slug, published_date
|
||||
FROM article
|
||||
@@ -348,7 +349,7 @@ async function getArticlesByYearMonth(db, year, month) {
|
||||
|
||||
async function getArticlesByCategory(db, name, limit, offset) {
|
||||
const articles = db.prepare(`
|
||||
SELECT a.slug, a.title, a.author, a.published_date
|
||||
SELECT a.id, a.slug, a.title, a.author, a.published_date
|
||||
FROM article a
|
||||
JOIN article__category ac ON a.id = ac.article_id
|
||||
JOIN category c ON c.id = ac.category_id
|
||||
@@ -380,7 +381,7 @@ async function countArticlesByCategory(db, name) {
|
||||
|
||||
async function getArticlesByTag(db, name, limit, offset) {
|
||||
const articles = db.prepare(`
|
||||
SELECT a.slug, a.title, a.author, a.published_date
|
||||
SELECT a.id, a.slug, a.title, a.author, a.published_date
|
||||
FROM article a
|
||||
JOIN article__tag a_t ON a.id = a_t.article_id
|
||||
JOIN tag c ON c.id = a_t.tag_id
|
||||
@@ -413,6 +414,45 @@ async function countTags(db) {
|
||||
return count.c
|
||||
}
|
||||
|
||||
function questionMarks(list){
|
||||
let s = ''
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
s += '?, '
|
||||
}
|
||||
return s.replace(/, $/, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of tags for the given list of article ids
|
||||
* @param {Database} db - SQLite3 database instance
|
||||
* @param {Array<Number>} ids - a list of article ids
|
||||
* @returns {Array<Array>} A list of [article.id, tag.name] pairs
|
||||
*/
|
||||
async function getTagsForArticles(db, ids) {
|
||||
const tags = db.prepare(`
|
||||
SELECT a.id, t.name
|
||||
FROM article a
|
||||
JOIN article__tag a_t ON a.id = a_t.article_id
|
||||
JOIN tag t ON t.id = a_t.tag_id
|
||||
WHERE a.id IN (${questionMarks(ids)})
|
||||
ORDER BY a.id, t.name
|
||||
`).all(...ids).reduce((m, a) => {
|
||||
if (!m[a.id]) {
|
||||
m[a.id] = []
|
||||
}
|
||||
m[a.id].push(a.name)
|
||||
return m
|
||||
}, {})
|
||||
return tags
|
||||
}
|
||||
|
||||
function applyTagsToArticles(articles, tags) {
|
||||
return articles.map((a) => {
|
||||
a.tags = tags[a.id]
|
||||
return a
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
db,
|
||||
fetchFeed,
|
||||
@@ -441,5 +481,7 @@ module.exports = {
|
||||
countArticlesByCategory,
|
||||
getArticlesByTag,
|
||||
countArticlesByTag,
|
||||
countTags
|
||||
countTags,
|
||||
getTagsForArticles,
|
||||
applyTagsToArticles
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ module.exports.GET = async (req, res) => {
|
||||
if (period.match(/-/)) {
|
||||
// year-month
|
||||
const [year, month] = period.split(/-/)
|
||||
const articles = await ds.getArticlesByYearMonth(db, year, month)
|
||||
const _articles = await ds.getArticlesByYearMonth(db, year, month)
|
||||
const tags = await ds.getTagsForArticles(db, _articles.map((a) => a.id))
|
||||
const articles = ds.applyTagsToArticles(_articles, tags)
|
||||
const out = await page.render('ad-year-month', { year, month, articles })
|
||||
send(res, 200, out)
|
||||
} else {
|
||||
|
||||
@@ -32,7 +32,9 @@ module.exports.GET = async (req, res) => {
|
||||
const query = qs.parse(req.query)
|
||||
const p = query.p ? parseInt(query.p) : 1
|
||||
const {limit, offset} = pagination.getValuesToPaginate({ currentPage: p, perPage: PER_PAGE })
|
||||
const articles = await ds.getArticlesByCategory(db, name, limit, offset)
|
||||
const _articles = await ds.getArticlesByCategory(db, name, limit, offset)
|
||||
const tags = await ds.getTagsForArticles(db, _articles.map((a) => a.id))
|
||||
const articles = ds.applyTagsToArticles(_articles, tags)
|
||||
const count = await ds.countArticlesByCategory(db, name)
|
||||
const totalPages = pagination.getTotalPages({ totalItems: count, perPage: PER_PAGE })
|
||||
//console.log('category', { articles, path, p, count, totalPages })
|
||||
|
||||
+3
-1
@@ -17,7 +17,9 @@ module.exports.GET = async (req, res) => {
|
||||
const query = qs.parse(req.query)
|
||||
const p = query.p ? parseInt(query.p) : 1
|
||||
const {limit, offset} = pagination.getValuesToPaginate({ currentPage: p, perPage: PER_PAGE })
|
||||
const articles = await ds.getArticlesByTag(db, name, limit, offset)
|
||||
const _articles = await ds.getArticlesByTag(db, name, limit, offset)
|
||||
const tags = await ds.getTagsForArticles(db, _articles.map((a) => a.id))
|
||||
const articles = ds.applyTagsToArticles(_articles, tags)
|
||||
const count = await ds.countArticlesByTag(db, name)
|
||||
const totalPages = pagination.getTotalPages({ totalItems: count, perPage: PER_PAGE })
|
||||
const out = await page.render('tag', { tag, articles, path, p, count, totalPages })
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
<div class="article-link">
|
||||
<h6><a href="https://dailystormer.su<%- art.slug %>"><%- art.title %></a> by <span class="author"><%- art.author %></span></h6>
|
||||
<h6><a href="https://dailystormer.su<%- art.slug %>"><%- art.title %></a></h6>
|
||||
<div class="row" >
|
||||
<div class="three columns" >
|
||||
by <a class="author" href="/search?q=<%- encodeURIComponent(`author:"${art.author}"`) %>"><%- art.author %></a>
|
||||
</div>
|
||||
<div class="seven columns tags" >
|
||||
<% if (art.tags) { %>
|
||||
<% art.tags.forEach((tag) => { %>
|
||||
<a href="/tag/<%- tag.replace(/\s+/g, '-') %>"><%= tag %></a>
|
||||
<% }) %>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+26
-2
@@ -46,6 +46,9 @@
|
||||
<meta name="msapplication-wide310x150logo" content="/images/mstile-310x150.png" />
|
||||
<meta name="msapplication-square310x310logo" content="/images/mstile-310x310.png" />
|
||||
|
||||
<%
|
||||
const linkColor = '#367bad'
|
||||
%>
|
||||
<style>
|
||||
body {
|
||||
margin-top: 2rem;
|
||||
@@ -56,17 +59,38 @@
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.article-link {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.article-link h6 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #367bad;
|
||||
color: <%- linkColor %>;
|
||||
}
|
||||
|
||||
.clean a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tags {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tags a {
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
text-decoration: none;
|
||||
background-color: <%- linkColor %>;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.author {
|
||||
font-weight: bold;
|
||||
cursor: crosshair;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.more {
|
||||
|
||||
Reference in New Issue
Block a user