从自托管私有Gitlab的Markdown页面同步内容至WordPress文章
自托管Gitlab到WP Engine WordPress的文档同步方案
针对你遇到的私有Gitlab无法被WP插件访问、WP Engine限制服务器安装内容的问题,以下是几个无依赖、易实现的同步方案:
方案1:Gitlab CI/CD + WordPress REST API(推荐)
完全在Gitlab侧执行同步,不需要WP服务器安装任何额外工具,利用Gitlab的CI/CD流水线触发推送,通过WP官方REST API更新文章。
操作步骤
WordPress侧配置API权限
- WP 5.6及以上版本内置「应用密码」功能,在用户个人资料页面生成一个具有「编辑文章」权限的应用密码,记录用户名和密码。
- 确保WP REST API处于启用状态(WP默认启用,WP Engine不会禁用该功能)。
编写Gitlab CI/CD流水线脚本
在Gitlab文档仓库根目录创建.gitlab-ci.yml,设置分支推送时自动执行同步:stages: - sync_to_wordpress sync_job: stage: sync_to_wordpress image: pandoc/core:latest # 自带Markdown转HTML工具 before_script: - apk add --no-cache curl jq # 安装HTTP请求和JSON处理工具 script: - | # 遍历仓库中所有Markdown文件(可自行调整路径) for md_file in ./docs/*.md; do # 提取Markdown标题(取第一个一级标题) POST_TITLE=$(head -n1 "$md_file" | sed 's/^# //') # 转换Markdown为HTML POST_CONTENT=$(pandoc -f markdown -t html "$md_file") # 生成文章slug(用文件名转小写、空格转连字符) POST_SLUG=$(basename "$md_file" .md | tr '[:upper:]' '[:lower:]' | tr ' ' '-') # 检查WP中是否已存在该文章 EXISTING_POST_ID=$(curl -s -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \ "${WP_SITE_URL}/wp-json/wp/v2/posts?slug=${POST_SLUG}" | jq '.[0].id') if [ "$EXISTING_POST_ID" != "null" ]; then # 更新已有文章 curl -X PUT -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \ "${WP_SITE_URL}/wp-json/wp/v2/posts/${EXISTING_POST_ID}" \ -H "Content-Type: application/json" \ -d '{ "title": "'"${POST_TITLE}"'", "content": "'"${POST_CONTENT}"'", "status": "publish" }' else # 创建新文章 curl -X POST -u "${WP_USERNAME}:${WP_APP_PASSWORD}" \ "${WP_SITE_URL}/wp-json/wp/v2/posts" \ -H "Content-Type: application/json" \ -d '{ "title": "'"${POST_TITLE}"'", "content": "'"${POST_CONTENT}"'", "slug": "'"${POST_SLUG}"'", "status": "publish" }' fi done only: - main # 指定触发同步的分支 variables: WP_SITE_URL: "https://your-wp-site.com" # 替换为你的WP站点地址 # 以下变量建议在Gitlab仓库CI/CD设置中添加(避免硬编码) # WP_USERNAME: "你的WP用户名" # WP_APP_PASSWORD: "生成的应用密码"- 登录Gitlab仓库,进入「设置」→「CI/CD」→「变量」,添加
WP_USERNAME和WP_APP_PASSWORD两个保密变量。
- 登录Gitlab仓库,进入「设置」→「CI/CD」→「变量」,添加
方案2:Gitlab服务器定时任务 + WP-CLI
利用你已在Gitlab服务器安装的WP-CLI,结合定时任务定期拉取仓库更新并同步到WP。
操作步骤
Gitlab服务器拉取文档仓库
- 在Gitlab服务器上生成SSH密钥,添加到Gitlab仓库的「部署密钥」中(赋予读取权限)。
- 克隆私有文档仓库到本地目录:
git clone git@your-gitlab-server:group/repo.git /path/to/docs-repo
编写同步脚本
创建wp-sync.sh脚本(需安装pandoc用于Markdown转HTML):#!/bin/bash REPO_DIR="/path/to/docs-repo" WP_SITE="https://your-wp-site.com" WP_USER="你的WP用户名" WP_PASS="你的WP应用密码" # 拉取仓库最新内容 cd $REPO_DIR git pull origin main # 遍历Markdown文件同步 for md_file in ./docs/*.md; do POST_TITLE=$(head -n1 "$md_file" | sed 's/^# //') POST_CONTENT=$(pandoc -f markdown -t html "$md_file") POST_SLUG=$(basename "$md_file" .md | tr '[:upper:]' '[:lower:]' | tr ' ' '-') # 检查文章是否存在 EXISTING_ID=$(wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post list --slug=$POST_SLUG --field=ID) if [ -n "$EXISTING_ID" ]; then wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post update $EXISTING_ID \ --post_title="$POST_TITLE" --post_content="$POST_CONTENT" --post_status=publish else wp --url=$WP_SITE --user=$WP_USER --password=$WP_PASS post create \ --post_title="$POST_TITLE" --post_content="$POST_CONTENT" --post_name="$POST_SLUG" --post_status=publish fi done- 给脚本添加执行权限:
chmod +x wp-sync.sh
- 给脚本添加执行权限:
设置定时任务
编辑crontab:crontab -e,添加定时规则(比如每天凌晨1点同步):0 1 * * * /path/to/wp-sync.sh >> /var/log/wp-sync.log 2>&1
方案3:Gitlab Webhook + WP自定义端点
通过Gitlab Webhook触发WP侧的同步逻辑,适合需要实时同步的场景,仅需在WP侧添加少量代码和轻量依赖。
操作步骤
Gitlab配置Webhook
- 进入仓库「设置」→「Webhooks」,添加WP端点URL:
https://your-wp-site.com/wp-json/sync/v1/gitlab - 设置触发事件为「Push events」,添加一个自定义密钥(比如
GITLAB_WEBHOOK_SECRET),保存。
- 进入仓库「设置」→「Webhooks」,添加WP端点URL:
WP侧添加同步逻辑
- 在当前主题的
functions.php中添加以下代码(需上传Parsedown.php轻量Markdown解析器到主题目录):
// 注册REST API端点 add_action('rest_api_init', function () { register_rest_route('sync/v1', '/gitlab', [ 'methods' => 'POST', 'callback' => 'sync_gitlab_docs', 'permission_callback' => function () { // 验证Webhook签名 $secret = 'GITLAB_WEBHOOK_SECRET'; $request_signature = $_SERVER['HTTP_X_GITLAB_TOKEN'] ?? ''; if (!hash_equals($secret, $request_signature)) { return new WP_Error('invalid_signature', '无效签名', ['status' => 403]); } return true; } ]); }); function sync_gitlab_docs($request) { $payload = $request->get_json_params(); $gitlab_token = '你的Gitlab个人访问令牌'; // 需有仓库读取权限 $project_path = urlencode($payload['project']['path_with_namespace']); // 处理推送的Markdown文件 foreach ($payload['commits'] as $commit) { foreach (array_merge($commit['added'], $commit['modified']) as $file) { if (pathinfo($file, PATHINFO_EXTENSION) !== 'md') continue; // 通过Gitlab API获取文件内容 $file_api_url = "https://your-gitlab-server/api/v4/projects/{$project_path}/repository/files/" . urlencode($file) . "?ref=main&private_token={$gitlab_token}"; $api_response = wp_remote_get($file_api_url); if (is_wp_error($api_response)) continue; $file_data = json_decode(wp_remote_retrieve_body($api_response), true); $md_content = base64_decode($file_data['content']); // 转换Markdown为HTML require_once get_template_directory() . '/Parsedown.php'; $parsedown = new Parsedown(); $html_content = $parsedown->text($md_content); // 提取标题和生成slug $title = preg_match('/^# (.*)$/m', $md_content, $matches) ? $matches[1] : pathinfo($file, PATHINFO_FILENAME); $slug = sanitize_title($title); // 更新或创建文章 $existing_post = get_posts([ 'name' => $slug, 'post_type' => 'post', 'post_status' => 'publish', 'numberposts' => 1 ]); if ($existing_post) { wp_update_post([ 'ID' => $existing_post[0]->ID, 'post_title' => $title, 'post_content' => $html_content ]); } else { wp_insert_post([ 'post_title' => $title, 'post_content' => $html_content, 'post_name' => $slug, 'post_status' => 'publish' ]); } } } return ['status' => '同步完成']; }- 下载
Parsedown.php后上传到主题根目录。
- 在当前主题的
内容的提问来源于stack exchange,提问作者jrod091
相关产品推荐
相关产品推荐

