Added RSS/Atom feeds to the news section.
This commit is contained in:
parent
6ecb590c57
commit
fc476ac28c
10 changed files with 232 additions and 4 deletions
25
assets/less/news/feed.less
Normal file
25
assets/less/news/feed.less
Normal file
|
@ -0,0 +1,25 @@
|
|||
.news__feed {
|
||||
display: flex;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 1.5em;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
transition: background-color .2s;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: fade(#fff, 20%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: fade(#fff, 10%);
|
||||
}
|
||||
|
||||
&__icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
6
assets/less/news/feeds.less
Normal file
6
assets/less/news/feeds.less
Normal file
|
@ -0,0 +1,6 @@
|
|||
.news__feeds {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 2px;
|
||||
padding: 2px;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
.news__list {
|
||||
margin: 2px 0;
|
||||
|
||||
&__item {
|
||||
text-decoration: none;
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
@import "preview";
|
||||
@import "sidebar";
|
||||
@import "post";
|
||||
@import "feeds";
|
||||
@import "feed";
|
||||
|
|
|
@ -9,6 +9,7 @@ if (!empty($_GET['n']) && is_string($_GET['n'])) {
|
|||
return;
|
||||
}
|
||||
|
||||
$feedMode = trim($_SERVER['PATH_INFO'] ?? '', '/');
|
||||
$categoryId = !empty($_GET['c']) && is_string($_GET['c']) ? (int)$_GET['c'] : 0;
|
||||
$postId = !empty($_GET['p']) && is_string($_GET['p']) ? (int)$_GET['p'] : 0;
|
||||
|
||||
|
@ -67,8 +68,23 @@ if ($categoryId > 0) {
|
|||
|
||||
$featured = news_posts_get(0, 10, $category['category_id'], true);
|
||||
|
||||
tpl_var('news_pagination', $categoryPagination);
|
||||
echo tpl_render('news.category', compact('category', 'posts', 'featured'));
|
||||
if ($feedMode === 'rss' || $feedMode === 'atom') {
|
||||
header("Content-Type: application/{$feedMode}+xml; charset=utf-8");
|
||||
echo news_feed($feedMode, $posts, [
|
||||
'title' => config_get('Site', 'name') . ' » ' . $category['category_name'],
|
||||
'subtitle' => $category['category_description'],
|
||||
'html-url' => url('news-category', ['category' => $category['category_id']]),
|
||||
'feed-url' => url("news-category-feed-{$feedMode}", ['category' => $category['category_id']]),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
echo tpl_render('news.category', [
|
||||
'category' => $category,
|
||||
'posts' => $posts,
|
||||
'featured' => $featured,
|
||||
'news_pagination' => $categoryPagination,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -94,5 +110,19 @@ if (!$posts) {
|
|||
return;
|
||||
}
|
||||
|
||||
tpl_var('news_pagination', $newsPagination);
|
||||
echo tpl_render('news.index', compact('categories', 'posts'));
|
||||
if ($feedMode === 'rss' || $feedMode === 'atom') {
|
||||
header("Content-Type: application/{$feedMode}+xml; charset=utf-8");
|
||||
echo news_feed($feedMode, $posts, [
|
||||
'title' => config_get('Site', 'name') . ' » Featured News',
|
||||
'subtitle' => 'A live featured news feed.',
|
||||
'html-url' => url('news-index'),
|
||||
'feed-url' => url("news-feed-{$feedMode}"),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
echo tpl_render('news.index', [
|
||||
'categories' => $categories,
|
||||
'posts' => $posts,
|
||||
'news_pagination' => $newsPagination,
|
||||
]);
|
||||
|
|
82
src/news.php
82
src/news.php
|
@ -297,3 +297,85 @@ function news_post_get(int $postId): array
|
|||
$getPost->bindValue(':post_id', $postId);
|
||||
return db_fetch($getPost);
|
||||
}
|
||||
|
||||
function news_feed(string $type, array $posts, array $info): string
|
||||
{
|
||||
$document = new DOMDocument('1.0', 'utf-8');
|
||||
$urlPrefix = url_prefix(false);
|
||||
$htmlUrl = $urlPrefix . $info['html-url'];
|
||||
$feedUrl = $urlPrefix . $info['feed-url'];
|
||||
|
||||
if ($type === 'rss') {
|
||||
$dateFormat = 'r';
|
||||
$rss = $document->appendChild($document->createElement('rss'));
|
||||
$rss->setAttribute('version', '2.0');
|
||||
$rss->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
|
||||
$feed = $rss->appendChild($document->createElement('channel'));
|
||||
$feed->appendChild($document->createElement('ttl', '900'));
|
||||
} else {
|
||||
$dateFormat = 'c';
|
||||
$feed = $document->appendChild($document->createElement('feed'));
|
||||
$feed->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
|
||||
$link = $feed->appendChild($document->createElement('link'));
|
||||
$link->setAttribute('href', $htmlUrl);
|
||||
}
|
||||
|
||||
$feed->appendChild($document->createElement('title', $info['title']));
|
||||
$feed->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'description' : 'subtitle', $info['subtitle']
|
||||
));
|
||||
$feed->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'link' : 'id', $htmlUrl
|
||||
));
|
||||
$feed->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'pubDate' : 'updated',
|
||||
date($dateFormat, strtotime($posts[0]['post_created']))
|
||||
));
|
||||
$link = $feed->appendChild($document->createElement($type === 'rss' ? 'atom:link' : 'link'));
|
||||
$link->setAttribute('rel', 'self');
|
||||
$link->setAttribute('href', $feedUrl);
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$entry = $feed->appendChild($document->createElement($type === 'rss' ? 'item' : 'entry'));
|
||||
$entry->appendChild($document->createElement('title', $post['post_title']));
|
||||
$entry->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'link' : 'id',
|
||||
$urlPrefix . url('news-post', ['post' => $post['post_id']])
|
||||
));
|
||||
$entry->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'pubDate' : 'updated',
|
||||
date($dateFormat, strtotime($post['post_created']))
|
||||
));
|
||||
|
||||
$entry->appendChild($document->createElement(
|
||||
$type === 'rss' ? 'description' : 'summary',
|
||||
first_paragraph($post['post_text'])
|
||||
));
|
||||
|
||||
if ($type === 'rss') {
|
||||
$entry->appendChild($document->createElement(
|
||||
'comments',
|
||||
$urlPrefix . url('news-post-comments', ['post' => $post['post_id']])
|
||||
));
|
||||
$guid = $entry->appendChild($document->createElement(
|
||||
'guid',
|
||||
$urlPrefix . url('news-post', ['post' => $post['post_id']])
|
||||
));
|
||||
$guid->setAttribute('isPermaLink', 'true');
|
||||
} else {
|
||||
$link = $entry->appendChild($document->createElement('link'));
|
||||
$link->setAttribute('href', $urlPrefix . url('news-post', ['post' => $post['post_id']]));
|
||||
$link->setAttribute('type', 'text/html');
|
||||
$html = $entry->appendChild($document->createElement(
|
||||
'content',
|
||||
htmlentities(parse_text($post['post_text'], MSZ_PARSER_MARKDOWN))
|
||||
));
|
||||
$html->setAttribute('type', 'html');
|
||||
$author = $entry->appendChild($document->createElement('author'));
|
||||
$author->appendChild($document->createElement('name', $post['username']));
|
||||
$author->appendChild($document->createElement('uri', $urlPrefix . url('user-profile', ['user' => $post['user_id']])));
|
||||
}
|
||||
}
|
||||
|
||||
return $document->saveXML();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ define('MSZ_URLS', [
|
|||
'news-post' => ['/news.php', ['p' => '<post>']],
|
||||
'news-post-comments' => ['/news.php', ['p' => '<post>'], 'comments'],
|
||||
'news-category' => ['/news.php', ['c' => '<category>', 'page' => '<page>']],
|
||||
'news-feed-rss' => ['/news.php/rss'],
|
||||
'news-category-feed-rss' => ['/news.php/rss', ['c' => '<category>']],
|
||||
'news-feed-atom' => ['/news.php/atom'],
|
||||
'news-category-feed-atom' => ['/news.php/atom', ['c' => '<category>']],
|
||||
|
||||
'forum-index' => ['/forum'],
|
||||
'forum-leaderboard' => ['/forum/leaderboard.php', ['id' => '<id>', 'mode' => '<mode>']],
|
||||
|
|
|
@ -56,4 +56,10 @@
|
|||
<link rel="og:url" href="{{ canonical_url }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if feeds is defined and feeds is iterable %}
|
||||
{% for feed in feeds %}
|
||||
<link rel="alternate" type="application/{{ feed.type }}+xml" title="{{ feed.title|default(feed.type) }}" href="{{ feed.url }}">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
|
|
|
@ -9,6 +9,19 @@
|
|||
'page': news_pagination.page > 2 ? news_pagination.page : 0,
|
||||
}) %}
|
||||
|
||||
{% set feeds = [
|
||||
{
|
||||
'type': 'rss',
|
||||
'title': '',
|
||||
'url': url('news-category-feed-rss', {'category': category.category_id}),
|
||||
},
|
||||
{
|
||||
'type': 'atom',
|
||||
'title': '',
|
||||
'url': url('news-category-feed-atom', {'category': category.category_id}),
|
||||
},
|
||||
] %}
|
||||
|
||||
{% block content %}
|
||||
<div class="news__container">
|
||||
<div class="news__preview__listing">
|
||||
|
@ -41,6 +54,29 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container">
|
||||
{{ container_title('Feeds') }}
|
||||
|
||||
<div class="news__feeds">
|
||||
<a href="{{ url('news-category-feed-atom', {'category': category.category_id}) }}" class="news__feed">
|
||||
<div class="news__feed__icon">
|
||||
<i class="fas fa-rss"></i>
|
||||
</div>
|
||||
<div class="news__feed__type">
|
||||
Atom
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ url('news-category-feed-rss', {'category': category.category_id}) }}" class="news__feed">
|
||||
<div class="news__feed__icon">
|
||||
<i class="fas fa-rss"></i>
|
||||
</div>
|
||||
<div class="news__feed__type">
|
||||
RSS
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -8,6 +8,19 @@
|
|||
}) %}
|
||||
{% set manage_link = '/manage/news.php?v=index' %}
|
||||
|
||||
{% set feeds = [
|
||||
{
|
||||
'type': 'rss',
|
||||
'title': '',
|
||||
'url': url('news-feed-rss'),
|
||||
},
|
||||
{
|
||||
'type': 'atom',
|
||||
'title': '',
|
||||
'url': url('news-feed-atom'),
|
||||
},
|
||||
] %}
|
||||
|
||||
{% block content %}
|
||||
<div class="news__container">
|
||||
<div class="news__preview__listing">
|
||||
|
@ -37,6 +50,29 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
{{ container_title('Feeds') }}
|
||||
|
||||
<div class="news__feeds">
|
||||
<a href="{{ url('news-feed-atom') }}" class="news__feed">
|
||||
<div class="news__feed__icon">
|
||||
<i class="fas fa-rss"></i>
|
||||
</div>
|
||||
<div class="news__feed__type">
|
||||
Atom
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ url('news-feed-rss') }}" class="news__feed">
|
||||
<div class="news__feed__icon">
|
||||
<i class="fas fa-rss"></i>
|
||||
</div>
|
||||
<div class="news__feed__type">
|
||||
RSS
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Add table
Reference in a new issue