A read-only Ruby client for WP-API v2

This unambitious client provides read-only access for WP-API v2.

It supports authentication via OAuth or Basic Auth.

It does not support comments, users or POST requests.

It requires Ruby 2.3 and is tested against WP-API 2.0-beta12.

Installation

gem install wp-api-client

And

require 'wp_api_client'

Usage examples

Set up the client and get some posts

# create a client

WpApiClient.configure do |api_client|
  api_client.endpoint = 'http://example.com/wp-json/wp/v2'
end

@api = WpApiClient.get_client

# get some posts
posts = @api.get('custom_post_type/') # or "posts/" etc
# => <WpApiClient::Collection:0x007fed432a5660 @resources=[#<WpApiClient::Entities::Post...

posts.map { |p| puts p.title }
# Custom Post Type 99
# Custom Post Type 98
# Custom Post Type 97

term = @posts.first.terms.first
# => #<WpApiClient::Entities::Term:0x007fed42b3e458 @resource={"id"=>2...
term.taxonomy
# => #<WpApiClient::Entities::Taxonomy:0x007f9c2c86f1a8 @resource={"name"=>"Custom taxonomy"...

term.posts
# => #<WpApiClient::Collection:0x007fd65d07d588 @resources=[#<WpApiClient::Entities::Post...

# term.posts("custom_post_type").first.terms("category").first.taxonomy... etc etc etc

Pagination

posts = @api.get('posts', page: 2)

posts.count
# => 10

posts.total_available
# => 100

next_page = @api.get(posts.next_page)
# => #<WpApiClient::Collection:0x00bbcafe938827 @resources=[#<WpApiClient::Entities::Post...

page_after_that = @api.get(next_page.page_after_that)
# => #<WpApiClient::Collection:0x00bbcafe938827 @resources=[#<WpApiClient::Entities::Post...

Defining relationships

The REST API docs invite you to define custom relationships to go alongside "http://api.w.org/term" etc.

For example, let's say you have a person post type and a post-to-post relation defined through meta and exposed in the REST API like this:

add_filter( 'rest_prepare_king', function( $data, $king ) {
    if( $king->queen ) {
        $data->add_link(
            'http://api.myuniqueuri.com/marriage',
            rest_url( '/wp/v2/person/'.$king->queen ),
            ['embeddable' => true]
        );
    }
    return $data;
}, 10, 2);

This will cause the http://api.myuniqueuri.com/marriage relation to be reflected in your _links property when you call up the King from the REST API.

But you'll get an error if you try to query this relationship using the client.

king = @api.get('person/1')
queen = king.relations("http://api.myuniqueuri.com/marriage").first
# => throws WpApiClient::RelationNotDefined

The solution is to register the relationship on configuration:

WpApiClient.configure do |c|
  c.define_mapping("http://api.myuniqueuri.com/marriage", :post)
end

...

king = @api.get('person/1')
queen = king.relations("http://api.myuniqueuri.com/marriage").first
# => #<WpApiClient::Entities::Post:0x007fed42b3e458 @resource={"id"=>2...

There is currently support for :post_type, :post, :term and :meta (key/value) relations.

 Loading a taxonomy via a slug

WP-API returns an array even if there's only one result, so you need to be careful here

term = @api.get('custom_taxonomy', slug: 'term_one').first
taxonomy_name = term.taxonomy.name
posts = term.posts

OAuth

Provide a symbol-keyed hash of token, token_secret, consumer_key and consumer_secret on configuration.

WpApiClient.configure do |api_client|
  api_client.oauth_credentials = oauth_credentials_hash
end

client = WpApiClient.get_client

Basic Auth

Provide a symbol-keyed hash of username and password on configuration.

WpApiClient.configure do |api_client|
  api_client.basic_auth = {username: 'miles', password: 'smile'}
end

client = WpApiClient.get_client

Testing and compatibility

This library comes with VCR cassettes recorded against a local WP installation running WP-API v2-beta12. It is not tested with other versions.

If you want to make your own VCR cassettes, use these scripts.

To run the tests, invoke rspec.

Structure

Public Objects

WpApiClient::Client

Accepts a WpApiClient::Connection and exposes a #get method.

Pass a URL into #get and it will do its best to return usable data.

The second parameter accepts an optional hash of query params.

WpApiClient::Connection

Initialize with an API endpoint like http://localhost:8080/wp-json/wp/v2, then pass into a new client. Faraday options might be pulled out of here in the future.

Internal Objects

WpApiClient::Collection

Wraps a set of WpApiClient::Entities in an Enumerable interface and provides next_page and previous_page methods. Pass these into @api and it will give you back the data you want

next_page = @api.get(posts.next_page)
# => #<WpApiClient::Collection:0x00bbcafe938827 @resources=[#<WpApiClient::Entities::Post...

WpApiClient::Entities::Base

Base class for Post, Term, Image and Taxonomy, so far. Not all methods are implemented.

Other

Thanks WP-API!