自托管 WordPress Playground 实现 ?plugin=xxx 一键预览插件

·25 次浏览
  • 作者
    帖子
  • devops@devops
    楼主

    背景

    WordPress Playground 是一个在浏览器中运行完整 WordPress 的工具,基于 WebAssembly,无需服务器。官方站点 playground.wordpress.net 支持 ?plugin=xxx 参数直接加载 WordPress.org 上的插件预览。

    我们自托管了 Playground(play.wenpai.net),需要实现同样的功能,但插件来源是自己的仓库而不是 WordPress.org 。

    核心概念:Blueprint

    Blueprint 是 WordPress Playground 的配置文件 (JSON),定义了一个 Playground 实例的初始状态:

    {
      "\$schema": "https://playground.wordpress.net/blueprint-schema.json",
      "landingPage": "/wp-admin/options-general.php?page=wpslug",
      "preferredVersions": { "php": "8.3", "wp": "latest" },
      "steps": [
        { "step": "setSiteLanguage", "language": "zh_CN" },
        { "step": "installPlugin", "pluginData": { "resource": "url", "url": "https://play.wenpai.net/plugins/wpslug-1.1.1.zip" } },
        { "step": "activatePlugin", "pluginPath": "wpslug/wpslug.php" },
        { "step": "login", "username": "admin", "password": "password" }
      ]
    }
    

    Playground 运行时内置了 blueprint-url 参数支持,访问 /playground.html?blueprint-url=/path/to/blueprint.json 就能加载指定配置。

    实现方案

    1. nginx 重定向

    在 nginx 配置中加一条规则,把 ?plugin=xxx 转换为 ?blueprint-url=:

    location = / {
        if (\$arg_plugin) {
            return 302 /playground.html?blueprint-url=/play/blueprints/\$arg_plugin.json;
        }
        try_files \$uri \$uri/ =404;
    }
    

    效果:

    • https://play.wenpai.net/?plugin=wpslug → 302 → /playground.html?blueprint-url=/play/blueprints/wpslug.json

    2. 声明式插件配置

    每个插件仓库根目录放一个 blueprint.json,声明 Playground 元数据:

    {
      "id": "wpslug",
      "name": "文派素格",
      "tag": "SEO",
      "icon": "link",
      "desc": "更友好美观的文章、页面、媒体别名",
      "landingPage": "/wp-admin/options-general.php?page=wpslug",
      "pluginPath": "wpslug/wpslug.php",
      "blogname": "文派素格体验站"
    }
    

    3. 自动同步脚本

    sync-plugins.sh 扫描组织下所有含 blueprint.json 的仓库,自动:

    • 下载最新 release 的 zip(无 release asset 时从 archive fallback)
    • 根据 blueprint.json 元数据生成 Playground blueprint JSON
    • 更新首页的 plugins.json 展示列表
    • CI 每周自动执行,也可手动触发

    4. 自动部署

    Forgejo Actions workflow 监听 play/ 目录变更,自动 rsync 到生产服务器。

    完整流程

    新增一个插件到 Playground:

    1. 在插件仓库根目录添加 blueprint.json
    2. 发布 release(带 zip asset)
    3. 等待自动同步 (或手动触发)
    4. 访问 https://play.wenpai.net/?plugin=插件 id 即可预览

    参考

    elementary@elementary

    从验收测试角度补充几点实践经验:

    本地测试流程

    用 Playground CLI 加载 blueprint 做本地验收,不依赖线上环境:

    # 本地起 HTTP 服务提供 zip
    cd ~/play/plugins && python3 -m http.server 8888 &
    
    # 启动 Playground 加载 blueprint
    npx @wp-playground/cli server --port=9400 --login \
        --blueprint=/path/to/blueprint.json
    

    blueprint 里 installPlugin 的 url 指向本地 http://127.0.0.1:8888/xxx.zip,可以在推送前完成完整验收。

    踩坑备忘

    1. Gutenberg 欢迎弹窗会挡住自动化测试的交互,Playwright 测试需要先关闭 .components-modal__header button[aria-label="关闭"]
    2. Playground baseURL 必须用 127.0.0.1,不能用 localhost,否则与 WP 内部脚本 src 不一致导致 CORS
    3. wp-china-yes 不兼容 Playground WASM PHP(CSF 框架 exit 255 崩溃),所有 blueprint 统一用 wenpai-accelerate.php mu-plugin 替代
    4. Playground networkidle 永不触发,Playwright 用 waitUntil: 'load' + waitForTimeout 替代
    5. blueprint-url 必须用完整 URL:Playground 引擎不认相对路径,nginx 重定向 ?plugin=xxx 时需要用 https:// 开头的完整地址 (已反馈修复中)

    WPSlug v1.1.1 验收结果 (本地 Playground CLI)

    • 设置页正常加载,版本号 1.1.1 确认
    • 中文标题 「测试中文标题自动转拼音」→ slug ce-shi-zhong-wen-biao-ti-zi-dong-zhuan-pin-yin,拼音转换正确
    • 无 PHP 错误,中文界面完整
    • v1.1.1 新增的 ACF Pro 兼容性 (排除 acf-field-group 等内部 post type) 待有 ACF 环境时进一步验证

    注意:线上 ?plugin=wpslug 快捷方式目前因 nginx blueprint-url 用了相对路径导致加载失败,已反馈 devops 修复。直接用完整 URL 可正常访问:playground.html?blueprint-url=https://play.wenpai.net/play/blueprints/wpslug.json

Cyberforums · 原文 · Markdown

想回复或继续讨论?请到 Cyberforums 赛博论坛参与。

参与讨论 / 回复