Plugins spelen een belangrijke rol bij het aanpassen en verbeteren van je WordPress sites. Ze worden gebruikt om functionaliteit zoals contactformulieren, e-commerce en analytics aan je sites toe te voegen zonder dat je daarvoor hoeft te coderen.

Net als WordPress, dat regelmatig updates ontvangt, ontvangen plugins ook regelmatig updates om nieuwe features toe te voegen, een veiligheidslek te repareren, de compatibiliteit te vergroten en nog veel meer. Daarom heeft Kinsta Plugin- en Themabeheer toegevoegd aan de tools die je kan gebruiken in MyKinsta voor al je sites.

Het bijwerken van plugins voor veel sites kan echter nog steeds vaak teveel zijn voor drukke klanten zoals bureaus. Dit artikel laat een oplossing zien die gebruik maakt van de Kinsta API om tegelijkertijd plugins te beheren voor meerdere sites.

Wat je gaat bouwen

Deze handleiding richt zich op het bouwen van een geavanceerde oplossing met behulp van de Kinsta API, die nu endpoints biedt voor het ophalen en bijwerken van plugins.

Hierin maken we een custom React applicatie die alle plugins van je Kinsta bedrijfsaccount ophaalt. Met deze tool kun je een specifieke plugin identificeren en bijwerken op meerdere sites, waardoor het proces aanzienlijk wordt gestroomlijnd.

Tool gebouwd met React en Kinsta API om WordPress plugins in bulk bij te werken op meerdere sites.
Tool gebouwd met React en Kinsta API om WordPress plugins in bulk bij te werken op meerdere sites.

Voorwaarden applicatie

Om dit project te kunnen volgen, moet je over het volgende beschikken:

De Kinsta API zelf

De Kinsta API is een krachtige tool waarmee je programmatisch kunt communiceren met diensten van Kinsta zoals gehoste WordPress sites. Het kan helpen bij het automatiseren van verschillende taken met betrekking tot WordPress beheer, waaronder het maken van sites, het ophalen van site informatie, het opvragen van de status van een site, het doorzoeken en herstellen van backups, en nog veel meer.

Om de API van Kinsta te gebruiken, moet je een account hebben met ten minste één WordPress site, applicatie of database in MyKinsta. Je moet ook een API sleutel genereren om je te authenticeren en toegang te krijgen tot je account.

Om een API sleutel te genereren:

  1. Ga naar je MyKinsta dashboard.
  2. Navigeer naar de pagina API sleutels (Je naam > Bedrijfsinstellingen > API sleutels).
  3. Klik op API sleutel aanmaken.
  4. Kies een vervaltijd of stel een custom begindatum in en het aantal uren dat de sleutel moet verlopen.
  5. Geef de sleutel een unieke naam.
  6. Klik op Genereer.

Nadat je een API sleutel hebt gemaakt, moet je deze kopiëren en ergens veilig opslaan (het gebruik van een wachtwoordmanager wordt aanbevolen). Je kunt meerdere API sleutels aanmaken, die worden weergegeven op de pagina API sleutels. Als je een API sleutel moet intrekken, klik je op de knop Intrekken.

Je React ontwikkelomgeving instellen

React is een populaire JavaScript bibliotheek voor het bouwen van gebruikersinterfaces. Hiermee kunnen developers declaratieve componenten maken die verschillende onderdelen van de gebruikersinterface vertegenwoordigen. Deze componenten worden gedefinieerd met JSX syntaxis, een combinatie van JavaScript en HTML.

Volg deze stappen om aan de slag te gaan:

  1. Navigeer naar de map waarin je je project wilt maken en gebruik create-react-app om een React project te maken:
    npx create-react-app <project-name>

    Wijzig <project-name> hierboven in de gewenste naam voor je project.

  2. Zodra dit is gelukt, navigeer je naar de projectmap en start je de ontwikkelserver:
    cd <project-name>
    npm run start

    Je React app wordt geopend in je standaard webbrowser op http://localhost:3000.

Door een React project te maken met create-react-app wordt een mappenstructuur opgezet. De cruciale map is src, waar de ontwikkeling plaatsvindt. De belangrijkste bestanden in deze map zijn:

  • App.js: Dit is de hoofdcomponent, die alle andere componenten in je React app rendert. Dit is waar al je code voor deze tool wordt toegevoegd.
  • index.js: Dit is het startpunt, wordt als eerste geladen en is verantwoordelijk voor het renderen van App.js.
  • index.css: Dit bestand definieert de algehele styling en layout van je app. Alle stijlen worden hier toegevoegd.

Gebruikersinterface maken en stylen

Laten we ons richten op het bouwen en stylen van de interface voor een basisapplicatie die is ondergebracht in het App.js bestand zonder routing. Onze belangrijkste UI is een formulier met een select veld om een lijst te maken van unieke plugins op je Kinsta sites naast een submit knop om sites op te halen met de geselecteerde plugin.

Gebruikersinterface voor pluginmanager om een lijst met plugins te openen en sites te laden.
Gebruikersinterface voor pluginmanager om een lijst met plugins te openen en sites te laden.

Daarnaast toont een weergavegedeelte sitegegevens zoals naam, pluginstatus en versie. Het bevat een knop om elke site bij te werken indien nodig en een algemene knop voor het in bulk bijwerken van alle sites die de plugin update nodig hebben.

Voeg in je App.js bestand de volgende code toe:

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;

Om dit project te stylen, bezoek je het CSS bestand in onze volledige GitHub repository en kopieer je de code ervan naar je index.css bestand.

Interactie met Kinsta API

De Kinsta API biedt een reeks endpoints die essentieel zijn voor toegang tot verschillende parameters die nodig zijn voor interactie met de plugin van een site. Als je bijvoorbeeld een plugin wilt ophalen of bijwerken, moet je eerst de omgevings-ID van de site ophalen.

Het verkrijgen van deze omgevings-ID is een sequentieel proces. Eerst moet je de ID van de site bepalen. Om de site-ID te krijgen, moet je je Kinsta bedrijfs-ID hebben. Dit bedrijfs-ID is beschikbaar in je MyKinsta dashboard (Bedrijfsinstellingen > Factureringsgegevens), en het is gevoelige informatie die je met niemand wilt delen, zoals je API sleutel.

Je kunt ze veilig opslaan als omgevingsvariabelen in je React applicatie door een .env bestand aan te maken in de hoofdmap van je project. Voeg in dit bestand het volgende toe met de juiste waarde:

REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' 
REACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'

Om toegang te krijgen tot deze omgevingsvariabelen binnen je project, kun je de syntaxis process.env.THE_VARIABLE gebruiken. Om bijvoorbeeld toegang te krijgen tot REACT_APP_KINSTA_COMPANY_ID, gebruik je process.env.REACT_APP_KINSTA_COMPANY_ID.

Door het .env bestand toe te voegen aan je .gitignore bestand is belangrijk om te voorkomen dat het naar GitHub gepushed wordt. Dit zorgt ervoor dat je gevoelige informatie privé en veilig blijft.

Alle sites en plugins ophalen met de Kinsta API

Om plugin gegevens op te halen voor alle sites die worden beheerd door je Kinsta bedrijfsaccount, kun je de Kinsta API gebruiken door drie API verzoeken uit te voeren. Hier volgt een stapsgewijze uitleg:

Begin met het opslaan van de Kinsta API URL in een variabele voor gemakkelijke referentie.

const KinstaAPIUrl = 'https://api.kinsta.com/v2';
  1. Lijst met bedrijfssites ophalen: Je moet een lijst ophalen met alle WordPress sites die aan je bedrijf zijn gekoppeld. Om dit te bereiken stel je een query samen met de ID van het bedrijf, doe je een GET verzoek met de juiste autorisatie, verwerk je het antwoord in JSON format en haal je de sitegegevens uit het antwoord.
    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. Siteomgevings-ID ophalen: De vorige stap retourneert een array van WordPress sites. Loop voor elke site door en doe nog een GET verzoek om de bijbehorende omgevingen op te halen.
    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. Lijst van WordPress site plugins ophalen: Na het verkrijgen van de site-ID, naam en omgeving, kun je nu de omgeving-ID gebruiken om een lijst van alle plugins op elke site op te halen. Je moet eerst de promises uit de vorige stap oplossen en dan de GET verzoeken voor de plugins doen:
    // 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. Het proces consolideren: Om het proces te stroomlijnen kun je deze API verzoeken inkapselen in een enkele asynchrone functie getSitesWithPluginData, die hergebruikt kan worden. Deze functie voert de hierboven beschreven stappen uit en retourneert een array met de essentiële informatie over elke site, waaronder de omgevings-ID, sitenaam en een array met 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;
    };

Unieke plugins van alle sites ophalen

In je applicatie wil je de lijst met plugins van alle sites weergeven in een vervolgkeuzemenu op select. Om dit te bereiken, haalt de functie getSitesWithPluginData de omgevings-ID, naam en plugins van elke site op. Deze gegevens vormen de basis voor het extraheren van een lijst met plugins.

Definieer een nieuwe functie, fetchAllSitesPlugins, die getSitesWithPluginData callt en de uitvoer verwerkt om een lijst met alle plugins te krijgen:

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

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

   // …
};

Deze code itereert de gegevens van elke site en stelt een lijst van plugins samen. Om ervoor te zorgen dat elke plugin maar één keer in de lijst voorkomt, gebruik je het JavaScript object Set, dat unieke waarden opslaat:

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

De methode .flat() maakt de array-structuur plat en .map() maakt een lus om alleen de plugin-namen eruit te halen. Het Set object filtert duplicaten eruit.

Om deze gegevens in je React applicatie te laden en weer te geven, gebruik je de haken useState() en 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
    //...
};

De useEffect() hook zorgt ervoor dat de gegevens worden opgehaald en ingesteld wanneer het component wordt gemount. De useState() hook onderhoudt de lijst met unieke plugins.

Tot slot worden deze plugins weergegeven in een select veld. Als de plugins nog aan het laden zijn, toon dan een placeholderbericht:

<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 deze code:

  • Het select element is gekoppeld aan een toestandsvariabele pluginName om de geselecteerde waarde op te slaan.
  • De onChange handler werkt deze toestand bij wanneer een nieuwe plugin wordt geselecteerd.
  • De plugins.map() functie maakt dynamisch optie-elementen aan voor elke plugin.

Door deze stappen te volgen, zal je applicatie effectief een unieke lijst van plugins tonen die van alle sites zijn opgehaald, waardoor een schone en gebruikersvriendelijke interface voor selectie ontstaat.

Selectieveld met lijst van unieke plugins van alle sites in Kinsta bedrijfsaccount.
Selectieveld met lijst van unieke plugins van alle sites in Kinsta bedrijfsaccount.

Sites met een specifieke plugin ophalen

Tot nu toe heb je plugins kunnen ophalen uit je Kinsta bedrijfsaccount, maar je wilt alle sites doorlopen om sites met een bepaalde plugin op te halen, ze opslaan in een status en ze vervolgens weergeven.

Om dit te doen, maak je twee toestanden aan: een om de sites op te slaan (sites) en een andere om de laadstatus aan te geven (isLoading).

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

Maak vervolgens een fetchSites functie om elke site te filteren om te controleren of deze de geselecteerde plugin bevat. Zo ja, dan worden de relevante gegevens van de site opgeslagen.

Deze functie begint met het instellen van isLoading op true en het wissen van de sites array. Vervolgens wordt getSitesWithPluginData gecallt om alle sitegegevens op te halen.

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);
};

Voor de functie sitesWithPluginDataFiltered geldt:

  • De methode .filter() isoleert sites die de geselecteerde plugin bevatten.
  • De methode .map() haalt dan de vereiste gegevens uit elke site.
  • Tot slot werken de hooks setSites en setIsLoading de status bij met de nieuwe gegevens en laadstatus.

Maak vervolgens een handleSubmit functie en voeg deze toe aan de knop Fetch sites with this plugin op het formulier om de functie aan te roepen wanneer een gebruiker een plugin selecteert en het formulier verzendt. Deze functie voorkomt de standaard formulieractie en roept fetchSites aan:

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

Hiermee worden, wanneer een gebruiker een bepaalde plugin selecteert en op de verzendknop klikt, alle sites met die plugin opgehaald en opgeslagen in de sites status.

Sites met de geselecteerde plugin weergeven

Nadat je de relevante sites met succes hebt opgeslagen in je sites status, is de volgende stap om deze gegevens weer te geven in de gebruikersinterface van je project. Het doel is om elke site te presenteren als een lijstitem met belangrijke details en een voorwaardelijke knop voor plugin-updates.

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

In de bovenstaande code wordt de array sites geïtereerd met de methode .map(), waardoor een lijst (<ul>) met sites (<li> elementen) ontstaat. Elk lijstitem bevat details over de site en een knop voor plugin-updates.

De knop in de UI verandert van stijl en functie op basis van de updatestatus van de plugin: hij is actief voor beschikbare updates, anders uitgeschakeld en gelabeld als “Up to date,” geregeld door voorwaardelijke CSS en het disabled attribuut.

Laten we ook, om de gebruikerservaring te verbeteren, een laadtekst toevoegen die conditioneel gebruik maakt van de isLoading status wanneer de sites worden opgehaald.

{isLoading && (
    <div className="loading">
        <p>Loading...</p>
    </div>
)}
Een lijst met sites die een bepaalde plugin gebruiken van de Kinsta bedrijfsaccount met knoppen om ze afzonderlijk of in één keer bij te werken.
Een lijst met sites die een bepaalde plugin gebruiken van de Kinsta bedrijfsaccount met knoppen om ze afzonderlijk of in één keer bij te werken.

Plugins bijwerken met Kinsta API

Tot nu toe hebben we sites kunnen ophalen met belangrijke details en toegang tot hun plugins. Het doel van deze tool is om het bijwerken van plugins op meerdere sites te vergemakkelijken met behulp van de Kinsta API. Het proces omvat het initiëren van updates en het bijhouden van de voortgang ervan.

Plugin-updates starten

Er is een knop voor elke site in de lijst. De vormgeving geeft aan of er een update beschikbaar is. Als er een update beschikbaar is, activeer je door op de knop te klikken de functie updatePlugin.

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

De onClick handler callt updatePlugin met de omgevings-ID van de site en de laatste versie van de plugin (updateVersion). Deze functie stuurt een PUT verzoek naar de Kinsta API om de plugin bij te werken.

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
};

De voortgang van de update volgen

Nadat je de update hebt gestart, moet je de voortgang ervan controleren. De Kinsta API geeft een respons zoals dit na het initiëren van een update:

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

De operation_id houdt de updatestatus bij via het operations endpoint. Maak een functie om dit API verzoek te doen en verwacht de operation_id als argument:

// 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;
};

Gebruik binnen updatePlugin een if statement om te controleren of de initiële update-aanvragen status 202 zijn. Als dat zo is, wordt er een interval ingesteld om checkPluginUpdateStatus elke vijf seconden (5000 milliseconden) aan te roepen.

Het interval controleert herhaaldelijk de updatestatus en als dat succesvol is, wordt het interval gewist en wordt fetchSites gecallt om de lijst met sites te verversen. Als er een fout optreedt tijdens deze controles, wordt deze gelogd op de console.

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);
}

Feedback van de gebruiker tijdens het gebruik

Alles werkt goed tot zover, maar het is goed om de gebruiker bewust te maken van de voortgang van de operatie in plaats van ze te laten gissen. Je kunt dit doen door een melding te tonen die verschijnt als de bewerking bezig is en weer verdwijnt als de bewerking klaar is. Maak een showStatusBar status om dit te regelen:

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

Wanneer showStatusBar true is, verschijnt er een statusbalk bovenaan het scherm die aangeeft dat er een update wordt uitgevoerd. Deze is zo vormgegeven dat hij vast aan de bovenkant van het scherm staat.

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

Je kunt nu het statement if in de functie updatePlugin aanpassen om showStatusBar in te stellen op true of false op basis van de updatestatus:

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);
}

Deze aanpak zorgt ervoor dat gebruikers op de hoogte blijven van de status van plugin-updates, wat de algehele bruikbaarheid van de tool verbetert.

Plugins bijwerken op meerdere sites met Kinsta API

De belangrijkste functie van deze tool is de mogelijkheid om een bepaalde plugin met één klik bij te werken op meerdere sites binnen je Kinsta account. Dit is vergelijkbaar met de functionaliteit die is geïmplementeerd voor het bijwerken van plugins op een enkele site.

Het proces bestaat uit het doorlopen van de sites status, die de sites bevat met de specifieke plugin die een update nodig heeft. Voor elke site die een update nodig heeft, wordt een API verzoek gedaan om de plugin bij te werken en vervolgens wordt de status van de bewerking bijgehouden:

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

Deze functie is gekoppeld aan een Update All knop. Om de gebruikerservaring te verbeteren, toont de knop het versienummer waarnaar de plugins worden bijgewerkt:

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

Bovendien geven we deze knop voorwaardelijk weer, zodat hij alleen verschijnt als meer dan één site een update voor de plugin nodig heeft. Als alle sites up-to-date zijn, wordt in plaats daarvan een bericht weergegeven:

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

Met deze implementaties kun je nu moeiteloos plugins bijwerken voor meerdere sites in je Kinsta account, wat de efficiëntie verhoogt en ervoor zorgt dat al je sites up-to-date zijn met de nieuwste pluginversies.

Deploy je statische React site gratis op Kinsta

We gebruiken de statische site hosting van Kinsta om de applicatie te demonstreren. In de praktijk zou je deze React app vanuit je eigen netwerk kunnen draaien of pas implementeren nadat je voor de veiligheid een authenticatiemiddel aan deze tool hebt toegevoegd.

Je kunt je React applicaties gemaakt met de create-react-app als een statische site hosten met behulp van onze statische site hosting, gratis, door je code naar een Git provider van je voorkeur te pushen (Bitbucket, GitHub of GitLab).

Zodra je repo klaar is, volg je deze stappen om je statische site te deployen op Kinsta:

  1. Log in of maak een account aan om je MyKinsta dashboard te bekijken.
  2. Autoriseer Kinsta met je Git provider.
  3. Klik op Statische sites op de linker zijbalk, klik dan op Site toevoegen.
  4. Selecteer de repository en de branch waarvan je wilt deployen.
  5. Geef je site een unieke naam.
  6. Voeg de bouwinstellingen toe in het volgende formaat:
    • Build commando: npm run build
    • Node versie: 18.16.0
    • Publish directory: build
  7. Klik ten slotte op Site maken.

En dat is het! Je hebt nu binnen een paar seconden een gedeployde site. Je krijgt een link waarmee je naar de gedeployde versie van je site kunt gaan. Als je wilt, kun je later je eigen domein en SSL certificaat toevoegen.

Als alternatief voor statische site hosting kun je je statische site deployen met Kinsta’s Applicatie Hosting, die een grotere hostingflexibiliteit, een breder scala aan voordelen en toegang tot robuustere features biedt. Bijvoorbeeld schaalbaarheid, custom deployments met behulp van een Dockerfile en uitgebreide analyses met real-time en historische gegevens.

Samenvatting

De Kinsta API opent mogelijkheden die verder gaan dan wat we hebben besproken. Een andere interessante toepassing zou het maken van een Slackbot kunnen zijn die je op Slack waarschuwt wanneer een plugin verouderd is. Deze integratie kan je workflow aanzienlijk stroomlijnen en je op de hoogte en proactief houden.

Je kunt ook een soortgelijke tool ontwikkelen, zoals uitgelegd in deze gids, om je thema’s bij te werken, omdat de Kinsta API hier al endpoints voor heeft.

Het Kinsta team werkt voortdurend aan het toevoegen van de volgende functies door feedback op de voet te volgen en ernaar te luisteren, zoals Kristof Siket, Development Team Lead voor Kinsta API, deelt:

Feedback van gebruikers bepaalt de prioritering van features. Het huidige plan dekt de Tools pagina niet volledig; in plaats daarvan worden functies gebaseerd op verzoeken van gebruikers en verzamelde feedback. Als je vindt dat een specifieke tool of endpoint moet worden opgenomen in de Kinsta API, stuur dan gerust je feedback.

Hoe gebruik je momenteel de Kinsta API? Welke functies of verbeteringen zou je graag zien in toekomstige updates?

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.