九、插件开发
9.1 插件文件结构
my-plugin/
├── my-plugin.php 主插件文件(必须)
├── readme.txt 插件说明(WordPress.org 要求)
├── uninstall.php 卸载脚本
├── includes/
│ ├── class-my-plugin.php 主类
│ ├── class-my-plugin-admin.php 后台类
│ └── class-my-plugin-frontend.php 前台类
├── admin/
│ ├── css/
│ ├── js/
│ └── views/
├── public/
│ ├── css/
│ ├── js/
│ └── views/
├── templates/
│ └── my-template.php
└── languages/
└── my-plugin.pot
9.2 插件主文件
<?php
/**
* Plugin Name: My Custom Plugin
* Plugin URI: https://example.com/my-plugin
* Description: A custom WordPress plugin for demonstration.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 7.4
* Author: Your Name
* Author URI: https://example.com
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: my-plugin
* Domain Path: /languages
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 常量定义
define('MY_PLUGIN_VERSION', '1.0.0');
define('MY_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('MY_PLUGIN_URL', plugin_dir_url(__FILE__));
// 激活钩子
register_activation_hook(__FILE__, 'my_plugin_activate');
function my_plugin_activate() {
// 创建数据库表
global $wpdb;
$table_name = $wpdb->prefix . 'my_plugin_data';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
value text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 设置默认选项
add_option('my_plugin_settings', array(
'enabled' => true,
'title' => 'My Plugin',
'items_per_page' => 10,
));
// 设置默认选项
flush_rewrite_rules();
}
// 停用钩子
register_deactivation_hook(__FILE__, 'my_plugin_deactivate');
function my_plugin_deactivate() {
flush_rewrite_rules();
}
// 加载国际化
function my_plugin_load_textdomain() {
load_plugin_textdomain('my-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
add_action('init', 'my_plugin_load_textdomain');
// 加载后台脚本
function my_plugin_admin_scripts($hook) {
if (strpos($hook, 'my-plugin') === false) {
return;
}
wp_enqueue_style('my-plugin-admin', MY_PLUGIN_URL . 'admin/css/admin.css', array(), MY_PLUGIN_VERSION);
wp_enqueue_script('my-plugin-admin', MY_PLUGIN_URL . 'admin/js/admin.js', array('jquery'), MY_PLUGIN_VERSION, true);
wp_localize_script('my-plugin-admin', 'myPluginAdmin', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('my_plugin_nonce'),
));
}
add_action('admin_enqueue_scripts', 'my_plugin_admin_scripts');
// 加载前台脚本
function my_plugin_frontend_scripts() {
wp_enqueue_style('my-plugin-frontend', MY_PLUGIN_URL . 'public/css/frontend.css', array(), MY_PLUGIN_VERSION);
wp_enqueue_script('my-plugin-frontend', MY_PLUGIN_URL . 'public/js/frontend.js', array(), MY_PLUGIN_VERSION, true);
}
add_action('wp_enqueue_scripts', 'my_plugin_frontend_scripts');9.3 添加后台菜单页面
<?php
// 添加顶级菜单
function my_plugin_menu() {
add_menu_page(
'My Plugin', // 页面标题
'My Plugin', // 菜单标题
'manage_options', // 权限
'my-plugin', // Slug
'my_plugin_settings_page', // 回调函数
'dashicons-admin-plugins', // 图标
80 // 位置
);
// 添加子菜单
add_submenu_page(
'my-plugin',
'Settings',
'Settings',
'manage_options',
'my-plugin-settings',
'my_plugin_settings_page'
);
add_submenu_page(
'my-plugin',
'Data',
'Data',
'manage_options',
'my-plugin-data',
'my_plugin_data_page'
);
// 隐藏重复的子菜单(第一个子菜单 = 顶级菜单)
global $submenu;
unset($submenu['my-plugin'][0]);
}
add_action('admin_menu', 'my_plugin_menu');
// 设置页面内容
function my_plugin_settings_page() {
?>
<div class="wrap">
<h1>My Plugin Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields('my_plugin_settings_group');
do_settings_sections('my-plugin-settings');
submit_button();
?>
</form>
</div>
<?php
}
// 注册设置
function my_plugin_register_settings() {
register_setting('my_plugin_settings_group', 'my_plugin_settings', array(
'sanitize_callback' => 'my_plugin_sanitize_settings',
));
add_settings_section(
'my_plugin_general_section',
'General Settings',
'my_plugin_section_callback',
'my-plugin-settings'
);
add_settings_field(
'my_plugin_enabled',
'Enable Plugin',
'my_plugin_enabled_callback',
'my-plugin-settings',
'my_plugin_general_section'
);
add_settings_field(
'my_plugin_title',
'Plugin Title',
'my_plugin_title_callback',
'my-plugin-settings',
'my_plugin_general_section'
);
}
add_action('admin_init', 'my_plugin_register_settings');
// 字段回调
function my_plugin_enabled_callback() {
$options = get_option('my_plugin_settings');
?>
<input type="checkbox" name="my_plugin_settings[enabled]" value="1" <?php checked(1, $options['enabled'] ?? 0); ?>>
<?php
}
function my_plugin_title_callback() {
$options = get_option('my_plugin_settings');
?>
<input type="text" name="my_plugin_settings[title]" value="<?php echo esc_attr($options['title'] ?? ''); ?>" class="regular-text">
<?php
}
// 清理回调
function my_plugin_sanitize_settings($input) {
$sanitized = array();
$sanitized['enabled'] = !empty($input['enabled']) ? 1 : 0;
$sanitized['title'] = sanitize_text_field($input['title'] ?? '');
return $sanitized;
}9.4 AJAX 处理
<?php
// AJAX 处理(登录用户)
function my_plugin_ajax_handler() {
// 验证 nonce
if (!wp_verify_nonce($_POST['nonce'] ?? '', 'my_plugin_nonce')) {
wp_send_json_error('Security check failed');
}
// 验证权限
if (!current_user_can('manage_options')) {
wp_send_json_error('Permission denied');
}
$action_type = sanitize_text_field($_POST['action_type'] ?? '');
switch ($action_type) {
case 'save_data':
$name = sanitize_text_field($_POST['name'] ?? '');
$value = sanitize_textarea_field($_POST['value'] ?? '');
global $wpdb;
$result = $wpdb->insert($wpdb->prefix . 'my_plugin_data', array(
'name' => $name,
'value' => $value,
));
if ($result) {
wp_send_json_success(array('message' => 'Data saved successfully'));
} else {
wp_send_json_error('Failed to save data');
}
break;
case 'get_data':
global $wpdb;
$data = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}my_plugin_data ORDER BY created_at DESC LIMIT 10");
wp_send_json_success($data);
break;
default:
wp_send_json_error('Unknown action');
}
}
add_action('wp_ajax_my_plugin_action', 'my_plugin_ajax_handler');
// AJAX 处理(未登录用户)
// add_action('wp_ajax_nopriv_my_plugin_action', 'my_plugin_ajax_handler');前端 AJAX 调用(JavaScript):
jQuery(document).ready(function($) {
// 保存数据
$.ajax({
url: myPluginAdmin.ajaxUrl,
type: 'POST',
data: {
action: 'my_plugin_action',
nonce: myPluginAdmin.nonce,
action_type: 'save_data',
name: 'test',
value: 'test value'
},
success: function(response) {
if (response.success) {
console.log(response.data.message);
}
}
});
});十、WordPress 钩子系统
10.1 Action(动作钩子)
// 添加动作
add_action('hook_name', 'callback_function', $priority, $accepted_args);
// 示例:在页面底部添加内容
function my_custom_footer_content() {
echo '<p>Powered by My Theme</p>';
}
add_action('wp_footer', 'my_custom_footer_content');
// 常用 Action 钩子
// init WordPress 初始化后(加载主题/插件后)
// wp_loaded 所有内容加载完成后
// template_redirect 模板加载前
// wp_head <head> 标签内
// wp_footer </body> 标签前
// wp_body_open <body> 标签打开后
// after_setup_theme 主题设置后
// wp_enqueue_scripts 前台脚本加载
// admin_enqueue_scripts 后台脚本加载
// save_post 保存文章后
// publish_post 发布文章后
// delete_post 删除文章后
// user_register 用户注册后
// wp_login 用户登录后
// wp_logout 用户登出后
// comment_post 发表评论后
// switch_theme 切换主题后
// admin_menu 添加后台菜单
// widgets_init 注册小工具10.2 Filter(过滤器钩子)
// 添加过滤器
add_filter('hook_name', 'callback_function', $priority, $accepted_args);
// 示例:修改文章标题
function my_custom_title($title) {
if (is_single()) {
$title = $title . ' - My Blog';
}
return $title;
}
add_filter('the_title', 'my_custom_title');
// 示例:修改摘要长度
function my_excerpt_length($length) {
return 50;
}
add_filter('excerpt_length', 'my_excerpt_length', 999);
// 常用 Filter 钩子
// the_title 文章标题
// the_content 文章内容
// the_excerpt 文章摘要
// excerpt_length 摘要长度
// excerpt_more 摘要后缀
// wp_title 页面标题
// body_class body 类名
// post_class 文章类名
// upload_mimes 允许上传的文件类型
// login_redirect 登录后跳转
// wp_mail_from 邮件发送者
// wp_mail_from_name 邮件发送者名称
// comment_text 评论内容
// wp_nav_menu_items 菜单项 HTML
// widget_display_callback 小工具显示
// the_editor 编辑器内容
// query_vars 查询变量
// cron_schedules 自定义 cron 间隔10.3 自定义钩子
// 自定义 Action
do_action('my_custom_action', $arg1, $arg2);
// 其他代码中使用
add_action('my_custom_action', 'my_callback_function', 10, 2);
function my_callback_function($arg1, $arg2) {
// 处理逻辑
}
// 自定义 Filter
$value = apply_filters('my_custom_filter', $original_value, $arg1);
// 其他代码中使用
add_filter('my_custom_filter', 'my_filter_function', 10, 2);
function my_filter_function($value, $arg1) {
return $value . ' modified';
}十一、REST API 二次开发
11.1 WordPress 内置 REST API
# 基础端点
GET /wp-json/ # API 信息
GET /wp-json/wp/v2/posts # 获取文章列表
GET /wp-json/wp/v2/posts/{id} # 获取单篇文章
GET /wp-json/wp/v2/pages # 获取页面
GET /wp-json/wp/v2/categories # 获取分类
GET /wp-json/wp/v2/tags # 获取标签
GET /wp-json/wp/v2/users # 获取用户(需权限)
GET /wp-json/wp/v2/media # 获取媒体
GET /wp-json/wp/v2/comments # 获取评论
GET /wp-json/wp/v2/settings # 获取设置(需权限)
# 带参数查询
GET /wp-json/wp/v2/posts?per_page=5&page=1
GET /wp-json/wp/v2/posts?search=keyword
GET /wp-json/wp/v2/posts?categories=1,2
GET /wp-json/wp/v2/posts?orderby=date&order=desc
GET /wp-json/wp/v2/posts?author=1
# 使用 curl 测试
curl https://example.com/wp-json/wp/v2/posts
curl https://example.com/wp-json/wp/v2/posts?per_page=311.2 注册自定义 REST API 端点
<?php
// 注册自定义端点
function my_plugin_register_rest_routes() {
register_rest_route('my-plugin/v1', '/data', array(
'methods' => 'GET',
'callback' => 'my_plugin_get_data',
'permission_callback' => 'my_plugin_check_permission',
'args' => array(
'per_page' => array(
'default' => 10,
'sanitize_callback' => 'absint',
),
'page' => array(
'default' => 1,
'sanitize_callback' => 'absint',
),
),
));
register_rest_route('my-plugin/v1', '/data', array(
'methods' => 'POST',
'callback' => 'my_plugin_create_data',
'permission_callback' => 'my_plugin_check_permission',
));
register_rest_route('my-plugin/v1', '/data/(?P<id>\d+)', array(
'methods' => 'PUT',
'callback' => 'my_plugin_update_data',
'permission_callback' => 'my_plugin_check_permission',
));
register_rest_route('my-plugin/v1', '/data/(?P<id>\d+)', array(
'methods' => 'DELETE',
'callback' => 'my_plugin_delete_data',
'permission_callback' => 'my_plugin_check_permission',
));
}
add_action('rest_api_init', 'my_plugin_register_rest_routes');
// 权限检查
function my_plugin_check_permission($request) {
return current_user_can('edit_posts');
}
// GET - 获取数据
function my_plugin_get_data($request) {
global $wpdb;
$per_page = $request->get_param('per_page');
$page = $request->get_param('page');
$offset = ($page - 1) * $per_page;
$data = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}my_plugin_data LIMIT %d OFFSET %d",
$per_page, $offset
));
$total = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->prefix}my_plugin_data");
return new WP_REST_Response(array(
'data' => $data,
'total' => (int) $total,
'page' => (int) $page,
'per_page' => (int) $per_page,
'total_pages' => ceil($total / $per_page),
), 200);
}
// POST - 创建数据
function my_plugin_create_data($request) {
global $wpdb;
$name = sanitize_text_field($request->get_param('name'));
$value = sanitize_textarea_field($request->get_param('value'));
$result = $wpdb->insert($wpdb->prefix . 'my_plugin_data', array(
'name' => $name,
'value' => $value,
));
if ($result) {
return new WP_REST_Response(array(
'id' => $wpdb->insert_id,
'message' => 'Created successfully',
), 201);
}
return new WP_REST_Response(array('message' => 'Failed to create'), 500);
}
// PUT - 更新数据
function my_plugin_update_data($request) {
global $wpdb;
$id = $request->get_param('id');
$result = $wpdb->update(
$wpdb->prefix . 'my_plugin_data',
array(
'name' => sanitize_text_field($request->get_param('name')),
'value' => sanitize_textarea_field($request->get_param('value')),
),
array('id' => $id)
);
return new WP_REST_Response(array('message' => 'Updated successfully'), 200);
}
// DELETE - 删除数据
function my_plugin_delete_data($request) {
global $wpdb;
$id = $request->get_param('id');
$result = $wpdb->delete($wpdb->prefix . 'my_plugin_data', array('id' => $id));
return new WP_REST_Response(array('message' => 'Deleted successfully'), 200);
}11.3 修改现有 REST API
<?php
// 修改文章 API 返回的字段
function my_plugin_modify_post_response($response, $post) {
$data = $response->get_data();
$data['custom_field'] = get_post_meta($post->ID, 'custom_field', true);
$data['reading_time'] = ceil(str_word_count(strip_tags($post->post_content)) / 200) . ' min';
$response->set_data($data);
return $response;
}
add_filter('rest_prepare_post', 'my_plugin_modify_post_response', 10, 2);
// 注册自定义文章字段
function my_plugin_register_post_meta() {
register_post_meta('post', 'custom_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() {
return current_user_can('edit_posts');
},
));
}
add_action('init', 'my_plugin_register_post_meta');十二、性能优化
12.1 缓存策略
# 1. 页面缓存(WP Rocket / W3 Total Cache / LiteSpeed Cache)
# 2. 浏览器缓存(Nginx/Apache 配置)
# 3. 对象缓存(Redis / Memcached)
# 4. CDN(Cloudflare / 阿里云 CDN / 腾讯云 CDN)Nginx 浏览器缓存配置:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg|webp)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}Redis 对象缓存:
# 安装 Redis
sudo apt install -y redis-server php-redis
# WordPress 安装 Redis Object Cache 插件
# 或手动配置 drop-in 文件
# wp-content/object-cache.php(Redis Object Cache 插件会自动创建)12.2 数据库优化
-- 查看数据库大小
SELECT
table_name,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'wordpress'
ORDER BY (data_length + index_length) DESC;
-- 清理文章修订版本
DELETE FROM wp_posts WHERE post_type = 'revision';
-- 清理自动草稿
DELETE FROM wp_posts WHERE post_status = 'auto-draft';
-- 清理回收站文章
DELETE FROM wp_posts WHERE post_status = 'trash';
-- 清理垃圾评论
DELETE FROM wp_comments WHERE comment_approved = 'spam';
-- 清理过期的临时数据
DELETE FROM wp_options WHERE option_name LIKE '_transient_%' AND option_value < UNIX_TIMESTAMP() - 86400;
-- 清理过期的临时数据(二)
DELETE FROM wp_options WHERE option_name LIKE '_site_transient_%' AND option_value < UNIX_TIMESTAMP() - 86400;
-- 优化表
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
OPTIMIZE TABLE wp_options;
OPTIMIZE TABLE wp_comments;
OPTIMIZE TABLE wp_commentmeta;12.3 PHP 优化
# php.ini 优化
sudo nano /etc/php/8.1/fpm/php.ini
# 内存
memory_limit = 256M
# 上传
upload_max_filesize = 64M
post_max_size = 64M
# 执行时间
max_execution_time = 300
max_input_time = 300
# OPcache(重要!生产环境必须开启)
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
opcache.save_comments = 1
# 重启 PHP
sudo systemctl restart php8.1-fpm12.4 图片优化
1. 上传前压缩
- TinyPNG / Squoosh / ImageOptim
- 目标:每张图 < 200KB
2. 使用 WebP 格式
- 插件:ShortPixel / Imagify / Converter for Media
- 手动转换:cwebp input.png -o output.webp
3. 懒加载(Lazy Load)
- WordPress 5.5+ 内置
- 插件:WP Rocket / a3 Lazy Load
4. 响应式图片
- WordPress 自动添加 srcset
5. 图片 CDN
- Cloudflare / 阿里云 OSS + CDN
12.5 其他优化
// functions.php 中添加优化代码
// 1. 禁用 Emoji 脚本(不需要时)
function disable_emoji() {
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
}
add_action('init', 'disable_emoji');
// 2. 移除不必要的头部信息
remove_action('wp_head', 'wp_generator'); // WordPress 版本号
remove_action('wp_head', 'wlwmanifest_link'); // Windows Live Writer
remove_action('wp_head', 'rsd_link'); // RSD
remove_action('wp_head', 'wp_shortlink_wp_head'); // 短链接
// 3. 禁用 XML-RPC(减少攻击面)
add_filter('xmlrpc_enabled', '__return_false');
// 4. 移除查询字符串
function remove_query_strings($src) {
if (strpos($src, '?ver=')) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
add_filter('style_loader_src', 'remove_query_strings');
add_filter('script_loader_src', 'remove_query_strings');
// 5. 限制修订版本数量
define('WP_POST_REVISIONS', 3);
// 6. 禁用文章自动保存
define('AUTOSAVE_INTERVAL', 300); // 5 分钟
// 7. 禁用文章版本控制(极端情况)
// define('WP_POST_REVISIONS', false);十三、安全加固
13.1 基本安全措施
// wp-config.php 安全配置
// 禁用文件编辑器
define('DISALLOW_FILE_EDIT', true);
// 禁用插件和主题安装(生产环境)
// define('DISALLOW_FILE_MODS', true);
// 强制 SSL(后台)
define('FORCE_SSL_ADMIN', true);
// 自动更新
define('WP_AUTO_UPDATE_CORE', 'minor'); // 仅小版本更新
// 文件系统
define('FS_METHOD', 'direct');13.2 文件权限
# 正确的文件权限
# 目录:755
# 文件:644
# wp-config.php:600(更安全)
# .htaccess:644
find /var/www/wordpress -type d -exec chmod 755 {} \;
find /var/www/wordpress -type f -exec chmod 644 {} \;
chmod 600 /var/www/wordpress/wp-config.php
# 文件所有者
chown -R www-data:www-data /var/www/wordpress # Debian/Ubuntu
# chown -R nginx:nginx /var/www/wordpress # CentOS/Nginx13.3 敏感文件保护
Nginx:
# 禁止访问敏感文件
location ~* /\.ht {
deny all;
}
location = /wp-config.php {
deny all;
}
location = /xmlrpc.php {
deny all;
}
location ~* /wp-content/debug\.log {
deny all;
}
location ~* /readme\.html {
deny all;
}
location ~* /license\.txt {
deny all;
}Apache(.htaccess):
# 保护 wp-config.php
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
# 禁止目录浏览
Options -Indexes
# 保护 .htaccess
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
# 禁止 XML-RPC
<Files xmlrpc.php>
Order Allow,Deny
Deny from all
</Files>13.4 登录安全
// 1. 修改登录 URL(插件:WPS Hide Login)
// 默认:/wp-admin / wp-login.php
// 修改后:/my-secret-login
// 2. 限制登录尝试(插件:Limit Login Attempts Reloaded)
// 或手动添加代码
// 3. 双因素认证(插件:WP 2FA / Google Authenticator)
// 4. 添加登录验证码
function my_login_captcha() {
?>
<p>
<label for="captcha">What is 3 + 4?</label><br>
<input type="text" name="captcha" id="captcha" class="input" required>
</p>
<?php
}
add_action('login_form', 'my_login_captcha');
function my_verify_login_captcha($user, $password) {
$answer = $_POST['captcha'] ?? '';
if ($answer != '7') {
return new WP_Error('captcha_error', 'Incorrect captcha answer.');
}
return $user;
}
add_filter('authenticate', 'my_verify_login_captcha', 20, 3);13.5 安全插件
推荐安全插件组合:
├── Wordfence Security 防火墙 + 恶意软件扫描
├── Limit Login Attempts 限制登录尝试
├── Really Simple SSL SSL 管理
├── UpdraftPlus 备份
└── WP Activity Log 活动日志
13.6 日常安全检查
# 1. 保持 WordPress、主题、插件最新
# 2. 删除不使用的主题和插件
# 3. 定期备份数据库和文件
# 4. 使用强密码(12+ 字符)
# 5. 限制用户权限(最小权限原则)
# 6. 启用 HTTPS
# 7. 禁用文件编辑器
# 8. 定期安全扫描
# 9. 监控登录日志
# 10. 使用 Web 应用防火墙(WAF)十四、SEO 优化
14.1 基本 SEO 设置
1. 固定链接设置(设置 → 固定链接)
推荐:/post-name/ 或 /category/post-name/
2. 站点标题和描述(设置 → 常规)
标题:包含关键词
描述:简洁描述站点内容
3. 设置首页(设置 → 阅读)
静态页面 or 最新文章
4. 搜索引擎可见性
开发时勾选"阻止搜索引擎"
上线后取消勾选
5. SSL 证书(HTTPS)
HTTPS 是 Google 排名因素
14.2 SEO 插件配置(Yoast SEO)
Yoast SEO 设置:
├── 常规
│ ├── 站点标题模板
│ ├── 分隔符(- | ~)
│ └── 知识图谱设置
├── 搜索外观
│ ├── 首页标题和描述
│ ├── 文章类型(标题模板、描述模板)
│ ├── 分类和标签
│ └── 面包屑导航
├── 社交
│ ├── Facebook / Twitter
│ ├── Open Graph 元标签
│ └── 社交图片
├── 站点地图(Sitemap)
│ ├── 自动生成 XML Sitemap
│ └── 包含/排除内容类型
├── 高级
│ ├── 面包屑导航
│ ├── 永久链接清理
│ └── RSS 优化
└── 工具
├── 导入/导出设置
└── 文件编辑器
14.3 页面级 SEO 优化
每篇文章/页面的 SEO 设置:
├── SEO 标题(Title Tag)
│ 格式:关键词 - 站点名称
│ 长度:50-60 字符
│
├── Meta 描述(Description)
│ 包含关键词
│ 吸引点击
│ 长度:150-160 字符
│
├── URL 别名(Slug)
│ 简短、包含关键词
│ 使用连字符分隔
│ 避免中文 URL
│
├── 焦点关键词(Focus Keyphrase)
│ 主要目标关键词
│ 检查关键词密度
│
├── 内容优化
│ 标题层级(H1-H6)
│ 关键词自然分布
│ 内部链接
│ 外部链接(权威来源)
│ 图片 alt 标签
│ 文章长度(1500+ 字)
│
├── 特色图片
│ 包含关键词的文件名
│ 适当尺寸(1200x630)
│ alt 标签
│
└── Schema 标记(结构化数据)
文章、面包屑、FAQ、评论等
14.4 技术 SEO
# 1. XML Sitemap
# Yoast SEO 自动生成:https://example.com/sitemap_index.xml
# 2. robots.txt
# https://example.com/robots.txt
User-agent: *
Disallow: /wp-admin/
Disallow: /wp-includes/
Allow: /wp-admin/admin-ajax.php
Sitemap: https://example.com/sitemap_index.xml
# 3. 301 重定向
# 插件:Redirection
# 或 Nginx:
# location /old-url/ {
# return 301 /new-url/;
# }
# 4. 面包屑导航
# Yoast SEO 内置支持
# 5. 页面速度
# Google PageSpeed Insights: https://pagespeed.web.dev
# 目标:移动端 ≥ 80,桌面端 ≥ 90
# 6. 移动端适配
# 响应式设计
# Google Mobile-Friendly Test
# 7. Core Web Vitals
# LCP(最大内容绘制)< 2.5s
# FID(首次输入延迟)< 100ms
# CLS(累积布局偏移)< 0.1十五、多站点管理
15.1 开启多站点
// wp-config.php 中添加
define('WP_ALLOW_MULTISITE', true);后台 → 工具 → 网络安装:
1. 选择子域名或子目录
2. 填写网络标题和管理员邮箱
3. 点击"安装"
然后按照提示将代码添加到 wp-config.php 和 .htaccess
15.2 多站点管理
/wp-admin/network/ 网络管理后台
功能:
├── 站点管理
│ ├── 添加新站点
│ ├── 编辑站点
│ ├── 删除站点
│ └── 站点列表
├── 用户管理
│ ├── 网络级用户
│ ├── 站点级用户
│ └── 超级管理员
├── 主题管理
│ ├── 网络启用主题
│ └── 站点可选主题
├── 插件管理
│ ├── 网络启用插件
│ └── 站点可选插件
├── 设置
│ ├── 网络设置
│ ├── 注册设置
│ └── 上传设置
└── 更新
├── WordPress 核心
├── 主题
└── 插件
十六、数据库管理
16.1 核心数据表
wp_options 站点设置选项
wp_posts 文章、页面、附件、修订版本
wp_postmeta 文章自定义字段
wp_users 用户信息
wp_usermeta 用户自定义字段
wp_comments 评论
wp_commentmeta 评论自定义字段
wp_terms 分类/标签
wp_term_taxonomy 分类法
wp_term_relationships 分类关系
wp_termmeta 分类自定义字段
wp_links 链接(旧版功能)
16.2 常用 SQL 操作
-- 查看所有选项
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';
-- 修改站点 URL
UPDATE wp_options SET option_value = 'https://new-domain.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://new-domain.com' WHERE option_name = 'home';
-- 修改管理员密码
UPDATE wp_users SET user_pass = MD5('newpassword') WHERE user_login = 'admin';
-- 注意:WordPress 使用 phpass,建议通过后台修改
-- 禁用所有插件
UPDATE wp_options SET option_value = 'a:0:{}' WHERE option_name = 'active_plugins';
-- 修改主题
UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'template';
UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'stylesheet';
-- 修改固定链接(/post-name/)
UPDATE wp_options SET option_value = '/%postname%/' WHERE option_name = 'permalink_structure';
-- 查看文章和自定义字段
SELECT p.ID, p.post_title, p.post_status, pm.meta_key, pm.meta_value
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE p.post_type = 'post' AND p.post_status = 'publish'
ORDER BY p.post_date DESC;
-- 批量替换 URL(域名迁移)
UPDATE wp_options SET option_value = REPLACE(option_value, 'http://old.com', 'https://new.com') WHERE option_name = 'siteurl' OR option_name = 'home';
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://old.com', 'https://new.com');
UPDATE wp_posts SET guid = REPLACE(guid, 'http://old.com', 'https://new.com');
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, 'http://old.com', 'https://new.com');16.3 数据库备份与恢复
# 备份
mysqldump -u root -p wordpress > wordpress_backup.sql
mysqldump -u root -p --all-databases > all_backup.sql
# 压缩备份
mysqldump -u root -p wordpress | gzip > wordpress_backup.sql.gz
# 恢复
mysql -u root -p wordpress < wordpress_backup.sql
gunzip -c wordpress_backup.sql.gz | mysql -u root -p wordpress
# 定时备份(crontab)
# 0 2 * * * mysqldump -u root -p'password' wordpress | gzip > /backup/wordpress_$(date +\%Y\%m\%d).sql.gz十七、Docker 部署
17.1 Docker Compose 配置
# docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
container_name: wordpress
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: YourStrongPassword123!
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_DEBUG: "false"
volumes:
- wordpress_data:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
depends_on:
- db
db:
image: mysql:8.0
container_name: wordpress-db
restart: always
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: YourStrongPassword123!
MYSQL_ROOT_PASSWORD: RootPassword123!
volumes:
- db_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
depends_on:
- db
redis:
image: redis:7-alpine
container_name: wordpress-redis
restart: always
volumes:
- redis_data:/data
volumes:
wordpress_data:
db_data:
redis_data:PHP 上传配置(uploads.ini):
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 300# 启动
docker compose up -d
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f wordpress
# 进入容器
docker exec -it wordpress bash
# 停止
docker compose down
# 停止并删除数据卷
docker compose down -v17.2 Nginx + Docker(反向代理)
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
}
client_max_body_size 64M;
}十八、常用 WP-CLI 命令
18.1 安装 WP-CLI
# 下载
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
# 移动到 PATH
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
# 验证
wp --info18.2 核心命令
# WordPress 核心
wp core download # 下载 WordPress
wp core install # 安装 WordPress
wp core update # 更新 WordPress
wp core version # 查看版本
# 安装 WordPress
wp core install --url="https://example.com" \
--title="My Site" \
--admin_user="admin" \
--admin_password="StrongPass123!" \
--admin_email="admin@example.com" \
--locale="zh_CN" \
--skip-email
# 数据库
wp db create # 创建数据库
wp db export backup.sql # 导出数据库
wp db import backup.sql # 导入数据库
wp db optimize # 优化数据库
wp db repair # 修复数据库
wp search-replace 'old.com' 'new.com' # 批量替换
# 文章
wp post list # 列出文章
wp post create --post_title="Hello" --post_content="World" --post_status=publish
wp post update 1 --post_title="New Title"
wp post delete 1 --force
wp post generate --count=10 # 生成测试文章
# 页面
wp post list --post_type=page
# 用户
wp user list # 列出用户
wp user create username email@example.com --role=author --user_pass="password"
wp user update 1 --user_pass="newpassword"
wp user delete 2 --reassign=1
wp user generate --count=5 # 生成测试用户
# 主题
wp theme list # 列出主题
wp theme install theme-name --activate # 安装并激活
wp theme activate theme-name # 激活
wp theme delete theme-name # 删除
# 插件
wp plugin list # 列出插件
wp plugin install plugin-name --activate # 安装并激活
wp plugin activate plugin-name # 激活
wp plugin deactivate plugin-name # 停用
wp plugin deactivate --all # 停用所有
wp plugin delete plugin-name # 删除
wp plugin update --all # 更新所有插件
# 选项(设置)
wp option get siteurl # 获取站点 URL
wp option update blogname "New Title" # 修改站点标题
wp option list # 列出所有选项
# 分类/标签
wp term list category # 列出分类
wp term create category "News" # 创建分类
# 媒体
wp media import image.jpg # 导入图片
# 转储缓存
wp cache flush # 清除缓存
wp rewrite flush # 刷新固定链接
# 评估
wp eval 'echo get_bloginfo("name");' # 执行 PHP 代码
wp shell # 交互式 PHP Shell
# 检查
wp doctor check # 站点健康检查
wp healthcheck # 健康检查十九、故障排查
19.1 白屏(White Screen of Death)
// 1. 开启调试模式
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
// 查看日志
tail -f /var/www/wordpress/wp-content/debug.log
// 2. 禁用所有插件(通过数据库)
mysql -u root -p wordpress -e "UPDATE wp_options SET option_value='a:0:{}' WHERE option_name='active_plugins';"
// 3. 切换默认主题(通过数据库)
mysql -u root -p wordpress -e "UPDATE wp_options SET option_value='twentytwentyfour' WHERE option_name='template';"
mysql -u root -p wordpress -e "UPDATE wp_options SET option_value='twentytwentyfour' WHERE option_name='stylesheet';"
// 4. 检查 PHP 内存限制
// php.ini 或 wp-config.php
define('WP_MEMORY_LIMIT', '256M');
// 5. 重新上传 WordPress 核心文件
wp core download --force19.2 500 Internal Server Error
# 1. 检查错误日志
tail -f /var/log/nginx/error.log
tail -f /var/log/apache2/error.log
# 2. 检查 .htaccess(Apache)
# 备份后删除 .htaccess,看是否恢复
mv .htaccess .htaccess.bak
# 3. 检查 PHP 版本兼容性
php -v
# 4. 检查文件权限
find /var/www/wordpress -type d -exec chmod 755 {} \;
find /var/www/wordpress -type f -exec chmod 644 {} \;
# 5. 增加 PHP 内存和执行时间
# php.ini:
# memory_limit = 256M
# max_execution_time = 30019.3 数据库连接错误
// "建立数据库连接时出错"
// 1. 检查 wp-config.php 中的数据库信息
define('DB_NAME', 'wordpress');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'password');
define('DB_HOST', 'localhost');
// 2. 检查 MySQL 服务
sudo systemctl status mysql
sudo systemctl restart mysql
// 3. 检查数据库用户权限
mysql -u root -p -e "SHOW GRANTS FOR 'wpuser'@'localhost';"
// 4. 测试数据库连接
mysql -u wpuser -p'password' wordpress -e "SELECT 1;"19.4 固定链接不工作(404 错误)
# Apache
# 确保 mod_rewrite 已启用
sudo a2enmod rewrite
sudo systemctl restart apache2
# 确保 AllowOverride All
# <Directory /var/www/wordpress>
# AllowOverride All
# </Directory>
# Nginx
# 确保配置中有:
# location / {
# try_files $uri $uri/ /index.php?$args;
# }
# 重新保存固定链接
# 后台 → 设置 → 固定链接 → 直接点击"保存更改"
# WP-CLI
wp rewrite flush19.5 上传文件失败
# 1. 检查 PHP 上传限制
# php.ini:
# upload_max_filesize = 64M
# post_max_size = 64M
# 2. 检查目录权限
chmod -R 755 /var/www/wordpress/wp-content/uploads
chown -R www-data:www-data /var/www/wordpress/wp-content/uploads
# 3. 检查磁盘空间
df -h
# 4. 检查 SELinux(CentOS)
sudo chcon -R -t httpd_sys_rw_content_t /var/www/wordpress/wp-content/uploads/19.6 网站速度慢
排查步骤:
1. 测试页面速度(PageSpeed Insights / GTmetrix)
2. 检查服务器负载(top / htop)
3. 检查数据库查询(Query Monitor 插件)
4. 检查 PHP 版本(建议 8.1+)
5. 启用缓存(WP Rocket / W3 Total Cache)
6. 启用 OPcache
7. 优化图片
8. 使用 CDN
9. 减少插件数量
10. 优化数据库
19.7 常见错误速查
| 错误 | 可能原因 | 解决方案 |
|---|---|---|
| 白屏 | PHP 错误 / 内存不足 | 开启 WP_DEBUG,禁用插件 |
| 500 Error | .htaccess / PHP 错误 | 检查 .htaccess,查看错误日志 |
| 数据库连接错误 | 配置错误 / MySQL 未启动 | 检查 wp-config.php,重启 MySQL |
| 404 错误 | 固定链接 / .htaccess | 重新保存固定链接 |
| 上传失败 | 上传限制 / 权限 | 修改 php.ini,检查权限 |
| 内存不足 | PHP 内存限制 | 增加 WP_MEMORY_LIMIT |
| 重定向循环 | SSL 配置 / 缓存 | 检查 HTTPS 设置,清除缓存 |
| 更新失败 | 文件权限 / 磁盘空间 | 修复权限,检查磁盘 |
| 邮件不发送 | 服务器 SMTP | 安装 WP Mail SMTP 插件 |
二十、完整实战示例
20.1 一键部署脚本
#!/bin/bash
# deploy_wordpress.sh
set -e
DOMAIN="example.com"
DB_NAME="wordpress"
DB_USER="wpuser"
DB_PASS=$(openssl rand -base64 24)
WP_DIR="/var/www/wordpress"
ADMIN_USER="admin"
ADMIN_PASS=$(openssl rand -base64 16)
ADMIN_EMAIL="admin@example.com"
echo "=== WordPress 一键部署 ==="
# 1. 安装 LAMP/LNMP
echo "[1/7] 安装环境..."
apt update && apt install -y nginx php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip php-intl mysql-server certbot python3-certbot-nginx
# 2. 创建数据库
echo "[2/7] 创建数据库..."
mysql -u root -p -e "
CREATE DATABASE IF NOT EXISTS $DB_NAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';
GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';
FLUSH PRIVILEGES;
"
# 3. 下载 WordPress
echo "[3/7] 下载 WordPress..."
cd /var/www
wget -q https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
chown -R www-data:www-data $WP_DIR
# 4. 配置 wp-config.php
echo "[4/7] 配置 WordPress..."
cd $WP_DIR
cp wp-config-sample.php wp-config.php
# 生成密钥
SALTS=$(curl -s https://api.wordpress.org/secret-key/1.1/salt/)
cat > wp-config.php << EOF
<?php
define('DB_NAME', '$DB_NAME');
define('DB_USER', '$DB_USER');
define('DB_PASSWORD', '$DB_PASS');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', 'utf8mb4_unicode_ci');
$SALTS
\$table_prefix = 'wp_';
define('WP_DEBUG', false);
define('WP_MEMORY_LIMIT', '256M');
define('DISALLOW_FILE_EDIT', true);
define('WP_AUTO_UPDATE_CORE', 'minor');
define('FS_METHOD', 'direct');
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
require_once ABSPATH . 'wp-settings.php';
EOF
# 5. 配置 Nginx
echo "[5/7] 配置 Nginx..."
cat > /etc/nginx/sites-available/wordpress << EOF
server {
listen 80;
server_name $DOMAIN www.$DOMAIN;
root $WP_DIR;
index index.php;
client_max_body_size 64M;
location / {
try_files \$uri \$uri/ /index.php?\$args;
}
location ~ \.php\$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
location ~* /\.ht { deny all; }
location = /wp-config.php { deny all; }
location = /xmlrpc.php { deny all; }
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)\$ {
expires 30d;
access_log off;
}
}
EOF
ln -sf /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
# 6. 安装 WordPress
echo "[6/7] 安装 WordPress..."
cd $WP_DIR
wp core install \
--url="http://$DOMAIN" \
--title="$DOMAIN" \
--admin_user="$ADMIN_USER" \
--admin_password="$ADMIN_PASS" \
--admin_email="$ADMIN_EMAIL" \
--locale="zh_CN" \
--skip-email \
--allow-root
# 7. 基本配置
echo "[7/7] 基本配置..."
wp option update permalink_structure '/%postname%/' --allow-root
wp rewrite flush --allow-root
wp plugin install akismet --activate --allow-root
wp plugin install wordpress-seo --activate --allow-root
wp theme install generatepress --activate --allow-root
echo ""
echo "=== 部署完成 ==="
echo "站点地址: http://$DOMAIN"
echo "后台地址: http://$DOMAIN/wp-admin"
echo "管理员: $ADMIN_USER"
echo "密码: $ADMIN_PASS"
echo "数据库: $DB_NAME"
echo "DB 用户: $DB_USER"
echo "DB 密码: $DB_PASS"
echo ""
echo "请立即登录后台并修改密码!"
echo "下一步:配置 SSL(sudo certbot --nginx -d $DOMAIN)"20.2 自定义短代码插件
<?php
/**
* Plugin Name: My Shortcodes
* Description: 自定义短代码集合
* Version: 1.0.0
* Author: Your Name
* Text Domain: my-shortcodes
*/
if (!defined('ABSPATH')) exit;
// 按钮短代码 [my_button url="#" text="点击这里" color="blue" size="large"]
function my_button_shortcode($atts) {
$atts = shortcode_atts(array(
'url' => '#',
'text' => 'Click Here',
'color' => 'blue',
'size' => 'medium',
'target' => '_self',
), $atts, 'my_button');
return sprintf(
'<a href="%s" class="my-btn my-btn-%s my-btn-%s" target="%s">%s</a>',
esc_url($atts['url']),
esc_attr($atts['color']),
esc_attr($atts['size']),
esc_attr($atts['target']),
esc_html($atts['text'])
);
}
add_shortcode('my_button', 'my_button_shortcode');
// 信息框短代码 [my_alert type="info" title="提示"]内容[/my_alert]
function my_alert_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'type' => 'info',
'title' => '',
), $atts, 'my_alert');
$types = array('info', 'success', 'warning', 'error');
$type = in_array($atts['type'], $types) ? $atts['type'] : 'info';
$html = '<div class="my-alert my-alert-' . esc_attr($type) . '">';
if (!empty($atts['title'])) {
$html .= '<strong>' . esc_html($atts['title']) . '</strong>';
}
$html .= '<p>' . wp_kses_post(do_shortcode($content)) . '</p>';
$html .= '</div>';
return $html;
}
add_shortcode('my_alert', 'my_alert_shortcode');
// 文章列表短代码 [my_posts category="news" count="5" layout="grid"]
function my_posts_shortcode($atts) {
$atts = shortcode_atts(array(
'category' => '',
'count' => 5,
'layout' => 'list',
), $atts, 'my_posts');
$args = array(
'post_type' => 'post',
'posts_per_page' => intval($atts['count']),
'orderby' => 'date',
'order' => 'DESC',
);
if (!empty($atts['category'])) {
$args['category_name'] = sanitize_text_field($atts['category']);
}
$query = new WP_Query($args);
$html = '<div class="my-posts my-posts-' . esc_attr($atts['layout']) . '">';
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$html .= '<div class="my-post-item">';
$html .= '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
$html .= '<p>' . get_the_excerpt() . '</p>';
$html .= '<span class="date">' . get_the_date() . '</span>';
$html .= '</div>';
}
} else {
$html .= '<p>暂无文章</p>';
}
$html .= '</div>';
wp_reset_postdata();
return $html;
}
add_shortcode('my_posts', 'my_posts_shortcode');
// 加载短代码样式
function my_shortcodes_styles() {
wp_enqueue_style('my-shortcodes', plugin_dir_url(__FILE__) . 'assets/css/shortcodes.css', array(), '1.0.0');
}
add_action('wp_enqueue_scripts', 'my_shortcodes_styles');20.3 自定义文章类型插件
<?php
/**
* Plugin Name: My Custom Post Types
* Description: 注册自定义文章类型和分类法
* Version: 1.0.0
*/
if (!defined('ABSPATH')) exit;
// 注册自定义文章类型
function my_register_post_types() {
// 作品集(Portfolio)
register_post_type('portfolio', array(
'labels' => array(
'name' => '作品集',
'singular_name' => '作品',
'add_new' => '添加作品',
'add_new_item' => '添加新作品',
'edit_item' => '编辑作品',
'new_item' => '新作品',
'view_item' => '查看作品',
'search_items' => '搜索作品',
'not_found' => '未找到作品',
'not_found_in_trash' => '回收站中无作品',
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'portfolio'),
'menu_icon' => 'dashicons-portfolio',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields', 'comments'),
'show_in_rest' => true,
'capability_type' => 'post',
));
// 产品(Product)
register_post_type('product', array(
'labels' => array(
'name' => '产品',
'singular_name' => '产品',
'add_new' => '添加产品',
'edit_item' => '编辑产品',
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'product'),
'menu_icon' => 'dashicons-cart',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'),
'show_in_rest' => true,
));
}
add_action('init', 'my_register_post_types');
// 注册自定义分类法
function my_register_taxonomies() {
// 作品分类
register_taxonomy('portfolio_category', 'portfolio', array(
'labels' => array(
'name' => '作品分类',
'singular_name' => '作品分类',
'add_new_item' => '添加作品分类',
),
'hierarchical' => true,
'rewrite' => array('slug' => 'portfolio-category'),
'show_admin_column' => true,
'show_in_rest' => true,
));
// 产品标签
register_taxonomy('product_tag', 'product', array(
'labels' => array(
'name' => '产品标签',
'singular_name' => '产品标签',
),
'hierarchical' => false,
'rewrite' => array('slug' => 'product-tag'),
'show_admin_column' => true,
'show_in_rest' => true,
));
}
add_action('init', 'my_register_taxonomies');
// 注册自定义元数据
function my_register_meta() {
register_post_meta('portfolio', 'project_url', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() { return current_user_can('edit_posts'); },
));
register_post_meta('portfolio', 'client_name', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() { return current_user_can('edit_posts'); },
));
register_post_meta('product', 'price', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() { return current_user_can('edit_posts'); },
));
register_post_meta('product', 'sku', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() { return current_user_can('edit_posts'); },
));
}
add_action('init', 'my_register_meta');附录 A:常用函数速查
| 函数 | 说明 |
|---|---|
get_header() |
加载 header.php |
get_footer() |
加载 footer.php |
get_sidebar() |
加载 sidebar.php |
get_template_part('content') |
加载 template-parts/content.php |
wp_head() |
在 中输出 |
wp_footer() |
在 前输出 |
wp_enqueue_style() |
加载 CSS |
wp_enqueue_script() |
加载 JS |
wp_nav_menu() |
输出导航菜单 |
dynamic_sidebar() |
输出侧边栏 |
is_active_sidebar() |
判断侧边栏是否有小工具 |
register_nav_menus() |
注册导航菜单位置 |
register_sidebar() |
注册侧边栏 |
add_theme_support() |
添加主题支持 |
add_image_size() |
添加自定义图片尺寸 |
the_post_thumbnail() |
输出特色图片 |
get_the_date() |
获取发布日期 |
get_permalink() |
获取文章链接 |
home_url('/') |
获取首页 URL |
admin_url('/') |
获取后台 URL |
get_option() |
获取选项值 |
update_option() |
更新选项值 |
get_post_meta() |
获取自定义字段 |
update_post_meta() |
更新自定义字段 |
wp_redirect() |
302 跳转 |
wp_safe_redirect() |
安全跳转 |
esc_html() |
HTML 转义 |
esc_attr() |
属性转义 |
esc_url() |
URL 转义 |
sanitize_text_field() |
清理文本 |
sanitize_email() |
清理邮箱 |
current_user_can() |
检查用户权限 |
wp_create_nonce() |
创建安全令牌 |
wp_verify_nonce() |
验证安全令牌 |
附录 B:推荐学习资源
书籍
| 书名 | 作者 | 方向 |
|---|---|---|
| 《Professional WordPress》 | Brad Williams | WordPress 开发 |
| 《WordPress 插件开发》 | Brad Williams | 插件开发 |
| 《WordPress 主题开发》 | Tessa Blakeley Silver | 主题开发 |
| 《WordPress 入门到精通》 | 国内多位作者 | 中文入门 |
在线资源
| 资源 | 网址 | 说明 |
|---|---|---|
| WordPress 官方文档 | https://developer.wordpress.org | 开发者文档 |
| WordPress Codex | https://codex.wordpress.org | 经典文档 |
| WP Tavern | https://wptavern.com | WordPress 新闻 |
| WPBeginner | https://www.wpbeginner.com | 新手教程 |
| Smashing Magazine | https://www.smashingmagazine.com | 设计与开发 |
| WordPress TV | https://wordpress.tv | 视频教程 |
| GitHub WordPress | https://github.com/WordPress | 官方源码 |
| GeneratePress | https://generatepress.com | 主题参考 |
| Elementor | https://elementor.com | 页面构建器 |
总结: WordPress 从入门到精通的核心路径是:先掌握后台管理 → 学会使用主题和插件 → 深入主题开发 → 学习插件开发 → 理解钩子系统 → 掌握 REST API → 优化性能和安全。WordPress 的生态系统极其丰富,无论是零代码建站还是深度开发,都能满足需求。持续学习官方文档、关注社区动态、多做项目实践,你将快速成为 WordPress 高手。
转载请注明出处