友情链接(Blogroll)是WordPress内置的一项重要功能,尽管在现代网站中使用频率有所下降,但了解其底层结构和调用方法对主题开发和网站维护仍然很有价值。
一、数据存储结构
WordPress的友情链接数据存储在两个数据表中,形成了经典的”分类-项目”关系:
1. 链接分类表:wp_link_categories
存储友情链接的分类信息:
| 字段 | 说明 |
|---|---|
cat_id | 分类ID(主键) |
cat_name | 分类名称 |
auto_toggle | 是否自动折叠 |
show_images | 是否显示图片 |
show_description | 是否显示描述 |
show_rating | 是否显示评分 |
show_updated | 是否显示更新时间 |
sort_order | 排序方式 |
text_before_link | 链接前文本 |
text_after_link | 链接后文本 |
text_after_all | 所有链接后文本 |
list_limit | 显示数量限制 |
2. 链接表:wp_links
存储具体的友情链接数据:
| 字段 | 说明 |
|---|---|
link_id | 链接ID(主键) |
link_url | 链接地址 |
link_name | 链接名称 |
link_image | 链接图片URL |
link_target | 打开方式(_blank等) |
link_category | 所属分类ID |
link_description | 链接描述 |
link_visible | 是否可见(Y/N) |
link_owner | 添加者ID |
link_rating | 链接评分 |
link_updated | 更新时间 |
link_rel | rel属性(如nofollow) |
link_notes | 管理员备注 |
link_rss | RSS地址 |
二、核心调用函数
1. wp_list_bookmarks() —— 最常用函数
这是输出友情链接列表的标准函数,位于wp-includes/bookmark-template.php。
基础用法:
<?php wp_list_bookmarks(); ?>
常用参数详解:
<?php
wp_list_bookmarks(array(
// 基础过滤
'orderby' => 'name', // 排序依据:name, url, rating, updated, id
'order' => 'ASC', // 排序方向:ASC, DESC
'limit' => -1, // 显示数量,-1为全部
'category' => '', // 指定分类ID,逗号分隔
'category_name' => '', // 指定分类名称
'hide_invisible' => 1, // 是否隐藏私密链接
// 显示控制
'show_description' => 1, // 是否显示描述
'show_images' => 1, // 是否显示图片
'show_name' => 1, // 是否显示名称
'show_rating' => 0, // 是否显示评分
'show_updated' => 0, // 是否显示更新时间
// 样式控制
'title_li' => __('Bookmarks'), // 列表标题
'title_before' => '<h2>', // 标题前标签
'title_after' => '</h2>', // 标题后标签
'category_orderby' => 'name', // 分类排序依据
'category_order' => 'ASC', // 分类排序方向
// 嵌套结构
'categorize' => 1, // 是否按分类分组显示
'category_before' => '<li id="[category id]" class="linkcat">', // 分类容器前
'category_after' => '</li>', // 分类容器后
// 链接包裹
'before' => '<li>', // 每个链接前
'after' => '</li>', // 每个链接后
'link_before' => '', // 链接文本前
'link_after' => '', // 链接文本后
// 分隔符(当categorize=0时使用)
'between' => "\n", // 链接之间的分隔
// 额外选项
'echo' => 1, // 是否直接输出(0则返回字符串)
'class' => 'linkcat', // 分类的CSS类
));
?>
2. get_bookmarks() —— 获取原始数据
当需要自定义输出格式时使用,返回数组而非直接打印:
<?php
$bookmarks = get_bookmarks(array(
'orderby' => 'rating',
'order' => 'DESC',
'limit' => 10,
'category' => '2,3', // 多个分类
'category_name' => '合作伙伴', // 按名称
'hide_invisible' => 1,
'search' => 'keyword', // 搜索关键词
));
if (!empty($bookmarks)) {
echo '<ul class="custom-links">';
foreach ($bookmarks as $bookmark) {
echo '<li>';
printf(
'<a href="%s" title="%s" target="%s" rel="%s">%s</a>',
esc_url($bookmark->link_url),
esc_attr($bookmark->link_description),
esc_attr($bookmark->link_target),
esc_attr($bookmark->link_rel),
esc_html($bookmark->link_name)
);
if ($bookmark->link_description) {
echo '<span class="desc">' . esc_html($bookmark->link_description) . '</span>';
}
echo '</li>';
}
echo '</ul>';
}
?>
3. get_bookmark() / get_bookmark_field() —— 获取单个链接
<?php
// 获取单个链接对象
$link = get_bookmark($link_id);
// 快速获取单个字段
$url = get_bookmark_field('link_url', $link_id);
$name = get_bookmark_field('link_name', $link_id);
?>
三、实战应用场景
场景1:简单的友情链接列表(无分类)
<?php
wp_list_bookmarks(array(
'categorize' => 0, // 不按分类分组
'title_li' => '', // 无标题
'before' => '<span class="friend-link">',
'after' => '</span>',
'between' => ' | ', // 链接间用竖线分隔
'show_images' => 0,
'show_rating' => 0,
'show_description' => 0,
));
?>
场景2:图文混排的友情链接
<?php
wp_list_bookmarks(array(
'orderby' => 'rating',
'order' => 'DESC',
'category' => '1', // 只显示"合作伙伴"分类
'show_images' => 1, // 显示Logo
'show_name' => 1, // 同时显示名称
'show_description' => 1,
'title_before' => '<h3 class="section-title">',
'title_after' => '</h3>',
'before' => '<div class="link-item">',
'after' => '</div>',
));
?>
场景3:自定义复杂布局(使用get_bookmarks)
<?php
// 按分类获取链接
$categories = get_terms('link_category', array('hide_empty' => true));
foreach ($categories as $cat) :
$links = get_bookmarks(array(
'category' => $cat->term_id,
'orderby' => 'name',
));
if (empty($links)) continue;
?>
<div class="link-category">
<h4><?php echo esc_html($cat->name); ?></h4>
<div class="links-grid">
<?php foreach ($links as $link) : ?>
<a href="<?php echo esc_url($link->link_url); ?>"
class="link-card"
target="<?php echo esc_attr($link->link_target); ?>"
rel="<?php echo esc_attr($link->link_rel); ?>">
<?php if ($link->link_image) : ?>
<img src="<?php echo esc_url($link->link_image); ?>"
alt="<?php echo esc_attr($link->link_name); ?>"
loading="lazy">
<?php else : ?>
<div class="link-placeholder">
<?php echo esc_html($link->link_name[0]); ?>
</div>
<?php endif; ?>
<div class="link-info">
<strong><?php echo esc_html($link->link_name); ?></strong>
<?php if ($link->link_description) : ?>
<p><?php echo esc_html($link->link_description); ?></p>
<?php endif; ?>
</div>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
四、后台管理界面
友情链接功能默认在新版WordPress中被隐藏,需要手动开启:
// 在主题的 functions.php 中添加
add_filter('pre_option_link_manager_enabled', '__return_true');
开启后,后台会出现 “链接” 菜单,支持:
添加/编辑/删除链接
创建链接分类
拖拽排序(需插件支持)
批量管理
五、现代替代方案
由于WordPress的友情链接功能较为陈旧,现代开发中常用以下替代方案:
方案A:使用自定义文章类型(CPT)
// 注册"合作伙伴"自定义文章类型
function register_partner_post_type() {
register_post_type('partner', array(
'labels' => array('name' => '合作伙伴'),
'public' => true,
'supports' => array('title', 'thumbnail', 'custom-fields'),
'menu_icon' => 'dashicons-groups',
));
}
add_action('init', 'register_partner_post_type');
// 调用
$partners = new WP_Query(array('post_type' => 'partner'));
while ($partners->have_posts()) : $partners->the_post();
$url = get_post_meta(get_the_ID(), 'partner_url', true);
// 自定义输出...
endwhile;
方案B:使用导航菜单
利用WordPress强大的菜单系统管理链接:
创建名为”友情链接”的菜单
使用自定义链接添加
通过wp_nav_menu()调用
优势:可视化拖拽排序,支持嵌套
六、性能优化建议
缓存查询结果:友情链接查询涉及多表连接,建议使用Transients API缓存
懒加载图片:如果显示链接Logo,务必添加loading=”lazy”
nofollow处理:对外链统一添加rel=”nofollow noopener” 防止权重流失
定期清理:删除失效链接,避免死链影响SEO
// 自动为所有外链添加nofollow(如果没有的话)
function auto_nofollow_links($bookmark) {
if (strpos($bookmark->link_rel, 'nofollow') === false) {
$bookmark->link_rel .= ' nofollow';
}
return $bookmark;
}
add_filter('get_bookmark', 'auto_nofollow_links');
WordPress的友情链接系统虽然传统,但结构清晰、功能完备。理解wp_list_bookmarks()和get_bookmarks() 的差异,掌握参数的灵活运用,可以在不安装额外插件的情况下实现多样化的链接展示需求。对于复杂业务场景,建议迁移到自定义文章类型或导航菜单系统,以获得更好的可扩展性和用户体验。