Last active
November 28, 2024 02:56
-
-
Save kvignos/fe24201fa2f972dde67e to your computer and use it in GitHub Desktop.
WIRED Day of REST 2016 Conference Presentation - Code Snippets
This file contains 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
// Author: Ross Patton (abbreviated by KV) | |
// Link to WIRED json feed | |
var apiUrl = 'http://' + location.host + '/wp-json/wp/v2/posts/'; | |
// Fallback if OBR not available | |
if ( typeof OBR === 'undefined' ) { | |
$( getAll('poweredByOutbrain') ).remove(); | |
return $.getJSON( apiUrl, function(res) { | |
if ( elementId === 'we-recommend' ) { | |
return smart.rec( get('we-recommend') ); | |
} | |
} | |
} |
This file contains 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
// Authors: Ross Patton, Kathleen Vignos, Tony Vongprachanh (abbreviated by KV) | |
smart = (function() { | |
/** | |
* @description functionality for latest news smart cards | |
*/ | |
var mostRecent = function( target ) { | |
var apiUrl = 'http://' + location.host + '/wp-json/wp/v2/posts/?_embed'; | |
function render( res ) { | |
var frag = document.createDocumentFragment(); | |
var data = res.slice( 0, 5 ); | |
data.forEach(function( value, i ) { | |
var currLi = document.createElement('li'); | |
var currAnchor = document.createElement('a'); | |
var currImg = document.createElement('img'); | |
var currAuth = document.createElement('span'); | |
var currTitle = document.createElement('h5'); | |
var postWrap = document.createElement('div'); | |
var currHr = document.createElement('hr'); | |
currLi.setAttribute( 'height', '108' ); | |
currLi.className = 'story-' + i; | |
// hides final 2 li if ad is tall | |
if ( i > 2 ) { | |
currLi.className += ' squish-hide'; | |
currHr.className += ' squish-hide'; | |
} | |
// create the anchor tag | |
currAnchor.setAttribute( 'href', value.link ); | |
currAnchor.className = 'clearfix pad'; | |
// create the img node | |
currImg.setAttribute( 'height', '75' ); | |
currImg.setAttribute( 'width', '75' ); | |
currImg.setAttribute( 'aria-hidden', 'true' ); | |
currImg.setAttribute( 'role', 'presentation' ); | |
currImg.className = 'thumb col mob-col-6 med-col-6 big-col-6'; | |
postWrap.className = 'col mob-col-12 med-col-12 big-col-12'; | |
currAuth.className = 'byline marg-b-micro'; | |
currAuth.appendChild( | |
document.createTextNode( value._embedded.author[0].name ) | |
); | |
currTitle.className = 'title exchange-sm'; | |
currTitle.innerHTML = value.title.rendered; | |
// currTime.className = 'marg-t-sm'; | |
// currTime.insertAdjacentHTML( 'beforeend', value.date_gmt ); | |
// append all these things together into the li | |
currLi.appendChild( currAnchor ); | |
currAnchor.appendChild( currImg ); | |
currAnchor.appendChild( postWrap ); | |
postWrap.appendChild( currAuth ); | |
postWrap.appendChild( currTitle ); | |
currHr.className = 'story-' + i; | |
// append everything to the frag | |
frag.appendChild( currLi ); | |
frag.appendChild( currHr ); | |
}); | |
// append frag to the dom | |
return target.appendChild( frag ); | |
} | |
return $.getJSON( apiUrl, render ); | |
}; | |
// expose | |
return { | |
rec: mostRecent | |
}; | |
}()); |
This file contains 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
{ | |
"role": "container", | |
"style": { | |
"backgroundColor": "#e1e1e1" | |
}, | |
"layout": "fullNoMarginIgnore", | |
"components": [ | |
{ | |
"role": "gallery", | |
"layout": "carouselLayoutNoTop", | |
"items": [ | |
{ | |
"path": "http://www.wired.com/wp-content/uploads/2016/01/CES_07-NEW-NEW2.jpg", | |
"URL": "bundle://CES_07-NEW-NEW2.jpg", | |
"caption": "Drones as far as the eye can see." | |
}, | |
{ | |
"path": "http://www.wired.com/wp-content/uploads/2016/01/CES_11-NEW-NEW2.jpg", | |
"URL": "bundle://CES_11-NEW-NEW2.jpg", | |
"caption": "There are still some old-school immersion tactics. This attendee is sitting through a pre-programmed routine to lower his heart rate and help him feel more relaxed." | |
}, | |
{ | |
"path": "http://www.wired.com/wp-content/uploads/2016/01/CES_08-NEW-NEW2.jpg", | |
"URL": "bundle://CES_08-NEW-NEW2.jpg", | |
"caption": "CES's infamous \"booth babes\" were, of course, back for 2016." | |
} | |
] | |
} | |
] | |
}, |
This file contains 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
{ | |
"role": "container", | |
"style": { | |
"backgroundColor": "#e1e1e1" | |
}, | |
"layout": "fullNoMarginIgnore", | |
"components": [ | |
{ | |
"role": "container", | |
"style": { | |
"backgroundColor": "#FFFFFF" | |
}, | |
"layout": "textBgContainerLayout", | |
"components": [ | |
{ | |
"role": "divider", | |
"layout": "thickTopDividerLayout", | |
"stroke": { | |
"color": "#000000", | |
"width": 25 | |
} | |
}, | |
{ | |
"role": "body", | |
"identifier": "textContainerWrap3", | |
"layout": "textContainerLayout", | |
"text": " You have to see CES to believe it. It's a mammoth show, spanning many days and multiple hotels and convention floors. But it's not just pure digital chaos; it's also something of a kitschy circus of humanity. People walk the floor, hoping to try the latest hot new things...and then fall asleep on the pavement outside the show. A big and beautiful neon mess, one that's better understood visually.", | |
"format": "markdown" | |
} | |
] | |
} | |
] | |
}, |
This file contains 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
"content": { | |
"rendered": "<p>You have to see CES to believe it. It’s a mammoth show, spanning many days and multiple hotels and convention floors. But it’s not just pure digital chaos; it’s also something of a kitschy circus of humanity. People walk the floor, hoping to try the latest hot new things…and then fall asleep on the pavement outside the show. A big and beautiful neon mess, one that’s better understood visually.</p>\n" | |
}, |
This file contains 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 | |
// Authors: Jake Spurlock and Kathleen Vignos (abbreviated by KV) | |
/** | |
* Register the Apple News endpoints | |
*/ | |
public function register_production_routes( $routes ) { | |
// Download a zip of all of the article assets. | |
register_rest_route( 'apple-news/v2', '/post/(?P<post_id>[\w-]+)/zip', array( | |
'methods' => WP_REST_Server::READABLE, | |
'callback' => array( $this, 'rest_download_zip' ), | |
'args' => array( | |
'post_id', | |
), | |
) ); | |
// Rendered post info for Apple News | |
register_rest_route( 'apple-news/v2', '/post/(?P<post_id>\w+)', array( | |
'methods' => WP_REST_Server::READABLE, | |
'callback' => array( $this, 'rest_post_output' ), | |
'args' => array( | |
'bundle', | |
'images', | |
'template', | |
), | |
) ); | |
// Get the article from Apple. This is the full data representation. | |
register_rest_route( 'apple-news/v2', '/article/(?P<post_id>[\w-]+)', array( | |
'methods' => WP_REST_Server::READABLE, | |
'callback' => array( $this, 'rest_get_article' ), | |
'args' => array( | |
'post_id', | |
), | |
) ); | |
} |
This file contains 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 | |
// Author: Zack Tollman (abbreviated by KV) | |
// **USES JSON REST API V1, written in late 2014 *** | |
public function __construct() { | |
// Push late to make sure all updates have executed | |
add_action( 'wp_insert_post', array( $this, 'notify_beta_site_post' ), 100, 3 ); | |
} | |
/** | |
* Notify the beta site that a data change has been made. | |
*/ | |
public function notify_beta_site_post( $post_id, $post, $update ) { | |
// Check the user's permissions. | |
if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) { | |
if ( ! current_user_can( 'edit_page', $post_id ) ) { | |
return; | |
} | |
} else { | |
if ( ! current_user_can( 'edit_post', $post_id ) ) { | |
return; | |
} | |
} | |
$this->update_object( $post_id, 'post' ); | |
} | |
/** | |
* Make the request to update the post. | |
* | |
*/ | |
public function update_object( $post_id, $object ) { | |
$this->make_request( $post_id, $object ); | |
} | |
/** | |
* Make a request to prompt data scraping. | |
*/ | |
public function make_request( $id, $object ) { | |
// Get the request URL | |
// example: 'http://www.wired.com/?beta-push=1'; | |
$request_url = $this->get_request_url(); | |
// Prepare the arguments for the request | |
$request_args = array( | |
'body' => array( | |
'id' => absint( $id ), | |
'object' => $object, | |
), | |
'headers' => array( | |
'api-key' => DATA_PUSH_API_KEY, | |
'api-secret' => DATA_PUSH_API_SECRET, | |
), | |
'blocking' => false, | |
); | |
// Post the request | |
$result = wp_remote_post( | |
$request_url, | |
$request_args | |
); | |
} |
This file contains 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 | |
// Author: Zack Tollman (abbreviated by KV) | |
// **USES JSON REST API V1, written in late 2014 *** | |
public function __construct() { | |
add_action( 'init', array( $this, 'route_pull_request' ), 11 ); | |
} | |
/** | |
* Monitor for a request to pull data. | |
*/ | |
public function route_pull_request() { | |
if ( ! $this->validate_request() ) { | |
return; | |
} | |
// Get the data needed to pull data | |
$id = $this->get_request_id(); | |
$object = $this->get_request_object(); | |
$data = $this->get_data( $id, 'post' ); | |
$result = $this->save_response_post( $id, $data ); | |
exit(); | |
} | |
/** | |
* Get the ID of the object being requested. | |
* | |
* @return int The post ID requesting a pull. | |
*/ | |
public function get_request_id() { | |
// Get the content of the request | |
$body = $this->$this->body; | |
return (int) $body['id']; | |
} | |
/** | |
* Get the type of object being requested. | |
* | |
* @return string The object type requesting a pull. | |
*/ | |
public function get_request_object() { | |
// Get the content of the request | |
$body = $this->$this->body; | |
return $body['object']; | |
} | |
/** | |
* Validate that a request for a pull has been received. | |
* | |
* @return bool True if the request is for a pull; false if it is not. | |
*/ | |
public function validate_request() { | |
if ( isset( $_GET['beta-push'] ) && 1 === (int) $_GET['beta-push'] ) { | |
$headers = getallheaders(); | |
$headers_present = false !== $headers; | |
$authed = isset( $headers['api-key'], $headers['api-secret'] ) && ( DATA_PUSH_API_KEY === $headers['api-key'] ) && ( DATA_PUSH_API_SECRET === $headers['api-secret'] ); | |
if ( $headers_present && $authed ) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Make a request to grab data for an object. | |
* | |
* @param int $id The ID of the object to get. | |
* @param string $object The type of the object to get. | |
* @return array The data for the request. | |
*/ | |
public function get_data( $id, $object ) { | |
$data = array(); | |
$request_url = get_request_url_post( $id ); | |
// example: https://www.wired.com/wp-json/posts/1234567?context=edit | |
// Make the JSON request | |
$response = wp_remote_get( | |
$request_url, | |
array_merge( | |
$args | |
) | |
); | |
if ( 200 === (int) wp_remote_retrieve_response_code( $response ) ) { | |
$body = json_decode( wp_remote_retrieve_body( $response ), true ); | |
// Check to make sure the data looks right | |
if ( isset( $body['ID'], $body['title'] ) ) { | |
$data = $body; | |
} | |
} | |
return $data; | |
} | |
/** | |
* Save the data for the post. | |
*/ | |
public function save_response_post( $id, $data ) { | |
$existing_post = get_post( $id ); | |
$prepared_data = $this->prepare_post_data( $data, $id ); | |
// Now, save the post itself | |
if ( empty( $existing_post ) ) { | |
// If the "ID" value is set, the method will think it's an update | |
if ( isset( $prepared_data['ID'] ) ) { | |
unset( $prepared_data['ID'] ); | |
} | |
$result = wp_insert_post( $prepared_data ); | |
} else { | |
// Update an existing post | |
$result = wp_update_post( $prepared_data ); | |
} | |
// Save the post meta | |
if ( is_int( $result ) && $result > 0 ) { | |
if ( isset( $data['post_meta'] ) ) { | |
foreach ( $data['post_meta'] as $meta ) { | |
/** | |
* Note that this will break serialized meta data. Our meta data does not include serialized meta data. | |
*/ | |
update_post_meta( $result, $meta['key'], $this->$meta['value'] ); | |
} | |
} | |
} | |
return $result; | |
} | |
/** | |
* Map JSON data to what is expected in wp_insert_post and wp_update_post. | |
*/ | |
public function prepare_post_data( $data, $id = 0 ) { | |
// Prepare the data to insert | |
$postarr = array( | |
// Defaults | |
'post_status' => $data['status'], | |
'post_type' => $data['type'], | |
'post_author' => $data['author']['ID'], | |
'ping_status' => $data['ping_status'], | |
'post_parent' => $data['parent'], | |
'menu_order' => $data['menu_order'], | |
'guid' => $data['guid'], | |
'post_excerpt' => $this->$data['excerpt_raw'], | |
'post_content' => $this->$data['content_raw'], | |
'post_title' => $data['title'], | |
'context' => '', | |
// Non-defaults | |
'post_name' => $data['slug'], | |
'post_date' => date_create( $data['date'] )->format( 'Y-m-d H:i:s' ), | |
'post_date_gmt' => date_create( $data['date_gmt'] )->format( 'Y-m-d H:i:s' ), | |
'comment_status' => $data['comment_status'], | |
); | |
// Append the post ID if it was passed | |
if ( absint( $id ) > 0 ) { | |
$postarr['ID'] = absint( $id ); | |
$postarr['import_id'] = absint( $id ); | |
} | |
return $postarr; | |
} |
This file contains 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
// Author: Zack Tollman (abbreviated by KV) | |
/** | |
* Send request to add a post to WordPress. | |
*/ | |
var addPost = function(preparedMessage, authorID) { | |
return new Promise( function(resolve, reject) { | |
// example wpAPIUrl: http://www.wired.com/wp-json/ | |
request( | |
extend( | |
requestBase, | |
{ | |
method: 'POST', | |
uri: config.wpAPIUrl() + '/liveblog', | |
body: { | |
type: 'liveblog', | |
status: 'publish', | |
title: preparedMessage.ts, | |
content: preparedMessage.text, | |
author: authorID, | |
featured_image: (preparedMessage.featuredImageID) ? preparedMessage.featuredImageID : 0 | |
} | |
} | |
), | |
function(err, httpResponse, body) { | |
if (err) { | |
log.info(err); | |
reject(err); | |
} else if (httpResponse.statusCode === 201 && body.id) { | |
log.info('Added post ' + body.id); | |
resolve(body.id); | |
} | |
reject(body); | |
} | |
); | |
}); | |
}; |
This file contains 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 | |
// Author: Zack Tollman (abbreviated by KV) | |
public function __construct() { | |
add_action( 'rest_api_init', array( $this, 'register_routes' ) ); | |
} | |
/** | |
* Register the API routes for the liveblogs. | |
*/ | |
public function register_routes() { | |
// example: http://www.wired.com/wp-json/wired/v2/liveblog/1949283/posts/ | |
// React script hits this endpoint to grab the post objects | |
register_rest_route( 'wired/v2', '/liveblog/(?P<post_id>\w+)/posts', array( | |
'methods' => WP_REST_Server::READABLE, | |
'callback' => array( $this, 'posts_callback' ), | |
'args' => array( | |
'post_id', | |
), | |
) ); | |
} | |
/** | |
* Get the individual posts associated with a liveblog. | |
*/ | |
public function get_liveblog_posts( $post_id ) { | |
$clean_posts = array(); | |
$liveblog_meta = get_post_meta( $post_id, '_liveblog', true ); | |
$channel = ( ! empty( $liveblog_meta['slack-channel-name'] ) ) ? $liveblog_meta['slack-channel-name'] : ''; | |
if ( ! empty( $channel ) ) { | |
// Query for the posts | |
$query = new WP_Query( array( | |
'posts_per_page' => 500, | |
'post_type' => array( wired_get_liveblog_post()->post_type ), | |
'tax_query' => array( | |
array( | |
'taxonomy' => wired_get_liveblog_post()->taxonomy, | |
'field' => 'name', | |
'terms' => $channel, | |
) | |
) | |
) ); | |
if ( $query->have_posts() ) { | |
while ( $query->have_posts() ) { | |
$query->the_post(); | |
$img_url = ''; | |
$thumb_id = get_post_thumbnail_id( get_the_ID() ); | |
if ( $thumb_id ) { | |
$img = wp_get_attachment_image_src( $thumb_id, '660-single-full' ); | |
if ( ! empty( $img[0] ) ) { | |
$img_url = esc_url( $img[0] ); | |
} | |
} | |
$clean_posts[] = array( | |
'id' => get_the_ID(), | |
'body' => apply_filters( 'the_content', get_the_content() ), | |
'author' => esc_attr( wp_strip_all_tags( $this->get_liveblog_byline( get_the_ID(), $post_id ) ) ), | |
'caption' => '', | |
'text' => '', // Likely can remove this | |
'source' => '', | |
'embed' => '', | |
'imgSrc' => esc_url( $img_url ), | |
'date' => get_the_date( 'm-d-Y' ), | |
'time' => get_the_date( 'h:i:s' ), | |
'zone' => 'PDT', | |
); | |
} | |
} | |
wp_reset_postdata(); | |
} | |
return $clean_posts; | |
} | |
/** | |
* Return the posts. | |
*/ | |
public function posts_callback( $request ) { | |
$posts = ''; | |
$params = $request->get_params(); | |
$post_id = ( isset( $params['post_id'] ) ) ? absint( $params['post_id'] ) : 0; | |
$liveblog_meta = get_post_meta( $post_id, '_liveblog', true ); | |
$posts = array( | |
'version' => time(), | |
'posts' => $this->get_liveblog_posts( $post_id ) | |
); | |
return $posts; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment