WordPress分类标签AI自动补全功能实现教程
在制作这个功能前,我没有去搜索有没有相关的功能插件,所以如果你已经找到了功能插件,我觉得可以不用看教程手动麻烦。
此工具的主要功能为:解决wordpress在建设中文网站,由于中文的分类、标签无法自动转换成英文而使用,中文都是转码了,很不友好SEO,而且市面常见的转拼音,我觉得对于谷歌SEO优化属于没啥意义,SEO一向以精细化为准,所以开始了以下功能的开发。
如果你也想跟我一样手动操作下,那么请跟着我下面的步骤。
1、备份数据库
再开始修改前备份我们的网站数据库是很好的习惯,我的是MySQL,想必大家大多都是这个。
2、检查关于分类、标签的表
表前缀_terms,内有如下字段:
字段名 | 含义 |
---|---|
term_id | 每个分类、标签或自定义分类的唯一ID,用于在其他表中引用。 |
name | 分类、标签或自定义分类的名称,用户在后台创建或编辑时输入的。 |
slug | URL友好名称,基于name 自动生成,用于构建分类等的URL。 |
term_group | 一个保留字段,现代WordPress中通常不被直接使用,可能用于高级用例或自定义开发。 |
需要根据 name
完善 slug
值,那么思路就是根据name的值提交Prompt给AI生成转换的英文,当然AI会生成一些别的提示词在里面,这时候我们需要过滤出英文字段。
第一轮测试如下:
更新成功:爆款内容创作 -> 1buzzworthycontentcreation2
更新成功:小红书专业号 -> xiaohongshuprofessionalaccount
更新成功:无需露脸直播 -> livewithoutvisibleface
更新成功:顶部导航 -> topnavigation
更新成功:家庭摄影 -> familyphotography
更新成功:精准人群营销 -> precisiontargetedmarketing
更新成功:高效提示词编写 -> efficientpromptwordcreation
更新成功:创意表达 -> creativeexpression
更新成功:快速上手视频号 -> quickstartvideoplatform
更新成功:精准曝光提升 -> precisionexposureenhancement
更新成功:抖音AI数字人 -> tiktokaidigitalhuman
更新成功:WordPress -> wordpress
很显然,不是我们想要的结果,英文中间的空格也被过滤掉了。
经过几轮测试,发现过滤效果都不是很理想,还是得从Prompt工程入手。

目前调试出的这个Prompt貌似可行,代入脚本继续尝试。
又经过十几轮测试,发现还是会有点小问题,批量去做还是有5%左右误差,当分类标签变多,不是很好维护,还是得人工审核,于是还是做了半手动的脚本:

搞定,并没有完全搞定,此时生成的英文中间有空格,不是-链接,wp是无法访问这种链接,空格在浏览器中解释会转码导致无法访问,还需要进一步优化,最终做出了插件形式,当然关注我的朋友,我直接送你一份在线版,已加鉴权,管理员登录才可以访问该页面。
主要思路有:
1、查出表前缀_terms表中slug值为空(非Null),且不是英文,包含%号中文转码的字段
2、slug显示出原始转码的字符,输入修改的信息点击修改后更新SQL表数据
3、点击AI生成,请求api发送转英文Prompt带入当前name值,返回的时候要过滤英文中间空格替换为-破折号,跟检查尾部是否含有.(若有则删除),另检查是否包含中文(包含则过滤)
最终修改_terms表slug的在线版为:

slug代码示例:
<?php
// 引入 WordPress 配置文件
require_once('../wp-config.php');
// 加载 WordPress 环境
require_once('../wp-load.php'); // 根据您的目录结构调整路径
// 检查用户是否已登录并且是管理员
if (!is_user_logged_in() || !current_user_can('manage_options')) {
wp_redirect(wp_login_url()); // 未登录或没有权限,重定向到登录页面
exit();
}
// 创建 MySQLi 连接
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
// 检查连接
if ($mysqli->connect_error) {
die('连接失败: ' . $mysqli->connect_error);
}
// 每页显示的条数
$limit = 10;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
// 处理更新请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$term_id = $_POST['term_id'];
$slug = $_POST['slug'];
// 更新数据库中的 slug
$update_stmt = $mysqli->prepare("UPDATE 表前缀_terms SET slug = ? WHERE term_id = ?");
$update_stmt->bind_param('si', $slug, $term_id);
$update_stmt->execute();
$update_stmt->close();
header("Location: " . $_SERVER['PHP_SELF'] . "?page=$page"); // 更新后重定向
exit();
}
// 查询 表前缀_terms 表中的数据(包含 slug 为空字符串或包含 % 的记录)
$stmt = $mysqli->prepare("SELECT term_id, name, slug FROM 表前缀_terms WHERE slug = '' OR slug LIKE '%\%%' LIMIT ?, ?");
$stmt->bind_param('ii', $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$terms = $result->fetch_all(MYSQLI_ASSOC);
// 查询总记录数(包含 slug 为空字符串或包含 % 的记录)
$total_stmt = $mysqli->query("SELECT COUNT(*) FROM 表前缀_terms WHERE slug = '' OR slug LIKE '%\%%'");
$total_terms = $total_stmt->fetch_row()[0];
$total_pages = ceil($total_terms / $limit);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表前缀 Terms 可编辑表</title>
<link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa; /* 背景颜色 */
}
h1 {
margin-bottom: 20px; /* 标题底部间距 */
}
.table th, .table td {
vertical-align: middle; /* 垂直居中 */
}
.pagination {
justify-content: center; /* 中心对齐 */
}
.form-control {
width: 80%; /* 输入框宽度 */
display: inline-block; /* 行内块显示 */
}
.btn-primary, .btn-warning {
margin-left: 10px; /* 按钮左侧间距 */
}
</style>
<script>
function generateSlug(termId, name) {
const prompt = `请将【${name}】转换成英文,直接输出转换的英文,不要有任何其他的信息。`;
fetch('slug_generator.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt }) // 修改为传递 prompt
})
.then(response => response.json())
.then(data => {
if (data.slug) {
document.querySelector(`#slug_${termId}`).value = data.slug; // 填充到相应的输入框
} else {
alert(data.error || '生成的 slug 无效,请重试。');
}
})
.catch(error => {
console.error('Error:', error);
alert('请求失败,请重试。');
});
}
</script>
</head>
<body>
<div class="container mt-5">
<h1 class="text-center">表前缀 Terms 可编辑表</h1>
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>Term ID</th>
<th>Name</th>
<th>Slug</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($terms as $term): ?>
<tr>
<td><?php echo htmlspecialchars($term['term_id']); ?></td>
<td><?php echo htmlspecialchars($term['name']); ?></td>
<td>
<form method="POST" action="" class="d-flex">
<input type="hidden" name="term_id" value="<?php echo htmlspecialchars($term['term_id']); ?>">
<input type="text" id="slug_<?php echo htmlspecialchars($term['term_id']); ?>" name="slug" value="<?php echo htmlspecialchars($term['slug']); ?>" class="form-control" required>
<button type="submit" class="btn btn-primary">修改</button>
<button type="button" class="btn btn-warning" onclick="generateSlug(<?php echo htmlspecialchars($term['term_id']); ?>, '<?php echo htmlspecialchars($term['name']); ?>')">AI生成</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- 分页 -->
<nav>
<ul class="pagination">
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?php echo $i === $page ? 'active' : ''; ?>">
<a class="page-link" href="?page=<?php echo $i; ?>"><?php echo $i; ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>
<?php
// 关闭连接
$mysqli->close();
?>
slug_generator.php 文件为请求ai返回翻译的英文slug
再来修改表前缀_term_taxonomy这个表:
字段名称 | 数据类型 | 描述 |
---|---|---|
term_taxonomy_id | bigint(20) | 该字段是表的主键,唯一标识每个分类法项目,自动递增。 |
term_id | bigint(20) | 关联到 wp_terms 表中的 term_id ,用于将术语与分类法关联。 |
taxonomy | varchar(32) | 表示分类法的类型,例如 category (分类)、post_tag (标签)等,确定术语的分类类型。 |
description | longtext | 对应术语的详细描述,可以是任意长度的文本。 |
parent | bigint(20) | 如果该分类法项目有父项,则 parent 存储父项的 term_taxonomy_id ,用于创建层级结构。 |
count | bigint(20) | 该分类法下的条目数量,例如某个标签下有多少篇文章或某个分类下有多少内容。 |
处理思路:
1、主要是修改description,term_id跟上面表前缀_terms中的term_id关联,用于取栏目或者标签的name值来生成description
2、taxonomy分为category跟post_tag,大致逻辑与上面处理slug一致,只是描述要生成中文的,一句话。
3、前端显示逻辑,取出description为空(不是Null)的值,并联表查询对应的term_id的name值展示。
代码示例:
<?php
// 引入 WordPress 配置文件
require_once '../wp-config.php';
// 加载 WordPress 环境
require_once('../wp-load.php'); // 根据您的目录结构调整路径
// 检查用户是否已登录并且是管理员
if (!is_user_logged_in() || !current_user_can('manage_options')) {
wp_redirect(wp_login_url()); // 未登录或没有权限,重定向到登录页面
exit();
}
// 数据库配置
$servername = DB_HOST;
$username = DB_USER;
$password = DB_PASSWORD;
$dbname = DB_NAME;
// 创建数据库连接
$mysqli = new mysqli($servername, $username, $password, $dbname);
// 检查连接
if ($mysqli->connect_error) {
die('连接失败: ' . $mysqli->connect_error);
}
// 每页显示的条数
$limit = 10;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
// 处理更新请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$term_id = $_POST['term_id'];
$description = $_POST['description'];
// 更新数据库中的 description
$update_stmt = $mysqli->prepare("UPDATE 表前缀_term_taxonomy SET description = ? WHERE term_id = ?");
$update_stmt->bind_param('si', $description, $term_id);
$update_stmt->execute();
header("Location: " . $_SERVER['PHP_SELF'] . "?page=$page"); // 更新后重定向
exit();
}
// 查询 表前缀_term_taxonomy 表中的数据(包含 description 为空的记录)
$stmt = $mysqli->prepare("SELECT term_taxonomy_id, term_id, taxonomy, description FROM 表前缀_term_taxonomy WHERE description = '' LIMIT ?, ?");
$stmt->bind_param('ii', $offset, $limit);
$stmt->execute();
$result = $stmt->get_result();
$taxonomies = $result->fetch_all(MYSQLI_ASSOC);
// 查询总记录数(包含 description 为空的记录)
$total_stmt = $mysqli->query("SELECT COUNT(*) FROM 表前缀_term_taxonomy WHERE description = ''");
$total_taxonomies = $total_stmt->fetch_row()[0];
$total_pages = ceil($total_taxonomies / $limit);
// 获取对应的 term name
$term_names = [];
if (!empty($taxonomies)) {
$term_ids = implode(',', array_column($taxonomies, 'term_id'));
$name_stmt = $mysqli->prepare("SELECT term_id, name FROM 表前缀_terms WHERE term_id IN ($term_ids)");
$name_stmt->execute();
$result = $name_stmt->get_result();
$term_names = $result->fetch_all(MYSQLI_ASSOC);
$term_names = array_column($term_names, 'name', 'term_id'); // term_id => name
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表前缀 Term Taxonomy 可编辑表</title>
<link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa; /* 背景颜色 */
}
h1 {
margin-bottom: 20px; /* 标题底部间距 */
}
.table th, .table td {
vertical-align: middle; /* 垂直居中 */
}
.pagination {
justify-content: center; /* 中心对齐 */
}
.form-control {
width: 80%; /* 输入框宽度 */
display: inline-block; /* 行内块显示 */
}
.btn-primary, .btn-warning {
margin-left: 10px; /* 按钮左侧间距 */
}
</style>
<script>
function generateDescription(termId, name) {
const prompt = `请为【${name}】生成简短且吸引人的描述,字数控制在50到100个字符之间,内容应突出该产品的主要特点和优势。请使用中文。`;
fetch('description_generator.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt }) // 修改为传递 prompt
})
.then(response => response.json())
.then(data => {
if (data.description) {
document.querySelector(`#description_${termId}`).value = data.description; // 填充到相应的输入框
} else {
alert(data.error || '生成的描述无效,请重试。');
}
})
.catch(error => {
console.error('Error:', error);
alert('请求失败,请重试。');
});
}
</script>
</head>
<body>
<div class="container mt-5">
<h1 class="text-center">表前缀 Term Taxonomy 可编辑表</h1>
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>Term Taxonomy ID</th>
<th>Term ID</th>
<th>Name</th>
<th>Taxonomy</th>
<th>Description</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($taxonomies as $taxonomy): ?>
<tr>
<td><?php echo htmlspecialchars($taxonomy['term_taxonomy_id']); ?></td>
<td><?php echo htmlspecialchars($taxonomy['term_id']); ?></td>
<td><?php echo htmlspecialchars($term_names[$taxonomy['term_id']] ?? '未知'); ?></td>
<td><?php echo htmlspecialchars($taxonomy['taxonomy']); ?></td>
<td>
<form method="POST" action="" class="d-flex">
<input type="hidden" name="term_id" value="<?php echo htmlspecialchars($taxonomy['term_id']); ?>">
<input type="text" id="description_<?php echo htmlspecialchars($taxonomy['term_id']); ?>" name="description" value="<?php echo htmlspecialchars($taxonomy['description']); ?>" class="form-control" required>
<button type="submit" class="btn btn-primary">修改</button>
<button type="button" class="btn btn-warning" onclick="generateDescription(<?php echo htmlspecialchars($taxonomy['term_id']); ?>, '<?php echo htmlspecialchars($term_names[$taxonomy['term_id']] ?? '未知'); ?>')">AI生成</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- 分页 -->
<nav>
<ul class="pagination">
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?php echo $i === $page ? 'active' : ''; ?>">
<a class="page-link" href="?page=<?php echo $i; ?>"><?php echo $i; ?></a>
</li>
<?php endfor; ?>
</ul>
</nav>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>
<?php
// 关闭连接
$mysqli->close();
?>
description_generator.php 同上述处理slug的api接口,只是换个接受Prompt,跟去掉对英文的过滤。
Comments
Post a Comment