通过 API 编写代码
通过 API 编写代码补充 WP-CLI

补充 WP-CLI

WP-CLI 是一个用于与 WordPress 交互的命令行工具,可帮助我们自动化任务。它允许我们安装新站点、创建或更新文章、激活插件、修改选项以及执行更多操作。

WP-CLI 命令可以嵌套使用:

  1. 执行一个返回某资源 ID 的 WP-CLI 命令
  2. 将该 ID 注入另一个 WP-CLI 命令,以对该资源执行操作

例如,以下脚本查找具有某个别名的文章的 ID,并更新其元数据:

wp post meta set $(wp post list --name="hello-world" --format=ids) _wp_page_template about.php

以下脚本反复创建菜单项,并将其 ID 设置为另一个新菜单项的父级,从而定义它们的层级关系("Most ancestor menu item" > "Parent menu item" > "Child menu item"):

wp menu item add-custom bottom-menu "Child menu item" https://bbc.com --parent-id=$(wp menu item add-post bottom-menu 1 --title="Parent menu item" --parent-id=$(wp menu item add-post bottom-menu 1 --title="Most ancestor menu item" --porcelain) --porcelain)

Gato GraphQL 可以增强 WordPress 的数据搜索能力。因此,我们也可以使用 Gato GraphQL 查找所需数据,并将其注入到 WP-CLI 中。

以下 queries 将演示如何实现这一点。

从终端执行 GraphQL query

让我们使用一个 GraphQL query 查找具有西班牙语区域设置的用户,并对该用户执行 WP-CLI 命令。

首先,我们将结果限制为仅 1 个用户(通过 pagination: { limit: 1 }):

query {
  users(
    filter: {
      metaQuery: {
        key: "locale",
        compareBy: {
          stringValue: {
            value: "es_[A-Z]+"
            operator: REGEXP
          }
        }
      }
    },
    pagination: {
      limit: 1
    }
  ) {
    id
    name
    locale: metaValue(key: "locale")
  }
}

在终端中,我们可以使用 curl(或类似工具)对 GraphQL 服务器执行 query,并传递以下数据:

  • 使用 POST 方法
  • 接受的内容类型为 application/json
  • 请求体是一个包含 "query" 条目和 GraphQL query 的字典(如需要,还包含 "variables""operationName" 条目)
  • query 字符串必须格式化:所有 " 必须转义为 \",换行符必须替换为 \n
  • 指向 Gato GraphQL 的端点 URL(单一端点或某个自定义端点)
curl \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "query {\n  users(\n    filter: {\n      metaQuery: {\n        key: \"locale\",\n        compareBy: {\n          stringValue: {\n            value: \"es_[A-Z]+\"\n            operator: REGEXP\n          }\n        }\n      }\n    },\n    pagination: {\n      limit: 1\n    }\n  ) {\n    id\n    name\n    locale: metaValue(key: \"locale\")\n  }\n}"}' \
  https://mysite.com/graphql/

这会将响应直接打印到终端:

{"data":{"users":[{"id":3,"name":"Subscriber Bennett","locale":"es_AR"}]}}

从 GraphQL 响应中提取 ID

与在 WP-CLI 中使用 --field=ID--format=ids--porcelain 类似,我们需要找到一种方法从 GraphQL 响应中提取所需的特定数据。在本示例中,即用户 ID。

我们将 GraphQL 响应赋值给一个环境变量(如 GRAPHQL_RESPONSE),并用特定别名(如 spanishLocaleUserID)标识用户 ID:

GRAPHQL_RESPONSE=$(curl \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"query": "query {\n  users(\n    filter: {\n      metaQuery: {\n        key: \"locale\",\n        compareBy: {\n          stringValue: {\n            value: \"es_[A-Z]+\"\n            operator: REGEXP\n          }\n        }\n      }\n    },\n    pagination: {\n      limit: 1\n    }\n  ) {\n    spanishLocaleUserID: id\n    name\n    locale: metaValue(key: \"locale\")\n  }\n}"}' \
  https://mysite.com/graphql/)

执行 echo $GRAPHQL_RESPONSE 可以查看响应:

{"data":{"users":[{"spanishLocaleUserID":3,"name":"Subscriber Bennett","locale":"es_AR"}]}}

接下来,我们使用匹配 "spanishLocaleUserID":{ID} 模式的正则表达式执行 grep,并将 ID 提取到环境变量 SPANISH_LOCALE_USER_ID 中:

SPANISH_LOCALE_USER_ID=$(echo $GRAPHQL_RESPONSE \
  | grep -E -o '"spanishLocaleUserID\":(\d+)' \
  | cut -d':' -f2- | cut -d'"' -f2- | rev | cut -d'"' -f2- | rev)

现在,我们可以将此变量的值注入到 WP-CLI 中:

wp user update "$(echo $SPANISH_LOCALE_USER_ID)" --locale=fr_FR

让 GraphQL query 更易读

将 GraphQL query 格式化后输入到 curl 中,会变得难以阅读。

解决方法是使用 bash 命令(如 trsed)来应用转换:

GRAPHQL_QUERY='
  query {
    users(
      filter: {
        metaQuery: {
          key: "locale",
          compareBy: {
            stringValue: {
              value: "es_[A-Z]+"
              operator: REGEXP
            }
          }
        }
      },
      pagination: {
        limit: 1
      }
    ) {
      spanishLocaleUserID: id
      name
      locale: metaValue(key: "locale")
    }
  }
'
GRAPHQL_BODY="{\"query\": \"$(echo $GRAPHQL_QUERY | tr '\n' ' ' | sed 's/"/\\"/g')\"}"
GRAPHQL_RESPONSE=$(curl \
  -X POST \
  -H "Content-Type: application/json" \
  -d $GRAPHQL_BODY \
  https://mysite.com/graphql/)

为 GraphQL query 添加语法高亮

在前一步骤的基础上进一步改进,可以将 GraphQL query 放置在独立的 .gql 文件中,然后使用编辑器(如 VSCode)进行编辑并使用其语法高亮功能:

# This query is stored in file "find-user-with-spanish-locale.gql"
query {
  users(
    filter: {
      metaQuery: {
        key: "locale",
        compareBy: {
          stringValue: {
            value: "es_[A-Z]+"
            operator: REGEXP
          }
        }
      }
    },
    pagination: {
      limit: 1
    }
  ) {
    spanishLocaleUserID: id
    name
    locale: metaValue(key: "locale")
  }
}

然后,我们使用 cat 读取该文件的内容:

GRAPHQL_QUERY=$(cat find-user-with-spanish-locale.gql)
GRAPHQL_BODY="{\"query\": \"$(echo $GRAPHQL_QUERY | tr '\n' ' ' | sed 's/"/\\"/g')\"}"
GRAPHQL_RESPONSE=$(curl \
  -X POST \
  -H "Content-Type: application/json" \
  -d $GRAPHQL_BODY \
  https://mysite.com/graphql/)