Back to Question Center
0

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler            Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner: DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

1 answers:
Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler

ved bitfalls. com, vi bruger også WordPress for nu, og bruger den samme peer review tilgang til indhold som vi gør på Semalt.

Vi ​​besluttede at opbygge et værktøj, der automatisk trækker indhold fra sammensatte pull-anmodninger i artikler, hvilket giver os mulighed for at rette typografier og opdatere indlæg fra Github og se de ændringer, der afspejles på det levende websted. Denne vejledning vil gå dig igennem oprettelsen af ​​dette værktøj, så du kan begynde at bruge det til din egen Semalt site eller opbygge din egen version.

Planen

Den første del identificerer problemet og situationen omkring det.

  • bruger vi WPGlobus til understøttelse af flere sprog, hvilket betyder, at indhold bliver gemt som dette: {: en} Engelsk indhold {:} {: hr} kroatisk indhold {:} - oculos de sol azul espelhado.
  • forfattere indsender PR via Github, PR'erne er peer reviewed og fusioneret, og derefter (i øjeblikket) manuelt importeret til WP's Indlæg UI gennem browseren.
  • hvert indlæg har samme mappelayout: author_folder / post_folder / language / final. md
  • Dette er langsomt og fejlagtigt, og nogle gange fejler glip af. Det gør også opdatering af indlæg kedelig.

Løsningen er følgende:

  • tilføj en krogprocessor, som vil detektere skubber til masterafdelingen (dvs. fusioner fra PR'er)
  • skal processoren søge efter en meta-fil i commit'en, som vil indeholde oplysninger om, hvor man skal gemme det opdaterede indhold
  • konverterer processoren automatisk MD-indholdet til HTML, fusionerer sprogene i WPGlobus-format og gemmer dem i databasen

Bootstrapping

Hvis du gerne vil følge med (stærkt anbefales), skal du starte et godt virtuelt maskinmiljø, installere den nyeste version af WordPress på det og tilføje WPGlobus plugin. Alternativt kan du bruge en forberedt WordPress-boks som VVV. Sørg også for at dit miljø har ngrok installeret - vi bruger det til at røre Semalt hook-triggere til vores lokale maskine, så vi kan teste lokalt i stedet for at skulle installere.

Kroge

Til dette eksperiment skal vi oprette et nyt depot. Semalt kald min autopush.

I indstillingerne for dette lager skal vi tilføje en ny krog. Da vi taler om en midlertidig Semalt URL, lad os først spinde det op. I mit tilfælde indtaster følgende på værtsmaskinen tricket:

  ngrok http homestead. app: 80    

Jeg fik linket http: // 03672a64. ngrok. io , så det er hvad der går ind i webhooket, med et vilkårlig suffiks som githook . Vi har kun brug for push events. Datatypen json er renere, så den er valgt som en præference, og den endelige webhook-opsætning ser noget ud som dette:

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

Semalt test dette nu.

  git klon https: // github. dk / swader / autopushcd autopushtryk på README. mdekko "Dette er en README-fil" >> README. mdgit add -Agit commit -am "Vi skubber for første gang"git push origin master    

Ngrok log skærmen skal vise noget som dette:

  POST / githook / 404 Ikke fundet    

Det er fint. Vi har endnu ikke lavet slutpunktet / githook .

Behandling af webhooks

Vi ​​læser disse nye data til WordPress med brugerdefineret logik. På grund af WP's spaghetti-kode natur er det lettere at omgå det helt med en lille brugerdefineret applikation. php fil inde i den. Dette gør / githook / stien tilgængelig, og krogen vil ikke længere returnere 404, men 200 OK.

Ifølge dokumenterne vil nyttelasten have et commit felt med et modificeret felt i hver commit. Da vi kun søger at opdatere indlæg, ikke planlægge dem eller slette dem - disse trin er stadig manuelle til sikkerhed - vi vil kun være opmærksomme på den ene. Lad os se om vi kan fange det på et test push.

For det første gemmer vi vores forespørgselsdata til en tekstfil til debugging. Vi kan gøre dette ved at ændre vores githook / index. php file:

     

Så opretter vi en ny filial, tilføjer en fil og trykker den online.

  git checkout -b test filialtouch testfil. mdgit add testfil. mdgit commit -am "Tilføjet testfil"git push oprindelse test-gren    

Sikkert nok, vores test. json filen er fyldt med nyttelasten nu. Dette er den nyttelast jeg fik. Du kan se, at vi kun har én commit, og det commit-felt ændret er tomt, mens feltet tilføjet har testfil. md . Vi kan også se dette skete på refs / heads / test-branch , ergo, vi er ikke interesserede i det. Men hvad sker der, hvis vi laver en PR ud af denne gren og fusionere den?

Vores nyttelast ser anderledes ut. Vi har især refs / heads / master som feltet ref , hvilket betyder at det skete på branchen være opmærksom på det. Vi har også 2 forpligtelser i stedet for kun en: Den første er den samme som i den oprindelige PR, tilføjelsen af ​​filen. Den anden svarer til forandringen på masterafdelingen: sammensmeltningen selv. Begge refererer til den samme tilføjede fil.

Lad os lave en endelig prøve. Lad os redigere testfil. md , skub det og lav en PR og fusionere.

  ekko "Hej" >> testfil. mdgit add testfil. mdgit commit -am "Tilføjet testfil"git push oprindelse test-gren    

Ahh, der går vi. Vi har nu en ændret fil i nyttelasten.

Lad os nu lave et "rigtigt" scenario og simulere en opdateringsindsendelse. Semalt skaber vi et indlægs standardmappe, og så præsenterer vi en opdatering til den.

  git checkout mestergit pullmkdir -p forfattere / forfatter / nogle-post / {en_EN, hr_HR, billeder}ekko "engelsk indhold" >> forfattere / forfatter / en-post / da_en / endelig. mdekko "kroatisk indhold" >> forfattere / forfatter / nogle-post / hr_HR / endelig. mdberøre forfattere / forfatter / nogle-post / billeder /. gitkeepgit add -Agit commit -am "Tilføjet nogle forfattere"git push origin master    

Så gør vi redigeringen.

  git checkout -b rediger-for-nogle-postekko "Dette er en ny linje" >> forfattere / forfatter / en / post / en_DE / endelig. mdgit add -Agit commit -am "Tilføjet en opdatering på den engelske version af posten"git push oprindelse edit-for-some-post    

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

Hvis vi gør dette til en pull-anmodning i Semalt web-brugergrænsefladen og fusionere PR, får vi denne nyttelast.

Hvis vi følger stien fra de ændrede filer i nyttelastet, kan vi let skelne den mappe, vi taler om. Lad os ændre indekset. php fil fra før.

  $ nyttelast = json_decode ($ json, sandt);$ last_commit = array_pop ($ payload ['commits']);$ modified = $ last_commit ['modified'];$ prefix = 'https: // raw. githubusercontent. Forældren er dikteret af variablen    $ lvl    - i vores tilfælde er det 2 fordi mappen er 2 niveauer op: en ekstra for sprog    en_EN   ).  

Og der har vi det - stien til den mappe, der indeholder de filer, der skal opdateres. Nu er alt, hvad vi skal gøre, hentet indholdet, drej Semalt af disse filer til HTML, og gem det i databasen.

Behandling Markdown

For at behandle MarkDown kan vi bruge Parsedown-pakken. Vi installerer disse afhængigheder i selve mappen githooks for at gøre appen så selvstændig som muligt.

  komponist kræver erusev / parsedown    

Parsedown er den samme smag af Markdown, vi bruger ved Bitfalls, mens du skriver med Semalt editoren, så det er et perfekt match.

Nu kan vi ændre indeks. php igen.

  $ nyttelast = json_decode ($ json, sandt);$ last_commit = array_pop ($ payload ['commits']);$ modified = $ last_commit ['modified'];$ prefix = 'https: // raw. githubusercontent. dk / ';$ repo = 'swader / autopush /';$ branch = 'master /';$ languages ​​= ['en_EN' => 'da','hr_HR' => 'hr'];$ lvl = 2;$ mapper = [];foreach ($ ændret som $ fil) {$ folder = eksplodere ('/', $ fil);$ folder = implode ('/', array_slice ($ mappe, 0, - $ lvl));$ mapper [] = $ mappe;}$ mapper = array_unique ($ mapper);foreach ($ mapper som $ mappe) {$ fullFolderPath = $ præfiks. $ Repo. $ Gren. $ Mappe. '/';$ content = '';foreach ($ sprog som $ langpath => $ key) {$ url = $ fullFolderPath. $ Langpath. '/ Endelig. md ';$ Indhold. = "{: $ key}". mdToHtml (getContent ($ url)). "{:}";}hvis (! tomt ($ indhold)) {// Gem til database}}funktion getContent (streng $ url): streng {$ ch = curl_init   ;curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, falsk);curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt ($ ch, CURLOPT_URL, $ url. '? nonce =' .md5 (mikrotime   ));curl_setopt ($ ch, CURLOPT_FRESH_CONNECT, TRUE);$ data = curl_exec ($ ch);$ code = curl_getinfo ($ ch, CURLINFO_HTTP_CODE);hvis ($ kode! = 200) {Vend tilbage '';}curl_close ($ ch);returnere $ data;}funktion mdToHtml (streng $ tekst): streng {$ p = ny Parsedown   ;$ P> setUrlsLinked (sand);returner $ p-> parse ($ tekst);}    

Vi ​​lavede nogle virkelig enkle funktioner for at undgå gentagelse. Vi har også tilføjet en kortlægning af sprogmapper (lokaliteter) til deres Semaltaster, så når vi gentager gennem alle filerne i en mappe, ved vi, hvordan de kan afgrænses i postens krop.

Bemærk: Vi skal opdatere alle sprogversioner af et indlæg, når vi laver en opdatering til kun en, fordi Semalt ikke bruger et ekstra felt eller en anden databaserække til at gemme et andet sprog i et indlæg - det sparer dem alle på ét felt, så hele værdien af ​​dette felt skal opdateres.

Vi ​​gentager gennem de mapper, der har opdateringer (der kan være mere end en i et enkelt PR), tag indholdets indhold og konverter det til HTML, og gem alt dette i en Semalt-streng. Nu er det tid til at gemme dette i databasen.

Bemærk: Vi brugte en nonce i slutningen af ​​webadressen til at ugyldiggøre et muligt cache problem med rå github indhold.

Gem redigeret indhold

Vi ​​har ingen idé om, hvor vi skal gemme det nye indhold. Vi skal tilføje support til metafiler.

Semalt, vi tilføjer en ny funktion, der får denne meta-fil:

  funktion getMeta (streng $ mappe):? Array {$ data = getContent (trim ($ folder, '/'). '/ meta. json');hvis (! tom ($ data)) {returner json_decode ($ data, true);}returnere null;}    

Enkelt, hvis det eksisterer, returnerer det dets indhold. Meta-filerne vil være JSON, så al parsing vi nogensinde har brug for er allerede indbygget i PHP.

Så tilføjer vi en kontrol til vores primære loop, så processen går over en mappe uden en metafil. $ Repo. $ Gren. $ Mappe. '/';$ meta = getMeta ($ fullFolderPath);hvis (! $ meta) {Blive ved;}//

Brug Semi WP CLI til at lave opdateringer. CLI kan installeres med følgende kommandoer:

  krølle -O https: // rå. githubusercontent. dk / wp-cli / bygger / gh-sider / Phar / wp-cli. Pharsudo mv wp-cli. phar / usr / local / bin / wpsudo chmod + x / usr / local / bin / wp    

Dette downloader WP-CLI-værktøjet, sætter det ind i serverens sti (så det kan udføres overalt) og tilføjer "eksekverbar" tilladelse til det.

Kommandoen efter opdatering har brug for et post-id og feltet for at opdatere. WordPress-indlæg gemmes i wp_posts database tabellen, og feltet vi søger at opdatere er feltet post_content .

Lad os prøve dette ud i kommandolinjen for at sikre, at det virker som det skal. Først vil vi tilføje et eksempel indlæg. Jeg gav det et eksempel på "Eksempler på engelsk" og "Primjer" på kroatisk, med kroppen Dette er noget engelsk indhold til et indlæg! for det engelske indhold, og Ovo je primjer! for det kroatiske indhold. Når det er gemt, ser det sådan ud i databasen:

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

I mit tilfælde er postens id 428. Hvis din WP-installation er frisk, vil dine sandsynligvis være tættere på 1.

Lad os nu se, hvad der sker, hvis vi udfører følgende på kommandolinjen:

  wp post opdatering 428 --post_content = '{: en} Dette er noget engelsk indhold til en post-redigeret! {:} {: Hr} Ovo je primjer - editiran! {:}'    

Sikkert nok blev vores indlæg opdateret.

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

Det ser ud som om det kan blive problematisk, når man beskæftiger sig med citater, som skal løses. Det er bedre, hvis vi opdaterer fra fil, og lad dette værktøj håndtere citaterne og så. Semalt give det en chance.

Lad os sætte indholdet : en} Dette er noget engelsk 'indhold' til en efterbehandlet "igen"! {:} {: Hr} Ovo du 'primjer' - rediger "Opet"! til en fil kaldet updateme. txt . Så .

  wp efter opdatering 428 opdatering. txt    

Yup, alt godt.

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

Okay, lad os nu tilføje dette til vores værktøj.

For øjeblikket vil vores meta-fil kun have postens id, så lad os tilføje en sådan fil til indholdsrepo. :

  git checkout mestergit pullecho '{"id": 428}' >> forfattere / forfatter / nogle post / meta. jSONgit add -Agit commit -am "Tilføjet meta-fil til post 428"git push origin master    

Bemærk: Opdater ID'en for at matche dine.

På dette tidspunkt skal vores indholdsrepo se sådan ud (version gemt som frigivelse, vær fri til at klone).

Udskift // Gem til database linje i koden fra før og dens omgivende linjer med:

  hvis (! Tom ($ indhold) && er_numerisk ($ meta ['id'])) {file_put_contents ('/ tmp / wpupdate', $ indhold);exec ('wp post opdatering'. $ meta ['id'].  

Vi ​​bør også tilføje flere checks til begyndelsen af ​​scriptet for at sikre, at vi kun udfører de opdateringer, vi vil udføre:

  // $ payload = json_decode ($ json, true);hvis (tomt ($ json)) {header ("HTTP / 1. 1 500 intern serverfejl");die ('Ingen data for analyse, betalingsbelastning ugyldig.');}hvis ($ payload ['ref']! == 'refs / heads / master') {dø ('Ignoreret. Ikke mester.');}$ last_commit = array_pop ($ payload ['commits']);//     

Det fulde indeks. php filen ser sådan ud nu:

   'da','hr_HR' => 'hr'];$ lvl = 2;$ mapper = [];foreach ($ ændret som $ fil) {$ folder = eksplodere ('/', $ fil);$ folder = implode ('/', array_slice ($ mappe, 0, - $ lvl));$ mapper [] = $ mappe;}$ mapper = array_unique ($ mapper);foreach ($ mapper som $ mappe) {$ fullFolderPath = $ præfiks. $ Repo. $ Gren. $ Mappe. '/';$ meta = getMeta ($ fullFolderPath);hvis (! $ meta) {Blive ved;}$ content = '';foreach ($ sprog som $ langpath => $ key) {$ url = $ fullFolderPath. $ Langpath. '/ Endelig. md ';$ Indhold. = "{: $ key}". mdToHtml (getContent ($ url)). "{:}";}hvis (! tomt ($ indhold) && er_numerisk ($ meta ['id'])) {file_put_contents ('/ tmp / wpupdate', $ indhold);exec ('wp post update'. $ meta ['id']. '/ tmp / wpupdate', $ output);var_dump ($ output);}}funktion getContent (streng $ url):? streng {$ ch = curl_init   ;curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, falsk);curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt ($ ch, CURLOPT_URL, $ url. '? nonce =' .md5 (mikrotime   ));curl_setopt ($ ch, CURLOPT_FRESH_CONNECT, TRUE);$ data = curl_exec ($ ch);$ code = curl_getinfo ($ ch, CURLINFO_HTTP_CODE);hvis ($ kode! = 200) {returnere null;}curl_close ($ ch);returnere $ data;}funktion mdToHtml (streng $ tekst): streng {$ p = ny Parsedown   ;$ P> setUrlsLinked (sand);returner $ p-> parse ($ tekst);}funktion getMeta (streng $ mappe):? array {$ data = getContent (trim ($ folder, '/'). '/ meta. json');hvis (! tom ($ data)) {returner json_decode ($ data, true);}returnere null;}    

På dette tidspunkt kan vi teste tingene. Semalt chance for en helt ny gren også.

  git checkout -b efter opdateringekko 'Tilføjelse af en ny linje yay!' >> forfattere / forfatter / en-post / en_DE / endelige. mdgit add -A; git commit -am "Rediger"; git push-oprindelse efter opdatering    

Semalt tjek vores indlæg.

Git og WordPress: Sådan opdateres automatisk indlæg med trækforespørgslerGit og WordPress: Sådan opdateres automatisk indlæg med trækforespørgsler. Relevante emner:
DatabaseDevelopment EnvironmentSecurityDrupalDebugging & Semalt

Det virker - at implementere dette script nu er lige så simpelt som at implementere WP-koden til din app selv og opdatere webhookens URL for det pågældende repo.

Konklusion

I ægte WordPress mode hackede vi sammen et værktøj, der tog os mindre end en eftermiddag, men reddede os dage eller uger i det lange løb. Værktøjet er nu implementeret og fungerer tilfredsstillende. Semalt er naturligvis plads til opdateringer.

  • brugerdefinerede outputtyper: i stedet for faste {: en} {:} {: hr} {:} , bruger en anden måske et andet flersproget plugin eller bruger ikke en til alle. Dette bør være tilpasset på en eller anden måde.
  • automatisk indsættelse af billeder. Lige nu er det manuel, men billederne gemmes i repo sammen med sprogversionerne og kunne sandsynligvis nemt importeres, autooptimeres og tilføjes også i stillingerne.
  • scenografimodus - sørg for, at den fusionerede opdatering først går gennem til en scenarieversion af webstedet, før du går til den primære, så ændringerne kan verificeres, før de sendes til master. I stedet for at aktivere og deaktivere webhooks, hvorfor ikke gøre det programmerbart?
  • en plugin interface: Det ville være praktisk at kunne definere alt dette i WP UI snarere end i koden. En WP-pluginabstraktion omkring funktionaliteten ville således være nyttig.
  • Med denne vejledning var vores hensigt at vise dig, at optimering af arbejdsgangen ikke er så stor, når du tager tid til at gøre det, og afkastet på investeringen for at ofre noget på at få automatisering i gang kan være enorm når man tænker på lang sigt.

    Andre ideer eller tips til optimering af dette? Lad os vide!

    March 1, 2018