主题插件

WordPress插件开发入门:写你的第一个插件

WordPress插件开发入门教程,从零开始创建一个WordPress插件,学习钩子、过滤器和插件API。

#插件开发 #WordPress开发 #PHP编程

前言

WordPress插件是扩展网站功能的核心方式。如果你有一些PHP基础,完全可以自己写插件来实现特定的功能。不用觉得写插件很难,最简单的插件只需要几行代码。今天从零开始,带你写出第一个WordPress插件。

开发环境准备

开始之前你需要:

准备项目推荐工具
本地WordPress环境LocalWP 或 XAMPP
代码编辑器VS Code
PHP基础知识变量、函数、数组、类
浏览器开发工具Chrome DevTools

如果你还没有本地开发环境,可以参考WordPress安装教程中的本地安装方法。

最简单的插件

创建插件文件

wp-content/plugins/ 目录下创建一个文件夹和文件:

wp-content/plugins/my-first-plugin/
└── my-first-plugin.php

插件头部信息

每个插件必须包含标准的头部注释:

<?php
/**
 * Plugin Name: My First Plugin
 * Plugin URI: https://example.com/my-first-plugin
 * Description: 这是我的第一个WordPress插件
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://example.com
 * License: GPL-2.0+
 * Text Domain: my-first-plugin
 */

// 防止直接访问
if (!defined('ABSPATH')) {
    exit;
}

保存后在后台 → 插件 中就能看到你的插件了,点击”激活”即可启用。

核心概念:钩子系统

WordPress的钩子(Hooks)系统是插件开发的核心。钩子分为两种:

Action(动作钩子)

Action在特定时间点执行代码:

// 在页脚输出内容
function my_footer_text() {
    echo '<p style="text-align:center;">感谢访问本站</p>';
}
add_action('wp_footer', 'my_footer_text');

常用的Action钩子:

钩子名称触发时机
initWordPress初始化完成
wp_head输出head标签内容
wp_footer输出footer内容
wp_enqueue_scripts加载前端脚本和样式
admin_menu注册后台菜单
save_post文章保存时
admin_init后台初始化

Filter(过滤器钩子)

Filter用于修改数据并返回:

// 在文章内容末尾添加关注提示
function add_follow_text($content) {
    if (is_single()) {
        $follow_text = '<div class="follow-box">';
        $follow_text .= '<p>如果觉得有用,请关注我的博客获取更多教程!</p>';
        $follow_text .= '</div>';
        $content .= $follow_text;
    }
    return $content;
}
add_filter('the_content', 'add_follow_text');

常用的Filter钩子:

钩子名称作用
the_content修改文章内容
the_title修改文章标题
the_excerpt修改文章摘要
wp_title修改页面标题
body_class添加body CSS类
login_url修改登录URL

实战:创建一个阅读时间插件

下面我们来写一个实用的插件:在每篇文章开头显示预计阅读时间。

<?php
/**
 * Plugin Name: Reading Time Estimator
 * Description: 在文章开头显示预计阅读时间
 * Version: 1.0.0
 * Author: Your Name
 */

if (!defined('ABSPATH')) {
    exit;
}

// 计算阅读时间
function rte_calculate_reading_time($content) {
    // 中文按每分钟400字计算
    $word_count = mb_strlen(strip_tags($content), 'UTF-8');
    $reading_time = ceil($word_count / 400);

    if ($reading_time < 1) {
        $reading_time = 1;
    }

    return $reading_time;
}

// 在文章内容前添加阅读时间
function rte_display_reading_time($content) {
    if (is_single() && in_the_loop() && is_main_query()) {
        $reading_time = rte_calculate_reading_time($content);
        $reading_html = '<div class="reading-time">';
        $reading_html .= '<span>预计阅读时间:' . $reading_time . ' 分钟</span>';
        $reading_html .= '</div>';
        $content = $reading_html . $content;
    }
    return $content;
}
add_filter('the_content', 'rte_display_reading_time');

// 添加样式
function rte_enqueue_styles() {
    if (is_single()) {
        $css = '
        .reading-time {
            background: #f0f8ff;
            padding: 10px 15px;
            border-left: 3px solid #0073aa;
            margin-bottom: 20px;
            font-size: 14px;
            color: #666;
            border-radius: 3px;
        }';
        wp_add_inline_style('wp-block-library', $css);
    }
}
add_action('wp_enqueue_scripts', 'rte_enqueue_styles');

创建设置页面

大多数插件需要一个设置页面。下面是基本框架:

// 注册设置页面
function mfp_add_admin_menu() {
    add_options_page(
        '我的插件设置',           // 页面标题
        '我的插件',              // 菜单标题
        'manage_options',        // 权限
        'my-first-plugin',      // 菜单slug
        'mfp_settings_page'     // 回调函数
    );
}
add_action('admin_menu', 'mfp_add_admin_menu');

// 注册设置项
function mfp_register_settings() {
    register_setting('mfp_settings_group', 'mfp_reading_speed');
    register_setting('mfp_settings_group', 'mfp_display_position');
}
add_action('admin_init', 'mfp_register_settings');

// 设置页面HTML
function mfp_settings_page() {
    ?>
    <div class="wrap">
        <h1>我的插件设置</h1>
        <form method="post" action="options.php">
            <?php settings_fields('mfp_settings_group'); ?>
            <table class="form-table">
                <tr>
                    <th>阅读速度(字/分钟)</th>
                    <td>
                        <input type="number" name="mfp_reading_speed"
                               value="<?php echo esc_attr(get_option('mfp_reading_speed', 400)); ?>">
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

安全最佳实践

编写插件时务必注意安全:

// 1. 数据验证
$speed = absint($_POST['reading_speed']); // 确保是正整数

// 2. 数据清理
$title = sanitize_text_field($_POST['title']); // 清理文本
$url = esc_url($_POST['url']); // 验证URL

// 3. 输出转义
echo esc_html($user_input); // 防止XSS
echo esc_attr($attribute);  // 属性转义

// 4. Nonce验证(防CSRF)
wp_nonce_field('mfp_save_settings', 'mfp_nonce');
// 验证
if (!wp_verify_nonce($_POST['mfp_nonce'], 'mfp_save_settings')) {
    die('安全验证失败');
}

// 5. 权限检查
if (!current_user_can('manage_options')) {
    wp_die('没有权限');
}

插件文件结构

一个规范的插件应该有清晰的文件结构:

my-plugin/
├── my-plugin.php          # 主文件
├── readme.txt             # 插件说明(提交到官方库需要)
├── uninstall.php          # 卸载时清理数据
├── includes/
│   ├── class-main.php     # 主类
│   └── functions.php      # 辅助函数
├── admin/
│   ├── admin-page.php     # 后台页面
│   └── css/admin.css      # 后台样式
├── public/
│   ├── css/style.css      # 前端样式
│   └── js/script.js       # 前端脚本
└── languages/
    └── my-plugin-zh_CN.po # 中文翻译

调试技巧

// 开启WordPress调试模式
// 在wp-config.php中设置
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);

// 在插件中使用error_log记录调试信息
error_log('变量值:' . print_r($variable, true));

// 查看日志
// wp-content/debug.log

也可以安装Query Monitor插件,它能显示所有钩子的执行情况、数据库查询和PHP错误。

从这里继续学习

掌握插件开发基础后,可以进一步学习:

  • WordPress REST API
  • 自定义文章类型和分类法
  • Ajax处理
  • 定时任务(WP Cron)
  • 主题开发也使用相同的钩子系统

推荐阅读WordPress官方开发者文档和必备插件的源码来学习最佳实践。

总结

WordPress插件开发的核心就是钩子系统:Action用来在特定时间点执行代码,Filter用来修改数据。从简单的功能开始,逐步学习设置页面、数据库操作和安全实践。动手写代码是最好的学习方式,先模仿再创新。


相关文章