Is Guten-Pain Good?

Gutenberg, the new WordPress post editor is coming soon and its a big change. Change makes people scared, that’s natural. Not all of that fear, in my opinion, matches up with the reality of what Gutenberg actually does and does not do. But, its a big change with some very real risks.

What WordCamp Montreal Taught Me

I attended WordCamp Montreal recently. Besides how great the vegan food was in Montreal I had two big takeaways:

First, industry veterans are excited about the possibility of Gutenberg and are also very worried about the transition. I think some of that is people still not understanding that Gutenberg WordPress 5.0 doesn’t change existing content. But also, there are some valid concerns there.

My other big set of takeaways was from a talk by Jer Clarke about Buddhism and WordPress. This was a great talk. It was not heavy on WordPress content but did make light of the how everything including WordPress changes.

It reminded me of how many times I’ve told people something like, “I used to be so stressed about technical debt and not having enough time for everything I want to build and not making enough money. Now, I’ve got technical debt, not enough time and not enough money.” Then they look at me as if I have something else to add, and I don’t. I’m just more at peace with the fact that these things are happening and less attached to worrying about them.

I still break down and cry, but way less often. I also meditate and exercise every day. I think it helps.

What About The Gutes?

Yes, Gutenberg is a big deal. My big concern, as someone whose business is based on WordPress’ huge market share, is that Gutenberg will lead to a shrinking size of the available customers for me.

It might.

Also, Squarespace. Also the rise in Laravel-backed CMS and CMS-like tools like Nova. Also, serverless static site platforms like Netlify are getting more CMS-like features.

I’m a big fan of the scenario where distributed web apps backed by an Etherum-like blockchain.

Some Disappointing Things Will Happen

I’ve been very concerned about what happens when folks, who chose WordPress based on its promise of backwards compatibility, have to chose between paying to fix problems created by Gutenberg and paying for a new site.

A lot of people own websites that they do not maintain. 

I wonder why we in the community are so attached to supporting those who do not expect to have to support their own sites. That’s their free choice, and if they leave WordPress when faced with this responsibility is that such a bad thing?

I Don’t Know Anything

Or maybe everything will go better than we fear. Maybe Gutenberg really is what WordPress needs to stay relevant.

I have no fucking clue. But I do know that, right now using WordPress, without Gutenberg, to create content is painful. Fearing what happens when you update is scary. These are all know threats to the WordPress ecosystem. They are are real and scary.

Things are changing and that’s difficult and scary.

Also, the sky is blue and no one is forcing you to update. Classic editor or staying on 4.x might be the best solution for existing sites.

I don’t know, but I so hope it goes well. I really want to keep going back to WordCamp Montreal every year, the began food is great.

How The WordPress REST API Changes WordPress Plugin Development

Over the last few months I’ve been working on creating a totally self-contained WordPress A/B testing plugin. It’s called Ingot, and we released version 1 right after christmas.

Since I did almost all of the development myself from scratch I was able to do it all “the Josh way” and refine what that even means. This allowed me to put a lot of my opinions on WordPress development to the test. I shared a lot of what I learned in yesterday’s post.

Lessons Learned Coding A Big, New WordPress Plugin

Ingot was in many ways written around around the REST API. The custom endpoints we built are used for the Angular app that Roy Sivan and I created for the admin screen. It’s also used in a very small front-end JavaScript file for tracking conversions, failed conversions and cache busting.

Today, I wanted to follow up yesterday’s post with what I think it means to create a WordPress plugin using the REST API. Next week, I’ll talk about the business and product design lessons I learned from Ingot. The design decisions that went into building the Ingot REST API will be a big part of that discussion.

How Things Change

As most people reading this know, I spent a lot of time over the last year or so thinking about how the WordPress REST API will change how we build WordPress plugins, themes and apps. I think this change is big and has to do with how the use of WordPress is changing.

WordPress didn’t get to 25% market share on blogs and it’s not going to get to 50% or whatever that way. The growth comes from eCommerce, publishing, membership sites, inbound marketers etc. These are all users that can benefit from being service providers.

Photo by: Jeff SheldonI think that those of us who empower these users by giving them the tool need to make their sites have to think API first. Your plugin’s interaction with the client is going to be more and more coming through the API.

That doesn’t mean WordPress plugins are suddenly all JavaScript magically. Your custom REST API routes are PHP code that you write around the rest of your plugin.

If the code they wrap must be solid and sufficiently decoupled from input method — if you call GET or POST in your CRUD still you’re not going to make this transition.

The hype around the WordPress REST api has been about the default routes and that might be exciting to you if you do front-end work. But the real potential in my mind is that your plugins can be repurposed SAAS service more easily and that your users can become service providers themselves.

The Developer End User


Photo by: Sonja LangfordToo often, when creating a plugin that is designed to be simple to use and not require technical knowledge, we forge that there are still developers as end-users. Keeping developer end-users happy is super important as they are often decision makers that choose whether or not their client uses your product or not. They are also likely, if happy, to become evangelist for your project.

The ability for developer end users to be able to customize and integrate with your plugin via your REST API as an alternative to learning the WordPress hook system is a big deal. It opens more doors and more opportunities. It means more integrations, more contributions and more potential developer evangelists.

Angular + REST API

I originally thought I would use the plugin generator that David and I use for CalderaWP plugins. I couldn’t make it work with the original DB structure I had. The first Ingot demo used a really bad UI I hacked together. I wrote a ton of PHP code full of admin-ajax callbacks and functions hooked to init in order to check for incoming form submissions. By all objective standards, it sucked.

So, I taught myself AngularJS.

Since I was trying starting at a Jon Snow-level understanding of AngularJS, I was bugging Roy Sivan for help a lot. Roy ended up doing a lot of the heavy lifting for me and now pretty much owns the Ingot UI. That’s awesome because I don’t like UI work and he’s better than me.


Photo by: Jonas NilssonBut, I did learn a ton about Angular. What I learned enabled me to write all the example code for the last section of my WordPress REST API course — Angular front-end for WordPress sites. I really like Angular and the angular-ui router. It’s a really great way to work. It almost makes me wish I made WordPress sites so I could make them with Angular.

Our admin doesn’t look very WordPress. It’s a very standard Bootstrap, which is a common pattern that I hope people are used to using. I would love to get a WordPress admin Bootstrap theme made soon though.

I’ve spent a lot of time in the past trying to force the MV* pattern on WordPress, which is insane for a lot of reasons. Using the WordPress REST API to provide data to Symfony or Angular is really great, and fairly simple.

A WordPress plugin, like any product is only as good as its interface. I’m convinced that working with Angular and custom WordPress REST API endpoints was the right decision in terms of UI/UX. It also means we have a solid REST API to use if we make an Ingot SAAS product or if end users want to use it.

This Is The New Way

At this point, I don’t think it makes sense to build a plugin without its own set of API endpoints. Doing so requires a PHP CRUD that is sufficiently decoupled from input to work seamlessly with the API. Writing your plugin knowing you will use the REST API makes dependency injection in your class design a necessity.

That’s going to be an issue for a lot of older plugins, and the backwards compatibility challenge is also there. I think it is worth the rewrite though, if this is an issue. This will make your plugin more easy to unit test, which is a great bonus.


Photo by: Jerry AdneyOlder plugins also have to deal with backwards compatibility concerns. Ingot requires WordPress 4.4 or later. It’s a new plugin so we don’t have a user base to worry about alienating. It’s a concern for me in my existing plugins, and we will see how that plays out as I modernize them to work around the REST API.

I will, because I think that plugins that do not embrace this new way risk being left behind. For new plugins, the REST API-first approach makes sense. It leads to better admin experiences, easier interfaces and allows your plugin to more easily become a part of  a stack that is not totally built in WordPress.

 

Speechless

For the 900th time, I’m trying to get into the daily blogging habit. But, I don’t want to write about WordPress, everyday, and when I do, I don’t want to just talk about WordPress business or tutorials. I want to share more of my story. But, that puts me in an emotionally vulnerable space. It’s scary and the fear holds me back.

How much of it is because, as hard as I push back, I’m still subject to the “be a man” gender-conditioning of our culture, I don’t know. It would be a shame if I put all this work into this awesome platform for people to make their voices heard, without telling the stories that I desperately want to tell. I hope, that by naming this fear, I’ll empower myself, or others — men, women and those in between and beyond a like — to conquer this fear.

Photo by:  Shlomit Wolf (CC0)
Photo by: Shlomit Wolf (CC0)

Pretentiousness In The Age of The Algorithim

When I was younger I didn’t want to listen to System of a Down because they were too mainstream. Eventually I got my head out of my butt, and gave them another chance. I’m still not into Toxicity, but the rest is pretty awesome.

Now I don’t want to listen to them because then Google Play will recommend I listen to Disturbed.

 

https://youtu.be/Jy_6Z7tto2k

Improving Client Relationships By Communicating Solely Via Slack

Like a lot of of organizations in the WordPress ecosystem, Pods, where I work, started using Slack soon after the WordPress project did. Slack is an amazing asynchronous communication tool. While Slack’s main focus is chat, it also has great integrations and a simple file management tool.

Over the last few months, I’ve been experimenting with a “joshpress” Slack for client work and its been great.

My initial experiments have gone so well, that I am going to require all new clients to communicate only through Slack, once we’ve passed the original scoping and negotiating phase. I’m tempted to replace my site’s contact form with an invite to my Slack.

Relationship Fuel

Doing for-hire programming work is a relationship. Like all relationship a precursor to success is communication. Having a clean, efficient, cross-platform, and easily searchable medium for communication takes much of the friction out of communication.

Communication is the fuel that powers relationships. Ease of access to the right information makes communication a stronger, more powerful fuel for the relationship.

Before I start doing actual work on a project I will have gathered a lot of information. I have an email where we agrees on requirements–for me and the client–and timeline. In addition there are access credentials provided by the clients as well as any mockups and other guides for the project.

Having to find all that information in one place, instead of scattered about various emails is great and is one of the many places that Slack’s file creation and searching shines. Once I set up a private channel for a project, the first thing I do now is add files for requirements, timeline and various access credentials.

Now all of the information I need is in one place. As the project goes on things change. Now its easy to change or add the requirements, or add additional information. In addition, any conversations about the project are in one place, not spread across multiple email threads.

Easy Onboarding

Recently I got in over my head on a project. Way over my head. I made it clear to the client that I needed to bring in additional developers and was lucky that both the client and the developers I wanted agreed. Since we were already using Slack–the client and I–for the project’s communication, so I just added them both to the Slack channel and they were in the know.

Compare that to the idea of scaling a two-way email-based communication to include two additional people. Getting all the right history to the newcomers and ensuring that all emails get replied to all… I can’t even.

Also, in two minutes I had Bitbucket notifications going to everyone every time there was a commit. That’s another important part of collaboration made easy by Slack.

In 2015 I’m trying to avoid working on projects as the only developer on a project. It takes more effort to collaborate, but the results are worth it. I want to work with others, not just because it is more fun to work that way, but so I can do better work and work on more complex projects.

What If They Will Not Use It?

One of the many, many benefits to positioning yourself as an expert, not a commodity, is that you do not have to act like a restaurant employee, bending over backwards to every client request. That doesn’t mean not being nice or accommodating, but it means that your clients should be buying into and buying your way of working. If they do not, then that’s too big a red flag to get past.

In my opinion, being organized is important to getting work done properly and maintaining a good client/ developer relationship. If a client doesn’t value organization or trust me to choose the best tools for communicating me, than I do not want to work with them. If they do not trust me on such simple things, than what’s going to happen when a judgment call is needed on something complicated and complex?

I’d feel differently if Slack were not so easy to use, and didn’t move seamlessly from the browser to mobile so effortlessly.

Email Is A Problem

If you ever want to create a startup, one of the pieces of advice you will get over and over again is “find a problem lots of people have and lots of people will want your solution.” It’s great advice. Many startups are trying to tackle the problems caused by email. There are lots of tools that aim to solve it, even as tools like Inbox by Google and Mailbox by Dropbox are doing a great job of reducing the problem.

Slack isn’t the only solution to the email problem. Asana is another good solution that I like, but do not love. Slack can’t replace the kind of project management that larger scale projects need, that a tool like Asana provide. But, I think Asana can be too much, and lacks a good discussion system, which sometimes is all you need. Plus, Slack integrates well with Asana and other project management systems when you need them.

So far, Slack is helping me out a lot with client work, as well as with other types of projects. It’s worth considering for solving the problems that communicating with your clients via email causes.

 

Using Composer To Increase Your WordPress Development Powers

In the last few months I’ve been using Composer to improve my development and deployment of WordPress projects. It’s an important tool that is not only easy to use, but also leads to increased code reusability, a reduction in copypasta errors, encourages best practices like using namespacing and autoloaders, and can aid in deployments.

I’ve covered how composer works in my posts for Torque on the subject already. But, in this post I wanted to just briefly go over the various scenarios in which composer is useful and how it can improve your life, and increase your personal powers as a developer and a human being.

If you are new to Composer, I recommend that you read my Torque posts on it. So far I have written an introduction to using Composer with WordPress and a guide to improving WordPress plugin development with Composer.

Improved Site Deployments

One of the trickiest things about moving between a development and production site is dealing with the parts of the project that do not belong in version control. Sometimes you end up with all of your plugins, and WordPress itself in the Git repo you use for the site.

This is, objectively speaking, an absolutely terrible idea. Why should you write every change to WordPress or a plugin to your Git history? That makes no sense. Use version control to track changes to code you are changing and no other code.

For HoloTree, we have a Git repo for building the live and development sites that establishes the structure of the site. It includes wp-config, my VVV config and a few other things, but does not include any plugins, the theme or WordPress itself. All of that gets pulled in by Composer.

Mark at Kinsta helped me set up dploy.io to automate the process. Since dploy.io connects to my server via SSH, it is able to run composer update for both the main repo and the plugins that power HoloTree, each of which pull various libraries.

This is all made easy by the fact that every plugin in the WordPress.org plugin and theme repositories are automatically available as a Composer package, thanks to wpackagist.

Update: I created a git repo that has everything set up for new WordPress site development using Vagrant, and my preferred way of using Composer for dependency management.

Sharing Code Between Plugins

As you go through life, you will find yourself developing repetitive patterns you like to use in all of your plugins. That’s great, unless you are cutting and pasting those patterns between projects.

Moving the classes and collections of functions you use for a part of a project into a Composer library is a little bit of extra work. You will see a return on investment for that small amount of work the first time you use the library again. When you fix a bug in the library and are able to easily share the change across all projects using that library… well that’s just awesome.

Using Other People’s Libraries

Packagist, GitHub and the internet at large are full of great libraries that you can pull into your plugin or other project using a dependency manager like Composer or NPM. Using a dependency manger makes doing so both easy to do and easy to keep up to date.

If you ever wanted to use a piece of another PHP framework, say for example Symphony, Composer makes it easy. Also, some talented WordPress developers publish libraries on Packagist. For example, Mark Jaquith, Andrey “Rarst” Savchenko and Eric Mann.

Of course, a package doesn’t have to be on Packagist. If it has a valid composer.json file, you can pull it directly from GitHub.

Composer Libraries Are Git Repos!

Note: I know they could be SVN or whatever repos, but using anything besides Git is, objectively speaking, silly.

Let’s say you have a plugin constructed of several Composer libraries, and one file with the plugin header and a function to include the autoloader. First off, great victory, you win a _doing_it_right() award in my book. You might be worried about having to maintain separate checked out version of the repo to commit changes to.

This is not the case. When Composer pulls in a package, it includes the .git file and sets the remote origin properly. If you have write access to the repo, you can simply CD into the package’s directory and commit and push like any other Git repo.

No New Copypasta!

copypastaDon’t Repeat Yourself (DRY) is one of the most sacred principles of programming for good reason. Cutting and pasting the same code between files is an equal, if not greater violation of this important principle.

Not making your code easily reusable for the benefit of yourself and others makes your life harder. Further, it robs you of the ability to help others while promoting yourself.

So stop.

 

Featured Image by:  Lance Anderson via Unsplash

WordPress Tallahassee Meetup: Turning WordPress Sites Into Web & Mobile Apps

For the second meeting of the Tallahassee WordPress Meetup I am presenting on solutions for turning WordPress sites into mobile apps and using WordPress as the back-end for a web and/or mobile app. This is a subject that I’ve thought a lot about as I work with the WordPress REST API, and my own projects.

Below you can see my slides and a list of helpful links:

Links From My Presentation:

 

 

Using The New WordPress REST API: Tally Code Camp 2014

Today I will be presenting at Tallahassee Code Camp 2014 on WordPress’ new RESTful API. My slides are embedded below:

Be sure to read my articles in Torque for more information on using the WordPress Rest API.

Frequently Asked Questions

Is This A Plugin, A Feature of WordPress or What?

Over the last two years, most big features of WordPress have been developed as plugins before being merged into WordPress itself. Right now the API is a plugin, that will *hopefully* be merged into WordPress core in version 4.1 or 4.2.

It is totally functional and committed to not breaking backwards compatibility. The “plugin as a feature” development model has a lot of advantages over working with patches to core only, One of those advantages is that you can easily use the feature while it’s under development. The other is that even if it doesn’t make it into core, it can still be used as a plugin.

Isn’t It Part of JetPack?

JetPack has its own RESTful API. Here’s a good slide breaking down the pros and cons of the JetPack API. JetPack’s RESTful API runs on WordPress.com’s servers, which may or may not be a good thing, depending on your needs and worldview on decentralization. The fact that it doesn’t work for local development is a big issue for me.

Is This Going To Replace XML-RPC In WordPress?

Yes and no. I doubt XML-RPC is going anywhere as WordPress is committed to backwards compatibility. I do think once this new API is mature and in core people will stop using XML-RPC because it’s a pain to use.

What Have I Made With It?

  • Josie – A single page web app (and hopefully node.js powered mobile app) framework for use with the REST API.
  • JP-REST-API-Client – A simple client for creating and updating posts via the WordPress REST API via the WordPress HTTP API.
  • Pods JSON API – I added new routes, endpoints and documentation to the add-on to the API for Pods.
  • Pods Deploy – A tool for automating the process of moving Pods configurations between sites.
  • JP-Tax-Query – A custom endpoint for making tax queries via the REST API.
  • JP-REST-Access – A library of WordPress filters for setting cross-origin domain (CORS) headers and improving access to post endpoints.
  • JP-Rest-Cache – A soft-expiring, server-side cache for the REST API.
  • JP-Menu-Routes – Adds routes & endpoints to the REST API.
  • A basic front-end post editor, detailed in this Torque article.

Using Dropbox To Keep VVV In Sync on Multiple Computers

Updated November 3, 2014 See below for a few issues we’ve come across.

I’ve been plotting for a while now to get a kick-ass desktop for development. Since I work once or twice a week at a co-working space and travel for WordCamps or to visit family fairly regularly, I’m going to need to keep my laptop for those situations. One of the things, besides clients owing me money that has kept me from getting said kick-ass desktop machine  is worrying about how to keep my development environment in sync between the two machines.

Lucky for me Scott Kingsley Clark, figured out how easy it is to keep VVV in sync between his shiny new iMac and his laptop. Scott was kind enough to share his strategy with me, which I have tested with a loaner computer and found to work very well.

Before We Get Started

I’m assuming that you’re already using VVV and are familiar with it. If you’re not, you should probably be reading my guide to getting started with VVV for local WordPress development instead.

Since you’re familiar with VVV, it’s a safe assumption that you know to install Vagrant itself and a Virtual Box or some other VM software on both computers. Right?

You can either use an existing VVV setup or create a new one for this. In this guide, I will be starting from scratch, but you could also do the same thing by temporarily moving your existing one into your Dropbox folder instead of creating a new one.

Also, for this guide, I will be calling the vagrant folder dvv, for Dropbox Varying Vagrants. You can call it whatever you want.

Setting It Up

Install VVV In Dropbox

The first step is to clone VVV itself into Dropbox:
cd ~/dropbox
git clone https://github.com/Varying-Vagrant-Vagrants/VVV dvv
You could also download the ZIP and extract it in Dropbox.

Symlink VVV Folder

On both computers you are going to want to symlink the VVV folder with a folder in your user root. This is mildly optional, as you could just work out of Dropbox. Personally, I agree with Scott on symlinking, as I love the ease of being able to cd directly into my VVV from a new bash shell. It’s a little thing, but I have to do it after every restart.

If you’re using an existing install, this step is extra important as it let’s you put the install back where you found it on the originating computer.

You must do the symlink on both computers:
ln -s ~/dropbox/dvv ~/dvv

Vagrant Up

On the remote machine you do a new vagrant provision and that’s it you’re good to go.

What This Doesn’t Do

This does not keep the virtual machines themselves in sync. I don’t think it makes any sense to do so, though I’m sure it’s possible. That means whenever you make changes to your configuration or add a new site, you will need to do a new vagrant up on the other computer.

Also, since the database is in the virtual machine. It does not keep the database in sync. If you have the Vagrant Triggers plugin installed you get a database backup every time you vagrant halt. You can use that to rebuild the DB when doing a new vagrant up or vagrant provision.

That’s Actually Very Simple

That’s it. Turns out this is very simple,  Scott’s pretty good at creating ways of making WordPress simpler.

OK, Maybe Not That Simple

Here are some caveats that Scott has discovered since starting to use this strategy since implementing Dropbox to sync his VVV between two computers:

1. My virtual machine tends to be recreated from time to time, forcing 100% install over again when doing a `vagrant up`, this is likely because some files synced by Dropbox are unique to the computer, and keep changing between ‘up’s on the different vagrants.

2. Because of the virtual machine recreation, DB changes can disappear and most commonly be restored by Vagrant during it’s provisioning. It’s important to note that when you use `vagrant halt`, it will backup the databases on the current virtual machine, and on `vagrant up` (first, or `vagrant provision`) it will attempt to restore those DB .sql files on the other machine.

Approach with caution, I currently now believe the best way to sync VVV is to limit the sync to the `www` folder, not the entire VVV folder contents.

JPD2 Easy Transient Caching Plugin

My newest plugin, JPD2, makes caching the results of a WP_Query, WP_User_Query and WP_Meta_Query, via the transients API easy. Realize increased performance, by caching the results of your queries, with one simple function.

All saved queries are automatically reset when any post is updated.

You can download it from WordPress.org or clone the GitHub repo.

Note plugin is brand new and is still undergoing testing. Please open an issue on GitHub if you find a bug.

Why Use Transient Caching

The Transients API creates temporary entries into your database. One great use is to store the result of complex queries, which allows WordPress to run one query–to get the transient–instead of many queries, and get the same results.

This article explains very well how that works. This plugin automates the process for you.

How To Use It

Usage is simple via the function jpd2_better_query(). The required arguments are $args, which are arguments to be passed to WP_Query (default,) WP_User_Query or WP_Meta_Query and $name, which is a name for the query. Useful if you wish to manually deleted the transient later with delete_transient().

Optional arguments, $type allows you to use WP_User_Query or WP_Meta_Query instead of WP_Query, and $expire lets you override the default expiration time for the transient.

<?php
/**
* Basic Use
*/
$args = array( 'post_type => 'page', 'posts_per_page' => 3 );
$name = foo;
$foo_query = jpd2_better_query( $args, $name );
/**
* Safest Usage
*/
//WP_Query Example
$args = array( 'post_type => 'page', 'posts_per_page' => 3 );
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $name );
}
else {
$foo_query = new WP_Query( $args );
}
//WP_User_Query
$args = array(
'search' => 'Josh',
'search_columns' => array( 'user_login', 'user_email' ),
);
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $type='WP_User_Query', $name );
}
else {
$foo_query = new WP_User_Query( $args );
}
//WP_Meta_Query
$args = array(
'relation' => 'OR',
array(
'key' => 'lightsbar_color',
'value' => 'red',
'compare' => '='
)
);
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $type='WP_Meta_Query', $name );
}
else {
$foo_query = new WP_User_Query( $args );
}
?>
view raw use_jpd2.php hosted with ❤ by GitHub

By default, transients last up to one day. There are three ways to change that, as shown below:

<?php
/**
* Basic Use
*/
$args = array( 'post_type => 'page', 'posts_per_page' => 3 );
$name = foo;
$foo_query = jpd2_better_query( $args, $name );
/**
* Safest Usage
*/
//WP_Query Example
$args = array( 'post_type => 'page', 'posts_per_page' => 3 );
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $name );
}
else {
$foo_query = new WP_Query( $args );
}
//WP_User_Query
$args = array(
'search' => 'Josh',
'search_columns' => array( 'user_login', 'user_email' ),
);
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $type='WP_User_Query', $name );
}
else {
$foo_query = new WP_User_Query( $args );
}
//WP_Meta_Query
$args = array(
'relation' => 'OR',
array(
'key' => 'lightsbar_color',
'value' => 'red',
'compare' => '='
)
);
if ( function_exists( 'jpd2_better_query' ) {
$name = foo;
$foo_query = jpd2_better_query( $args, $type='WP_Meta_Query', $name );
}
else {
$foo_query = new WP_User_Query( $args );
}
?>
view raw use_jpd2.php hosted with ❤ by GitHub