本文代码基于Typecho构建,handsome主题测试,其他主题理论上不通用。
基于很受欢迎的handsome主题堆出来一个聚合页。
加入了异步加载机制,并支持缓存,默认2小时。
重要提示:假如以下代码文件在handsome文件夹下,使用缓存时,在handsome文件夹下建立cache目录,总之此文件和cache目录必须在同一个目录下。
第一次刷新获取,所有友链将缓存存储在cache目录下,2小时后自动过期。2小时内刷新页面直接取cache文件显示,2小时后过期重新获取新的xml存储在cache目录。如果需要强制更新,删除cache目录下所有文件并重新刷新页面即可。
本地演示如下:
代码逻辑可以参考WordPress篇,这个和WP不同的地方在于没有加入缓存机制,实时的,但是本地测试挺快。
代码如下:
<?php
/**
* RSS朋友圈
*
* @package custom
*/
date_default_timezone_set('Asia/Shanghai'); // 设置时区为上海,即中国标准时间
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
$this->need('component/header.php');
?>
<?php $this->need('component/aside.php'); ?>
<style>.avatar{width:60px;height:60px;border-radius:50%;transition:transform 1s ease-in-out;margin:0 auto}.avatar:hover{transform:rotate(360deg)}.post-content{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:stretch}.post-content-item{flex-basis:100%;display:flex;border:1px dashed #ccc;margin-bottom:20px}.post-content-left{flex-basis:20%;display:flex;flex-direction:column;justify-content:space-around;padding:10px;box-sizing:border-box}.post-content-right{flex-basis:80%;display:flex;flex-direction:column;justify-content:space-between;padding:10px;box-sizing:border-box}.site-name{text-align:center;cursor:pointer}.post-title{cursor:pointer;font-size:1.8rem}.post-content-description{margin-bottom:10px}.author-info{text-align:right}</style>
<main class="app-content-body" <?php Content::returnPageAnimateClass($this); ?>>
<div class="hbox hbox-auto-xs hbox-auto-sm">
<div class="content">
<article class="post">
<div class="post-content">
<?php
$db = Typecho_Db::get();
$links = $db->fetchAll($db->select()->from('table.links'));
$rssFeeds = [];
foreach ($links as $link) {
$url = rtrim($link['url'], '/');
// 判断协议并添加
if (!preg_match('#^https?://#i', $url)) {
$url = 'http://' . $url;
}
if (substr($url, -1) === '/') {
$url .= 'feed';
} else {
$url .= '/feed';
}
// 使用 curl 函数获取远程内容
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
$rssContent = curl_exec($curl);
if ($rssContent === false) {
echo '获取 RSS 内容失败';
continue;
}
$rss = simplexml_load_string($rssContent, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($rss === false) {
echo '解析 RSS 内容失败';
continue;
}
// 获取网站链接
$siteLink = (string) $rss->channel->link;
$items = $rss->channel->item;
foreach ($items as $item) {
$description = (string) $item->description;
if (empty($description)) {
$description = mb_substr(strip_tags((string) $item->content), 0, 60, 'utf-8');
} else {
$description = mb_substr(strip_tags($description), 0, 60, 'utf-8');
}
$rssFeeds[] = [
'title' => (string) $item->title,
'link' => (string) $item->link,
'pubDate' => strtotime((string) $item->pubDate),
'name' => htmlspecialchars($link['name']), // 对数据进行转义
'image' => htmlspecialchars($link['image']), // 对数据进行转义
'description' => htmlspecialchars($description), // 对数据进行转义
'author' => (string) $item->children('dc', true)->creator,
'siteLink' => htmlspecialchars($siteLink), // 网站链接
];
}
}
// 按照更新时间降序排列
usort($rssFeeds, function ($a, $b) {
return $b['pubDate'] - $a['pubDate'];
});
// 显示前30条记录
$rssFeeds = array_slice($rssFeeds, 0, 30);
// 输出友情链接的 RSS 内容
foreach ($rssFeeds as $rssFeed) {
echo '<div class="post-content-item">';
echo '<div class="post-content-left">';
echo '<img class="avatar" src="' . $rssFeed['image'] . '" alt="站标">';
echo '<p class="site-name" onclick="window.open(\'' . $rssFeed['siteLink'] . '\', \'_blank\')">' . $rssFeed['name'] . '</p>';
echo '</div>';
echo '<div class="post-content-right">';
echo '<h3 class="post-title" onclick="window.open(\'' . $rssFeed['link'] . '\', \'_blank\')">' . $rssFeed['title'] . '</h3>';
echo '<p class="post-content-description">' . $rssFeed['description'] . '</p>';
echo '<p class="author-info">作者:' . $rssFeed['author'] . ' | 更新时间:' . date('Y-m-d H:i:s', $rssFeed['pubDate']) . '</p>';
echo '</div>';
echo '</div>';
}
?>
</div>
</article>
</div>
<?php echo WidgetContent::returnRightTriggerHtml() ?>
<?php $this->need('component/sidebar.php'); ?>
</div>
</main>
<?php $this->need('component/footer.php'); ?>
大功告成!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容