Last active
November 24, 2025 03:28
-
-
Save mcascardi/0e81913a46016113cac056ba678eae2b to your computer and use it in GitHub Desktop.
Wordpress wp-json API example using OOP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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 ?? []; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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