Programmieren mit einer API
Programmieren mit einer APIWP-CLI ergänzen

WP-CLI ergänzen

WP-CLI ist ein Kommandozeilen-Tool zur Interaktion mit WordPress, das dir hilft, Aufgaben zu automatisieren. Es ermöglicht dir, eine neue Website zu installieren, Beiträge zu erstellen oder zu aktualisieren, Plugins zu aktivieren, Optionen zu ändern und vieles mehr.

WP-CLI-Befehle können verschachtelt werden:

  1. Einen WP-CLI-Befehl ausführen, der die ID einer Ressource zurückgibt
  2. Diese ID in einen anderen WP-CLI-Befehl einspeisen, um eine Operation auf dieser Ressource auszuführen

Dieses Script findet zum Beispiel die ID des Beitrags mit einem bestimmten Slug und aktualisiert dessen Metadaten:

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

Dieses Script erstellt wiederholt ein Menüelement und setzt dessen ID als übergeordnetes Element eines neuen Menüelements, wodurch ihre Hierarchie definiert wird ("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 kann die WordPress-Funktionen für die Datensuche erweitern. Daher können wir Gato GraphQL auch nutzen, um die benötigten Daten zu finden und sie in WP-CLI einzuspeisen.

Die folgenden queries zeigen, wie das geht.

Eine GraphQL-Query vom Terminal aus ausführen

Verwenden wir eine GraphQL-Query, um Benutzer mit dem spanischen Locale zu finden, und führen wir dann einen WP-CLI-Befehl auf diesem Benutzer aus.

Zunächst begrenzen wir das Ergebnis auf nur einen Benutzer (über 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")
  }
}

Im Terminal können wir curl (oder ein ähnliches Tool) verwenden, um eine Query gegen den GraphQL-Server auszuführen, und dabei folgende Daten übergeben:

  • Die POST-Methode verwenden
  • Akzeptierter Content-Type ist application/json
  • Der Body ist ein Dictionary mit dem Eintrag "query" und der GraphQL-Query (und bei Bedarf auch den Einträgen "variables" und "operationName")
  • Die Query-Zeichenkette muss formatiert sein: Alle " müssen als \" escaped werden, und Zeilenumbrüche müssen durch \n ersetzt werden
  • Auf die Endpoint-URL von Gato GraphQL zeigen (entweder den einzelnen Endpoint oder einen benutzerdefinierten Endpoint)
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/

Die Antwort wird direkt im Terminal ausgegeben:

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

Die ID aus der GraphQL-Antwort extrahieren

Ähnlich wie bei --field=ID, --format=ids oder --porcelain in WP-CLI müssen wir einen Weg finden, das spezifische Datenstück, das wir benötigen, aus der GraphQL-Antwort zu extrahieren. In diesem Beispiel ist das die Benutzer-ID.

Wir weisen die GraphQL-Antwort einer Umgebungsvariablen zu (z. B. GRAPHQL_RESPONSE) und identifizieren die Benutzer-ID mit einem bestimmten Alias (z. B. 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/)

Mit echo $GRAPHQL_RESPONSE können wir die Antwort anzeigen:

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

Als nächstes führen wir grep mit einer Regex aus, die dem Pattern "spanishLocaleUserID":{ID} entspricht, und extrahieren die ID in die Umgebungsvariable 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)

Jetzt können wir den Wert dieser Variablen in WP-CLI einspeisen:

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

Die GraphQL-Query lesbarer machen

Bei der Formatierung der GraphQL-Query zur Eingabe in curl wurde sie schwer lesbar.

Eine Lösung besteht darin, die Transformationen mit bash-Befehlen wie tr und sed durchzuführen:

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/)

Syntax-Highlighting zur GraphQL-Query hinzufügen

Eine weitere Verbesserung gegenüber dem vorherigen Schritt besteht darin, die GraphQL-Query in einer separaten .gql-Datei abzulegen, die dann mit einem Editor (wie VSCode) bearbeitet werden kann und dessen Syntax-Highlighting nutzt:

# 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")
  }
}

Anschließend lesen wir den Inhalt dieser Datei mit 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/)