• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

WP Dev Life

A Journey through WordPress

  • About Jay
  • Dev Tools
  • Contact Us

WordPress

Using withSelect for WordPress Block Components

November 26, 2019 by Jay

I’ve been working on a block that requires the use of fetching data from the WordPress REST API in a couple of my components. The first component needing data was my PostList component. This component is responsible for displaying a list of posts in the editor as well as inside of a modal for my post picker component. The second was for fetching the categories that each post was assigned, so that I could display the category names for each post.

Thankfully the Core Data API in WordPress allows us to use the withSelect higher order component to fetch this data and pass it to our component as props. The getEntityRecords function allows us to fetch data to certain REST API endpoints to get back any data we want to use within our component.

There currently isn’t a documented list of entities that we’re able to query, however the Gutenberg source code provides us the default entities. Note that the widgetArea entity is experimental as of writing. For this article we’ll focus on the postType and taxonomy entities.

NameBase URL
site/wp/v2/settings
postType/wp/v2/types
media/wp/v2/media
taxonomy/wp/v2/taxonomies
widgetArea/__experimental/widget-areas

Exploring the Data API

Using your browser’s JavaScript console we can explore the WordPress Data API. The data API is exposed as the wp.data object. If you type in wp.data.select("core") this will access the core data API. From there we can run wp.data.select("core").getEntityRecords()which will return an empty array. getEntityRecords expects 4 parameters.

  • state Object: State tree
  • kind string: Entity kind.
  • name string: Entity name.
  • query ?Object: Optional terms query.

To select all of our posts in the console run: wp.data.select("core").getEntityRecords('postType', 'post', { per_page: -1 }) If you get back null the first time run it again and you’ll get back an object with all of your posts. In this case the entity kind was postType, post was the entity name since we wanted back that specific post type. We could have replaced that with any other post type or custom post type that was exposed on the REST API to get back those specific results. The object that we passed is the terms query. Using the REST API parameters, corresponding to their endpoints, we can filter the data we want to get back . For Post Query Parameters see the REST API Handbook. We’ll use these next as we build our basic component.

Building our Component

React has begun moving away from class based components, and in truth not every component needs to be an entire class when functional components can do everything just as well. First we need our component that we’ll pass to withSelect and our withSelect export.

import { withSelect } from '@wordpress/data';

const PostList = ( props ) => {
  return(
    // Post Info will be displayed here
  )
}

export default withSelect( (select, ownProps ) => {
  const { getEntityRecords } = select( 'core ');
  const postQuery = {
    per_page: 10,
    page: 2
  }
  return {
    postList: getEntityRecords('postType', 'post' postQuery ),
  }
})(PostList)

In the above example we wrap the PostList component in a withSelect higher order component, and use getEntityRecords to fetch back postList and pass that as props to the PostList component. The postQuery can further be modified using more parameters. If you wanted to dynamically control the parameters you could do so with attributes or passing them into the PostList component as props from a component higher up in the block.

Using Lodash Map to display data

If we were to try to render any data we got the result from the REST API, we would get some errors so we first need to verify that the data we got back is expected, and that it’s of a good length. We then will render a placeholder if we don’t have the data back, which will show the data once that select has finished.

import { map } from 'lodash';
import { withSelect } from '@wordpress/data';
import { Placeholder, Spinner } from '@wordpress/components';
import { Fragment } from '@wordpress/element';

const PostList = ( props ) => {
  const { postList } = props;
  const hasPosts = Array.isArray( postList ) && postList.length;
  if ( ! hasPosts ) {
    return (
      <Placeholder
       icon="excerpt-view"
       label={ __( 'Post Block', '' ) }
      >
	{ ! Array.isArray( postList ) ? <Spinner /> : __( 'No posts found.', '' ) }
      </Placeholder>
    );
  }
  return(
    <Fragment>
      {
        map( postList, ( post ) => {
          return (
	    <div>{ post.title.raw }</div>
          );
      })}
    </Fragment>
  );
}

export default withSelect( (select, ownProps ) => {
  const { getEntityRecords } = select( 'core ');
  const postQuery = {
    per_page: 10,
    page: 2
  }
  return {
    postList: getEntityRecords('postType', 'post' postQuery ),
  }
})(PostList)

Conclusion

This example component should be enough to get off the ground writing your own components fetching data from the REST API. I hope that as Gutenberg grows the number of entities can grow as well to target all of the endpoints. Once I figured out how components can all fit together and power one another the new editor has become a blast to develop for. It can almost be described as a giant puzzle. I have not yet gotten a full understanding of the compose function which can help join your higher order components together, but once I do I’ll have a follow up article exploring that. I love to talk development on Twitter so if you’re up for chatting Gutenberg or React give me a shout.

Filed Under: Programming, REST API, WordPress

Gutenberg: Attributes vs State

November 23, 2019 by Jay

It’s been almost three full months since I became a professional developer, and in that time my team and I launched the new Torque website. This was the team’s first foray into Gutenberg and React, and my first real foray into it. I’d explored a few things and knew some concepts, but still struggled in some areas. The blocks we ended up creating work, however there’s room for improvement.

We created two separate blocks that needed shared functionality. After trying to fix the bugs in those blocks we came to the conclusion that we should just have one block that could cover all of the use cases of the two blocks. This may sound complex, and it is. It’s a block that’s meant to be used in place of two different blocks with those blocks and displays having different markup on the frontend.

The Challenge

One of the main challenges with this Post block is I need to be able to show either the latest posts, or show specifically picked posts. This means I need attributes that correspond to values in a WP_Query or REST API call, and that these values should be saved in the block so that the frontend is able to process them.

So I setup attributes for order, orderBy, categories, per_page, etc. I used a QueryControls component to set the attributes in the sidebar, but I need the same QueryControls component in the PostPicker component that I created. This component is a Modal window that pops open that has query controls, and displays a list of posts next to a checkbox. When you check the box, the post ID is added to an array that is also an attribute.

The main challenge I ran into is that when I was using the QueryControls in the PostPicker component the query would update behind the modal too and result in multiple components re-rendering but that’s not what I wanted.

How should I approach this?

I was reading a lot of the React documentation yesterday, especially around Functional Components vs Class Components, as well as State management. My thinking now, instead of having each QueryControl component control attributes, what if we use React’s State Management hooks to manage the QueryControls for the PostPicker, while the attributes stay attached to the main QueryControls component.

Conclusion

There’s a lot of work to be done still with the new editor, and there’s a lot to learn about the inner workings. We already see a large number of Block Suite plugins, but I feel like not many of them are pushing the limits yet, mostly due to the lack of documentation about what the limits are. I get my blocks into really weird states but I think this exercise of creating this Super Post Block proof of concept, to bring back to my team is definitely going to open up an avenue for me to get back into technical writing to contribute back to the WordPress community so that others don’t struggle as much with the same issues I’ve ran into.

Filed Under: WordPress

Getting Started with Unit Tests

May 31, 2019 by Jay

What is Unit Testing?

Unit Testing is the process of writing code to ensure that other code functions with its expected behavior.

Why should I write tests?

Writing tests for your code can help drive the development of your code. This is referred to as Test Driven Development (TDD). Recently I was working on a method that sanitizes the input of a form field, and I needed this function to perform different conditionals and formatting. Instead of dumping a variable out and refreshing the page, to see the output, I was able to write test cases with what I expect the output to be, and the actual output that was returned. This allowed me to speed up the development process, and easily iterate through each condition I needed to sanitize against, and it ensured that the code returned what we wanted it to return.

Let’s Get Started

I utilize a custom Docker environment for my local development that has a separate container for PHP, MySQL, NGINX, and I’ve got a few others in there to help mimic my production environment but those aren’t really needed. I’m able to open up an SSH connection into the containers that have my site mounted, and I have access to WP-CLI. The only real requirement here is that you’ve got WP-CLI, but this walk through assumes you’re using something similar, you’ve got access to /tmp, and WP-CLI. Additionally you will need Composer, a PHP package manager, installed as that is how we’ll be requiring our vendor dependencies like PHPUnit.

If you’ve already got a plugin or theme setup but no tests, WP-CLI has the scaffold command which has a few options to scaffold just tests for a plugin or theme.

$ wp scaffold theme-tests <plugin-name>
OR
$ wp scaffold plugin-tests <theme-name>

The two above WP-CLI commands will scaffold all of the necessary files to begin writing tests, as well as providing a test-sample.php file.

This creates a phpunit.xml.dist file as well as the tests folder which contains the test-sample.php file.

Filed Under: Programming, WordPress

WordPress REST API

May 17, 2019 by Jay

What’s an API?

An API is an interface that allows applications to use, create or modify data from another application.


What’s the WordPress REST API?

The WordPress REST API takes information from the database and serves it in JSON format. This includes, posts, media, pages, and users and others. We’ll cover the Core endpoints further down.

The REST API can have two different structures depending on how permalinks are setup. On sites without pretty permalinks, the route is instead added to the URL as the rest_route parameter. For a site using the default permalink structure the REST API full URL would then be http://example.com/?rest_route=/wp/v2/posts/123

Plugins can extend this feature to generate their build their own API for use. A good example of this is the Woocommerce API, which we touch on below.


What is a route?

A route, in the context of the WordPress REST API, is a URI which can be mapped to different HTTP methods. The mapping of an individual HTTP method to a route is known as an “endpoint”. 

ResourceRoute
Posts/wp/v2/posts
Revisions/wp/v2/revisions
Categories/wp/v2/categories
Tags
/wp/v2/tags
Pages/wp/v2/pages
Comments/wp/v2/comments
Taxonomies/wp/v2/taxonomies
Media/wp/v2/media
Users/wp/v2/users
Post Types/wp/v2/types
Post Statuses/wp/v2/statuses
Settings/wp/v2/settings

HTTP Request Methods

Every time we go to a website, we’re making multiple HTTP requests. One to the server and then that sends a response which tells us we need to make more requests to get assets so that the browser renders the page properly. That is an example of a GET request. Whenever a slider changes, and triggers a request to admin-ajax.php, those are POST requests. Below is a table of different request methods availbab

GET Read data from an endpoint
POST Send data to an endpoint to create new data
PUTUsed for updating already existing data
DELETEDelete data from an endpoint
OPTIONS Used to determine which methods an endpoint accepts

Caching

GET requests will be cached per normal varnish rules.

POST requests will always be uncached.


Custom Routes

It is possible for plugins and themes to extend the WordPress REST API with their own routes. Woocommerce uses /wp-json/wc/v3 as their endpoint. They then have routes for products, orders, customers, coupons and more. Most of these requests will require authentication with a Woocommerce API key which can be generated in their Woocommerce settings page in their dashboard.


Responses

The WordPress REST API returns data in JSON format. This can then be consumed by other applications to process the data. When you load the REST API in your browser it will look similar to this:

[{"id":95,"date":"2019-05-31T15:40:16","date_gmt":"2019-05-31T15:40:16","guid":{"rendered":"http:\/\/wpdev.life\/?p=95"},"modified":"2019-05-31T15:40:16","modified_gmt":"2019-05-31T15:40:16","slug":"53w5","status":"publish","type":"post","link":"https:\/\/wpdev.life\/53w5\/","title":{"rendered":"53w5"},"content":{"rendered":"\n<p>weqtwetq<\/p>\n","protected":false},"excerpt":{"rendered":"<p>weqtwetq<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"wpe_featured":["yes"],"_links":{"self":[{"href":"https:\/\/wpdev.life\/wp-json\/wp\/v2\/posts\/95"}],"collection":[{"href":"https:\/\/wpdev.life\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpdev.life\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpdev.life\/wp-json\/wp\/v2\/users\/1"}],"replies":........}]

You can make this look prettier using the JSONViewer Chrome Extension.

All of the information about a post or page can be obtained through the REST API. This is what allows developers to create phone applications, or run Headless WordPress sites, where the front end is a Node or React application powered by the WordPress REST API.

Filed Under: Programming, WordPress

Authentication and the REST API

January 5, 2019 by Jay

Why authenticate and how?

The WordPress RESTful API was a major addition to the core ecosystem when it launched with WordPress 4.7. Having these endpoints opened up a slew of possibilities to be able to power the future of digital experiences. By using the REST API, developers are able to create native mobile and web applications that are driven by the WordPress backend. This is what’s referred to as a Headless WordPress site.

By default, anyone can make a GET request to any of the API endpoints for posts, pages, users, media, etc to garner data about your site and its information. WordPress Core has  included a full list of REST API endpoints which can be found in the developer handbook here.. When it comes to creating posts or pages or adding information to your site via an API you don’t want any random person spamming your site with junk, and that is where authentication comes into play.

There’s a few options available for authentication. The easiest for development and testing purposes would be Basic Authentication, which requires that you send an appropriate username and password encoded in base64 with each request.  You may have set up an .htpasswd file in conjunction with your .htaccess file in the past if you use Apache as your backend web server, and this is pretty similar to that, however instead of storing information in a hidden file, WordPress uses usernames and passwords from your database to authenticate. You can install the Basic Auth plugin from https://github.com/WP-API/Basic-Auth. Since this requires sending a username and password with every single request, I do not recommend using this in a production environment.

Another way of authenticating with the WordPress REST API would be to utilize JWT Authentication, or JSON Web Tokens, which is an open industry standard for representing claims securely between two parties. There’s a multitude of JWT Authentication plugins out there, but I typically see either the WP-API teams jwt-auth plugin used, which is still experimental, or the JWT Authentication for WP REST API plugin . Additionally Jonathan Dejong has also created a Simple JWT Authentication plugin, but they all seem to function on the same basic premises. Once this plugin is installed and configured you’ll need to generate a token to be able to prove that your application has the required permissions to access specific endpoints, such as showing all posts with the status of draft. By sending a POST request to the plugin’s token endpoint, containing a username and password combination, you’ll get back a token which you can use in the headers of future requests for authentication.

Testing Authentication and the REST API

So we’ve got our WordPress instance running, an authentication plugin setup and configured so now how do we make sure it is working as intended? Postman is my go to application for testing REST API calls. It’s interface is great, it has support for a multitude of platforms, and is just all around excellent, because let’s be real, who wants to write out long curl commands, manually setting headers, running the request again because you didn’t get all the information you needed. Sure that’s fine for a few people, but Postman simplifies the process tremendously.

When we make GET request to the posts endpoint we get back a JSON array that contains all of the posts on our site.

But if we change that GET to a POST we get a 401 Not Authorized error back, and this is because we haven’t authenticated our requests yet.

Basic Authentication with Postman

Let’s say the Basic Auth plugin is installed on our site, and we want to try to create a post. We can use a POST request to create a post within Postman. If you send a default POST request to the /wp-json/wp/v2/posts endpoint you’ll receive a 401 error. Click on the Authorization tab within Postman, and in the dropdown choose Basic Auth. To the right of that fill in your username and password you use for logging into the Admin Dashboard, and click Send.

You’ll get back a 400 response because we didn’t send any other data to WordPress to create a post.

If we fill in the required information as form-data on the Body tab in Postman, which in this case is Content, title, and excerpt we can create a draft post.

If you were to change the username or password in the Basic Auth settings you would get back a response telling you to reset your password. Just as a reminder, we don’t recommend the use of Basic Auth in production requests due to constantly having to pass your username and password.

JWT Authentication with Postman

JWT Authentication uses the Bearer authorization header rather than the Basic authorization header. To be able to generate the token for the header though we first have to make a request to the Token endpoint of our respective JWT Auth plugin to get this token, except you only need to pass in the username and password in the body of the request to generate the token. Once you have the token, you can then just send that in the headers instead of having to pass your username and password on every request.

On the Authorization tab in Postman, set the dropdown to No Auth, and change the request url to your JWT Authentication Token endpoint. For the body, set your username and password entries and submit your POST request to get your token.

Once you have that token, change the endpoint you want to authenticate against. Go back to the Authorization tab, change the dropdown from No Auth to Bearer and copy and paste your token into the Token field. Then create another post similar to what we did with the Basic Auth one. For the Body, ensure you have Content, title, and excerpt values and send your POST request. If everything is configured right you should get back a 200 response and see your new post’s JSON data in the bottom of Postman.

Final Thoughts

As Gutenberg becomes more prevalent in use throughout the WordPress community, I believe that REST API knowledge is going to become absolutely necessary. With different plugins extending WordPress’ core API, like Woocommerce’s API, this ll paves the way for some extremely slick digital experiences powered by WordPress as we move into the future. If you see anything I missed, or may not be 100% accurate about feel free to drop me a mention on Twitter, @wpdevlife.

Filed Under: REST API, WordPress Tagged With: rest-api, wordpress

  • Go to page 1
  • Go to page 2
  • Go to Next Page »

Primary Sidebar

Learn Linux

Use LinuxAcademy to learn Linux, AWS, or other Cloud technologies.

Find Something

Categories

Recent Posts

  • Using withSelect for WordPress Block Components
  • Gutenberg: Attributes vs State
  • Getting Started with Unit Tests
  • WordPress REST API
  • Authentication and the REST API

Archives

  • November 2019
  • May 2019
  • January 2019
  • July 2018
  • February 2018

Copyright © 2025 · Wp Devlife on Genesis Framework · WordPress · Log in