Coderen met een API
Coderen met een APIIntegratie met WP-CLI

Integratie met WP-CLI

WP-CLI is een opdrachtregelprogramma om met WordPress te communiceren, dat helpt bij het automatiseren van taken. Het stelt je in staat om een nieuwe site te installeren, posts aan te maken of bij te werken, plugins te activeren, opties te wijzigen, en nog veel meer.

WP-CLI-opdrachten kunnen worden genest:

  1. Voer een WP-CLI-opdracht uit die het ID van een resource retourneert
  2. Injecteer dat ID in een andere WP-CLI-opdracht om een bewerking op die resource uit te voeren

Dit script vindt bijvoorbeeld het ID van een post met een bepaalde slug en werkt de bijbehorende meta bij:

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

Dit script maakt herhaaldelijk een menu-item aan en stelt het ID ervan in als bovenliggend item voor een nieuw menu-item, waarmee de hiƫrarchie wordt bepaald ("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 kan de WordPress-mogelijkheden voor het zoeken naar gegevens uitbreiden. Zo kunnen we Gato GraphQL ook gebruiken om de benodigde gegevens te vinden en deze in WP-CLI te injecteren.

De volgende queries laten zien hoe je dat doet.

Een GraphQL-query uitvoeren vanuit de terminal

Laten we een GraphQL-query gebruiken om gebruikers met de Spaanse locale te vinden en een WP-CLI-opdracht op die gebruiker uit te voeren.

We beperken het resultaat eerst tot slechts 1 gebruiker (via 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")
  }
}

In de terminal kunnen we curl (of een vergelijkbaar hulpmiddel) gebruiken om een query uit te voeren tegen de GraphQL-server, waarbij we de volgende gegevens meegeven:

  • Gebruik de POST-methode
  • Het geaccepteerde inhoudstype is application/json
  • De body is een woordenboek met de invoer "query" en de GraphQL-query (en indien nodig ook de invoeren "variables" en "operationName")
  • De queryreeks moet worden opgemaakt: alle " moeten worden geĆ«scaped als \", en regeleinden moeten worden vervangen door \n
  • Verwijs naar de endpoint-URL van Gato GraphQL (het enkelvoudige endpoint of een aangepast 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/

Dit geeft de respons direct weer in de terminal:

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

Het ID extraheren uit de GraphQL-respons

Net als bij --field=ID, --format=ids of --porcelain in WP-CLI moeten we een manier vinden om het specifieke stukje data dat we nodig hebben uit de GraphQL-respons te extraheren. In dit voorbeeld is dat het gebruikers-ID.

We kennen de GraphQL-respons toe aan een omgevingsvariabele (zoals GRAPHQL_RESPONSE) en identificeren het gebruikers-ID met een bepaalde alias (zoals 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/)

Door echo $GRAPHQL_RESPONSE uit te voeren, kunnen we de respons bekijken:

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

Vervolgens voeren we grep uit met een reguliere expressie die overeenkomt met het patroon "spanishLocaleUserID":{ID}, en extraheren we het ID in de omgevingsvariabele 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)

Nu kunnen we de waarde van deze variabele injecteren in WP-CLI:

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

De GraphQL-query leesbaarder maken

Bij het opmaken van de GraphQL-query om deze in curl in te voeren, werd het moeilijk leesbaar.

Een oplossing is om de transformaties toe te passen met bash-opdrachten, zoals tr en sed:

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

Syntaxismarkering toevoegen aan de GraphQL-query

Een verdere stap ten opzichte van het vorige stadium is om de GraphQL-query in een apart .gql-bestand te plaatsen, dat vervolgens met een editor (zoals VSCode) kan worden bewerkt met syntaxismarkering:

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

Vervolgens lezen we de inhoud van dit bestand in met 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/)