Subscribe to PHP Freaks RSS

Git and WordPress: How to Auto-Update Posts with Pull Requests

syndicated from www.sitepoint.com on October 18, 2017

At Bitfalls.com, we also use WordPress for now, and use the same peer review approach for content as we do at SitePoint.

We decided to build a tool which automatically pulls content from merged pull requests into articles, giving us the ability to fix typos and update posts from Github, and see the changes reflected on the live site. This tutorial will walk you through the creation of this tool, so you can start using it for your own WordPress site, or build your own version.

The Plan

The first part is identifying the problem and the situation surrounding it.

  • we use WPGlobus for multi-language support, which means content gets saved like this: {:en}English content{:}{:hr}Croatian content{:}.
  • authors submit PRs via Github, the PRs are peer reviewed and merged, and then (currently) manually imported into WP's Posts UI through the browser.
  • every post has the same folder layout: author_folder/post_folder/language/final.md
  • this is slow and error prone, and sometimes mistakes slip by. It also makes updating posts tedious.

The solution is the following:

  • add a hook processor which will detect pushes to the master branch (i.e. merges from PRs)
  • the processor should look for a meta file in the commit which would contain information on where to save the updated content
  • the processor automatically converts the MD content to HTML, merges the languages in the WPGlobus format, and saves them into the database

Bootstrapping

If you'd like to follow along (highly recommended), please boot up a good virtual machine environment, install the newest version of WordPress on it, and add the WPGlobus plugin. Alternatively, you can use a prepared WordPress box like VVV. Additionally, make sure your environment has ngrok installed - we'll use that to pipe Github hook triggers to our local machine, so we can test locally instead of having to deploy.

Hooks

For this experiment, let's create a new repository. I'll call mine autopush.

In the settings of this repository, we need to add a new hook. Since we're talking about a temporary Ngrok URL, let's first spin that up. In my case, entering the following on the host machine does the trick:

ngrok http homestead.app:80

I was given the link http://03672a64.ngrok.io, so that's what goes into the webhook, with an arbitrary suffix like githook. We only need push events. The json data type is cleaner, so that's selected as a preference, and the final webhook setup looks something like this:

Webhook setup

Let's test this now.

git clone https://github.com/swader/autopush
cd autopush
touch README.md
echo "This is a README file" >> README.md
git add -A
git commit -am "We're pushing for the first time"
git push origin master

The ngrok log screen should display something like this:

POST /githook/                  404 Not Found

This is fine. We haven't made the /githook endpoint yet.

Processing Webhooks

We'll read this new data into WordPress with custom logic. Due to the spaghetti-code nature of WP itself, it's easier to circumvent it entirely with a small custom application. First, we'll create the githook folder in the WordPress project's root, and an index.php file inside it. This makes the /githook/ path accessible, and the hook will no longer return 404, but 200 OK.

According to the docs, the payload will have a commits field with a modified field in each commit. Since we're only looking to update posts, not schedule them or delete them - those steps are still manual, for safety - we'll only be paying attention to that one. Let's see if we can catch it on a test push.

First, we'll save our request data to a text file, for debugging purposes. We can do this by modifying our githook/index.php file:

<?php
file_put_contents('test.txt', file_get_contents('php://input'));

Then we'll create a new branch, add a file, and push it online.

git checkout -b test-branch
touch testfile.md
git add testfile.md
git commit -am "Added test file"
git push origin test-branch

Sure enough, our test.json file is filled with the payload now. This is the payload I got. You can see that we have only one commit, and that commit's modified field is empty, while the added field has testfile.md. We can also see this happened on refs/heads/test-branch, ergo, we're not interested in it. But what happens if we make a PR out of this branch and merge it?

Continue reading %Git and WordPress: How to Auto-Update Posts with Pull Requests%