插件名称:FriendLinksLight(友情链接 Light 版)
适用环境:Typecho 1.3 / PHP 8.2+(需开启 cURL 扩展)
数据存储:JSON 文件(无需数据库表)
核心特性:分类管理、存活检测、卡片级缓存、短代码/模板双调用、定时 Cron 任务
将插件文件夹命名为 FriendLinksLight,上传至 Typecho 的插件目录:
usr/plugins/FriendLinksLight/
目录结构应包含:
FriendLinksLight/
├── Plugin.php # 主插件文件
├── Action.php # 路由动作(Cron / Ajax)
├── panel.php # 后台管理面板
├── cache/ # 卡片渲染缓存目录(自动创建)
└── data/ # JSON 数据目录(自动创建)
├── links.json # 链接数据
├── categories.json # 分类数据
└── front_map.json # 前台映射缓存
登录 Typecho 后台 → 控制台 → 插件 → 找到 FriendLinksLight → 点击 启用。
首次启用时,插件会自动创建 cache/ 和 data/ 目录,并初始化空的 JSON 数据文件。
注意:PHP 必须已安装并启用 cURL 扩展,否则插件将无法启用。
启用后,点击插件列表中的 设置 进入配置页面:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| 请求超时(秒) | 10 |
存活检测时 cURL 请求的最大等待时间 |
| 默认图标 URL | /favicon.png |
当链接未填写图标时,显示此默认图标 |
| 容器模板 | <div class="{container_class}">{cards}</div> |
外层容器 HTML,必须包含 {cards} 和 {container_class} 占位符 |
| 卡片模板 | (见下文) | 单张卡片的 HTML 结构,支持多个占位符 |
| 自定义 CSS | (见下文) | 插件自动输出到前台的样式代码 |
| 前台排序方式 | 手动排序 |
前台展示时的排序规则 |
| 跳过异常网站 | 不跳过 |
前台默认是否隐藏存活状态为「异常」的链接 |
| Cron 密钥 | 空 | 定时任务的安全密钥,留空则不校验 |
| 禁用时删除数据文件 | 不删除 |
禁用插件时是否自动删除所有数据文件(慎用) |
- 手动排序:按后台设置的
sort值从小到大排列,sort 相同时按 ID 排序。 - 添加时间(新→旧):按创建时间倒序。
- 添加时间(旧→新):按创建时间正序。
- 标题 A→Z / Z→A:按标题字母顺序排列。
- 随机:服务器按手动顺序输出 DOM,由浏览器端 JavaScript 随机打乱,兼容 HTML 缓存。
启用插件后,后台侧边栏会出现 友情链接 菜单入口(需管理员权限)。
分类用于对链接进行分组展示。系统默认存在一个逻辑上的 未分类。
- 在分类卡片区域点击 ➕ 添加分类。
- 填写分类名称和排序值(数字越小越靠前,留空则自动排到末尾)。
- 点击 保存。
点击分类卡片上的 ✏️ 按钮,可修改分类名称和排序。
提示:修改分类名称后,该分类下所有链接的卡片缓存会自动重建,以更新前台显示的分类名。
点击分类卡片上的 🗑️ 按钮并确认后:
- 该分类会被删除;
- 原属于该分类的链接会自动变为 未分类;
- 相关链接的卡片缓存也会自动重建。
点击工具栏的 ➕ 添加链接,在弹窗中填写:
| 字段 | 必填 | 说明 |
|---|---|---|
| 标题 | 否 | 网站名称,留空则自动提取 URL 的主机名 |
| URL | 是 | 网站地址,需以 http:// 或 https:// 开头 |
| 描述 | 否 | 网站简介 |
| 图标 | 否 | 网站图标的 URL 地址 |
| 分类 | 否 | 选择归属分类,留空则为「未分类」 |
| 状态 | 否 | 显示 或 隐藏,仅「显示」的链接才会在前台输出 |
| 排序 | 否 | 数字,越小越靠前,留空则自动排到末尾 |
保存后,插件会自动执行一次存活检测,并生成该链接的卡片缓存文件。
在表格中点击 编辑 按钮,修改后保存。保存时会自动重建该链接的卡片缓存。
点击 删除 按钮并确认,链接数据及对应的卡片缓存将被移除。
工具栏右侧提供两个下拉框:
- 分类筛选:全部 / 未分类 / 异常 / 具体分类
- 排序方式:手动 / 时间 ↓ / 时间 ↑ / A-Z / Z-A / 随机
切换后点击 🔄 按钮,或分页下拉框选择每页条数(10 / 20 / 50),表格会以 Ajax 方式局部刷新,无需整页重载。
| 按钮 | 功能 | 说明 |
|---|---|---|
| 检查所有状态 | 批量存活检测 | 对所有链接发起 HTTP 请求,更新存活状态 |
| 刷新缓存 | 清除所有卡片缓存 | 强制重建前台映射和卡片缓存 |
| 重整序号 | 重新排列 sort 值 | 按当前顺序将 sort 重置为 1, 2, 3... |
| 删除异常链接 | 一键清理 | 删除所有存活状态为「异常」的链接(不可恢复) |
页面顶部的 数据状态 卡片显示:
links.json和categories.json是否存在- 数据文件总大小
- 最后修改时间
插件提供两种前台输出方式:短代码(适合文章/页面内使用)和 模板函数(适合主题模板内使用)。
在文章或独立页面中插入:
[friendlinks]
参数可任意顺序组合,无值属性直接写名称即可:
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
dead |
无值属性 | 仅输出存活状态为「异常」的链接(忽略全局「跳过异常」设置) | [friendlinks dead] |
container_class="..." |
字符串 | 外层容器追加的 CSS 类名,默认 friendlinks-container |
container_class="my-links" |
card_class="..." |
字符串 | 每张卡片追加的 CSS 类名 | card_class="compact-card" |
category_id="数字" |
整数 | 仅输出指定分类 ID 的链接 | category_id="1" |
include_uncategorized="1/0/2" |
枚举 | 未分类链接的包含模式:1=全部(默认),0=仅已分类,2=仅未分类。当指定 category_id 时此参数被忽略 |
include_uncategorized="0" |
<!-- 默认输出所有可见链接 -->
[friendlinks]
<!-- 输出分类ID为2的链接,并追加卡片样式类 -->
[friendlinks category_id="2" card_class="my-card"]
<!-- 仅输出异常链接,并自定义容器类 -->
[friendlinks dead container_class="dead-links"]
<!-- 排除未分类,只显示已归属分类的链接 -->
[friendlinks include_uncategorized="0"]
<!-- 多参数任意顺序组合 -->
[friendlinks card_class="wide" dead container_class="alert-links"]
在主题模板(如 page.php、sidebar.php)中直接调用 PHP 静态方法:
<?php FriendLinksLight_Plugin::output(); ?><?php FriendLinksLight_Plugin::outputDead(); ?>public static function output(
string $containerClass = 'friendlinks-container',
string $cardClass = '',
?int $categoryId = null, // null = 所有分类,数字 = 指定分类ID
int $uncategorizedMode = 1 // 0=排除未分类,2=仅未分类,1=全部
): void;
// outputDead() 参数与 output() 完全一致,但强制只输出异常链接<?php
// 默认方式
FriendLinksLight_Plugin::output();
// 自定义容器类,不显示未分类
FriendLinksLight_Plugin::output('sidebar-links', '', null, 0);
// 只显示分类ID为3的链接
FriendLinksLight_Plugin::output('', '', 3);
// 只显示异常链接,并追加卡片类
FriendLinksLight_Plugin::outputDead('error-links', 'highlight-card');
?>插件支持在后台设置中自定义 容器模板、卡片模板 和 自定义 CSS,实现完全个性化的展示效果。
| 占位符 | 说明 |
|---|---|
{cards} |
所有卡片 HTML 的拼接结果 |
{container_class} |
由参数传入的容器 CSS 类名(默认 friendlinks-container) |
注意:容器模板中必须包含
{cards},否则插件会自动回退到默认模板。
| 占位符 | 说明 |
|---|---|
{url} |
网站地址 |
{title} |
网站标题 |
{description} |
网站描述 |
{icon} |
图标 URL(若链接未设置则使用默认图标) |
{last_update} |
最后更新日期(格式 Y-m-d) |
{alive} |
存活状态文字:正常 / 异常 / 未知 |
{category} |
所属分类名称(未分类则显示「未分类」) |
<div class="friendlink-card">
<div class="result-header">
<div class="favicon"><img src="{icon}" alt="favicon"></div>
<div>
<div class="title">{title}</div>
<div class="url-display"><a href="{url}" target="_blank">{url}</a></div>
</div>
</div>
<div class="description">
<div class="label">描述</div>
{description}
</div>
<div class="badge-group">
<span class="badge badge-category">{category}</span>
<span class="badge badge-update">{last_update}</span>
<span class="badge badge-status">{alive}</span>
</div>
</div>插件通过 HTTP HEAD 请求检测目标网站是否可访问:
- 判定标准:HTTP 状态码在
200~399范围内视为「正常」,否则为「异常」。 - 超时时间:由插件设置中的「请求超时」控制,默认 10 秒。
- 自动检测:添加/编辑链接时,会自动执行一次存活检测。
- 手动检测:后台表格中可对单条链接点击 检查 按钮。
- 批量检测:点击 检查所有状态,插件会使用
curl_multi并发检测所有链接。 - 前台影响:若开启「跳过异常网站」,存活状态为「异常」的链接不会在前台输出(
[friendlinks dead]除外)。
插件内置 Cron 接口,可被服务器定时任务触发,自动批量更新所有链接的存活状态。
https://你的域名/friendlinkslight/cron
如果插件设置中填写了 Cron 密钥,则必须在 URL 中携带密钥参数:
https://你的域名/friendlinkslight/cron?key=你的密钥
密钥错误时,接口会返回 HTTP 403。
每 2 小时执行一次检测:
0 */2 * * * curl -s "https://你的域名/friendlinkslight/cron?key=你的密钥" > /dev/null 2>&1每天凌晨 3 点执行:
0 3 * * * curl -s "https://你的域名/friendlinkslight/cron?key=你的密钥" > /dev/null 2>&1插件采用两级缓存策略,兼顾性能与实时性:
- 每个链接、每种卡片模板对应一个独立的 HTML 缓存文件,位于
usr/plugins/FriendLinksLight/cache/。 - 文件名格式:
card_{linkId}_{templateHash}.html - 当链接内容、分类名称、存活状态发生变化时,相关缓存会自动重建。
- 管理面板的 刷新缓存 可手动清空全部卡片缓存。
front_map.json存储了所有「显示」状态链接的精简元数据(分类、存活状态、排序、时间、标题)。- 前台渲染时先读取映射,再按需加载卡片缓存,避免解析整个
links.json。 - 任何增删改操作都会自动触发映射重建。
links.json和categories.json采用「写入临时文件 + 原子重命名」策略,防止并发写入损坏数据。
- 检查链接的 状态 是否为「显示」。
- 检查是否开启了 跳过异常网站,且所有链接恰好检测为异常。
- 检查短代码或模板函数的参数是否过滤过严(如指定了不存在的
category_id)。 - 尝试点击后台的 刷新缓存。
- 检查链接的 图标 字段是否填写正确。
- 检查 默认图标 URL 是否可访问。
- 图标地址支持绝对路径(如
/favicon.ico)或完整 URL。
- 部分网站会拦截 HEAD 请求或返回非 2xx 状态码,可手动在后台点击 检查 复核。
- 适当增加 请求超时 时间(如 15~20 秒)。
- 如果目标网站有 CDN 或防火墙,可能需要多次检测才能稳定。
- 随机排序依赖浏览器端 JavaScript 执行,请确保前台没有禁用 JS。
- 若使用了全站缓存插件(如 Typecho 的静态缓存),随机效果可能在缓存周期内保持不变。
- 在插件设置的 自定义 CSS 中直接覆盖样式。
- 或通过 卡片模板 / 容器模板 完全重写 HTML 结构。
- 也可以通过短代码/模板函数的
container_class和card_class参数追加自定义类名,在主题样式表中控制。
- 数据以 JSON 文件形式保存在
usr/plugins/FriendLinksLight/data/目录下。 - 建议定期备份该目录。
- 若插件设置中开启了 禁用时删除数据文件,则禁用插件后数据会被清空,请谨慎开启。
在后台 插件 列表中点击 禁用,数据文件会保留,重新启用后数据仍在。
如需在卸载时删除所有数据:
- 进入插件 设置。
- 将 禁用时删除数据文件 设为 删除(红色警告选项)。
- 返回插件列表点击 禁用。
- 此时
data/和cache/目录下的相关文件将被清空。
⚠️ 警告:此操作不可恢复,请提前备份数据文件。
确保 Web 服务器对以下目录有读写权限:
usr/plugins/FriendLinksLight/cache/ # 755 或 775
usr/plugins/FriendLinksLight/data/ # 755 或 775
如果启用插件时提示目录创建失败,请手动创建并赋予相应权限。
文档版本:v1.0.0
最后更新:2026-05-31