Skip to content

Commit

Permalink
feat: Basic video playlist block
Browse files Browse the repository at this point in the history
  • Loading branch information
claudiulodro committed Jan 29, 2020
1 parent 3add1f0 commit d66485a
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 2 deletions.
2 changes: 1 addition & 1 deletion block-list.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"production": [ "carousel", "donate", "homepage-articles" ]
"production": [ "carousel", "donate", "homepage-articles", "video-playlist" ]
}
14 changes: 14 additions & 0 deletions class-newspack-blocks-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ public static function newspack_blocks_get_primary_category( $object ) {

return $category->name;
}

public static function register_video_playlist_endpoint() {
register_rest_route( 'newspack-blocks/v1', '/video-playlist', [
'methods' => 'GET',
'callback' => [ 'Newspack_Blocks_API', 'video_playlist_endpoint' ],
]
);
}

public static function video_playlist_endpoint( $request ) {
$args = $request->get_params();
return new \WP_REST_Response( newspack_blocks_get_video_playlist( $args ), 200 );
}
}

add_action( 'rest_api_init', array( 'Newspack_Blocks_API', 'register_rest_fields' ) );
add_action( 'rest_api_init', array( 'Newspack_Blocks_API', 'register_video_playlist_endpoint' ) );
2 changes: 1 addition & 1 deletion newspack-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

define( 'NEWSPACK_BLOCKS__BLOCKS_DIRECTORY', 'dist/' );
define( 'NEWSPACK_BLOCKS__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'NEWSPACK_BLOCKS__VERSION', '1.0.0-alpha.24' );
define( 'NEWSPACK_BLOCKS__VERSION', rand().'1.0.0-alpha.24' );

require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'class-newspack-blocks.php';
require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'class-newspack-blocks-api.php';
Expand Down
76 changes: 76 additions & 0 deletions src/blocks/video-playlist/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { Component, Fragment } from '@wordpress/element';
import { Placeholder, Spinner } from '@wordpress/components';

class Edit extends Component {
constructor( props ) {
super( props );
this.state = {
isLoading: false,
error: '',
embed: '',
};
}

componentDidMount() {
this.getSettings();
}

getSettings() {
const path = '/newspack-blocks/v1/video-playlist';

this.setState( { isLoading: true }, () => {
apiFetch( { path } )
.then( response => {
const { html } = response;
this.setState( {
embed: html,
isLoading: false,
} );
} )
.catch( error => {
this.setState( {
isLoading: false,
error: error.message,
} );
} );
} );
}

renderPlaceholder() {
const { isLoading, error } = this.state;

if ( isLoading ) {
return <Placeholder icon={ <Spinner /> } className="component-placeholder__align-center" />;
}

if ( error.length ) {
return (
<Placeholder
icon="warning"
label={ __( 'Error', 'newspack-blocks' ) }
instructions={ error }
/>
);
}

return null;
}

render() {
const { embed } = this.state;

return (
<Fragment>
{ this.renderPlaceholder() }
<div className="wp-block-embed__wrapper" dangerouslySetInnerHTML={ { __html: embed } } />
</Fragment>
);
}
}

export default Edit;
7 changes: 7 additions & 0 deletions src/blocks/video-playlist/editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Internal dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
import { name, settings } from '.';

registerBlockType( `newspack-blocks/${ name }`, settings );
7 changes: 7 additions & 0 deletions src/blocks/video-playlist/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import '../../shared/sass/colors';
@import '../../shared/sass/placeholder';

.wp-block-newspack-blocks-video-playlist {
background: $color__primary;
border: 5px solid red;
}
61 changes: 61 additions & 0 deletions src/blocks/video-playlist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* External dependencies
*/
import { Path, SVG } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import edit from './edit';

/**
* Style dependencies - will load in editor
*/
import './editor.scss';
import './view.scss';

export const name = 'video-playlist';
export const title = __( 'Video Playlist', 'newspack-blocks' );

/* From https://material.io/tools/icons */
export const icon = (
<SVG xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
<Path d="M0 0h24v24H0V0z" fill="none" />
<Path d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9 8H3V9h9v2zm0-4H3V5h9v2z" />
</SVG>
);

export const settings = {
title,
icon,
category: 'newspack',
keywords: [
__( 'video', 'newspack-blocks' ),
__( 'playlist', 'newspack-blocks' ),
__( 'youtube', 'newspack-blocks' ),
],
description: __( 'Embed a playlist of latest or specific YouTube videos.', 'newspack-blocks' ),
attributes: {
className: {
type: 'string',
},
manual: {
type: 'boolean',
},
videos: {
type: 'array',
default: [],
},
categories: {
type: 'array',
default: [],
},
},
supports: {
html: false,
// align: false,
},
edit,
save: () => null, // to use view.php
};
5 changes: 5 additions & 0 deletions src/blocks/video-playlist/view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Style dependencies
*/

import './view.scss';
133 changes: 133 additions & 0 deletions src/blocks/video-playlist/view.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
/**
* Server-side rendering of the `newspack-blocks/video-playlist` block.
*
* @package WordPress
*/

/**
* Renders the `newspack-blocks/video-playlist` block on server.
*
* @param array $attributes The block attributes.
*
* @return string
*/
function newspack_blocks_render_block_video_playlist( $attributes ) {
Newspack_Blocks::enqueue_view_assets( 'video-playlist' );

$videos = newspack_blocks_get_video_playlist( $attributes );
return $videos['html'];
}

/**
* Registers the `newspack-blocks/donate` block on server.
*/
function newspack_blocks_register_video_playlist() {
register_block_type(
'newspack-blocks/video-playlist',
array(
'attributes' => array(
'className' => [
'type' => 'string',
],
'manual' => [
'type' => 'boolean',
],
'videos' => [
'type' => 'array',
'default' => [],
],
'categories' => [
'type' => 'array',
'default' => [],
],
),
'render_callback' => 'newspack_blocks_render_block_video_playlist',
)
);
}
add_action( 'init', 'newspack_blocks_register_video_playlist' );

function newspack_blocks_get_video_playlist( $args ) {
$defaults = [
'categories' => [],
'videos' => [],
'limit' => 5,
];
$args = wp_parse_args( $args, $defaults );

if ( $args['videos'] ) {
$videos = array_map( 'esc_url_raw', $args['videos'] );
} else {
$videos = newspack_blocks_get_video_playlist_videos( $args );
}

$html = '';
if ( $videos ) {
$html = newspack_blocks_get_video_playlist_html( $videos );
}

return [
'videos' => $videos,
'html' => $html,
];
}

function newspack_blocks_get_video_playlist_videos( $args ) {
$defaults = [
'categories' => [],
'limit' => 5,
];
$args = wp_parse_args( $args, $defaults );

$query_args = [
'post_type' => 'post',
'post_status' => 'publish',
's' => 'core-embed/youtube',
'posts_per_page' => $args['limit'],
];

$videos = [];
$posts = get_posts( $query_args );
foreach ( $posts as $post ) {
$blocks = parse_blocks( $post->post_content );
$youtube_blocks = array_filter( $blocks, function( $blocks ) {
return 'core-embed/youtube' === $blocks['blockName'];
} );
foreach ( $youtube_blocks as $youtube_block ) {
$videos[] = $youtube_block['attrs']['url'];
}
}

return array_slice( array_unique( $videos ), 0, $args['limit'] );
}

function newspack_blocks_get_video_playlist_html( $videos ) {
$video_ids = [];
foreach ( $videos as $video ) {
$url_parts = wp_parse_url( $video );
if ( empty( $url_parts['query'] ) ) {
continue;
}

wp_parse_str( $url_parts['query'], $query_parts );
if ( ! empty( $query_parts['v'] ) ) {
$video_ids[] = $query_parts['v'];
}
}

if ( empty( $video_ids ) ) {
return '';
}

$url = 'https://www.youtube.com/embed/' . $video_ids[0] . '?rel=0&showinfo=1';
if ( count( $video_ids ) > 1 ) {
$url .= '&playlist=' . implode( ',', array_slice( $video_ids, 1 ) );
}

ob_start();
?>
<iframe width="560" height="315" src="<?php echo esc_attr( $url ); ?>" frameborder="0" allowfullscreen></iframe>
<?php
return ob_get_clean();
}
Empty file.

0 comments on commit d66485a

Please sign in to comment.