Skip to content

Instantly share code, notes, and snippets.

@mcascardi
Last active November 24, 2025 03:28
Show Gist options
  • Select an option

  • Save mcascardi/0e81913a46016113cac056ba678eae2b to your computer and use it in GitHub Desktop.

Select an option

Save mcascardi/0e81913a46016113cac056ba678eae2b to your computer and use it in GitHub Desktop.
Wordpress wp-json API example using OOP
<?php
include_once 'news-api.class.php';
// Implementation Steps:
// Step 1: Call init() in your custom theme or custom plugin code.
$news_api = new News_API();
$news_api->init();
// Step 2: Use the static News_API::get_news_api_posts() method to retrieve the posts in your template file.
$query = new \WP_Query( ['post_type' => 'news', 'posts_per_page' => 5] );
$fetched_news_posts = News_API::get_news_api_posts();
$news_posts = !empty($fetched_news_posts) ?
array_merge($query->posts, $fetched_news_posts) :
$query->posts ?? [];
<?php
class News_API {
const API_ENDPOINT_PROD = 'https://mattcascardi.info/wp-json';
const API_ENDPOINT_STG = 'https://matt.issmarterthanyou.com/wp-json';
const API_SITE_CACHE_KEY = 'news_keywords';
const API_NEWS_CACHE_KEY = 'news_fmt';
public function init() {
add_action('wp_head', [$this, 'fetch']);
}
public static function get_news_api_posts() {
return get_transient(self::API_NEWS_CACHE_KEY) ?? [];
}
public function fetch() {
$this->endpoint = wp_get_environment_type() === 'production' ?
self::API_ENDPOINT_PROD : self::API_ENDPOINT_STG;
$result = wp_remote_head( $this->endpoint );
if ($this->_handle_request_error($result)) {
return false;
}
$url = "{$this->endpoint}/wp/v2/news_keyword";
$news_endpoint = "{$this->endpoint}/wp/v2/news";
$this->news_keywords = get_site_transient(self::API_SITE_CACHE_KEY);
if (! $this->news_keywords ) {
$this->news_keywords = $this->_do_get_request($url);
set_site_transient(self::API_SITE_CACHE_KEY, $this->news_keywords, DAY_IN_SECONDS);
delete_transient(self::API_NEWS_CACHE_KEY);
}
foreach( $this->news_keywords as $keyword ) {
$news_keyword_id = $keyword->id;
}
if (empty($news_keyword_id)) {
return;
}
$news_api_cache_key = self::API_NEWS_CACHE_KEY;
if ( get_transient( $news_api_cache_key ) ) return;
$this->news_json = $this->_do_get_request($news_endpoint, ['news_keyword' => $news_keyword_id], true);
if (empty($this->news_json)) return;
// Save the representation of the post cards in transient form
set_transient(
API_NEWS_CACHE_KEY, $this->get_formatted_news_posts(), DAY_IN_SECONDS
);
}
private function get_formatted_news_posts() {
$news_api_posts = json_decode($this->news_json);
$posts = [];
if (!is_array($news_api_posts) ) {
return $posts;
}
$top_news= array_slice($news_api_posts, 0, 3) ?? [];
foreach ($top_news as $news_post) {
$save_post = new \stdClass;
$save_post->ID = $news_post->id;
$save_post->card_data = [];
$save_post->card_data['title'] = $news_post->title->rendered;
$save_post->card_data['excerpt'] = $news_post->excerpt->rendered;
$save_post->card_data['link'] = $news_post->link;
$save_post->card_data['date'] = date('M, j, Y', strtotime($news_post->date));
// Needs featured image if it has one
foreach ($news_post->_links as $linkname => $data) {
if ( 'wp:featuredmedia' === $linkname ) {
$imageres=$this->_do_get_request($data[0]->href);
$save_post->card_data['featuredimage'] = $imageres->media_details->sizes->medium->source_url;
}
}
$posts[] = $save_post;
}
return $posts;
}
private function _do_get_request($endpoint_url, $params = null, $return_json = false) {
$endpoint_url .= (!empty($params)) ? '?' . http_build_query($params) : '';
$result = wp_remote_get($endpoint_url);
if ($this->_handle_request_error($result)) return null;
$body = wp_remote_retrieve_body($result);
return $return_json ? $body : json_decode( $body ) ;
}
/**
* Returns true if error
* // API Helper
*
*/
private function _handle_request_error($result) {
if (!is_array($result)) {
// It's an error
error_log(print_r($result->get_error_messages(), true));
return true;
}
if ($result['response']['code'] !== 200) {
error_log("Error {$result['response']['code']}: {$result['response']['status']} ");
return true;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment