bs-wpapideprecated

WordPress API get function, JSON Decoders, and React hooks.

Usage no npm install needed!

<script type="module">
  import bsWpapi from 'https://cdn.skypack.dev/bs-wpapi';
</script>

README

bs-wpapi

WordPress API get function, JSON Decoders, and React hooks.

ReasonReact usage

The following are the optional arguments and their default values

~endpoint="posts",
~base="wp/v2",
~fetch=true,
~order=Desc,
~page: option(int)=None,
~perPage: option(int)=None,
~offset: option(int)=None,
~embed=false,

Get Posts

Get the latest 100 posts

let (posts, setPosts) = React.useState(() => [||]);
    let response =
      WpApi.useGet(
        ~perPage=Some(100),
        (),
      );

    React.useEffect1(
      () => {
        switch (response) {
        | Success(response) => setPosts(_ => response |> Types.Decode.posts)
        | _ => ()
        };
        Some(() => ());
      },
      [|response|],
    );

Get Custom Post type's posts

Get the latest 100 "homes" custom post type

let (homes, setHomes) = React.useState(() => [||]);
    let response =
      WpApi.useGet(
        ~endpoint="homes",
        ~perPage=Some(100),
        (),
      );

    React.useEffect1(
      () => {
        switch (response) {
        | Success(response) => setHomes(_ => response |> Types.Decode.homes)
        | _ => ()
        };
        Some(() => ());
      },
      [|response|],
    );

Use Non-WP base wp/v2

Get the latest 100 posts, but from the endpoint exposed by the ACF to WP REST API plugin. Keep in mind if you're using the mentioned plugin you can still just use the default WP endpoint and get ACF data appended to each post w/out any configuration in the Plugin or WP.

let (posts, setPosts) = React.useState(() => [||]);
    let response =
      WpApi.useGet(
        ~perPage=Some(100),
                ~base="acf/v3"
        (),
      );

    React.useEffect1(
      () => {
        switch (response) {
        | Success(response) => setPosts(_ => response |> Types.Decode.posts)
        | _ => ()
        };
        Some(() => ());
      },
      [|response|],
    );

Decoding

By default the response given by the hook is:

type fetch('e) =
  | NotAsked
  | Loading
  | Success(Js.Json.t)
  | Failure('e);

So, you'll likely want to decode the response into a Reason record. Many decoders area already provided. If you have no custom field data associated with the posts you're retrieving then you can just use the default decoder:

response |> Types.Decode.posts

If you do have custom fields you'll want to the following:

  1. Define your the type and provide a decoder for it. Note that ReasonML doesn't allow you to really extend types in the way TS and Flow do so this may be a little odd coming from those libs, but this helps keep our type system sound. Notice that we're not spreading the post prop on the home type so all of the standard fields will be nested within the post prop on our home record. If this nesting bothers you, you can write out the decoders for each of the post fields within your home type which can all be found within the src file.
type home = {
  post: WpApi.wp_post_response,
  neighborhood: array(int),
  school_district: array(int),
  home_type: array(int),
};

module Decode = {
  let home = json => {
    Json.Decode.{
      post: json |> WpApi.Decode.post,
      neighborhood: json |> field("neighborhood", array(int)),
      school_district: json |> field("school_district", array(int)),
      home_type: json |> field("home_type", array(int)),
    };
  };

  let homes = home |> Json.Decode.array;
};
  1. Pass the JSON retrieved from the API into your decoder:
response |> MyDecoederFileName.Decode.homes

Featured Images in the REST API

You may notice that WP by default doesn't actually give you any featured image data in the REST response. You can fix this by adding this plugin, https://wordpress.org/plugins/better-rest-api-featured-images/

Decoders are already setup for this "better_featured_image". To use it, setup a type and JSON decoder like the example above for posts with custom fields. Then just include "better_featured_image"

type post = {
  post: WpApi.wp_post_response,
  featured_image: WpApi.better_featured_image,
};

module Decode = {
  let home = json => {
    Json.Decode.{
      post: json |> WpApi.Decode.post,
      featured_image: json |> field("better_featured_image", WpApi.Decode.better_featured_image),
    };
  };

  let homes = home |> Json.Decode.array;
};

Current Limitations

  • Only supports Get requests
  • Only works in ReasonReact, not in React.js for now.