ReactJS + WordPress Search

I want to get this out in the open right off the bat: I’m no ReactJS developer 😳. I put this ReactJS WordPress Search plugin together after seeing someone else do it, and tweaked a bunch of stuff to suit the needs of a project. This isn’t a large project, but it was fun and got me more into ReactJS. So if you know your ReactJS and see how I can improve this, please drop a comment below!

I do plan on going back over the plugin as there are some optimizations that I think would help.

I’ve rebuilt it here for this website and have documented the process.

I would like to point out that the groundwork for this was laid by Igor BeniΔ‡. I came across his post about the same subject some time ago. I was searching for something similar, and the closest to what I wanted was Igor’s. His project became the basis for mine.

Getting Started: Basic Structure + NPM

I put this search bar into a plugin. The search function is closely tied into my theme (hint: WP Rig), but I wanted it portable anyways.

To kick things off, I created a folder in my /plugins directory. I use terminal, but create the following however you are comfortable:

  • $ cd your/sites/path/wp-content/plugins
  • $ mkdir awc-react-search
  • $ cd awc-react-search
  • $ touch awc-react-search.php

We’ll leave the PHP file alone for now and get started on NPM (Node Package Manager) packages. I’ll assume you at least know what NPM is, and have previously installed a package or three!

Let’s get a package.json file created in plugins/awc-react-search by using $ npm init in terminal. You’ll be met with a few questions. Unless otherwise noted, I pressed ENTER for “yes”,

  • package name: (awc-react-search)
  • version: (1.0.0)
  • description: (whatever you like, or none)
  • entry point: (index.js) (we’ll change this later)
  • test command: I used “test”
  • git repository: I didn’t put one
  • keywords: ditto
  • author: Your name! Or my name!
  • license: (ISC)
  • Is this OK? (yes)

Now let’s install all the packages necessary for this tutorial:

devdependencies:

$ npm i -D @babel/core @babel/preset-env @babel/preset-react webpack webpack-cli babel-loader

dependencies:

$ npm i react react-dom

Your package.json should look similar to mine – the versions may be differ:

Now let’s get webpack going: $ touch webpack.config.js. Open that file up and insert the following:

There is one item in the above file I should point out:

entry: './src/js/public.js',

At the start of this tutorial we created our package.json file and listed the entry point as index.js. I opted for a src folder, so let’s create that and the public.js file.

  • $ mkdir src src/js
  • $ touch src/js/public.js

Now you can run $ npm run watch in the terminal, and assets/js/public.min.js will be automagically πŸ¦„πŸ¦„πŸ¦„ created!

Next Steps: Make this thing a WP Plugin!

Let’s go back to awc-react-search.php and put in the following code. The code is just enough to make a “plugin” – you can activate it at this point – but it has no functionality. Yet!

The above is pretty much taken from the WordPress Plugin Handbook. You can find the basic header info here.

Now we can start adding more to the main plugin file to get the stuff that we need. We’ll start with basic, minimal security:

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

Now we’re going to enqueue public.min.js and expose some WP REST API endpoints so that file can access them. To expose the endpoints, we use wp_localize_script. This takes three arguments: the enqueued file’s handle (react-rest-js), the JavaScript object name that will be used in your .js file – in this case wp_react_js, and an array of the data to be passed (key => data).

I used the wp/v2/search endpoint because I wanted to search pages, posts, and custom post types. I think there is a different way to do this but this served my needs.

add_action( 'wp_enqueue_scripts', 'awc_react_search_rest_api_scripts' );
/**
* Enqueueing the script
*/
function awc_react_search_rest_api_scripts() {
    wp_enqueue_script( 'react-rest-js', plugin_dir_url( __FILE__ ) . 'assets/js/public.min.js', array(), '', true );
    wp_localize_script( 'react-rest-js', 'wp_react_js', array(
        //   https://medium.com/@dalenguyen/how-to-get-featured-image-from-wordpress-rest-api-5e023b9896c6
        'rest_search_posts' => rest_url( 'wp/v2/search?search=%s&_embed' ),
        'rest_media_endpoint' => rest_url( 'wp/v2/media/' ),
        )
    );
    wp_script_add_data( 'react-rest-js', 'async', true );
    wp_script_add_data( 'react-rest-js', 'precache', true );
}

You’ll notice I’ve used wp_script_add_data to async and precache our public.min.js file.

I also wanted to include the featured image url in the API response. WordPress doesn’t do this out-of-the-box so Google came to the rescue here. This link helped, but it’s for post/page/CPT endpoints. It works with the endpoint I’ve used, but you have to drill down a bit further. Essentially, I added &_embed to the endpoint in conjunction with the following code from the aforementioned link:

add_action('rest_api_init', 'register_rest_images' );

function register_rest_images(){
    register_rest_field( array('post', 'awc-portfolio'),
        'fimg_url',
        array(
            'get_callback'    => 'get_rest_featured_image',
            'update_callback' => null,
            'schema'          => null,
        )
    );
}

function get_rest_featured_image( $object, $field_name, $request ) {
    if( $object['featured_media'] ){
        // $img = wp_get_attachment_image_src( $object['featured_media'], 'app-thumb' );
        $img = wp_get_attachment_image_src( $object['featured_media'] );
        return $img[0];
    }
    return false;
}

My next step was to put this search box somewhere. I chose to append it to my navigation items, like so:

add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);

function add_admin_link($items, $args){
    $items .= '<li id="awcSearch"></li>';
    return $items;
}

Putting that altogether results in this:

And now for some ReactJS!

We’ll kick things of with the public.js file:

First off, we import React, and ReactDOM. We need to use React, of course, and ReactDOM to render our components.

The third import brings in our searchForm component. This is the component that kicks things off.

To render this component we use ReactDOM.render(searchFormElement, searchField). This function mounts the element variable searchFormElement in the component variable searchField. We defined searchField by grabbing the element #awcSearch from our main PHP file above.

We need to create our searchFormElement component now. From this plugin’s directory we create another directory (components) and the component file: searchForm.js:

  • $ mkdir src/components
  • $ touch src/components/searchForm.js

Working with WP Rig

WP Rig is an interesting starter theme for WordPress. It has all sorts of neat stuff baked in for developers. The learning curve is a steeper than a lot of WP themes I’ve worked with but the more I get familiar with it, the more I enjoy and appreciate the direction it is on.

Webpack + Cool Tools

I haven’t played around with Webpack too much – but WP Rig comes with it baked in. I like how it deals with files: you can write a lot of currently cutting edge stuff, like nested CSS, and the workflow will (for the most part!) spit out styles/scripts that are ready for the real world. It lints/concatenates/prefixes/optimizes everything, images are compressed and lazy loaded using intersectionObserver, and so much more.

All Components on deck

There are a lot of functionality separated out into components. These components can be called out anywhere you choose in the theme. You can also tie styles to components so that the styles will only show up if that component is showing.

wp rig components structure wordpress theme.
Registering WP Rig components

Check it out here!!!

WordPress Plugin Boilerplate + Gulp

TL;DR

  • get your copy of the WPPB and unzip it in your plugins folder
  • $ cd into/your/wppb/dir
  • $ git clone https://gitlab.com/alexanderwinstoncoleman/gulp-workflow-for-wordpress-plugin-boilerplate
  • $ npm install
  • $ gulp startUp
  • $ gulp watchCSS

I like working with the WordPress Plugin Boilerplate (WPPB). When I first started working with it I felt I was in over my head. I still sometimes question if I’m using it in the best way, but I think a lot of us question ourselves frequently. I still search quite a bit for “how to” use it. I was happy to find this GitHub repo with tutorials and documentation. It has some pointers on how and where to insert code for different tasks, like registering custom post types, getting templates for said CPT from within the plugin, and far more. Check it out!

WPPB is a quick method of getting a plugin off the ground. You can activate it, the CSS and JS for public and admin is enqueued for you, and you’re off to the races! Sort of…

I wanted my CSS (and eventually JS) to be minified, prefixed, and ready for production. That’s why I wrote this WordPress Plugin Boilerplate + Gulp rabbit hole! Now onto Node Package Manager territory!

In my development process I use NPM packages to help me with my code. Mostly linting/prefixing/ES6-ing stuff using Gulp or Webpack. A few other things if needed. The past couple of times I used WPPB I integrated my Gulp workflow. I didn’t use Webpack because I felt that it wasn’t the correct hammer for the nail I was using. All I really wanted to do was compile and minify my code on the fly, and not worry too much about browsers and prefixing and all that annoying stuff. I also wanted to continue working with CSS nesting (read more about the state of CSS nesting here) and few other things. So I thought I’d write a post about this – it’ll help me remember this stuff a little easier. Perhaps I’ll even connect with other folks who can help improve it by suggesting other tools (or better implementation of the currents ones) or by asking for help.

First off: a quick note

I use VS Code as my editor. As mentioned above, CSS linting was part of my process – using the NPM package Stylelint. It’s quite popular (1.3 MILLION weekly downloads!). However I found the VS Code + Stylelint had some issues. Pretty much just annoying stuff – I really noticed it while using the WP Rig theme though. Turns out a VS Code extension helped the issue: VS Code Stylelint.

Getting Started: Get WPPB

Head on over to https://wppb.me/ and fill in all the fields to get a zip of all the files. Download and unzip the zip into the plugins directory of your installation (hopefully your developing locally!).

FYI: Folder Structure

There are a few folder structures out there for development. I waffled a bit on this, and decided to stick with keeping the original WPPB structure and put src directories next to the compiled files. I may change this in the future, but it’s what I went with.

Please note: you don’t need to create anything. running gulp startUp will create the necessary folders and files.

How to get started!

  • get your copy of the WPPB and unzip it in your plugins folder
  • $ cd into/your/wppb/dir
  • $ git clone https://gitlab.com/alexanderwinstoncoleman/gulp-workflow-for-wordpress-plugin-boilerplate
  • $ npm install
  • $ gulp startUp
  • $ gulp watchCSS

Now you’re ready! Visit the admin/css/src or public/css/src to get started. Please note that this Gulp workflow includes using nested CSS, but not SASS! (I mean, you could change that very easily!).

Since we’ve fired up $ gulp watchCSS, Gulp will watch for any CSS changes and minify/compile them into the parent folder.

TODO:

  1. On startUp: copy file from parent to src folder, remove original file.
  2. Get JS linting/transpiling working.
  3. Get a production zip built and which will removed all src files, and create a zip that can be dropped into wp-content/plugins/.

handy links:

Helper: postcss-loader not minifying css

Helper: postcss-preset-env

Helper: mini css extract