WordPress单页模板,友链及博友圈RSS聚合

友链及博友圈RSS聚合单页来自“晨风自定义 for WordPress”插件剥离重构,采用单页模板的方式实现。推荐使用子主题更改代码。

效果截图

友链页面

博友圈页面

使用方法

接下的代码来使用以WordPress官方《twentytwentyone》主题创建子主题为例,按部就班实现友情链接和博友圈RSS聚合功能。

为什么要创建子主题,首先声明这不是必须的,但为了不影响原主题的代码或防止原主题升级时会覆盖已修改的代码,推荐使用子主题。

关于子主题的创建方式可以参考wpjam的《使用 WordPress 的子主题(Child Themes)功能快速制作自己的主题》文章。

即使您没有看wpjam的文章也不用担心,接下来我们将按照步骤创建这些文件和代码。

1. 创建文件

目录结构:

wordpress
├─ wp-content
  ├─ themes(主题文件夹)
    ├─ twentytwentyone(父主题目录)
      ├─ ...
    ├─ my-child(子主题目录)
      ├─ templates(模板目录)
        ├─ my-links.php(友情链接单页模板)
        ├─ my-links-rss.php(博友圈RSS单页模板)
      ├─ functions.php(子主题类库)
      ├─ style.css(子主题声明文件及样式)

共4个文件,3个PHP文件,1个CSS文件。

1.1 创建子主题目录

在WordPress主题目录中创建相应的子主题目录。

子主题目录路径: wp-content -> themes -> my-child

这里的 my-child 为子主题的目录,注意该名称可自定义但不要使用中文字符。

1.2 创建 style.css

文件路径: wp-content -> themes -> my-child -> style.css

下面注释的代码里面,Theme Name为子主题名称可自定义;Template为父主题的目录名称。

创建好style.css文件后,将下面的代码复制粘贴后保存,注意修改Template为您的父主题目录名称,我的父主题名称为twentytwentyone

/*
Theme Name:     My Child
Theme URI:      http://example.com/
Description:    Child theme for the Twenty Twelve theme
Author:         Your name here
Author URI:     http://example.com/about/
Template:       twentytwentyone
Version:        0.1.0
*/

@import url("../twentytwentyone/style.css");

/* 友情链接页面样式 */
.my-links {
	margin-bottom: 30px;
}
.my-links .category {
	margin-bottom: 30px;
}
.my-links .list {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}
.my-links .list .item {
	display: flex;
	position: relative;
	top: 0;
	flex-direction: column;
	justify-content: center;
	width: 190px;
	height: 50px;
	padding-left: 60px;
	padding-right: 5px;
	margin-bottom: 15px;
	font-size: 14px;
	border-radius: 3px;
	background-color: snow;
	box-shadow: 0 0 10px gray;
	overflow: hidden;
	transition: all 0.5s;
	-webkit-transition:all 0.5s;
}
.my-links .list .item:hover {
	top: -3px;
	box-shadow: 0 0 20px gray;
}
.my-links .list .item .image {
	position: absolute;
	top: 0;
	left: 0;
	width: 50px;
	height: 50px;
}
.my-links .list .item .title {
	font-weight: bold;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
}
.my-links .list .item .desc {
	font-size: 12px;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
}

/* 博友圈页面样式 */
.my-links-rss {
	margin-bottom: 30px;
}
.my-links-rss .item {
	position: relative;
	top: 0;
	padding: 15px;
	margin-bottom: 30px;
	border-radius: 10px;
	background-color: rgb(200, 233, 253);
	box-shadow: 0 0 10px gray;
	transition: all 0.5s;
	-webkit-transition:all 0.5s;
}
.my-links-rss .item:hover {
	top: -5px;
	box-shadow: 0 0 20px gray;
}
.my-links-rss .item .title {
	margin-bottom: 15px;
}
.my-links-rss .item .meta {
	margin-bottom: 15px;
	font-size: medium;
}
.my-links-rss .item .desc {
	
}

.feed-info {
	padding: 15px;
	margin-bottom: 30px;
	background-color: lightpink;
	border-radius: 20px;
	box-shadow: 0 0 10px grey;
	font-size: 14px;
}

1.3 创建 functions.php

文件路径:wp-content -> themes -> my-child -> functions.php

该文件内有一个MyLinksAndRSSModel类库,单页模板调用该类库实现功能,可以修改代码中配置项。

复制粘贴以下代码:

<?php
// 引入子主题的style.css
add_action('wp_enqueue_scripts', function () {
    wp_enqueue_style('my-links-style', get_stylesheet_uri(), array(), MY_LINKS_VERSION);
});
    
// 启动MyLinksAndRSSModel(必须)
MyLinksAndRSSModel::getInstance()->run();

/**
 * 
 * 友情链接 & 链接RSS 模块类
 * 
 * @author 阿锋
 * @link https://feng.pub
 *
 */
class MyLinksAndRSSModel {
    
    /**
     * 配置项(可以根据需求修改)
     * @var array
     */
    private $config = [
        // ++++++++++++++++++++++++++++++
        // + 样式外观
        // ++++++++++++++++++++++++++++++
        
        // 链接默认图片地址
        'default_link_image' => 'https://litepress.cn/cravatar/wp-content/uploads/sites/9/2021/07/1.jpg',
        
        
        // ++++++++++++++++++++++++++++++
        // + 友情链接页面相关配置
        // ++++++++++++++++++++++++++++++
        
        // 页面显示的链接分类(填写分类ID数组,示例:[1, 2, 3];可以留空:[],留空表示显示所有分类。)
        'show_links_cats' => [],
        
        // 页面显示的链接分类排序方式(NAME_ASC:分类名称升序;NAME_DESC:分类名称降序;ID_ASC:分类ID升序;ID_DESC:分类ID降序。)
        'show_links_cats_order' => 'ID_ASC',
        
        // 页面显示的链接排序方式(RAND:随机排序;NAME_ASC:链接名称升序;NAME_DESC:链接名称降序;ID_ASC:链接ID升序;ID_DESC:链接ID降序。)
        'show_links_order' => 'RAND',
        
        // ++++++++++++++++++++++++++++++
        // + RSS页面相关配置
        // ++++++++++++++++++++++++++++++
        
        // 设置友情链接分类ID,当下分类链接Feed项目将被显示在RSS页面上(示例:[1, 2, 3];可以留空:[],留空表示显示所有分类)
        'show_rss_links_cats' => [],
        
        // 设置RSS页面显示条数
        'show_rss_items_count' => 50,
        
        // 设置RSS条目显示摘要的字数
        'show_rss_item_desc_word_count' => 100,
        
        // 数据缓存过期时间,单位秒
        'data_cache_expire' => 7200,
        
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // + WP_Cron定时功能
        // + -------------------------------------
        // + 开启该功能后,每隔一小时执行一次检查Feed的功能。
        // + 推荐使用宝塔面板实现WP_Cron功能,使用方法:https://www.wpdaxue.com/baota-wp-cron.html
        // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        
        // 启用WP_Cron功能,开启:true,关闭:false
        'open_check_links_rss_cron' => true,
        
        // wp_cron_hock_name,重复执行的事件名称
        'check_links_rss_cron_hack_name' => 'my_links_check_rss_cron_hook',
        
    ];
    
    // 单例模式私有静态变量
    private static $_instance;
    
    /**
     * 公共静态方法获取静态单例
     * @return MyLinksAndRSSModel
     */
    public static function getInstance($config = []) {
        if (self::$_instance === null) {
            self::$_instance = new MyLinksAndRSSModel();
        }
        if($config) self::$_instance->setConfig($config);
        return self::$_instance;
    }
    
    /**
     * 设置配置项
     * @param array $config
     */
    public function setConfig($config) {
        $this->config = array_merge($this->config, $config);
    }
    
    /**
     * 启动
     */
    public function run() {
        // 定义链接&RSS版本号
        if(!defined('MY_LINKS_VERSION')) define('MY_LINKS_VERSION', '0.0.1');
        
        // 检查是否恢复WP链接功能,如未恢复将自动恢复
        if(has_filter('pre_option_link_manager_enabled') === false) add_filter('pre_option_link_manager_enabled', '__return_true');
        
        $this->myLinksRssCron();
    }
    
    /**
     * 获取链接分类
     * @param int|array $args
     * @return WP_Term[]|number[]|string[]|string|WP_Error
     */
    public function getLinksCats($args = []) {
        $args = array_merge([
            'taxonomy' => 'link_category',
            'orderby' => 'id',
            'order' => 'DESC',
        ], $args);
        $cats = get_terms($args);
        return $cats;
    }
    
    /**
     * 获取要显示的链接分类
     * @param array $args
     * @return WP_Term[]|number[]|string[]|string|WP_Error
     */
    public function getShowLinksCats($args = []){
        switch ($this->config['show_links_cats_order']) {
            case 'NAME_ASC':
                $args['orderby'] = 'name';
                $args['order'] = 'ASC';
                break;
            case 'NAME_DESC':
                $args['orderby'] = 'name';
                $args['order'] = 'DESC';
                break;
            case 'ID_ASC':
                $args['orderby'] = 'id';
                $args['order'] = 'ASC';
                break;
            case 'ID_DESC':
                $args['orderby'] = 'id';
                $args['order'] = 'DESC';
                break;
        }
        if ($this->config['show_links_cats']) $args['include'] = $this->config['show_links_cats'];
        return $this->getLinksCats($args);
    }
    
    /**
     * 获取链接列表
     * @param array $args
     * @return object[]
     */
    private function getLinks($args = []) {
        $args = array_merge([
            'orderby' => 'id',
            'order' => 'DESC',
        ], $args);
        return get_bookmarks($args);
    }
    
    /**
     * 获取页面显示的链接
     * @param array $args
     * @return object[]
     */
    public function getShowLinks($args = []) {
        switch ($this->config['show_links_order']) {
            case 'RAND':
                $args['orderby'] = 'rand';
                break;
            case 'ID_ASC':
                $args['orderby'] = 'id';
                $args['order'] = 'ASC';
                break;
            case 'ID_DESC':
                $args['orderby'] = 'id';
                $args['order'] = 'DESC';
                break;
            case 'NAME_ASC':
                $args['orderby'] = 'name';
                $args['order'] = 'ASC';
                break;
            case 'NAME_DESC':
                $args['orderby'] = 'name';
                $args['order'] = 'DESC';
                break;
            case 'NAME_DESC':
                $args['orderby'] = 'name';
                $args['order'] = 'DESC';
                break;
        }
        return $this->getLinks($args);
    }
    
    /**
     * 获取友情链接模板所需数据
     * @return array
     */
    public function fetchLinksPageData() {
        $linksPageVar = [];
        $cats = $this->getShowLinksCats();
        if ($cats) {
            foreach ($cats as $cat) {
                // 链接分类
                $linksList = $this->getShowLinks(['category' => $cat->term_id]);
                
                $linksPageVar[] = [
                    'category' => $cat,
                    'list' => $linksList
                ];
            }
        }else {
            $linksList = $this->getShowLinks();
            $linksPageVar[] = [
                'category' => [],
                'list' => $linksList
            ];
        }
        return $linksPageVar;
    }
    
    /**
     * 友情链接页面HTML
     * @param string $linkHtmlTemplate
     * @param string $catHtmlTemplate
     * @return string
     */
    public function fetchLinksPage() {
        add_filter('the_content', function ($content) {
            if (! is_page()) {
                return $content;
            }
            return $content .= $this->fetchLinksPageHTML();
        });
    }
    
    /**
     * 渲染友情链接页面HTML
     * @return string
     */
    private function fetchLinksPageHTML() {
        $output = '<div class="my-links">';
        $cats = $this->getShowLinksCats();
        if ($cats) {
            foreach ($cats as $cat) {
                // 链接分类
                $output .= '<h3 class="category" id="my-links-cat-' . $cat->id . '">' . $cat->name . '</h3>';
                $linksList = $this->getShowLinks(['category' => $cat->term_id]);
                $output .= $this->fetchLinksPageListHTML($linksList);
            }
        }else {
            $linksList = $this->getShowLinks();
            $output .= $this->fetchLinksPageListHTML($linksList);
        }
        $output .= '</div>';
        
        return $output;
    }
    
    /**
     * 渲染链接页面HTML,链接列表
     * @param object $linksList
     * @return string
     */
    private function fetchLinksPageListHTML($linksList) {
        $output = '';
        if ($linksList) $output .= '<div class="list">';
        foreach ($linksList as $link) {
            $target = $link->link_target ?  $link->link_target : '_blank';
            $output .= '<div class="item" id="my-links-item-' . $link->link_id . '">';
            $linkImage = $link->link_image ?  $link->link_image : $this->config['default_link_image'];
            $output .= '<a class="image" target="' . $target . '" href="' . $link->link_url . '"><img src="' . $linkImage . '" /></a>';
            $output .= '<a class="title" target="' . $target . '" href="' . $link->link_url . '" title="' . $link->link_name . '">' . $link->link_name . '</a>';
            $output .= '<p class="desc" title="' . $link->link_description . '">' . $link->link_description . '</p>';
            $output .= '</div>';
        }
        if ($linksList) $output .= '</div>';
        return $output;
    }
    
    /**
     * 获取RSS项目
     * @return array
     */
    public function checkLinksRss() {
        // 获取需要被检查的Feed链接
        $feedUrls = $this->getLinksRssUrls();
        if (!$feedUrls) return [];
        
        // 获取结果
        $feed = $this->fetchFeed($feedUrls);
        
        // 记录错误信息
        $error = $feed->error();
        if ($error) {
            $feedUrls = $feed->multifeed_url;
            foreach ($error as $key => $value) {
                $error[$key] = [
                    'feed_url' => $feedUrls[$key],
                    'error' => $value,
                ];
            }
        }
        wp_cache_add('MY_LINKS_RSS_ERROR', $error, '', $this->config['data_cache_expire'] + 600);
        
        // 获取到的RSS数据
        $rssItems = $feed->get_items(0, $this->config['show_links_rss_count']);
        wp_cache_add('MY_LINKS_RSS_ITEMS', $rssItems, '', $this->config['data_cache_expire'] + 600);
        
        // 记录检查Feeds的时间
        wp_cache_add('MY_LINKS_RSS_CHECK_TIME', current_time('Y-m-d H:m:s'), '', $this->config['data_cache_expire'] + 600);
        
        if (!is_page()) echo '<p>' . $this->config['check_links_rss_cron_hack_name'] . ' - OK</p>';
        
        // 返回feed数据
        return $feed;
    }
    
    /**
     * 获取需要被检查的Feed网址
     */
    private function getLinksRssUrls() {
        $links = $this->getLinks(['category' => $this->config['show_rss_links_cats']]);

        $feedSites = [];
        $feedUrls = [];
        foreach ($links as $link) {
            if ($link->link_rss) {
                $feedUrls[] = $link->link_rss;
                $feedSites[] = $link;
            }
        }
        wp_cache_add('MY_LINKS_FEED_SITES', $feedSites, '', $this->config['data_cache_expire'] + 600);
        return $feedUrls;
    }
    
    /**
     * Builds SimplePie object based on RSS or Atom feed from URL.
     * Copy and rewrite source code from wp-includes/feed.php
     * @param string|array $url
     * @return WP_Error|SimplePie
     */
    private function fetchFeed( $url ) {
        if ( ! class_exists( 'SimplePie', false ) ) {
            require_once ABSPATH . WPINC . '/class-simplepie.php';
        }
        
        require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php';
        require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php';
        require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php';
        
        $feed = new SimplePie();
        
        $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
        // We must manually overwrite $feed->sanitize because SimplePie's constructor
        // sets it before we have a chance to set the sanitization class.
        $feed->sanitize = new WP_SimplePie_Sanitize_KSES();
        
        // Register the cache handler using the recommended method for SimplePie 1.3 or later.
        if ( method_exists( 'SimplePie_Cache', 'register' ) ) {
            SimplePie_Cache::register( 'wp_transient', 'WP_Feed_Cache_Transient' );
            $feed->set_cache_location( 'wp_transient' );
        } else {
            // Back-compat for SimplePie 1.2.x.
            require_once ABSPATH . WPINC . '/class-wp-feed-cache.php';
            $feed->set_cache_class( 'WP_Feed_Cache' );
        }
        
        $feed->set_file_class( 'WP_SimplePie_File' );
        
        $feed->set_feed_url( $url );
        /** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */
        // 设置缓存时间
        $feed->set_cache_duration($this->config['data_cache_expire']);
        
        /**
         * Fires just before processing the SimplePie feed object.
         *
         * @since 3.0.0
         *
         * @param SimplePie       $feed SimplePie feed object (passed by reference).
         * @param string|string[] $url  URL of feed or array of URLs of feeds to retrieve.
         */
        do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
        
        $feed->init();
        $feed->set_output_encoding( get_option( 'blog_charset' ) );
        
        return $feed;
    }
    
    /**
     * 获取博友圈RSS页面所需的数据
     */
    public function fetchLinksRssPageData() {
        $checkTime = wp_cache_get('MY_LINKS_RSS_CHECK_TIME');
        $feedSites = wp_cache_get('MY_LINKS_FEED_SITES');
        $feedItems = wp_cache_get('MY_LINKS_RSS_ITEMS');
        $error = wp_cache_get('MY_LINKS_RSS_ERROR');
        return [
            'check_time' => $checkTime,
            'items' => $feedItems,
            'sites' => $feedSites,
            'error' => $error,
        ];
    }
    
    /**
     * 渲染博友圈RSS页面HTML
     * @return string
     */
    public function fetchLinksRssPage() {
        add_filter('the_content', function ($content) {
            if (! is_page()) {
                return $content;
            }
            return $content .= $this->fetchLinksRssPageHTML();
        });
        return '';
    }
    
    /**
     * 渲染博友圈RSS页面HTML
     * @return string
     */
    private function fetchLinksRssPageHTML() {
        $output = '<div class="my-links-rss">';
        
        // 获取检查Feed时间
        $checkRssTime = wp_cache_get('MY_LINKS_RSS_CHECK_TIME');
        if (!$checkRssTime) {
            $this->checkLinksRss();
            $checkRssTime = wp_cache_get('MY_LINKS_RSS_CHECK_TIME');
        }
        
        // WP后台设置的时间格式
        $date_format = get_option('date_format') . ' ' . get_option('time_format');
        
        // 获取RSS缓存数据
        $rssItems = wp_cache_get('MY_LINKS_RSS_ITEMS');
        
        foreach ($rssItems as $item) {
            $blogFeed = $item->get_feed();
            $blogTitle = esc_attr($blogFeed->get_title());
            $blogUrl = esc_url($blogFeed->get_permalink());
            $author = esc_attr($item->get_author()->name);
            $publish_date = wp_date($date_format, $item->get_date('U'));
            $title = esc_attr($item->get_title());
            $permalink = esc_url($item->get_permalink());
            $description = wp_trim_words(sanitize_textarea_field($item->get_description()), $this->config['show_rss_item_desc_word_count'], '...');
            $output .= '<div class="item">';
            $output .= '<div class="title"><h3><a target="_blank" href="' . $permalink . '">' . $title . '</a></h3></div>';
            $output .= '<div class="meta">';
            $output .= '<span>' . $publish_date . '</span><span>「<a target="_blank" href="' . $blogUrl . '">' . $blogTitle .'</a>';
            if ($author) {
                $output .= '<i>(作者:' . $author . ')</i>';
            }
            $output .= '」</span></div>';
            $output .= '<div class="desc">' . $description . '</div>';
            $output .= '</div>';
        }
        $output .= '</div>';
        
        if (current_user_can('manage_options')) {
            $output .= '<div class="feed-info"> <p><b>该卡片仅管理员可见~</b></p>';
            $output .= '<p class="check-time">RSS检查时间:<span>' . $checkRssTime . '</span></p>';
            
            // 获取检查RSS错误缓存数据
            $rssError = wp_cache_get('MY_LINKS_RSS_ERROR');
            if ($rssError) {
                $feedSites = wp_cache_get('MY_LINKS_FEED_SITES');
                $output .= '<table class="error">';
                $output .= '<thead><tr><th>站点</th><th>错误信息</th></tr></thead><tbody>';
                foreach ($rssError as $key => $value) {
                    $site = $feedSites[$key];
                    $feedUrl = $value['feed_url'];
                    $error = $value['error'];
                    $output .= '<tr>';
                    $output .= '<td><p><a target="_blank" href="' . $site->link_url . '">' . $site->link_name . '</a></p><p><a target="_blank" href="' . $feedUrl . '">' . $feedUrl . '</a></p></td>';
                    $output .= '<td>' . $error . '</td>';
                    $output .= '</tr>';
                }
                $output .= '</tbody></table>';
            }else {
                $output .= '<p>All OK</p>';
            }
            $output .= '</div>';
        }
        
        return $output;
    }
    
    /**
     * 定时执行RSS聚合
     */
    public function myLinksRssCron() {
        if ($this->config['open_check_links_rss_cron']) {
            $MyLinksAndRSSModel = MyLinksAndRSSModel::getInstance();
            add_action('my_links_check_rss_cron_hook', array($MyLinksAndRSSModel, 'checkLinksRss'));
            if(!wp_next_scheduled('my_links_check_rss_cron_hook')){
                wp_schedule_event(time(), 'hourly', 'my_links_check_rss_cron_hook');
            }
        }
    }
    
    /**
     * 删除定时执行RSS聚合任务
     */
    public function myLinksRssCronUnset() {
        $timestamp = wp_next_scheduled( 'my_links_check_rss_cron_hook' );
        if ($timestamp) {
            wp_unschedule_event( $timestamp, 'my_links_check_rss_cron_hook' );
        }
    }
}

1.4 创建单页模板 my-links.php

文件路径:wp-content -> themes -> my-child -> themplates -> my-links.php

该文件为参考父主题(twentytwentyone)模板单页编写,提供了两种方法。方法一比较简单,可以通过修改css样式定制。方法二可更改html标签结构定制化程度更高,但需要php基础,可能会花费大量时间。

参考复制粘贴以下代码:

<?php 
/*
 * Template Name: 友情链接
 */
get_header();

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法一 · 开始】输出友情链接页面HTML
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MyLinksAndRSSModel::getInstance()->fetchLinksPage();

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法一 · 结束】输出友情链接页面HTML
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

/* Start the Loop */
while ( have_posts() ) :
the_post();

get_template_part( 'template-parts/content/content-page' );

/**
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法二 · 开始】输出友情链接页面HTML,自定义能力强
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$myLinks = MyLinksAndRSSModel::getInstance()->fetchLinksPageData();
foreach ($myLinks as $item) {
    $category = $item['category'];
    $list = $item['list'];
    if($category){
        ?>
        <h2 id="my-links-cat-<?php echo $category->id; ?>"><?php echo $category->name; ?></h2>
        <?php
    }
    if($list) {
        ?>
        <div>
        <?php 
        foreach ($list as $link) {
        ?>
        <div id="my-links-item-<?php echo $link->link_id ?>">
        	<img src="<?php echo $link->link_image; ?>" />
        	<h3><?php echo $link->link_name; ?></h3>
        	<em><?php echo $link->link_url; ?></em>
        	<p><?php echo $link->link_description;?></p>
        </div>
        <?php 
        }
        ?>
        </div>
        <?php 
    }
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法二 · 结束】输出友情链接页面HTML
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/

// If comments are open or there is at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
    comments_template();
}
endwhile; // End of the loop.

get_footer();

1.5 创建单页模板 my-links-rss.php

文件路径:wp-content -> themes -> my-child -> themplates -> my-links-rss.php

该文件为参考父主题(twentytwentyone)模板单页编写,提供了两种方法。方法一比较简单,可以通过修改css样式定制。方法二可更改html标签结构定制化程度更高,但需要php基础,可能会花费大量时间。

参考复制粘贴以下代码:

<?php
/*
 * Template Name: 博友圈RSS
 */
get_header();

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法一 · 开始】输出博友圈RSS页面HTML
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MyLinksAndRSSModel::getInstance()->fetchLinksRssPage();
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法一 · 结束】输出博友圈RSS页面HTML
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

/* Start the Loop */
while ( have_posts() ) :
the_post();

get_template_part( 'template-parts/content/content-page' );

/**
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法二 · 开始】输出博友圈RSS页面HTML,自定义能力强
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$myLinksRssData = MyLinksAndRSSModel::getInstance()->fetchLinksRssPageData();
if ($myLinksRssData['items']) {
    foreach ($myLinksRssData['items'] as $key => $item) {
        // 博客名称
        $blogTitle = esc_attr($item->get_feed()->get_title());
        // 博客链接
        $blogUrl = esc_url($item->get_feed()->get_permalink());
        // 文章标题
        $title = esc_attr($item->get_title());
        // 文章链接
        $permalink = esc_url($item->get_permalink());
        // 文章作者
        $author = esc_attr($item->get_author()->name);
        // 发布日期
        $publishDate = wp_date('Y-m-d H:m:s', $item->get_date('U'));
        // 文章摘要(截取100个字)
        $description = wp_trim_words(sanitize_textarea_field($item->get_description()), 100, '...');
        ?>
        <div class="card">
        <p><a target="_blank" href="<?php echo $blogUrl ?>"><?php echo $blogTitle ?></a></p>
        <h3><a target="_blank" href="<?php echo $permalink ?>"><?php echo $title ?></h3>
        <p><?php echo $author ?> · <?php echo $publishDate ?></p>
        <p><?php echo $description ?></p>
        </div>
        <?php
    }
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + 【方法二 · 结束】输出博友圈RSS页面HTML,自定义能力强
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/

// If comments are open or there is at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
    comments_template();
}
endwhile; // End of the loop.

get_footer();

恭喜您,截止目前已经创建好文件,接下来需要登录你的WordPress后台操作,马上就成功了。

2. 管理后台设置

2.1 启用子主题

登录管理后台,主题 -> 主题 -> 启用刚才创建的子主题。

启用之后会发现后台管理页面的左侧菜单会多出一个链接菜单。对,这里就是添加链接及分类的地方。

2.2 添加链接

后台管理可添加链接和分类,仪表盘 -> 链接 -> 添加新链接

需要注意的是添加修改链接页面,有一个高级选项卡,里面图片地址为链接图片,RSS地址将被用于博友圈RSS聚合。

2.3 新建页面

又进一步,拿上就能看到效果了。

接下来要创建友情链接及博友圈RSS页面,仪表盘 -> 页面 -> 新建页面

这里要注意的是选择页面模板,点击模板下拉框就会发现可选择的对应项,然后发布或更新页面即可。

点击查看页面即可看到效果,至此友链及博友圈RSS页面全部实现。

说明

该方法采用WordPress集成的SimplePie检查RSS源,采用WP_Corn每隔1小时会执行一次检查更新,其中缓存时间(data_cache_expire)默认设置为7200秒(2小时),您可以修改他,但不建议小于3600秒(1小时)。

相关链接

晨风自定义 for WordPress:https://gitee.com/ouros/feng-custom
SimplePie官网:http://simplepie.org/
创建子主题:https://blog.wpjam.com/article/child-themes/
宝塔面板实现WP_Cron功能:https://www.wpdaxue.com/baota-wp-cron.html

如果您在使用过程中有疑问,联系我或在这里留言。

guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

19 评论
最新
最旧
内联反馈
查看所有评论
段先森

知更鸟自带子主题,我使用上述方法后打开是个空白页,不太理解哪里出问题了

来自甘肃
段先森

好奇怪,没有接收到邮件提醒,还是自己过来看才看到的回复,那我去试试,我主要是想用这个rss聚合功能,实在不行用插件,用插件的话感觉聚合那个页面很卡,不过我看你的挺快。

来自甘肃
Mr.Chou

真不错,还是wp折腾的人多~我表示看看就好。

来自广东
Jeff

正是我要找的。

来自广东
小彦

好看,感谢阿锋友链了个站哈!

来自广东
wu先生

必须安装一个wp测试一下。哈哈。

来自湖北
网友小宋

插件是我喜欢的功能,但是目前使用typecho。所以只能推荐给使用WordPress的朋友们了

来自广东
土木坛子

刚开始吓我一跳,出现的文章标题,哈哈。有心了。

来自广东
Teacher Du

还能调用正文,不错!

来自北京
S̆̈

like

来自江苏
紫慕

厉害,这样就能直接浏览了友链的最新文章了。

来自湖北