WordPress首页调用typecho教程(1.3.0版)

折腾永远都不会停的,2024年的时候,折腾《WordPress首页调用typecho方法!》,当时用的是 Restful 插件。前几天把typecho升级到了最新的1.3.0版,结果功能失效了。原因是Restful 插件直接报 Fatal Error,跟 1.3.0 完全不兼容了。作者也停更了,没办法只能换插件。找了一圈,发现了 Typecho-Api 这个插件(项目地址:https://github.com/Coder-Soder/Typecho-Api),功能够用,但问题来了——API 的返回格式跟 Restful 完全不一样,原来的代码全部要改。

这次折腾比上次久,前后花了大半天,主要踩了几个坑:

1.目录名大小写:Typecho 1.3.0 的自动加载器严格按类名找文件。插件类名是 Api_Action,自动加载器去找 /usr/plugins/Api/Action.php,但插件目录叫 api(小写),Linux 区分大小写,直接 500。改成 Api 就好了。

2.插件默认不返回完整正文和分类:Typecho-Api 插件的 getarticle 接口只返回截断的摘要(summary),不返回完整正文(text),也不返回文章分类(categories)。而我们要在 WordPress 提取文章图片和显示分类名,这两个字段缺一不可。所以必须手动改插件代码。

3.时区问题:API 返回的时间是北京时间字符串,WordPress 服务器如果是 UTC,用 strtotime() 直接解析会差 8 小时。加个 ‘ +0800’ 就搞定。

4.Markdown 图片:typecho 文章用 Markdown 写,图片是 ![alt](https:) 格式,不是 HTML 的 <img> 标签。原来只匹配 <img> 的正则根本抓不到图片,得两种格式都匹配。

下面直接上代码,一共四步。

第零步(重点!重点!重点!):修改 Typecho-Api 插件的 Action.php

这步不做,后面全部白搭。插件默认的 getarticle 接口只返回摘要不返回正文,也不返回分类。我们需要改两处。

找到 /usr/plugins/Api/Action.php(注意目录名大写 Api),搜索 getarticle,在那个方法里改两处:

第一处:加分类查询。 找到获取 tags 的代码:

$tagQuery = $db->select('name')->from($prefix . 'metas')
    ->join($prefix . 'relationships', $prefix . 'relationships.mid = ' . $prefix . 'metas.mid')
    ->where($prefix . 'relationships.cid = ?', $article['cid'])
    ->where('type = ?', 'tag');
$tags = $db->fetchAll($tagQuery);

在它下面加上这段:

$catQuery = $db->select('name')->from($prefix . 'metas')
    ->join($prefix . 'relationships', $prefix . 'relationships.mid = ' . $prefix . 'metas.mid')
    ->where($prefix . 'relationships.cid = ?', $article['cid'])
    ->where('type = ?', 'category');
$categories = $db->fetchAll($catQuery);

第二处:返回数据加上 categories 和 text。找到返回数据那堆:

$result[] = array(
    'cid' => $article['cid'],
    'title' => $article['title'],
    'slug' => $article['slug'],
    'created' => date('Y-m-d H:i:s', $article['created']),
    'authorId' => $article['authorId'],
    'tags' => array_column($tags, 'name'),
    'summary' => mb_substr(strip_tags($article['text']), 0, 200) . '...'
);

改成:

$result[] = array(
    'cid' => $article['cid'],
    'title' => $article['title'],
    'slug' => $article['slug'],
    'created' => date('Y-m-d H:i:s', $article['created']),
    'authorId' => $article['authorId'],
    'tags' => array_column($tags, 'name'),
    'categories' => array_column($categories, 'name'),
    'summary' => mb_substr(strip_tags($article['text']), 0, 200) . '...',
    'text' => $article['text']
);

就加了两行:`’categories’ => …` 和 `’text’ => …`。改完之后 API 就会返回完整正文和分类名了。

不想修改代码的,可以直接到我的仓库里自取吧:https://github.com/laozhangge/typecho-api

第一步:把下面的代码插入到主题文件的 index.php 合适位置。(代码和旧版相同)

<?php
$data = fetch_typecho_data();
if ($data):
?>
<div class="latest-update" style="background-color: #f8f8f8;">
<div class="latest-update-header">
<h2>最新动态</h2>
<span class="latest-update-time"><?php echo esc_html($data['time_content']); ?></span>
</div>
<div class="latest-update-divider"></div>
<div class="latest-update-content"><?php echo esc_html($data['content']); ?></div>
<div class="latest-update-images">
<?php foreach ($data['image_content'] as $img_url): ?>
<a href="<?php echo esc_url($img_url); ?>" data-lightbox="latest-update-gallery">
<img src="<?php echo esc_url($img_url); ?>" alt="Image">
</a>
<?php endforeach; ?>
</div>
<div class="latest-update-footer">
<span class="latest-update-tag"><?php echo esc_html($data['tag_content']); ?></span>
<a class="latest-update-link" href="<?php echo esc_url($data['link_content']); ?>" target="_blank">查看全文</a>
</div>
</div>
<?php endif; ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/js/lightbox-plus-jquery.min.js" defer></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/css/lightbox.min.css">

第二步:CSS 样式代码放到主题 CSS 定义设置里,或者直接放到 style.css 中。(代码和旧版相同)

/* 首页调用typecho样式 */
.latest-update {
width: calc(100% - 40px);
background-color: #f8f8f8;
border: 1px solid #ddd;
border-radius: 10px;
padding: 20px 20px 10px 20px;
margin: 20px 0;
text-align: left;
margin-top: -10px;
margin-bottom: 30px;
margin-right: 20px;
}
.latest-update-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.latest-update h2 {
font-size: 15px;
margin: 0;
padding-left: 0px;
}
.latest-update-time {
font-size: 14px;
color: #666;
margin-right: 0px;
}
.latest-update-divider {
border-bottom: 1px solid #333;
margin: 10px 0;
}
.latest-update-content {
text-align: left;
line-height: 1.5;
margin: 10px 0;
}
.latest-update-images {
text-align: left;
margin: 10px 0;
}
.latest-update-images img {
width: 100px;
height: 75px;
object-fit: cover;
border-radius: 8px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 1);
margin: 3px;
transition: transform 0.3s, opacity 0.3s;
}
.latest-update-images img:hover {
transform: scale(1.1);
opacity: 0.9;
}
.latest-update-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid #ddd;
}
.latest-update-tag {
background-color: #e0e0e0;
border-radius: 5px;
padding: 5px 10px;
font-size: 14px;
}
.latest-update-link {
text-decoration: none;
color: #0073aa;
font-size: 14px;
}

第三步:把下面代码插入到主题 functions.php 文件中。


//-------首页调用typecho代码-----开始(适配 Typecho-Api 插件)
function fetch_typecho_data() {
    $api_url = "https://你的typecho地址/index.php/api?token=你的token&method=getarticle&page=1&pageSize=1";
    $response = wp_remote_get($api_url);
    if (is_wp_error($response)) {
        return;
    }
    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body, true);

    if (empty($data['success']) || empty($data['data'])) {
        return;
    }

    $post = $data['data'][0];

    // 1. 链接内容
    $link_content = "https://你的typecho地址/archives/" . $post['cid'] . ".html";

    // 2. 分类内容
    $tag_content = !empty($post['categories']) ? $post['categories'][0] : "";

    // 3. 时间内容(+0800 北京时间校正)
    $created_time = strtotime($post['created'] . ' +0800');
    $current_time = time();
    $time_diff = $current_time - $created_time;

    if ($time_diff < 3600) {
        $time_content = floor($time_diff / 60) . "分钟前";
    } elseif ($time_diff < 86400) {
        $time_content = floor($time_diff / 3600) . "小时前";
    } elseif ($time_diff < 2592000) {
        $time_content = floor($time_diff / 86400) . "天前";
    } else {
        $time_content = date("Y年m月d日", $created_time);
    }

    // 4. 摘要内容(去掉Markdown图片语法和HTML标签后截取200字)
    $full_text = $post['text'];
    $clean_text = preg_replace('/!\[.*?\]\(.*?\)/', '', $full_text); // 去掉Markdown图片
    $plain_text = strip_tags($clean_text);
    $content = mb_strlen($plain_text, 'UTF-8') <= 200 ? $plain_text : mb_substr($plain_text, 0, 200, 'UTF-8') . "......";

    // 5. 图片内容(同时匹配HTML img标签和Markdown图片语法)
    $image_content = [];
    preg_match_all('/<img[^>]+src=["\']([^"\']+)["\']/', $full_text, $html_imgs);
    preg_match_all('/!\[.*?\]\(([^)]+)\)/', $full_text, $md_imgs);
    $image_content = array_filter(array_merge($html_imgs[1], $md_imgs[1]));

    return [
        'link_content' => $link_content,
        'tag_content' => $tag_content,
        'time_content' => $time_content,
        'content' => $content,
        'image_content' => $image_content
    ];
}


 

 

 

评论区

共 13 条评论
  1. 头像
    老张 博主
    heo-3d眼镜
    1月前
  2. 头像
    老张 博主
    adsfasdfa
    1月前
  3. 头像
    老张 博主
    苯胺大地震
    1月前
  4. 头像
    老张 博主
    基材
    1月前
  5. 头像
    老张 博主
    测试站,速度很好哟,折腾站,用于开发插件等。
    1月前
    1. 头像
      老张 博主
      @老张 测试站,速度很好哟,折腾站,用于开发插件等。
      1月前
      1. 头像
        老张 博主
        @老张 没得说了
        1月前
  6. 头像
    织梦岁月 Lv2.初识寒暄
    学习了,目前还没开始使用Typecho,以后用得上
    1月前
  7. 头像
    花非花 Lv3.点头之交
    之前Typecho升级也遇到了主题、插件兼容问题,都是用AI修改后用的
    2月前
  8. 头像
    obaby Lv6.推心置腹
    系统整合,一旦升级就容易出bug
    2月前
  9. 头像
    老刘博客 Lv2.初识寒暄
    还是memos简单
    2月前
  10. 头像
    wp张
    最怕这种基础设施做破坏性更新,太折腾了
    2月前
😊