Back to Question Center
0

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiert            Git und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen: DatabaseDevelopment EnvironmentSicherheitDrupalDebugging & Semal

1 answers:
Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiert

Bei Bitfehlern. com, wir verwenden WordPress für den Moment und verwenden den gleichen Peer-Review-Ansatz für Inhalte wie bei Semalt.

Wir haben beschlossen, ein Tool zu erstellen, das automatisch Inhalte aus zusammengeführten Pull-Anfragen in Artikel aufnimmt. Dadurch können wir Tippfehler korrigieren und Beiträge von Github aktualisieren und die Änderungen auf der Live-Site sehen - anaokullar. Dieses Tutorial führt Sie durch die Erstellung dieses Tools, damit Sie es für Ihre eigene Semalt-Site verwenden oder Ihre eigene Version erstellen können.

Der Plan

Der erste Teil identifiziert das Problem und die Situation, die es umgibt.

  • Wir benutzen WPGlobus für mehrsprachige Unterstützung, was bedeutet, dass Inhalte wie folgt gespeichert werden: {: en} Englischer Inhalt {:} {: hr} Kroatischer Inhalt {:} .
  • Autoren geben PRs über Github ein, die PRs werden von Experten geprüft und zusammengeführt und dann (derzeit) manuell über den Browser in die Post-Benutzeroberfläche von WP importiert.
  • Jeder Beitrag hat das gleiche Ordnerlayout: author_folder / post_folder / language / final. md
  • das ist langsam und fehleranfällig, und manchmal entgehen Fehler. Es macht auch das Aktualisieren von Posts langweilig.

Die Lösung ist folgende:

  • füge einen Hook-Prozessor hinzu, der Pushs zum Master-Zweig erkennt (d. H. Von PRs mergt)
  • Der Prozessor sollte beim Commit nach einer Metadatei suchen, die Informationen darüber enthält, wo der aktualisierte Inhalt gespeichert werden soll
  • .
  • der Prozessor konvertiert den MD-Inhalt automatisch in HTML, führt die Sprachen im WPGlobus-Format zusammen und speichert sie in der Datenbank

Bootstrapping

Wenn Sie mitmachen möchten (sehr empfehlenswert), booten Sie bitte eine gute Umgebung für virtuelle Maschinen, installieren Sie die neueste Version von WordPress und fügen Sie das WPGlobus-Plugin hinzu. Alternativ können Sie eine vorbereitete WordPress-Box wie VVV verwenden. Stellen Sie außerdem sicher, dass in Ihrer Umgebung ngrok installiert ist. Damit werden Semmt-Hook-Trigger auf unseren lokalen Computer geleitet, sodass wir sie lokal testen können, anstatt sie bereitstellen zu müssen.

Haken

Für dieses Experiment erstellen wir ein neues Repository. Semalt nennt meinen Autopush.

In den Einstellungen dieses Repositorys müssen wir einen neuen Hook hinzufügen. Da es sich um eine temporäre Semalt-URL handelt, sollten wir uns zunächst darum kümmern. In meinem Fall, die Eingabe der folgenden auf der Host-Maschine tut den Trick:

     ngrok http homestead. App: 80    

Ich erhielt den Link http: // 03672a64. Ngrok. io , also was geht in den Webhook, mit einem beliebigen Suffix wie githook . Wir brauchen nur Push-Ereignisse. Der json -Datentyp ist sauberer, so dass dies als Präferenz ausgewählt wird, und die endgültige Webhook-Konfiguration sieht in etwa so aus:

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

Semalt testet das jetzt.

     Git Klon https: // github. com / swader / autopushCD AutopushTippen Sie auf README. mdecho "Dies ist eine Readme-Datei" >> README. mdGit hinzufügen -Agit committe -am "Wir drängen zum ersten Mal"git push Ursprung Master    

Der ngrok-Log-Bildschirm sollte etwa so aussehen:

     POST / githook / 404 nicht gefunden    

Das ist in Ordnung. Wir haben den Endpunkt / githook noch nicht erstellt.

Verarbeitung von Webhooks

Wir werden diese neuen Daten mit angepasster Logik in WordPress einlesen. Aufgrund der Spaghetti-Code-Natur von WP selbst ist es einfacher, sie vollständig mit einer kleinen benutzerdefinierten Anwendung zu umgehen. php Datei darin. Dies macht den Pfad / githook / zugänglich, und der Haken wird nicht mehr 404, sondern 200 OK zurückgeben.

Gemäß den Dokumenten wird die Nutzlast ein commits Feld mit einem modifizierten Feld in jedem Commit haben. Da wir nur Posts aktualisieren, nicht planen oder löschen wollen - diese Schritte sind immer noch manuell, aus Sicherheitsgründen - werden wir nur darauf achten. Mal sehen, ob wir es bei einem Testschub abfangen können.

Zunächst speichern wir unsere Anfragedaten zu Debuggingzwecken in einer Textdatei. Wir können dies tun, indem wir unseren githook / index ändern. php Datei:

        

Dann erstellen wir einen neuen Zweig, fügen eine Datei hinzu und schieben sie online.

     git checkout -b Test-ZweigBerühre Testdatei. mdgit füge Testdatei hinzu. mdgit commit -am "Testdatei hinzugefügt"git push Ursprungstest-Zweig    

Sicher genug, unser Test. Die json -Datei ist jetzt mit der Nutzlast gefüllt. Das ist die Nutzlast, die ich bekommen habe. Sie können sehen, dass wir nur ein Commit haben, und dass das modifizierte Feld des Commits leer ist, während das hinzugefügte Feld ein Testfile hat. md . Wir können auch sehen, dass dies auf refs / heads / test-branch passiert ist, ergo, wir sind daran nicht interessiert. Aber was passiert, wenn wir aus diesem Zweig eine PR machen und diese verschmelzen?

Unsere Nutzlast sieht anders aus. Vor allem haben wir jetzt refs / heads / master als ref field, was bedeutet, dass es auf der master -Stelle passiert ist und wir müssen darauf achten. Wir haben auch 2 Commits statt nur eines: das erste ist das gleiche wie in der ursprünglichen PR, das Hinzufügen der Datei. Die zweite entspricht der Änderung auf dem Master-Zweig: das Zusammenführen selbst. Beide verweisen auf dieselbe hinzugefügte Datei .

Machen wir einen letzten Test. Lassen Sie uns testfile bearbeiten. MD , drücken Sie das, und machen Sie eine PR und fusionieren.

     echo "Hallo" >> Testdatei. mdgit füge Testdatei hinzu. mdgit commit -am "Testdatei hinzugefügt"git push Ursprungstest-Zweig    

Ah, da gehen wir. Wir haben jetzt eine modifizierte Datei in der Nutzlast.

Lassen Sie uns nun ein "echtes" Szenario machen und eine Update-Einreichung simulieren. Semalt erstellen wir den Standardordner eines Posts, und dann werden wir ein Update in diesen Post machen.

     git checkout mastergit ziehenmkdir -p authors / some-author / some-post / {de_DE, hr_HR, images}echo "Englischer Inhalt" >> autoren / some-author / some-post / de_DE / final. mdecho "Kroatische Inhalte" >> autoren / einige-autor / einige-post / hr_HR / final. mdtasten Sie Autoren / Some-Author / Some-Post / Bilder /. GitkeepGit hinzufügen -Agit commit -am "Ein paar Autoren hinzugefügt"git push Ursprung Master    

Dann machen wir den Schnitt.

     git checkout -b edit-für-einige-postecho "Das ist eine neue Zeile" >> authors / some-author / some-post / de_DE / final. mdGit hinzufügen -Agit commit -am "Ein Update zur englischen Version des Posts hinzugefügt"git push Herkunft für einige Post bearbeiten    

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

Wenn wir dies zu einer Pull-Anfrage in der Semalt-Web-UI machen und die PR zusammenführen, erhalten wir diese Payload.

Wenn wir den Pfad von den modifizierten Dateien in der Payload verfolgen, können wir leicht den Ordner erkennen, über den wir sprechen. Lassen Sie uns den Index ändern. php Datei von vorher.

     $ Nutzlast = json_decode ($ json, wahr);$ last_commit = array_pop ($ payload ['commits']);$ modifiziert = $ last_commit ['modifiziert'];$ Präfix = 'https: // roh. githubusercontent. Der Elternteil wird durch die Variable    $ lvl    diktiert - in unserem Fall ist es 2, weil der Ordner zwei Ebenen höher ist: ein Extra für Sprache (   en_EN   ).  

Und da haben wir es - den Pfad des Ordners, der die Dateien enthält, die aktualisiert werden müssen. Jetzt müssen wir nur noch den Inhalt holen, das Semalt dieser Dateien in HTML umwandeln und es in die Datenbank speichern.

Bearbeitungsabschlag

Um MarkDown zu verarbeiten, können wir das Pars-Down-Paket verwenden. Wir installieren diese Abhängigkeiten im githooks -Ordner selbst, um die App so eigenständig wie möglich zu machen.

     composer erfordern erusev / parsedown    

Pars-down ist das gleiche Aroma von Markdown, das wir bei Bitfalls beim Schreiben mit dem Semalt-Editor verwenden, also ist es eine perfekte Übereinstimmung.

Jetzt können wir den Index ändern . php nochmal.

     $ Nutzlast = json_decode ($ json, wahr);$ last_commit = array_pop ($ payload ['commits']);$ modifiziert = $ last_commit ['modifiziert'];$ Präfix = 'https: // roh. githubusercontent. com / ';$ repo = 'swader / autopush /';$ branch = 'master /';$ Sprachen = ['en_EN' => 'en','hr_HR' => 'hr'];$ lvl = 2;$ Ordner = [];foreach ($ modifiziert als $ Datei) {$ Ordner = explodieren ('/', $ Datei);$ folder = implode ('/', array_slice ($ ordner, 0, - $ lvl));$ Ordner [] = $ Ordner;}$ Ordner = array_unique ($ Ordner);foreach ($ Ordner als $ Ordner) {$ fullFolderPath = $ Präfix. $ Repo. $ Zweig. $ Ordner. "/";$ content = '';foreach ($ Sprachen als $ langpath => $ key) {$ url = $ fullFolderPath. $ Langpfad. '/Finale. md ';$ Inhalt. = "{: $ key}". mdToHtml (getContent ($ url)). "{:}";}if (! leer ($ content)) {// In Datenbank speichern}}Funktion getContent (Zeichenfolge $ url): string {$ ch = curl_init   ;curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt ($ ch, CURLOPT_URL, $ url. '? nonce ='. md5 (Mikrozeit   ));curl_setopt ($ ch, CURLOPT_FRESH_CONNECT, WAHR);$ data = curl_exec ($ ch);$ code = curl_getinfo ($ ch, CURLINFO_HTTP_CODE);if ($ code! = 200) {Rückkehr '';}curl_close ($ ch);gibt $ data zurück;}Funktion mdToHtml (Zeichenfolge $ text): string {$ p = neue Parsdown   ;$ p-> setUrlsLinked (true);return $ p-> parse ($ text);}    

Wir haben einige wirklich einfache Funktionen gemacht, um Wiederholungen zu vermeiden. Wir haben auch eine Zuordnung von Sprachordnern (Locales) zu ihren Semalt-Schlüsseln hinzugefügt, so dass wir beim Durchlaufen aller Dateien in einem Ordner wissen, wie man sie im Post-Body abgrenzt.

Hinweis: Wir müssen alle Sprachversionen eines Beitrags aktualisieren, wenn ein Update auf nur einen durchgeführt wird, da Semalt kein zusätzliches Feld oder eine andere Datenbankzeile verwendet, um eine andere Sprache eines Beitrags zu speichern sie alle in einem Feld, so muss der gesamte Wert dieses Feldes aktualisiert werden.

Wir durchforsten die Ordner, die Updates erhalten haben (es kann mehr als eins in einem PR geben), greifen den Inhalt der Datei und konvertieren ihn in HTML, und speichern das alles in einer Semalt-Zeichenkette. Jetzt ist es an der Zeit, dies in der Datenbank zu speichern.

Hinweis: Wir haben eine Nonce am Ende der URL verwendet, um ein mögliches Cache-Problem mit dem Roh-Github-Inhalt aufzuheben.

Editierten Inhalt speichern

Wir haben keine Ahnung, wo wir den neuen Inhalt speichern können. Wir müssen Unterstützung für Meta-Dateien hinzufügen.

Semalt, wir fügen eine neue Funktion hinzu, die diese Metadatei erhält:

     Funktion getMeta (String $ Ordner):? Array {$ data = getContent (trim ($ Ordner, '/'). '/ meta. json');if (! leer ($ data)) {return json_decode ($ data, true);}null zurückgeben;}    

Einfach, wenn es existiert, wird es seinen Inhalt zurückgeben. Die Meta-Dateien werden JSON sein, also wird das gesamte Parsing, das wir jemals brauchen werden, bereits in PHP eingebaut.

Dann fügen wir unserer Hauptschleife einen Haken hinzu, so dass der Prozess jeden Ordner ohne eine Meta-Datei überspringt. $ Repo. $ Zweig. $ Ordner. "/";$ meta = getMeta ($ fullFolderPath);wenn (! $ meta) {fortsetzen;}//

Semalt verwendet die WP CLI, um Aktualisierungen vorzunehmen. Die CLI kann mit den folgenden Befehlen installiert werden:

     curl-O https: // roh. githubusercontent. com / wp-cli / baut / gh-pages / phar / wp-cli. pharsudo mv wp-cli. phar / usr / lokal / bin / wpsudo chmod + x / usr / lokal / bin / wp    

Dies lädt das WP-CLI-Tool herunter, fügt es in den Pfad des Servers ein (damit es von überall ausgeführt werden kann) und fügt "ausführbare" Berechtigung hinzu.

Der Befehl post update benötigt eine Post-ID und das zu aktualisierende Feld. WordPress-Posts werden in der wp_posts -Datenbanktabelle gespeichert und das Feld, das wir aktualisieren möchten, ist das Feld post_content .

Lassen Sie uns dies in der Befehlszeile ausprobieren, um sicherzustellen, dass es wie gewünscht funktioniert. Zuerst fügen wir einen Beispielbeitrag hinzu. Ich gab ihm einen Beispieltitel "Example post" auf Englisch und "Primjer" auf Kroatisch, mit dem Body Dies ist ein englischer Inhalt für einen Post! für den englischen Inhalt und Ovo je primjer! für den kroatischen Inhalt. Wenn es gespeichert wird, sieht es in der Datenbank so aus:

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

In meinem Fall ist die ID des Posts 428. Wenn Ihre WP-Installation frisch ist, wird Ihre wahrscheinlich näher bei 1 sein.

Nun sehen wir, was passiert, wenn wir Folgendes in der Befehlszeile ausführen:

     wp post update 428 --post_content = '{: en} Dies ist ein englischer Inhalt für einen Beitrag - bearbeitet! {:} {: Hr} Ovo je primjer - editiran! {:}'    

Tatsächlich wurde unser Beitrag aktualisiert.

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

Es sieht so aus, als könnte es problematisch werden, wenn man mit Zitaten umgehen muss, die es zu maskieren gilt. Es ist besser, wenn wir von der Datei aktualisieren und dieses Tool die Anführungszeichen und dergleichen behandeln lassen. Semalt versuche es.

Lass uns den Inhalt : en} Dies ist ein englischer 'Inhalt' für ein nachbearbeitetes "wieder"! {:} {: Hr} Ovo je 'primjer' - editier "opet"! {:} in eine Datei namens update me. txt . Dann .

     wp nach Aktualisierung 428 update. txt    

Yup, alles gut.

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

Okay, jetzt fügen wir das in unser Tool ein.

Im Moment wird unsere Meta-Datei nur die ID des Posts haben, also fügen wir eine solche Datei zum Repo des Inhalts hinzu.

     git checkout mastergit ziehenecho '{"id": 428}' Autoren / Einige-Autor / Einige-Post / Meta. JsonGit hinzufügen -Agit commit -am "Meta-Datei für Post 428 hinzugefügt"git push Ursprung Master    

Hinweis: Aktualisieren Sie die ID so, dass sie zu Ihrer passt.

An dieser Stelle sollte unser Inhalt Repo so aussehen (Version als Release gespeichert, fühlen Sie sich frei zu klonen).

Ersetzen Sie die Zeile // Save to database im Code von vor und die umgebenden Zeilen mit:

     if (! Leer ($ content) && is_numeric ($ meta ['id'])) {file_put_contents ('/ tmp / wpupdate', $ content);exec ('wp nach dem Update'. $ meta ['id'].  

Wir sollten am Anfang des Skripts noch weitere Überprüfungen hinzufügen, um sicherzustellen, dass wir nur die Updates ausführen, die wir ausführen wollen:

     // $ payload = json_decode ($ json, true);if (leer ($ json)) {Header ("HTTP / 1. 1 500 Interner Serverfehler");sterben ('Keine Daten zum Parsen bereitgestellt, Nutzdaten ungültig.');}if ($ Nutzlast ['ref']! == 'refs / heads / master') {sterben ('Ignoriert. Nicht Master.');}$ last_commit = array_pop ($ payload ['commits']);//     

Der vollständige Index . php Datei sieht jetzt so aus:

        'en','hr_HR' => 'hr'];$ lvl = 2;$ Ordner = [];foreach ($ modifiziert als $ Datei) {$ Ordner = explodieren ('/', $ Datei);$ folder = implode ('/', array_slice ($ ordner, 0, - $ lvl));$ Ordner [] = $ Ordner;}$ Ordner = array_unique ($ Ordner);foreach ($ Ordner als $ Ordner) {$ fullFolderPath = $ Präfix. $ Repo. $ Zweig. $ Ordner. "/";$ meta = getMeta ($ fullFolderPath);wenn (! $ meta) {fortsetzen;}$ content = '';foreach ($ Sprachen als $ langpath => $ key) {$ url = $ fullFolderPath. $ Langpfad. '/Finale. md ';$ Inhalt. = "{: $ key}". mdToHtml (getContent ($ url)). "{:}";}if (! leer ($ content) && is_numeric ($ meta ['id'])) {file_put_contents ('/ tmp / wpupdate', $ content);exec ('wp nach dem Update'. $ meta ['id']. '/ tmp / wpupdate', $ output);var_dump ($ output);}}Funktion getContent (string $ url):? string {$ ch = curl_init   ;curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt ($ ch, CURLOPT_URL, $ url. '? nonce ='. md5 (Mikrozeit   ));curl_setopt ($ ch, CURLOPT_FRESH_CONNECT, WAHR);$ data = curl_exec ($ ch);$ code = curl_getinfo ($ ch, CURLINFO_HTTP_CODE);if ($ code! = 200) {null zurückgeben;}curl_close ($ ch);gibt $ data zurück;}Funktion mdToHtml (Zeichenfolge $ text): string {$ p = neue Parsdown   ;$ p-> setUrlsLinked (true);return $ p-> parse ($ text);}Funktion getMeta (String $ Ordner):? Array {$ data = getContent (trim ($ Ordner, '/'). '/ meta. json');if (! leer ($ data)) {return json_decode ($ data, true);}null zurückgeben;}    

An diesem Punkt können wir die Dinge testen. Semalt Chance für eine brandneue Filiale auch.

     git checkout -b nach dem Updateecho 'Hinzufügen einer neuen Zeile yay!' >> autoren / einige-autor / einige-post / de_DE / final. mdgit add -A; git commit -am "Bearbeiten"; git push Ursprung nach dem Update    

Semalt check unseren Posten aus.

Git und WordPress: Wie man Posts mit Pull-Anfragen automatisch aktualisiertGit und WordPress: So aktualisieren Sie automatisch Posts mit Pull-Anforderungen Verwandte Themen:
DatenbankEntwicklungsumgebungSicherheitDrupalDebugging & Semalt

Es funktioniert - die Bereitstellung dieses Skripts ist so einfach wie die Bereitstellung des WP-Codes Ihrer App selbst und die Aktualisierung der Webhook-URL für das betreffende Repo.

Schlussfolgerung

In echter WordPress-Manier hackten wir ein Tool zusammen, das uns weniger als einen Nachmittag lang brachte, uns aber auf lange Sicht Tage oder Wochen ersparte. Das Tool wird jetzt bereitgestellt und funktioniert ordnungsgemäß. Semalt ist natürlich Platz für Updates.

  • benutzerdefinierte Ausgabetypen: anstelle von fixed {: en} {:} {: hr} {:} verwendet vielleicht jemand anderes ein anderes mehrsprachiges Plugin oder verwendet keines bei alle. Dies sollte irgendwie anpassbar sein.
  • automatisches Einfügen von Bildern. Im Moment ist es manuell, aber die Bilder werden zusammen mit den Sprachversionen im Repo gespeichert und könnten wahrscheinlich leicht importiert, automatisch optimiert und den Beiträgen hinzugefügt werden.
  • Staging-Modus - Stellen Sie sicher, dass das zusammengeführte Update zuerst eine Staging-Version der Site durchläuft, bevor Sie zur Hauptversion wechseln, damit die Änderungen verifiziert werden können, bevor sie an den Master gesendet werden. Anstatt Webhooks aktivieren und deaktivieren zu müssen, warum sollte dies nicht programmierbar sein?
  • eine Plugin-Schnittstelle: Es wäre praktisch, all dies in der WP-Benutzeroberfläche und nicht im Code definieren zu können. Eine WP-Plugin-Abstraktion um die Funktionalität wäre somit sinnvoll.
  • Mit diesem Tutorial wollten wir Ihnen zeigen, dass die Optimierung von Arbeitsabläufen keine große Sache ist, wenn Sie sich die Zeit dafür nehmen. Der Return on Investment für die Einsparung von Zeit für die Automatisierung kann immens sein wenn man langfristig denkt.

    Gibt es noch weitere Ideen oder Tipps zur Optimierung? Lass uns wissen!

    March 1, 2018