Du musst nicht viele der 800 Millionen WordPress-Sites im Internet verwalten, bevor du nach Möglichkeiten suchst, neue Websites effizient zu starten.

Das Klonen einer bestehenden WordPress-Konfiguration ist eine Möglichkeit, schnell loszulegen, und Kunden des Managed WordPress Hosting Service von Kinsta wissen, dass dies über unser benutzerfreundliches MyKinsta-Dashboard ganz einfach möglich ist.

Außerdem kannst du WordPress-Websites in großem Umfang klonen, indem du deine bevorzugten Technologien zur Anwendungsentwicklung und die Kinsta-API nutzt. In diesem Tutorial zeigen wir dir, wie das mit dieser API und React, einer der beliebtesten JavaScript-Bibliotheken, funktioniert.

Was du bauen wirst

Hier ist das Szenario: Du bist eine WordPress-Entwicklungsagentur mit einer oder mehreren Websites, die als Startvorlagen verwendet werden können. Die React-Anwendung zum Klonen von WordPress-Seiten, die wir bauen, sieht so aus:

React-Anwendung zum Klonen von Websites mit der Kinsta-API
React-Anwendung zum Klonen von Websites mit der Kinsta-API

Voraussetzungen

Um diesem Tutorial folgen zu können, brauchst du ein grundlegendes Verständnis von HTML, CSS und JavaScript und eine gewisse Vertrautheit mit React. Außerdem musst du Node.js und npm (den Node Package Manager) oder yarn auf deinem Computer installiert haben. Der Schwerpunkt dieses Projekts liegt auf der Erstellung einer WordPress-Kloning-Anwendung mit React und der Kinsta-API und nicht auf den Details der UI-Erstellung und des Stylings.

Einrichten der Entwicklungsumgebung

Du kannst eine React-Anwendung von Grund auf neu erstellen und deine eigene Oberfläche entwickeln oder du kannst die oben erwähnte Git-Starter-Vorlage nutzen, indem du die folgenden Schritte befolgst:

  1. Besuche das GitHub-Repository dieses Projekts.
  2. Wähle Diese Vorlage verwenden > Neues Repository erstellen, um den Startcode in ein Repository in deinem GitHub-Konto zu kopieren. (Aktiviere das Kontrollkästchen, um alle Zweige einzuschließen.)
  3. Ziehe das Repository auf deinen lokalen Computer und wechsle mit dem Befehl in den starter-files-Zweig: git checkout starter-files
  1. Installiere die notwendigen Abhängigkeiten, indem du den Befehl npm install laufen lässt

Sobald die Installation abgeschlossen ist, kannst du das Projekt auf deinem lokalen Computer mit npm run start starten. Dadurch wird das Projekt unter http://localhost:3000/ geöffnet.

Die Projektdateien verstehen

Der Ordner src ist das Herzstück einer React-Anwendung, denn er enthält das JavaScript, das von webpack benötigt wird. In diesem Ordner befindet sich die Datei App.js, in der die beiden Routen für dieses Projekt konfiguriert sind.

Innerhalb des Ordners src befinden sich die Unterordner components und pages. Der Ordner components enthält wiederverwendbare Komponenten wie die Header.jsx und Footer.jsx, die in den Seiten Home.jsx und Operations.jsx verwendet werden.

Hier geht es darum, die Logik in Home.jsx und Operations.jsx zu implementieren, da Styling und Routing in unseren GitHub-Starterdateien zu finden sind.

Home.jsx hat ein Formular mit zwei Feldern: den Namen der Seite, die du erstellen willst, und ein Auswahlfeld, das die WordPress-Seiten in deinem MyKinsta-Konto auflistet (diese Liste wird über die Kinsta-API abgerufen).

Wenn du auf den Submit-Button des Formulars (Website klonen) klickst, wird ein Objekt mit der Eigenschaft operation_id zurückgegeben. Diese ID und der Anzeigename werden als Routenparameter an Operations.jsx übergeben, wo der Status des Klonvorgangs gemeldet wird. Die Schnittstelle enthält auch Links zum WordPress-Admin-Login und zur Startseite der Website.

Operations-Seite mit Links zum WP-Admin und zur Website
Operations-Seite mit Links zum WP-Admin und zur Website

Verwendung der Kinsta-API zum Klonen einer WordPress-Website

In Home.jsx werden drei API-Anfragen an die Kinsta-API gestellt. Die erste Anfrage dient dazu, eine Liste der Websites in deinem Kinsta-Konto zu erhalten. Diese wird in einem Status gespeichert und dann zum Auswahlfeld iteriert. Diese Anfrage wird unmittelbar nach dem Rendering der Seite über den useEffect-Hook gestellt.

Die zweite und dritte Anfrage wird gestellt, sobald du auf die Schaltfläche Website klonen klickst. Bei der zweiten Anfrage wird die Umgebungs-ID der Website abgefragt, die du klonen möchtest. Die dritte Anfrage verwendet diese Umgebungs-ID und den Anzeigenamen der Site, um das Klonen der Site zu starten.

Interaktion mit der Kinsta-API in React

In diesem Leitfaden interagierst du mit zwei Endpunkten der Kinsta-API:

  • /sites: Damit kannst du eine Liste aller Websites zurückgeben, eine Site Environment ID anfordern und schließlich eine bestehende Website klonen.
  • /operations: Mit diesem Endpunkt kannst du den Status der Operation abfragen. Wenn zum Beispiel das Klonen einer Site im Gange ist, kannst du diesen Endpunkt verwenden, um den Status des Vorgangs programmatisch zu verfolgen und festzustellen, wann er abgeschlossen ist.

Um mit der Kinsta-API zu interagieren, brauchst du deine Unternehmens-ID (du findest sie in MyKinsta unter Unternehmen > Rechnungsdetails > Unternehmens-ID) und einen API-Schlüssel. Hier erfährst du, wie du einen Kinsta-API-Schlüssel erstellst.

Sobald du diese Zugangsdaten hast, speicherst du sie am besten sicher als Umgebungsvariablen in deiner React-Anwendung. Um die Umgebungsvariablen einzurichten, erstellst du eine .env-Datei im Stammverzeichnis deines Projekts. Füge in diese Datei die folgenden Zeilen ein:

REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' 
REACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'

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

Eine bestehende Website mit der Kinsta-API klonen

Wir beginnen damit, dass wir die Liste aller Websites, die Home.jsx rendert, mit dem useEffect Hook abrufen und sie in einem Status speichern. Dazu importierst du die Hooks useEffect und useState und erstellst einen Status, in dem du die Liste der abgerufenen Websites speicherst:

import { useState, useEffect } from 'react';
const [sites, setSites] = useState([]);

Als Nächstes verwendest du den useEffect Hook, um die Kinsta API mit der JavaScript Fetch API abzufragen. Erstelle zunächst zwei konstante Variablen, um die Kopfzeilen und die URL der Kinsta-API zu speichern. Dies geschieht, um Wiederholungen zu vermeiden, da du auf dieser Seite mehr als eine Anfrage an die Kinsta-API senden wirst:

const KinstaAPIUrl = 'https://api.kinsta.com/v2';
const headers = useMemo(() => {
    return {
        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`
    };
}, []);

Im obigen Code merkt sich der useMemo-Hook das Header-Objekt, damit es nicht bei jedem Rendering neu ausgewertet werden muss, da sein Wert konstant ist. Jetzt kannst du die API-Anfrage erstellen:

useEffect(() => {
    const fetchAllSites = async () => {
        const query = new URLSearchParams({
            company: process.env.REACT_APP_KINSTA_COMPANY_ID,
        }).toString();
        const resp = await fetch(
            `${KinstaAPIUrl}/sites?${query}`,
            {
                method: 'GET',
                headers
            }
        );
        const data = await resp.json();
        setSites(data.company.sites);
    };
    fetchAllSites();
}, [headers]);

Im obigen Code wird eine asynchrone Funktion fetchAllSites erstellt. In dieser Funktion definierst du zunächst den Parameter query (deine Unternehmens-ID), den du aus deiner .env-Datei abrufst. Dann stellst du mit dem Parameter query eine GET-Anfrage an den Endpunkt /sites der Kinsta-API. Die Antwort wird im sites Status gespeichert, den du zuvor erstellt hast. Schließlich rufst du fetchAllSites auf, um den Abrufprozess zu starten.

Jetzt werden die im Status sites gespeicherten Werte in einer Schleife verarbeitet, um das Auswahlfeld zu füllen. Der Anzeigename wird dem Benutzer angezeigt, während die Website-ID als Optionswert verwendet wird. Auf diese Weise kann beim Absenden des Formulars die ID der ausgewählten Website für die Abfrage von Umgebungsdetails verwendet werden:

<div className="input-div">
    <label>Select a site</label>
    <span>Select the site you want to clone</span>
    <select className="form-control">
        <option> value=""></option>
        {sites && (
            sites.map((site) => {
                return (
                    <option> key={site.id} value={site.id}>{site.display_name}</option>
                )
            })
        )}
    </select>
</div>

Fahren wir fort mit dem Absenden des Formulars und dem Abrufen von Werten aus dem Formular. Dazu musst du Zustandsvariablen für jedes Eingabefeld erstellen:

const [selectedSiteId, setSelectedSiteId] = useState('');
const [displayName, setDisplayName] = useState('');

Als Nächstes bindest du die Formularfelder an ihre jeweiligen Statuswerte, indem du die Attribute value und onChange zu jedem Eingabeelement hinzufügst. So sieht das Formular dann aus:

<form>
    <div className="form-container">
        <div className="input-div">
            <label>Display name</label>
            <span>Helps you identify your site. Only used in MyKinsta and temporary domain</span>
            <input type="text" className="form-control" value={displayName} onChange={(e) => setDisplayName(e.target.value)} />
        </div>
        <div className="input-div">
            <label>Select a site</label>
            <span>Select the site you want to clone</span>
            <select className="form-control" value={selectedSiteId} onChange={(e) => setSelectedSiteId(e.target.value)}>
                <option value=""></option>
                {sites && (
                    sites.map((site) => {
                        return (
                            <option key={site.id} value={site.id}>{site.display_name}</option>
                        )
                    })
                )}
            </select>
        </div>
        <button className='btn'>Clone Site</button>
    </div>
</form>

Im obigen Code ist das value-Attribut jedes Eingabeelements auf die entsprechende Zustandsvariable gesetzt, und das onChange -Attribut wird verwendet, um den Zustandswert zu aktualisieren, wenn der Nutzer mit den Eingabefeldern interagiert.

Um die Übermittlung des Formulars zu verarbeiten, füge dem Formularelement eine onSubmit Methode hinzu. Zum Beispiel:

<form> onSubmit={handleSubmission}>
    {/* form details */}
</form>

Definiere die Methode handleSubmission, bei der zwei API-Anfragen an die Kinsta-API gestellt werden. Die erste Anfrage ruft die Umgebungs-ID der zu klonenden Website ab, und die zweite Anfrage führt den Klonvorgang durch.

Beginnen wir mit der Abfrage der Umgebungs-ID. Erstelle innerhalb der Methode handleSubmission eine asynchrone Funktion, die diese Anfrage bearbeitet. Die Funktion sendet eine GET-Anfrage an den Endpunkt /sites und fügt die ID der ausgewählten Site hinzu, gefolgt von der Angabe /environments endpunkt:

const handleSubmission = async (e) => {
    e.preventDefault();
    const fetchEnvironmentId = async (siteId) => {
        const resp = await fetch(
            `${KinstaAPIUrl}/sites/${siteId}/environments`,
            {
                method: 'GET',
                headers
            }
        );
        const data = await resp.json();
        let envId = data.site.environments[0].id;
        return envId;
    }
    let environmentId = await fetchEnvironmentId(selectedSiteId);
}

fetchEnvironmentId ist eine asynchrone Funktion, die eine GET-Anfrage an die Kinsta-API sendet. Sie holt die Umgebungen der ausgewählten Website ab und extrahiert die Umgebungs-ID aus der Antwort. Die Umgebungs-ID wird in der Variablen envId gespeichert und dann zurückgegeben. Wenn wir die Funktion aufrufen, weisen wir ihren Rückgabewert der Variablen envId zu.

Jetzt kannst du eine bestehende Website mit der Kinsta-API klonen, denn du hast die wichtigsten Informationen über die Ausgangsseite: Unternehmens-ID, Anzeigename und Umgebungs-ID.

Erstelle in der Methode handleSubmission eine Funktion namens cloneExistingSite, die diese API-Anfrage bearbeitet. Diese Anfrage ist an den /sites/clone Endpunkt gerichtet. Im Gegensatz zu den vorherigen Anfragen sind die Kopfzeilen für diese Anfrage anders, da du Content-Type als application/json angeben musst. Außerdem handelt es sich um eine POST-Anfrage, d.h. du musst einen Request Body mit den Daten, die du an die API senden willst, einfügen. So wird die Anfrage aufgebaut:

const handleSubmission = async (e) => {
    e.preventDefault();

    // fetch environment Id

    const cloneExistingSite = async (env_Id) => {
        const resp = await fetch(
            `${KinstaAPIUrl}/sites/clone`,
            {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`
                },
                body: JSON.stringify({
                    company: `${process.env.REACT_APP_KINSTA_COMPANY_ID}`,
                    display_name: displayName,
                    source_env_id: env_Id,
                })
            }
        );
        const data = await resp.json();
        navigate(`/operations/${displayName}/${data.operation_id}`)
        console.log(data);
    }
    cloneExistingSite(environmentId);
}

In diesem Code wird die Anfrage body mithilfe von JSON.stringify() erstellt, um das Payload-Objekt in einen JSON-String zu konvertieren. Die Antwort wird dann in der Variablen data gespeichert. Mit der Methode useNavigate aus der Bibliothek react-router-dom werden displayName und operation_id als Routenparameter übergeben. Stelle sicher, dass du die Methode useNaviagte importierst und instanziierst:

// Import the required method 
import { useNavigate } from 'react-router-dom'; 

// Instantiate the useNavigate method 
const navigate = useNavigate();

Wenn du nun das Formular ausfüllst und auf die Schaltfläche Seite klonen klickst, wird eine neue Seite geklont, die in deinem MyKinsta-Dashboard sichtbar ist. Wir wollen den Vorgang des Klonens jedoch programmatisch in der benutzerdefinierten Benutzeroberfläche verfolgen. Das machst du in Operations.jsx mit den Daten, die über die Route gesendet werden.

Implementierung der Überprüfung des Vorgangsstatus mit der Kinsta-API

In Operations.jsx rufst du mit der Methode useParams von react-router-dom die ID des Vorgangs aus der Route ab. Diese ID wird für eine API-Anfrage verwendet, wenn du auf die Schaltfläche Check Site Status klickst.

Importiere zunächst die Methode useParams und verwende sie, um die Variablen displayName und operationId zu instanziieren:

// Import the useParams library
import { useParams } from 'react-router-dom';

// Instantiate the paramters
const { displayName, operationId } = useParams();

Als Nächstes erstellst du einen Status, um den Betriebsstatus zu speichern, wenn die Anfrage gestellt wird:

const [operationData, setOperationData] = useState({ message: "Operation in progress." });

Im obigen Code wird der Status mit einer Standardnachricht initialisiert, die angezeigt wird, bis die Schaltfläche Check Site Status angeklickt wird. Füge ein onClick Ereignis zur Schaltfläche Check Site Status hinzu und rufe die Methode checkOperation auf, wenn die Schaltfläche angeklickt wird:

<button> className='sm-btn' onClick={() => checkOperation()}>Check Site Status</button>

Erstelle nun die Funktion checkOperation, um die Anfrage an die Kinsta-API zu stellen. Speichere die Konstanten headers und KinstaAPIUrl in Variablen und verwende sie dann in der API-Anfrage:

const KinstaAPIUrl = 'https://api.kinsta.com/v2';
const headers = useMemo(() => {
    return {
        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`
    };
}, []);

const checkOperation = async () => {
    const resp = await fetch(
        `${KinstaAPIUrl}/operations/${operationId}`,
        {
            method: 'GET',
            headers
        }
    );
    const data = await resp.json();
    setOperationData(data);
};

Im obigen Code wird eine GET-Anfrage mit der Vorgangs-ID an den Endpunkt /operations gesendet, und die Antwort wird im Status operationData gespeichert. Jetzt kannst du die Daten in deinem Markup verwenden:

<div className="services">
    <div className="details">
        <p>{operationData.message}..</p>
        <button> className='sm-btn' onClick={() => checkOperation()}>Check Site Status</button>
    </div>
</div>

Schließlich werden die displayName Daten, die über die Route übergeben werden, verwendet, um die URL für die neue Website und die WordPress-Admin-URL zu erstellen. Beide Links werden in einem neuen Tab geöffnet.

<div className="details">
    <a href={`http://${displayName}.kinsta.cloud/wp-admin/`} target="_blank" rel="noreferrer" className='detail-link'>
        <p>Open WordPress admin</p>
        <FiExternalLink />
    </a>
    <a href={`http://${displayName}.kinsta.cloud/`} target="_blank" rel="noreferrer" className='detail-link'>
        <p>Open URL</p>
        <FiExternalLink />
    </a>
</div>

Mit diesen Änderungen ruft Operations.jsx die ID des Vorgangs von der Route ab, stellt eine API-Anfrage, wenn die Schaltfläche angeklickt wird, zeigt den Status des Vorgangs an und liefert Links zum WordPress-Admin und zur URL der Website auf der Grundlage der Daten von displayName.

Bereitstellen deiner Anwendung bei Kinsta

Um deine Anwendung auf der Anwendungs-Hosting-Plattform von Kinsta bereitzustellen, musst du das Projekt bei deinem bevorzugten Git-Anbieter pushen. Wenn dein Projekt auf GitHub, GitLab oder Bitbucket gehostet wird, kannst du mit dem Deployment auf Kinsta beginnen.

Befolge diese Schritte, um dein Repository auf Kinsta bereitzustellen:

  1. Melde dich auf dem MyKinsta-Dashboard an oder erstelle dein Kinsta-Konto.
  2. Klicke in der linken Seitenleiste auf Anwendungen und dann auf Dienst hinzufügen.
  3. Wähle Anwendung aus dem Dropdown-Menü, um eine React-Anwendung auf Kinsta bereitzustellen.
  4. Wähle in dem erscheinenden Modal das Repository aus, das du bereitstellen möchtest. Wenn du mehrere Zweige hast, kannst du den gewünschten Zweig auswählen und einen Namen für deine Anwendung vergeben.
  5. Wähle einen der verfügbaren Rechenzentrumsstandorte aus der Liste der 25 Optionen aus.
  6. Kinsta erkennt automatisch den Startbefehl für deine Anwendung.

Schließlich ist es nicht sicher, API-Schlüssel an öffentliche Hoster wie deinen Git-Provider weiterzugeben. Beim Hosten kannst du sie als Umgebungsvariablen hinzufügen, indem du denselben Variablennamen und Wert wie in der .env-Datei angibst.

Setze Umgebungsvariablen auf MyKinsta, wenn du die Anwendung bereitstellst
Setze Umgebungsvariablen auf MyKinsta, wenn du die Anwendung bereitstellst

Sobald du die Bereitstellung deiner Anwendung initiierst, beginnt der Prozess und ist normalerweise innerhalb weniger Minuten abgeschlossen. Eine erfolgreiche Bereitstellung erzeugt einen Link zu deiner Anwendung, wie https://clone-wp-site-12teh.kinsta.app/.

Zusammenfassung

Die Kinsta-API bietet dir die Flexibilität, eigene Benutzeroberflächen für die Verwaltung von WordPress-Sites zu erstellen, einschließlich der Möglichkeit, bestehende Websites zu klonen und verschiedene Aspekte deiner WordPress-Umgebung zu verwalten.

In diesem Artikel hast du gelernt, wie du eine Anwendung entwickelst, die das Klonen von Websites außerhalb von MyKinsta ermöglicht.

Wie nutzt du die Kinsta-API? Welche Funktionen und Endpunkte würdest du dir für die API wünschen? Teile sie im Kommentarbereich mit!

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.