Plugins spielen eine wichtige Rolle bei der Anpassung und Verbesserung deiner WordPress-Websites. Sie werden verwendet, um Funktionen wie Kontaktformulare, E-Commerce und Analysen zu deinen Seiten hinzuzufügen, ohne dass du programmieren musst.

Wie WordPress, das regelmäßig aktualisiert wird, erhalten auch Plugins regelmäßig Updates, um neue Funktionen hinzuzufügen, Sicherheitslücken zu schließen, die Kompatibilität zu verbessern und vieles mehr. Deshalb hat Kinsta die Plugin- und Theme-Verwaltung zu den Tools hinzugefügt, die in MyKinsta für jede deiner Websites verfügbar sind.

Für vielbeschäftigte Kunden wie Agenturen kann die Aktualisierung von Plugins für viele Websites jedoch eine große Herausforderung sein. In diesem Artikel wird eine Lösung vorgestellt, die die Kinsta-API nutzt, um Plugins für mehrere Websites gleichzeitig zu verwalten.

Was du bauen wirst

In diesem Leitfaden geht es um den Aufbau einer fortgeschrittenen Lösung mit der Kinsta-API, die jetzt Endpunkte zum Abrufen und Aktualisieren von Plugins bietet.

Darin erstellen wir eine benutzerdefinierte React-Anwendung, die alle Plugins von deinem Kinsta-Unternehmenskonto abruft. Mit diesem Tool kannst du ein bestimmtes Plugin auf mehreren Websites identifizieren und aktualisieren, was den Prozess erheblich vereinfacht.

Mit React und der Kinsta-API erstelltes Tool zur Massenaktualisierung von WordPress-Plugins auf mehreren Websites
Mit React und der Kinsta-API erstelltes Tool zur Massenaktualisierung von WordPress-Plugins auf mehreren Websites

Anwendungsvoraussetzungen

Um an diesem Projekt mitzuarbeiten, solltest du Folgendes mitbringen:

Die Kinsta-API verstehen

Die Kinsta-API ist ein leistungsstarkes Werkzeug, mit dem du programmatisch mit Kinsta-Diensten wie gehosteten WordPress-Seiten interagieren kannst. Sie kann dir helfen, verschiedene Aufgaben im Zusammenhang mit der WordPress-Verwaltung zu automatisieren, z. B. das Erstellen von Websites, das Abrufen von Website-Informationen, das Abrufen des Status einer Website, das Durchsuchen und Wiederherstellen von Backups und vieles mehr.

Um die Kinsta-API zu nutzen, musst du ein Konto mit mindestens einer WordPress-Site, -Anwendung oder -Datenbank in MyKinsta haben. Außerdem musst du einen API-Schlüssel erstellen, um dich zu authentifizieren und auf dein Konto zuzugreifen.

So generierst du einen API-Schlüssel:

  1. Gehe zu deinem MyKinsta-Dashboard.
  2. Navigiere zur Seite mit den API-Schlüsseln (Dein Name > Unternehmenseinstellungen > API-Schlüssel).
  3. Klicke auf API-Schlüssel erstellen.
  4. Wähle ein Ablaufdatum oder lege ein benutzerdefiniertes Startdatum und die Anzahl der Stunden fest, nach denen der Schlüssel abläuft.
  5. Gib dem Schlüssel einen eindeutigen Namen.
  6. Klicke auf Erzeugen.

Nachdem du einen API-Schlüssel erstellt hast, kopiere ihn und bewahre ihn an einem sicheren Ort auf (es wird empfohlen, einen Passwortmanager zu verwenden). Du kannst mehrere API-Schlüssel erstellen, die dann auf der Seite API-Schlüssel aufgelistet werden. Wenn du einen API-Schlüssel widerrufen musst, klicke auf die Schaltfläche Widerrufen.

Richte deine React-Entwicklungsumgebung ein

React ist eine beliebte JavaScript-Bibliothek zum Erstellen von Benutzeroberflächen. Sie ermöglicht es Entwicklern, deklarative Komponenten zu erstellen, die verschiedene Teile der Benutzeroberfläche darstellen. Diese Komponenten werden mit der JSX-Syntax definiert, einer Kombination aus JavaScript und HTML.

Um loszulegen, befolge diese Schritte:

  1. Navigiere in den Ordner, in dem du dein Projekt erstellen möchtest, und benutze create-react-app, um ein React-Projekt zu erstellen:
    npx create-react-app <project-name>

    Ändere <project-name> oben in den gewünschten Namen für dein Projekt.

  2. Sobald dies erfolgreich war, navigiere in den Projektordner und starte den Entwicklungsserver:
    cd <project-name>
    npm run start

    Deine React-Anwendung öffnet sich in deinem Standard-Webbrowser auf http://localhost:3000.

Wenn du ein React-Projekt mit create-react-app erstellst, wird eine Ordnerstruktur angelegt. Der wichtigste Ordner ist src, in dem die Entwicklung stattfindet. Die wichtigsten Dateien in diesem Ordner sind:

  • App.js: Dies ist die Hauptkomponente, die alle anderen in deiner React-Anwendung gerendert wird. Hier wird dein gesamter Code für dieses Tool eingefügt.
  • index.js: Sie ist der Einstiegspunkt, wird zuerst geladen und ist für das Rendern von App.js verantwortlich.
  • index.css: Diese Datei definiert das allgemeine Styling und Layout deiner Anwendung. Alle Stile werden hier eingefügt.

Benutzeroberfläche erstellen und gestalten

Konzentrieren wir uns auf das Erstellen und Gestalten der Benutzeroberfläche für eine einfache Anwendung, die in der Datei App.js untergebracht ist, ohne das Routing zu berücksichtigen. Unsere Hauptbenutzeroberfläche ist ein Formular mit einem select Feld, in dem du die einzelnen Plugins deiner Kinsta-Websites auflisten kannst, und einer submit Schaltfläche, mit der du die Websites mit dem ausgewählten Plugin abrufen kannst.

Benutzeroberfläche für das Plugin-Manager-Tool, um auf eine Liste von Plugins zuzugreifen und Websites zu laden
Benutzeroberfläche für das Plugin-Manager-Tool, um auf eine Liste von Plugins zuzugreifen und Websites zu laden

Außerdem werden in einem Anzeigebereich Website-Details wie Name, Plugin-Status und Version angezeigt. Es gibt eine Schaltfläche, mit der du jede einzelne Seite aktualisieren kannst, und eine allgemeine Schaltfläche, mit der du alle Seiten, die ein Plugin-Update benötigen, auf einmal aktualisieren kannst.

Füge in deiner App.js-Datei den folgenden Code ein:

import KinstaLogo from './images/kinsta_logo.png';

const App = () => {
    return (
        <div className="container">
            <div className="title-section">
                <img src={KinstaLogo} className="logo" alt="" />
                <h2>Manage your site's plugins</h2>
                <p>
                    Easily update plugins across all sites hosted with Kinsta using the
                    Kinsta API.
                </p>
            </div>
            <div> className="info-section">
                <p>
                    This application allows you to retrieve a list of all sites within
                    your company that uses a specific plugin. You can then choose to update
                    the plugin across all these sites simultaneously or individually.
                </p>
            </div>
            <div className="form-section">
                <form>
                    <div className="form-control">
                        <label> htmlFor="plugin-name">Plugin name</label>
                        <select name="plugin-name" id="plugin-name">
                            <option> value="">Select a plugin</option>
                        </select>
                    </div>
                    <button> className="btn">Fetch sites with this plugin</button>
                </form>
            </div>
            <div className="display_container">
                <div className="site-list">
                    <div className="list-title">
                        <h3>Sites with WooCommerce plugin</h3>

                        <button> className="sm-btn">Update all sites to v.3.6</button>
                    </div>
                    <ul>
                        <li>
                            <div className="info">
                                <p>
                                    <b>Site Name:</b> WooCommerce
                                </p>
                                <p>
                                    <b>Plugin Status:</b> active
                                </p>
                                <p>
                                    <b>Plugin Version:</b> 3.5.1
                                </p>
                            </div>
                            <button> className="sm-btn">Update to v.5.6</button>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    );
};

export default App;

Um dieses Projekt zu gestalten, besuche die CSS-Datei in unserem vollständigen GitHub-Repository und kopiere den Code in deine index.css-Datei.

Mit der Kinsta-API interagieren

Die Kinsta-API bietet eine Reihe von Endpunkten, über die du auf verschiedene Parameter zugreifen kannst, die für die Interaktion mit dem Plugin einer Website notwendig sind. Wenn du zum Beispiel ein Plugin abrufen oder aktualisieren möchtest, musst du zunächst die Umgebungs-ID der Website ermitteln.

Die Ermittlung dieser Umgebungs-ID ist ein sequentieller Prozess. Zunächst musst du die ID der Website ermitteln. Um die Site-ID zu erhalten, brauchst du deine Kinsta-Unternehmens-ID. Diese Unternehmens-ID findest du in deinem MyKinsta-Dashboard (Unternehmenseinstellungen > Abrechnungsdetails). Es handelt sich dabei um sensible Informationen, die du wie deinen API-Schlüssel mit niemandem teilen möchtest.

Du kannst sie sicher als Umgebungsvariable in deiner React-Anwendung speichern, indem du eine .env-Datei im Stammverzeichnis deines Projekts erstellst. In dieser Datei fügst du Folgendes mit dem richtigen Wert ein:

REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' 
REACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'

Um innerhalb deines Projekts auf diese Umgebungsvariablen zuzugreifen, kannst du die Syntax process.env.THE_VARIABLE verwenden. Um zum Beispiel auf die REACT_APP_KINSTA_COMPANY_ID zuzugreifen, würdest du process.env.REACT_APP_KINSTA_COMPANY_ID verwenden.

Wenn du die .env-Datei zu deiner .gitignore datei hinzuzufügen, ist wichtig, um zu verhindern, dass sie auf GitHub veröffentlicht wird. So wird sichergestellt, dass deine sensiblen Informationen privat und sicher bleiben.

Abruf aller Websites und Plugins über die Kinsta-API

Um die Plugin-Daten für alle Websites abzurufen, die von deinem Kinsta-Unternehmenskonto verwaltet werden, kannst du die Kinsta-API nutzen, indem du drei API-Anfragen stellst. Hier ist eine kurze Erklärung:

Speichere zunächst die Kinsta-API-URL in einer Variablen, damit du sie leicht wiederfinden kannst.

const KinstaAPIUrl = 'https://api.kinsta.com/v2';
  1. Liste der Unternehmensseiten abrufen: Du musst eine Liste aller WordPress-Seiten abrufen, die mit deinem Unternehmen verbunden sind. Dazu erstellst du eine Abfrage mit der ID des Unternehmens, stellst eine GET-Anfrage mit der entsprechenden Berechtigung, verarbeitest die Antwort im JSON-Format und extrahierst die Website-Details aus der Antwort.
    const query = new URLSearchParams({
        company: process.env.REACT_APP_KINSTA_COMPANY_ID,
    }).toString();
    const response = await fetch(`${KinstaAPIUrl}/sites?${query}`, {
        method: 'GET',
        headers: { Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}` },
    });
    
    const data = await response.json();
    const companySites = data.company.sites;
  2. Abfrage der Site Environment ID: Der vorherige Schritt liefert ein Array mit WordPress-Websites. Führe für jede Website eine Schleife durch und stelle eine weitere GET-Anfrage, um die zugehörigen Umgebungen abzurufen.
    const sitesEnvironmentData = companySites.map(async (site) => {
        const siteId = site.id;
        const resp = await fetch(`${KinstaAPIUrl}/sites/${siteId}/environments`, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
            },
        });
        const data = await resp.json();
        const environments = data.site.environments;
        return {
            id: siteId,
            name: site.display_name,
            environments: environments,
        };
    });
  3. Liste der WordPress-Website-Plugins abrufen: Nachdem du die Site-ID, den Namen und die Umgebung erhalten hast, kannst du jetzt die Umgebungs-ID verwenden, um eine Liste aller Plugins auf jeder Website abzurufen. Zuerst musst du die Versprechen aus dem vorherigen Schritt auflösen und dann die GET-Anfragen für die Plugins stellen:
    // Wait for all the promises to resolve
    const sitesData = await Promise.all(sitesEnvironmentData);
    
    // Get all plugins for each environment
    const sitesWithPlugin = sitesData.map(async (site) => {
        const environmentId = site.environments[0].id;
        const resp = await fetch(
            `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
            {
                method: 'GET',
                headers: {
                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                },
            }
        );
        const data = await resp.json();
        const plugins = data.environment.container_info;
        return {
            env_id: environmentId,
            name: site.name,
            plugins: plugins,
        };
    });
    
    const sitesWithPluginData = await Promise.all(sitesWithPlugin);
    return sitesWithPluginData;
  4. Konsolidierung des Prozesses: Um den Prozess zu straffen, kannst du diese API-Anfragen in einer einzigen asynchronen Funktion getSitesWithPluginData kapseln, die wiederverwendet werden kann. Diese Funktion führt die oben beschriebenen Schritte aus und gibt ein Array mit den wichtigsten Informationen zu jeder Website zurück, darunter die Umgebungs-ID, den Website-Namen und ein Array mit den Plugins.
    const getSitesWithPluginData = async () => {
        const query = new URLSearchParams({
            company: process.env.REACT_APP_KINSTA_COMPANY_ID,
        }).toString();
        const resp = await fetch(`${KinstaAPIUrl}/sites?${query}`, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
            },
        });
    
        const data = await resp.json();
        const companySites = data.company.sites;
    
        // Get all environments for each site
        const sitesEnvironmentData = companySites.map(async (site) => {
            const siteId = site.id;
            const resp = await fetch(`${KinstaAPIUrl}/sites/${siteId}/environments`, {
                method: 'GET',
                headers: {
                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                },
            });
            const data = await resp.json();
            const environments = data.site.environments;
            return {
                id: siteId,
                name: site.display_name,
                environments: environments,
            };
        });
    
        // Wait for all the promises to resolve
        const sitesData = await Promise.all(sitesEnvironmentData);
    
        // Get all plugins for each environment
        const sitesWithPlugin = sitesData.map(async (site) => {
            const environmentId = site.environments[0].id;
            const resp = await fetch(
                `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
                {
                    method: 'GET',
                    headers: {
                        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                    },
                }
            );
            const data = await resp.json();
            const plugins = data.environment.container_info;
            return {
                env_id: environmentId,
                name: site.name,
                plugins: plugins,
            };
        });
    
        // Wait for all the promises to resolve
        const sitesWithPluginData = await Promise.all(sitesWithPlugin);
        return sitesWithPluginData;
    };

Eindeutige Plugins von allen Websites abrufen

In deiner Anwendung möchtest du die Liste der Plugins für alle Websites in einem select Dropdown-Menü anzeigen. Um dies zu erreichen, ruft die Funktion getSitesWithPluginData die Umgebungs-ID, den Namen und die Plugins jeder Website ab. Diese Daten bilden die Grundlage für die Extraktion einer Liste von Plugins.

Definiere eine neue Funktion, fetchAllSitesPlugins, die getSitesWithPluginData aufruft und deren Ausgabe verarbeitet, um eine Liste aller Plugins zu erhalten:

const fetchAllSitesPlugins = async () => {
    const sitesWithPluginData = await getSitesWithPluginData();

    // get all plugins
    const allPlugins = sitesWithPluginData.map((site) => {
        const { plugins } = site;
        return plugins.wp_plugins.data;
    });

   // …
};

Dieser Code durchläuft die Daten jeder Website und stellt eine Liste der Plugins zusammen. Um sicherzustellen, dass jedes Plugin nur einmal aufgelistet wird, verwendest du das JavaScript Set Objekt, das eindeutige Werte speichert:

// get unique plugins
    const uniquePlugins = [
        ...new Set(allPlugins.flat().map((plugin) => plugin.name)),
    ];

Die Methode .flat() glättet die Array-Struktur und .map() führt eine Schleife durch, um nur die Plugin-Namen zu extrahieren. Das Set Objekt filtert Duplikate heraus.

Um diese Daten zu laden und in deiner React-Anwendung anzuzeigen, verwendest du die Hooks useState() und useEffect():

import { useState, useEffect } from 'react';

const App = () => {
    const [pluginName, setPluginName] = useState('');
    const [plugins, setPlugins] = useState([]);

    //Get sites with plugin data
    const getSitesWithPluginData = async () => {
        // perform requests
    };

    useEffect(() => {
        const fetchAllSitesPlugins = async () => {
            const sitesWithPluginData = await getSitesWithPluginData();
            // get all plugins
            const allPlugins = sitesWithPluginData.map((site) => {
                const { plugins } = site;
                return plugins.wp_plugins.data;
            });
            // get unique plugins
            const uniquePlugins = [
                ...new Set(allPlugins.flat().map((plugin) => plugin.name)),
            ];
            setPlugins(uniquePlugins);
        };

        fetchAllSitesPlugins();
    }, []);

     // JSX render code follows
    //...
};

Der useEffect() Hook sorgt dafür, dass die Daten beim Einhängen der Komponente geholt und gesetzt werden. Der useState() Hook verwaltet die Liste der einzelnen Plugins.

Schließlich werden diese Plugins in einem select Feld angezeigt. Wenn die Plugins noch geladen werden, zeige eine Platzhaltermeldung an:

<select>
    name="plugin-name"
    id="plugin-name"
    value={pluginName}
    onChange={(e) => setPluginName(e.target.value)}
>
    {plugins.length > 0 ? (
        <>
            <option value="">Select a plugin</option>
            {plugins.map((plugin) => (
                <option key={plugin} value={plugin.toLowerCase()}>
                    {plugin}
                </option>
            ))}
        </>
    ) : (
        <option> value="">Loading plugins...</option>
    )}
</select>

In diesem Code:

  • Das Element select ist mit einer Statusvariablen pluginName verknüpft, um den ausgewählten Wert zu speichern.
  • Der onChange Handler aktualisiert diesen Status, wenn ein neues Plugin ausgewählt wird.
  • Die Funktion plugins.map() erstellt dynamisch Optionselemente für jedes Plugin.

Wenn du diese Schritte befolgst, zeigt deine Anwendung eine eindeutige Liste von Plugins an, die von allen Websites abgerufen wurden, und bietet eine übersichtliche und benutzerfreundliche Oberfläche für die Auswahl.

Wähle ein Feld aus, das die Liste der Plugins von allen Websites im Kinsta-Unternehmenskonto anzeigt
Wähle ein Feld aus, das die Liste der Plugins von allen Websites im Kinsta-Unternehmenskonto anzeigt

Websites mit einem bestimmten Plugin abrufen

Bisher konntest du Plugins von deinem Kinsta-Firmenkonto abrufen, aber du möchtest eine Schleife durch alle Websites ziehen, um Websites mit einem bestimmten Plugin abzurufen, sie in einem Status zu speichern und sie dann anzuzeigen.

Dazu erstellst du zwei Zustände: einen, um die Websites zu speichern (sites) und einen, um den Ladestatus anzuzeigen (isLoading).

const [sites, setSites] = useState([]);
const [isLoading, setIsLoading] = useState(false);

Als Nächstes erstellst du eine fetchSites Funktion, die jede Seite daraufhin überprüft, ob sie das ausgewählte Plugin enthält. Ist dies der Fall, werden die relevanten Details der Seite gespeichert

Diese Funktion beginnt damit, dass sie isLoading auf true setzt und das Array sites löscht. Dann ruft sie getSitesWithPluginData auf, um alle Website-Daten abzurufen.

const fetchSites = async () => {
    setIsLoading(true);
    setSites([]);
    const sitesWithPluginData = await getSitesWithPluginData();

    // Filter out sites that don't have the plugin
    const sitesWithPluginDataFiltered = sitesWithPluginData
        .filter((site) => {
            const sitePlugins = site.plugins.wp_plugins.data;
            return sitePlugins.some((plugin) => {
                return plugin.name === pluginName;
            });
        })
        .map((site) => {
            const { env_id, name } = site;
            const { version, status, update, update_version } =
                site.plugins.wp_plugins.data.find(
                    (plugin) => plugin.name === pluginName
                );
            return {
                env_id,
                name,
                version,
                status,
                updateAvailable: update,
                updateVersion: update_version,
            };
        });
    setSites(sitesWithPluginDataFiltered);
    setIsLoading(false);
};

In der Funktion sitesWithPluginDataFiltered:

  • Die Methode .filter() isoliert die Websites, die das ausgewählte Plugin enthalten.
  • Die Methode .map() extrahiert dann die erforderlichen Details von jeder Website.
  • Schließlich aktualisieren die Hooks setSites und setIsLoading den Status mit den neuen Daten und dem Ladestatus.

Als Nächstes erstellst du eine Funktion handleSubmit und fügst sie der Schaltfläche Websites mit diesem Plugin abrufen auf dem Formular hinzu, um die Funktion aufzurufen, wenn ein Nutzer ein Plugin auswählt und das Formular abschickt. Diese Funktion verhindert die Standardaktion des Formulars und ruft fetchSites auf:

const handleSubmit = (e) => {
    e.preventDefault();
    fetchSites();
};

Wenn ein Nutzer ein bestimmtes Plugin auswählt und auf die Schaltfläche „Absenden“ klickt, werden alle Websites mit diesem Plugin abgerufen und im Status sites gespeichert.

Websites mit dem ausgewählten Plugin anzeigen

Nachdem du die relevanten Websites in deinem sites Status gespeichert hast, musst du diese Daten in der Benutzeroberfläche deines Projekts anzeigen. Das Ziel ist es, jede Website als Listenelement mit den wichtigsten Details und einer Schaltfläche für die Aktualisierung des Plugins anzuzeigen.

<ul>
    {sites.map((site) => (
        <li key={site.env_id}>
            <div className="info">
                <p>
                    <b>Site Name:</b> {site.name}
                </p>
                <p>
                    <b>Plugin Status:</b> {site.status}
                </p>
                <p>
                    <b>Plugin Version:</b> {site.version}
                </p>
            </div>
            <button>
                className={`sm-btn ${
                    site.updateAvailable !== 'available' ? 'disabled-btn' : ''
                }`}
                disabled={site.updateAvailable !== 'available'}
            >
                {site.updateAvailable === 'available'
                    ? `Update to v.${site.updateVersion}`
                    : 'Up to date'}
            </button>
        </li>
    ))}
</ul>

Im obigen Code wird das Array sites mit der Methode .map() durchlaufen und eine Liste (<ul>) von Websites (<li> Elemente) erstellt. Jedes Listenelement enthält Details über die Seite und eine Schaltfläche für Plugin-Aktualisierungen.

Die Schaltfläche in der Benutzeroberfläche ändert ihren Stil und ihre Funktion je nach Aktualisierungsstatus des Plugins: Sie ist aktiv, wenn Updates verfügbar sind, andernfalls ist sie deaktiviert und mit „Aktuell“ beschriftet, was durch bedingtes CSS und das Attribut disabled gesteuert wird.

Um das Nutzererlebnis zu verbessern, fügen wir außerdem einen Ladetext hinzu, der sich nach dem Zustand von isLoading richtet, wenn die Seiten abgerufen werden.

{isLoading && (
    <div className="loading">
        <p>Loading...</p>
    </div>
)}
Eine Liste der Websites, die ein bestimmtes Plugin aus dem Kinsta-Unternehmenskonto verwenden, mit Schaltflächen, um sie einzeln oder auf einmal zu aktualisieren
Eine Liste der Websites, die ein bestimmtes Plugin aus dem Kinsta-Unternehmenskonto verwenden, mit Schaltflächen, um sie einzeln oder auf einmal zu aktualisieren

Plugins mit der Kinsta-API aktualisieren

Bis jetzt konnten wir Websites mit wichtigen Details abrufen und auf ihre Plugins zugreifen. Das Ziel dieses Tools ist es, die Aktualisierung von Plugins für mehrere Websites über die Kinsta-API zu erleichtern. Der Prozess umfasst das Auslösen von Aktualisierungen und das Verfolgen ihres Fortschritts.

Plugin-Updates auslösen

Für jede aufgelistete Website gibt es eine Schaltfläche. Sie ist so gestaltet, dass sie anzeigt, ob ein Update verfügbar ist. Wenn ein Update verfügbar ist, löst ein Klick auf die Schaltfläche die Funktion updatePlugin aus.

<button>
    className={`sm-btn ${
        site.updateAvailable !== 'available' ? 'disabled-btn' : ''
    }`}
    disabled={site.updateAvailable !== 'available'}
    onClick={() =>
        updatePlugin(site.env_id, site.updateVersion)
    }
>
    {site.updateAvailable === 'available'
        ? `Update to v.${site.updateVersion}`
        : 'Up to date'}
</button>

Der onClick Handler ruft updatePlugin mit der Umgebungs-ID der Website und der neuesten Version des Plugins (updateVersion) auf. Diese Funktion sendet eine PUT-Anfrage an die Kinsta-API, um das Plugin zu aktualisieren.

const updatePlugin = async (envId, pluginVersion) => {
    const resp = await fetch(`${KinstaAPIUrl}/sites/environments/${envId}/plugins`, {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
        },
        body: JSON.stringify({
            name: pluginName,
            update_version: pluginVersion,
        }),
    });

    const data = await resp.json();
    // Further processing
};

Aktualisierungsfortschritt verfolgen

Nachdem du die Aktualisierung eingeleitet hast, musst du den Fortschritt der Aktualisierung überwachen. Die Kinsta-API liefert eine Antwort wie diese, wenn eine Aktualisierung eingeleitet wird:

{
  "operation_id": "wp-plugin:update-54fb80af-576c-4fdc-ba4f-b596c83f15a1",
  "message": "Updating WordPress plugin in progress",
  "status": 202
}

Die operation_id verfolgt den Aktualisierungsstatus über den Operations-Endpunkt. Erstelle eine Funktion, die diese API-Anfrage stellt und die operation_id als Argument erwartet:

// Check plugin update status
const checkPluginUpdateStatus = async (operationId) => {
    const resp = await fetch(`${KinstaAPIUrl}/operations/${operationId}`, {
        method: 'GET',
        headers: {
            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
        },
    });
    const data = await resp.json();
    return data.status;
};

Innerhalb von updatePlugin überprüfst du mit der Anweisung if, ob die anfänglichen Aktualisierungsanfragen status 202 sind. Wenn ja, wird ein Intervall festgelegt, um checkPluginUpdateStatus alle fünf Sekunden (5000 Millisekunden) aufzurufen.

Das Intervall prüft wiederholt den Aktualisierungsstatus, und wenn er erfolgreich ist, löscht er das Intervall und ruft fetchSites auf, um die Liste der Websites zu aktualisieren. Tritt bei diesen Überprüfungen ein Fehler auf, wird er auf der Konsole protokolliert.

if (data.status === 202) {
    const interval = setInterval(() => {
        checkPluginUpdateStatus(data.operation_id)
            .then((status) => {
                console.log(status);
                if (status === 200) {
                    clearInterval(interval);
                    fetchSites();
                }
            })
            .catch((error) => {
                // Handle any errors that occur during the promise resolution
                console.error('Error:', error);
            });
    }, 5000);
}

Benutzerfeedback während des Betriebs

An diesem Punkt funktioniert alles gut, aber es ist gut, den Nutzer über den Fortschritt der Operation zu informieren, anstatt ihn im Ungewissen zu lassen. Das kannst du tun, indem du eine Benachrichtigung anzeigst, die erscheint, wenn der Vorgang läuft, und die gelöscht wird, wenn der Vorgang abgeschlossen ist. Erstelle einen showStatusBar Status, um dies zu steuern:

const [showStatusBar, setShowStatusBar] = useState(false);

Wenn showStatusBar true ist, erscheint oben auf dem Bildschirm eine Statusleiste, die anzeigt, dass eine Aktualisierung im Gange ist. Sie ist so gestaltet, dass sie am oberen Rand des Bildschirms fixiert ist.

{showStatusBar && (
    <div className="status-bar">
        <p>Updating WordPress plugin in progress...</p>
    </div>
)}

Du kannst nun die Anweisung if in der Funktion updatePlugin anpassen, um showStatusBar je nach Aktualisierungsstatus auf true oder false zu setzen:

if (data.status === 202) {
    setShowStatusBar(true);
    const interval = setInterval(() => {
        checkPluginUpdateStatus(data.operation_id)
            .then((status) => {
                console.log(status);
                if (status === 200) {
                    setShowStatusBar(false);
                    clearInterval(interval);
                    fetchSites();
                }
            })
            .catch((error) => {
                // Handle any errors that occur during the promise resolution
                console.error('Error:', error);
            });
    }, 5000);
}

Auf diese Weise wird sichergestellt, dass die Nutzer/innen über den Status der Plugin-Aktualisierungen informiert werden, was die Benutzerfreundlichkeit des Tools insgesamt verbessert.

Plugins über mehrere Websites mit der Kinsta-API aktualisieren

Die wichtigste Funktion dieses Tools ist die Möglichkeit, ein bestimmtes Plugin mit einem Klick auf mehreren Websites innerhalb deines Kinsta-Kontos zu aktualisieren. Diese Funktion ähnelt der, die für die Aktualisierung von Plugins auf einer einzelnen Website implementiert wurde.

Dabei wird eine Schleife durch den Status von sites gezogen, der die Websites enthält, auf denen das jeweilige Plugin aktualisiert werden muss. Für jede Website, die ein Update benötigt, wird eine API-Anfrage gestellt, um das Plugin zu aktualisieren und den Status der Operation zu verfolgen:

// Update all plugins
const updateAllPlugins = async () => {
    sites.map(async (site) => {
        if (site.updateAvailable === 'available') {
            const environmentId = site.env_id;
            const resp = await fetch(
                `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
                {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json',
                        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                    },
                    body: JSON.stringify({
                        name: pluginName,
                        update_version: site.updateVersion,
                    }),
                }
            );
            const data = await resp.json();
            if (data.status === 202) {
                setShowStatusBar(true);
                const interval = setInterval(() => {
                    checkPluginUpdateStatus(data.operation_id)
                        .then((status) => {
                            console.log(status);
                            if (status === 200) {
                                setShowStatusBar(false);
                                clearInterval(interval);
                                fetchSites();
                            }
                        })
                        .catch((error) => {
                            // Handle any errors that occur during the promise resolution
                            console.error('Error:', error);
                        });
                }, 5000);
            }
        }
    });
};

Diese Funktion ist mit einer Schaltfläche Alle aktualisieren verbunden. Um die Benutzerfreundlichkeit zu erhöhen, zeigt die Schaltfläche die Versionsnummer an, auf die die Plugins aktualisiert werden:

<button> className="sm-btn" onClick={updateAllPlugins}>
    Update all sites to v.
    {
        sites.find((site) => site.updateVersion !== null)
            ?.updateVersion
    }
</button>

Außerdem wird diese Schaltfläche nur dann angezeigt, wenn mehr als eine Website ein Update für das Plugin benötigt. Wenn alle Websites auf dem neuesten Stand sind, wird stattdessen eine Meldung angezeigt:

<div className="list-title">
    <h3>Sites with {pluginName} plugin</h3>
    {sites.filter((site) => site.updateAvailable === 'available')
        .length > 1 && (
        <button className="sm-btn" onClick={updateAllPlugins}>
            Update all sites to v.
            {
                sites.find((site) => site.updateVersion !== null)
                    ?.updateVersion
            }
        </button>
    )}
    {sites.every((site) => site.updateAvailable !== 'available') && (
        <p>All sites are up to date</p>
    )}
</div>

Mit diesen Implementierungen kannst du jetzt mühelos Plugins für mehrere Websites in deinem Kinsta-Konto aktualisieren, was die Effizienz steigert und sicherstellt, dass alle deine Websites mit den neuesten Plugin-Versionen ausgestattet sind.

Stelle deine statische React-Website kostenlos auf Kinsta bereit

Wir nutzen das Statische-Seiten-Hosting von Kinsta, um die Anwendung zu demonstrieren. In der Praxis könntest du diese React-Anwendung in deinem eigenen Netzwerk ausführen oder sie erst dann bereitstellen, wenn du diesem Tool aus Sicherheitsgründen eine Authentifizierungsmöglichkeit hinzugefügt hast.

Du kannst deine React-Anwendungen, die du mit create-react-app erstellt hast, als statische Website mit unserem kostenlosen Statische-Seiten-Hosting hosten, indem du deinen Code zu einem bevorzugten Git-Anbieter (Bitbucket, GitHub oder GitLab) schiebst.

Sobald dein Repo fertig ist, befolge diese Schritte, um deine statische Website auf Kinsta bereitzustellen:

  1. Logge dich ein oder erstelle ein Konto, um dein MyKinsta-Dashboard zu sehen.
  2. Autorisiere Kinsta bei deinem Git-Anbieter.
  3. Klicke in der linken Seitenleiste auf Statische Websites und dann auf Website hinzufügen.
  4. Wähle das Repository und den Zweig aus, von dem aus du bereitstellen möchtest.
  5. Gib deiner Website einen eindeutigen Namen.
  6. Füge die Build-Einstellungen in folgendem Format hinzu:
    • Build-Befehl: npm run build
    • Node-Version: 18.16.0
    • Verzeichnis für die Veröffentlichung: build
  7. Zum Schluss klickst du auf Website erstellen.

Und das war’s! Innerhalb weniger Sekunden hast du eine fertige Website. Du erhältst einen Link, über den du auf die bereitgestellte Version deiner Website zugreifen kannst. Du kannst später deine eigene Domain und dein SSL-Zertifikat hinzufügen, wenn du möchtest.

Als Alternative zum Hosting statischer Websites kannst du deine statische Website auch mit dem Applikations-Hosting von Kinsta bereitstellen, das eine größere Hosting-Flexibilität, ein breiteres Spektrum an Vorteilen und den Zugang zu robusteren Funktionen bietet. Dazu gehören z. B. Skalierbarkeit, benutzerdefinierte Bereitstellung mithilfe eines Dockerfiles und umfassende Analysen, die Echtzeit- und historische Daten umfassen.

Zusammenfassung

Die Kinsta-API eröffnet Möglichkeiten, die über das hinausgehen, was wir besprochen haben. Eine spannende Anwendung könnte die Erstellung eines Slackbots sein, der dich auf Slack benachrichtigt, wenn ein Plugin veraltet ist. Diese Integration kann deinen Arbeitsablauf erheblich vereinfachen, da du immer informiert bist und proaktiv handeln kannst.

Du kannst auch ein ähnliches Tool entwickeln, wie in diesem Leitfaden beschrieben, um deine Themes zu aktualisieren, da die Kinsta-API bereits Endpunkte dafür hat.

Das Kinsta-Team arbeitet ständig daran, die nächsten Funktionen hinzuzufügen, indem es das Feedback genau verfolgt und zuhört, wie Kristof Siket, Development Team Lead für die Kinsta API, erzählt:

Das Feedback der Nutzerinnen und Nutzer bestimmt die Prioritäten für die Veröffentlichung der Funktionen. Der aktuelle Plan deckt die Tools-Seite nicht vollständig ab; stattdessen basieren die Funktionen auf den Nutzeranfragen und dem gesammelten Feedback. Wenn du glaubst, dass ein bestimmtes Tool oder ein Endpunkt in die Kinsta-API aufgenommen werden sollte, kannst du uns gerne dein Feedback schicken.

Wie nutzt du derzeit die Kinsta-API? Welche Funktionen oder Verbesserungen würdest du gerne in zukünftigen Updates sehen?

Joel Olawanle Kinsta

Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 200 technical articles majorly around JavaScript and it's frameworks.