FEEDBACK FROM MATTHEW (29 March 2019)
Excellent. As you note, the new editor (Gutenberg) that is built into the latest version of WordPress is itself built using React, and the Editor blocks that people [including yourselves] will write will be written in React. So within a year or so, knowledge of this approach will be quite in demand.
Your write-up is very clear, and although part of it is straight factual, it is pleasing you have related it to the PCP project. This helps in two ways: it demonstrated that your writing in indeed original to you; it helps readers in the class see that this topic is indeed highly applicable to our current studies.
Mark : Not written here. Please see Blackboard.
What is React and Why Should We Use It?
WP-Reactivate is a plugin boiler plate which allows us to embed React into three separate WordPress views – Admin (React embedded within the Admin Dashboard), Widget (React embedded within a Widget) and lastly Short-code which allow us to embed React into any page or post via a unique ID which is enclosed between opening and closing [brackets].
Using WP-Reactivate means you do not have to deal with the headache of Babel and Webpack or the pain of setting up all the config for your project – instead you are given a clean slate which you can cd into, npm start and get started building components using familiar React code.
You can download the zip of the WP-Reactivate repository or fork the project from here: https://github.com/gopangolin/wp-reactivate
File Structure Breakdown
Like most WordPress plugins, WP-Reactivate is composed of various PHP, JS files and CSS Stylesheets. The PHP files allow us to communicate with the back-end of the site and carry out functionalities such as writing to the database, activating/making changes to the plugins and setting up REST API endpoints.
The JS (and JSX) files act as the view and logic of what we see within the front-end. We define JSX tags in our return statements of each necessary React container (Admin, Shortcode, Wiget) and embed data within these tags which we want the user to see. Within the React front end, we can make HTTP calls to the exposed wp-json back-end which allows us to work with data of our WordPress sites dynamically.
The PHP Part
The includes/endpoint folder is where the code which sets up our REST endpoints live. WP-Reactivate comes equipped with a PHP function named register_rest_route() which does exactly what it says on the tin – it allows you to pass in your namespace, desired endpoint URL along with an array full of all the necessary details, validation of what data can be entered and from all the data passed, it creates a brand new shiny endpoint for you to call over REST. All of the routes you register are stored inside a public register_routes function, this helps you contain all of your endpoints in an easy to read place. Typically you will have 4 routes for each setting – READABLE (Makes endpoint viewable over REST), CREATABLE (Can create a new piece of data over REST), EDITABLE (Edit endpoint over REST using POST(ed) data) and DELETABLE (remove the endpoint data completely and leave blank). Although this may vary depending on needs. Below is a quick example of my READABLE and CREATABLE endpoints used to register a title for our plugin:
The React Part – Shortcode.jsx
WP-Reactivate by default gives us access to it’s own fetchWP() function which is used to call our newly created endpoints. Within any container of your choice, you can create a new instance of the fetchWP class (located within utils/fetchWP.js) and pass it the relevant object parameter using the restURL and restNonce values we get from props. The nonce acts as authentication so we can assure only the site itself is making and editing changes over REST.
Once a new instance has been created, we can then call the get() method on fetchWP and pass the endpoint String you created within the endpoint PHP file. For the example below, we are just setting state with the data we get back, whether that is the actual data we need, or an error we catch due to the API call failing.
As WordPress exposes its back-end using wp-json, we can make queries from the front-end to existing WordPress data and render whatever we like within the React container. In the project for our client we decided to do this for Posts as we wanted to customise the way in which posts were displayed and manipulated within our App. We used multiple GET requests to achieve this, the request below demonstrates how we got a parent category name using an ID.
Once we have setState() with our endpoint and wp-json data, we can then drill down in the state object of React and get the data out which we need. It’s a good idea to break your project down into separate React components, that way you can reuse code and make your projects much easier to read when you need to come back and change something. If you decide to split a container into separate components (just like I do in this example for <AllPosts />) then you can pass down the data which we stored into our containers state by adding props onto the component which will give you access to the data to use within your child component.
The React Part – Admin.jsx
So far we have created our own endpoints in PHP and we have hooked up these endpoints to the front-end so we can render data from the back-end to the user. However there still is a piece of the puzzle left – how do we allow logged in users to make changes to the plugin? How can they configure their own settings? The answer is the Admin.jsx Container.
As briefly mentioned at the start, Admin.jsx is a view contained within the dashboard of WordPress. We can write something like the below to create a form which the user will see:
For now, all we are returning is a single input which we have hooked up to fire the updateSettingsInput() handler when the element text is changed. I really like this handler as it allows us to create a second <input /> and all we have to change is the placeholder, value and name of the element, we don’t have to write another handler function to run onChange of the second input.
Once we have dealt with updating the state of our form elements, we can then create a function such as updateTitleSetting() above which will POST the data over our REST endpoints to the PHP back-end. Until this point if we refreshed the page, we would be greeted with exactly the same data as before because nothing would have been POST(ed). Realistically and depending on your settings requirement you will also need functions which get the current settings, delete the current settings and create new settings. Whatever you defined at the start of this post when creating the endpoint attributes in PHP(CREATEABLE, EDITABLE etc) is what you will be calling within these functions inside the Admin.jsx container.
Tips & Gotchas
- As of WordPress v5, Gutenberg blocks and the Gutenberg editor are now available for us to use. The Gutenberg editor is written in React, which means we can utilise the power and speed of React to create our own blocks which users can configure. The downside to Gutenblocks is that React is only present within the editor, while everything which is configured when using the editor is stored into the database as HTML code. This means that the end users don’t get the benefit of the speed and usability which React offers, however it does allow the users of the page/post editor to get this benefit. When planning and designing your plugin use cases, it is important you decide whether you need React to display within the front-end or if you just need static HTML elements created using a robust visual designer. Another example from our clients project was a deliverable which said the “new post” feature needs to be as simple and intuitive as possible. Therefore we decided to use create-guten-block to allow a non techy user to create a new post using predefined elements. Our custom block only posts what is needed/entered by the user to the database, E.g if a user doesn’t add a Facebook URL of the project within the new post block, then it doesn’t render the Facebook icon with the relevant wrapping <a> tag in the front-end. As a little aside, we achieved this by using the code below where a ternary expression checks for whether or not the facebookUrl prop is null:
- If you’re using a certain theme and/or do not want to use the Gutenberg editor, then check your themes website for current options of integrating React. The theme we are using (Divi) included their own create-divi-extension which at first seemed like our perfect solution, but we quickly realised when comparing the GitHub repos that create-guten-block was better in the long run. This was due to create-guten-block being much more regularly maintained and had a significant smaller number of issues/pull requests than create-divi-extension. We also must think about maintainability after we do the final hand over of the project to the client. If our client would like changes to be made to our software in the future and hires a developer to do this, it is a lot more likely that they are comfortable using the native create-guten-block than they are using a propitiatory Divi custom extension.
- When deploying a WP-Reactivate plugin for production, all you need to do is run npm prod, delete the node_modules and app folders and you’re ready to go.
- When troubleshooting React, I can’t recommend the official React Chrome Extension enough. It breaks down each component for you – displaying active props and state which is invaluable when figuring our why something is not working correctly.
Useful Links & Sources
- Create-guten-block Repository – https://github.com/ahmadawais/create-guten-block
- Create-divi-extension Repository – https://github.com/elegantthemes/create-divi-extension
- Great Tutorial on how to get started with WP-Reactivate – https://gopangolin.com/building-wordpress-plugin-with-react-part-1/
- Interview with the creator of create-guten-block, Ahmad Awais- https://www.youtube.com/watch?v=AwyUm4DafZc