Better embeds with

Media Explorer

WP SLC 11/2014

 Hi, I'm Jeff.

WordPress / PHP Developer

Development Lead, Voce Communications

Overestimates snowboarding prowess

...what is

So...

Media Explorer?

Media Explorer is an

extensible embed tool,

built by Automattic, used on WordPress.com

Installation

Get the code

cd wp-content/plugins
git clone https://github.com/Automattic/media-explorer.git .

Clone the repository

or

https://github.com/Automattic/media-explorer/archive/master.zip

Add credentials to mexp-creds.php

add_filter( 'mexp_twitter_credentials', 'mexp_twitter_credentials_callback' );

function mexp_twitter_credentials_callback() {

    return array(
	'consumer_key'       => '',
	'consumer_secret'    => '',
	'oauth_token'        => '',
	'oauth_token_secret' => ''
    );

}

add_filter( 'mexp_youtube_developer_key', 'mexp_youtube_developer_key_callback' );

function mexp_youtube_developer_key_callback() {

    return '';

}

add_filter( 'mexp_instagram_credentials', 'mexp_instagram_credentials_callback' );

function mexp_instagram_credentials_callback( $credentials ) {

    return array( 
	'access_token' => '',
    );

}

Activate the plugin

Activate oAuth Credentials as well (mexp-creds.php)

Adding a Service

Write some code

MEXP_Service

MEXP_Template

Register service

Subclass

MEXP_Service

<?php

abstract class MEXP_Service {

	public $template = null;

	/**
	 * Handles the AJAX request and returns an appropriate response. This should be used, for
	 * example, to perform an API request to the service provider and return the results.
	 *
	 * @param array $request The request parameters.
	 * @return Response|false|WP_Error A Response object should be returned on success, boolean false should be returned if there are no results to show, and a WP_Error should be returned if there is an error.
	 */
	abstract function request( array $request );

	/**
	 * Returns an array of custom text labels for this service. See the get_labels() method for default labels.
	 *
	 * @return array Associative array of labels.
	 */
	abstract function labels( array $labels );

	/**
	 * Returns an array of tabs (routers) for the service's media manager panel.
	 *
	 * @return array Associative array of tabs. The key is the tab ID and the value is an array of tab attributes.
	 */
	abstract function tabs( array $tabs );

	/**
	 * Fired when the service is loaded. Allows the service to enqueue JS/CSS only when it's required. Akin to WordPress' load action.
	 *
	 * @return null
	 */
	public function load() {}

}

MEXP_Template

<?php

abstract class MEXP_Template {

	/**
	 * Outputs the Backbone template for an item within search results.
	 *
	 * @param string $id  The template ID.
	 * @param string $tab The tab ID.
	 * @return null
	 */
	abstract public function item( $id, $tab );

	/**
	 * Outputs the Backbone template for a select item's thumbnail in the footer toolbar.
	 *
	 * @param string $id The template ID.
	 * @return null
	 */
	abstract public function thumbnail( $id );

	/**
	 * Outputs the Backbone template for a tab's search fields.
	 *
	 * @param string $id  The template ID.
	 * @param string $tab The tab ID.
	 * @return null
	 */
	abstract public function search( $id, $tab );

}

Register the service

<?php

/**
 * Create our new service. Everything starts here.
 *
 * @param array $services Associative array of Media Explorer services to load
 * @return array $services Associative array of Media Explorer services to load
 */
function test_mexp_service_new( array $services ) {

    // This key name is important.
    // You must use the same name for the tabs() and labels() methods in Test_MEXP_New_Service. 
    $services['test_mexmp_service'] = new Test_MEXP_New_Service;
    return $services;

}

add_filter( 'mexp_services', 'test_mexp_service_new' );

Demo

Getting Creative

Can we add a non-URL?

foreach ( $response_data->results as $event ) {

    $item = new MEXP_Response_Item();
    
    $item->set_id( $event->id );
    $item->set_url( $event->event_url );
    $item->set_content( $event->name );
    $item->set_date( ( $event->time / 1000 ) + ( $event->utc_offset / 1000 ) );
    $item->set_date_format( 'l, M j, Y, g:i A' );
    
    $item->add_meta( 'description', isset( $event->description ) ? $event->description : '' );
    $item->add_meta( 'group', (array) $event->group );

    $mexp_response->add_item( $item );

}
/**
 * Response Item class. Used within the Response class to populate the items in a response.
 */
final class MEXP_Response_Item {

    ....

    /**
     * Set the URL for the response item.
     *
     * @param string $url The response item URL.
     * @return null
     */
    public function set_url( $url ) {
        $this->url = esc_url_raw( $url );
    }

    ....

}
/**
 * Response Item class. Used within the Response class to populate the items in a response.
 */
final class MEXP_Response_Item {

    public $id          = null;
    public $url         = null;
    public $thumbnail   = null;
    public $content     = null;
    public $date        = null;
    public $date_format = null;
    public $meta        = array();

    /**
     * Set the URL for the response item.
     *
     * @param string $url The response item URL.
     * @return null
     */
    public function set_url( $url ) {
        $this->url = esc_url_raw( $url );
    }

    ....

}

 Yes.

Adding a shortcode

foreach ( $query->posts as $post ) {

    $item = new MEXP_Response_Item();
    
    $item->set_content( $post->post_title );
    $item->set_date( strtotime( $post->post_date ) );
    $item->set_date_format( 'g:i A - j M y' );
    $item->set_id( $post->ID );
    $item->url = sprintf( '[post id="%d"]', $post->ID );
    
    $thumbnail_id = get_post_thumbnail_id( $post->ID );
    
    if ( $thumbnail_id ) {
    
        $image = wp_get_attachment_image_src( $thumbnail_id );
        
        $item->set_thumbnail( $image[0] );
        
    } else {
    
        $item->set_thumbnail( plugins_url( 'placeholder.jpg', __FILE__ ) );
    
    }
    
    $response->add_item( $item );

}

Demo

Reusing Components

Just a demo

Resources

Code from this talk

Media Explorer Plugin Boilerplate

Extending Media Explorer

Media Explorer Source Code

Thank You

Questions?

Email me

Github