- 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 写,图片是  格式,不是 HTML 的 <img> 标签。原来只匹配 <img> 的正则根本抓不到图片,得两种格式都匹配。
- 第零步(重点!重点!重点!):修改 Typecho-Api 插件的 Action.php
- 第一步:把下面的代码插入到主题文件的 index.php 合适位置。(代码和旧版相同)
- 第二步:CSS 样式代码放到主题 CSS 定义设置里,或者直接放到 style.css 中。(代码和旧版相同)
- 第三步:把下面代码插入到主题 functions.php 文件中。
折腾永远都不会停的,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 写,图片是  格式,不是 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
];
}


1.3 的问题好多啊。 依然坚持1.2.1
最怕这种基础设施做破坏性更新,太折腾了
还是memos简单
系统整合,一旦升级就容易出bug
之前Typecho升级也遇到了主题、插件兼容问题,都是用AI修改后用的