body_class REST field in WP-API

get_body_class() relies on $wp_query to do its thing, which is apparently a no-go for the JSON API.

I considered creating a global object to hold the body class, and just using that to keep the body_class up to date…but that wouldn’t work without page reloads, and there would be no assurance that the object was up-to-date.

The only way I could get it to remotely work was by hijacking the main $wp_query object, which is a no-no.

The semi-working code looked something like:

function bsd_get_body_class($id) {
  global $wp_query;
  $wp_query = $orig_query;

  $new_query = new WP_Query( array( 'p' => $id, 'post_type' => 'any' ) );

  $wp_query = $new_query;
  $classes = get_body_class();

  wp_reset_postdata(); 

  $wp_query = $old_query;

  return $classes;
} 

// Add $classes as a REST field to the API according to docs

Even then, though, $classes didn’t necessarily match the output of body_class() inside my template files, I think because it happened earlier in the query than in the templates.

So I scrapped it.

I ended up writing a simple class builder in JS that re-creates some of the WP functionality, instead of using the API and storing the classes in my app’s state. It looks like this:

export const bodyClass = (data) => {
  var classes = [];

  if (data['id'] && data['type'])
    classes.push(data['type'] + '-id-' + data['id']);
  if (data['type'])
    classes.push(data['type']);
  if (data['is-front-page'] === true)
    classes.push('home')
  else
    classes.push('internal');

  return classes;
}

If somebody out there knows a good way to get presentational data from the WP API, I’m all ears, but after days of hacking, I couldn’t find a reliable, consistent way to get the classes out of $wp_query. (post_classes, on the other hand, works like a charm.)