友链的朋友圈 RSS的聚合页 (Typecho->handsome主题篇)

本文代码基于Typecho构建,handsome主题测试,其他主题理论上不通用

基于很受欢迎的handsome主题堆出来一个聚合页。

加入了异步加载机制,并支持缓存,默认2小时。

重要提示:假如以下代码文件在handsome文件夹下,使用缓存时,在handsome文件夹下建立cache目录,总之此文件和cache目录必须在同一个目录下。

第一次刷新获取,所有友链将缓存存储在cache目录下,2小时后自动过期。2小时内刷新页面直接取cache文件显示,2小时后过期重新获取新的xml存储在cache目录。如果需要强制更新,删除cache目录下所有文件并重新刷新页面即可。

本地演示如下:

友链的朋友圈 RSS的聚合页 (Typecho->handsome主题篇)-似水流年

代码逻辑可以参考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
喜欢就支持一下吧
点赞10赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容