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に注入することも可能です。

以下のクエリでその方法をご紹介します。

ターミナルからGraphQLクエリを実行する

スペイン語ロケールを持つユーザーをGraphQLクエリで検索し、そのユーザーに対して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サーバーに対してクエリを実行できます。以下のデータを渡します。

  • POSTメソッドを使用する
  • 受け入れるコンテンツタイプはapplication/json
  • ボディは"query"エントリとGraphQLクエリを含むディクショナリ(必要に応じて"variables""operationName"も含む)
  • クエリ文字列はフォーマットが必要:すべての"\"としてエスケープし、改行は\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など)に割り当て、ユーザーIDを特定のエイリアス(spanishLocaleUserIDなど)で識別します。

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クエリを読みやすくする

GraphQLクエリをcurlに入力するためにフォーマットすると、読みにくくなってしまいます。

解決策として、trsedなどのbashコマンドを使って変換を適用する方法があります。

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クエリにシンタックスハイライトを追加する

前のステップからさらに発展させて、GraphQLクエリを別の.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/)