Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Connecting Content Silos: One CMS, Many Sites With The WordPress REST API

4,577 views

Published on

Combining content from multiple WordPress sites using the WordPress REST API.

http://joshpress.net/wordpress-rest-api-as-connector/

#wpcamus

Published in: Software
  • Be the first to comment

Connecting Content Silos: One CMS, Many Sites With The WordPress REST API

  1. 1. @Josh412 Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
  2. 2. @Josh412 CalderaLabs.org Hi I'm Josh Lead Developer: CalderaWP I make WordPress plugins I teach about WordPress I wrote a book about the WordPress REST API I am core contributor to WordPress I am a member of The WPCrowd
  3. 3. @Josh412 CalderaLabs.org Introduction: What Is The REST API? And why do we care?
  4. 4. @Josh412 CalderaLabs.org The WordPress REST API Is Two Things
  5. 5. @Josh412 REST API Infrastructure Tools for making REST APIs with WordPress Included in WordPress 4.4+ The WordPress REST API Default Routes WordPress CRUD via REST API for WordPress content wordpress.org/plugins/rest-api
  6. 6. @Josh412 Using The REST API For Posts yoursite.com/wp-json/wp/v2/posts First page of posts yoursite.com/wp-json/wp/v2/posts?page=2 Second page of post yoursite.com/wp-json/wp/v2/posts/42 Post 42
  7. 7. @Josh412 Learn More: Basics Course: learn.JoshPress.net Book: JPWP.me/rest-book More: JoshPress.net/rest-api
  8. 8. @Josh412 CalderaLabs.org Introduction: Strategies For Combining CMSs Why Do We Want To Do This?
  9. 9. @Josh412 Ways To Combine Posts With REST API Client-side Server-side Other Ways RSS Database sync Scrape content
  10. 10. @Josh412 CalderaLabs.org Example One: JavaScript + Static HTML What If We Have No CMS?
  11. 11. @Josh412 CalderaLabs.org Why Client-side? No database, no server-side- scripting? No Problem!
  12. 12. @Josh412 CalderaLabs.org Why Client-side? Local Storage!
  13. 13. @Josh412 var posts1, posts2, posts; $.get( 'https://calderawp.com/wp-json/wp/v2/posts' ).done( function( r ){ posts1 = r; }); $.get( 'https://IngotHQ.com/wp-json/wp/v2/posts' ).done( function( r ){ posts2 = r; }); //errors are about to happen posts = posts1.concat( posts2 ); console.log( posts ); Promises Will Be Needed!
  14. 14. @Josh412 Promises $.when( //one or more functions that return a promise ).then( function(){ //stuff to do after all promises are resolved });
  15. 15. @Josh412 Promises var posts; $.when( $.get( 'https://calderawp.com/wp-json/wp/v2/posts' ).done( function( r ){ return r; }), $.get( 'https://IngotHQ.com/wp-json/wp/v2/posts' ).done( function( r ){ posts2 = r; }) ).then( function( d1, d2 ) { posts = d1[0].concat( d2[0] ); console.log( posts ); });
  16. 16. @Josh412 API For AJAX and Local Storage function api( url ) { var key = 'clCachez' + url.replace(/^https?:///i, ""); var local = localStorage.getItem( key ); //this line uses underscores.js!! if ( ! _.isString( local ) || "null" == local ) { return $.get( url ).then( function ( r ) { localStorage.setItem( key, JSON.stringify( r ) ); return r; } ); } else { return JSON.parse( local ); } };
  17. 17. @Josh412 Sorting function merge( obj1, obj2 ) { var merged; a1 = _.toArray(obj1); a2 = _.toArray(obj2); merged = a1.concat(a2); return merged; }; function sort( list, sort ) { var sorted = _.sortBy( list, sort ); return sorted.reverse(); };
  18. 18. @Josh412 Templating <script type="text/html" id="tmpl--multiblog"> <article class="entry multi-blog-{{prefix}}"> <span class="image"> <img src="placeholder.png" alt="" class="img-{{prefix}}" data-media-id="{{featured_media}}" /> </span> <a href="{{link}}" title="Read Full Post"> <h2>{{title.rendered}}</h2> <div class="content"> <p>{{excerpt.rendered}}</p> </div> </a> </article> </script>
  19. 19. @Josh412 Templating var posts; $.when( getCWP(), getIngot() ).then( function( d1, d2 ) { var all = merge( d1, d2 ); all = sort( all, 'date' ); _.templateSettings = { interpolate: /{{(.+?)}}/g }; var html = ''; var templateHTML = document.getElementById( 'tmpl--multiblog' ).innerHTML; var template = _.template( templateHTML ); var item, templatedItem; $.each( all, function ( i, post ) { templatedItem = template( post ); html += templatedItem; }); document.getElementById( 'posts' ).innerHTML = html; });
  20. 20. @Josh412 Learn More: Client-Side Solution All Example Code: jpwp.me/wpc-js-ex Article: torquemag.io/2016/07/combine-wordpress- sites-rest-api/ See It In Action: CalderaLabs.org/blog.html github.com/CalderaWP/calderawp.github.io
  21. 21. @Josh412 CalderaLabs.org Example Two PHP + Server-Side Caching Wouldn't It Be Better To Cache Server Side?
  22. 22. @Josh412 Structure -- plugin ---- Endpoint ---- MultiBlog $caldera = new Endpoint( 'https://CalderaWP.com/wp-json/wp/v2/posts' ); $ingot = new Endpoint( 'https://IngotHQ.com/wp-json/wp/v2/posts' ); $multi = new MultiBlog( 1 ); $posts = $multi->get_posts();
  23. 23. @Josh412 Settings Up Endpoints class Endpoint { /** @var string */ protected $url; /** @var array */ protected $posts = []; public function __construct( $url ){ $this->url = $url; $this->get_cache(); } //REST OF THE CLASS… }
  24. 24. @Josh412 Settings Up Endpoints class Endpoint { /** @var string */ protected $url; /** @var array */ protected $posts = []; public function __construct( $url ){ $this->url = $url; $this->get_cache(); } //REST OF THE CLASS… }
  25. 25. @Josh412 Caching Responses protected function set_cache(){ if ( ! empty( $this->posts ) ) { set_transient( $this->cache_key(), $this->posts, DAY_IN_SECONDS ); } } protected function get_cache(){ if( is_array( $posts = get_transient( $this->cache_key() ) ) ){ $this->posts = $posts; } } protected function cache_key(){ return md5( preg_replace( "(^https?://)", "", $this->url ) ); }
  26. 26. @Josh412 Querying Endpoints public function get_posts( $page = 1){ if( isset( $this->posts[ $page ] ) ){ return $this->posts[ $page ]; }else{ $this->make_request( $page ); if( isset( $this->posts[ $page ] ) ) { return $this->posts[ $page ]; } } return []; } protected function make_request( $page ){ $request = wp_remote_get( add_query_arg( 'page', (int) $page, $this->url ) ); if( ! is_wp_error( $request ) && 200 == wp_remote_retrieve_response_code( $request ) ){ $this->posts[ $page ] = json_decode( wp_remote_retrieve_body( $request ) ); } }
  27. 27. @Josh412 Merging Our Endpoints class MultiBlog { /** @var array */ protected $posts = []; /** @var array */ protected $endpoints = []; /** @var bool */ protected $looped = false; /** @var int */ protected $page; public function __construct( $page = 1 ){ $this->page = 1; } public function add_endpoint( Endpoint $endpoint ){ $this->endpoints[] = $endpoint; } //REST OF CLASS… }
  28. 28. @Josh412 Merging Our Endpoints class MultiBlog { /** @var array */ protected $posts = []; /** @var array */ protected $endpoints = []; /** @var bool */ protected $looped = false; /** @var int */ protected $page; public function __construct( $page = 1 ){ $this->page = 1; } public function add_endpoint( Endpoint $endpoint ){ $this->endpoints[] = $endpoint; } //REST OF CLASS… }
  29. 29. @Josh412 Merging Our Endpoints protected function merge(){ if( ! empty ( $this->endpoints ) ){ /** @var Endpoint $endpoint */ foreach ( $this->endpoints as $endpoint ){ $this->posts[] = $endpoint->get_posts( $this->page ); } $this->posts = $this->sort( $this->posts ); } } protected function sort( array $data ){ usort( $data, function ( $a, $b ) { return strtotime( $a->date ) - strtotime( $b->date ); } ); return array_reverse( $data ); }
  30. 30. @Josh412 Collecting The Posts public function get_posts( $page = 1 ){ if( isset( $this->posts[ $page ] ) ){ return $this->posts[ $page ]; }else{ $this->merge(); if( ! empty( $this->posts ) ){ return $this->posts; } } return []; }
  31. 31. @Josh412 Putting It Together function multiBlogPosts( $page ) { $caldera = new Endpoint( 'https://CalderaWP.com/wp-json/wp/v2/posts' ); $ingot = new Endpoint( 'https://IngotHQ.com/wp-json/wp/v2/posts' ); $multi = new MultiBlog( 1 ); return $multi->get_posts( $page ); }
  32. 32. @Josh412 Learn More: Server-Side Solution All Example Code: jpwp.me/wpc-ex-php Article: torquemag.io/2016/07/combine-wordpress- sites-rest-api-php/ Widget To Show Remote Posts: github.com/Shelob9/remote-recent-posts
  33. 33. @Josh412 CalderaLabs.org Thanks! Any questions?
  34. 34. @Josh412 CalderaLabs.org Josh Pollock JoshPress.net CalderaLabs.org CalderaWP.com IngotHQ.com @Josh412

×