From aad5e230cff42385f7a6b00083be4973d3adf0d7 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 14:49:32 +0100 Subject: [PATCH 01/11] Rename poster post meta key --- includes/Media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Media.php b/includes/Media.php index cf3935204f9e..050fa965593f 100644 --- a/includes/Media.php +++ b/includes/Media.php @@ -70,7 +70,7 @@ class Media { * * @var string */ - const POSTER_POST_META_KEY = 'amp_is_poster'; + const POSTER_POST_META_KEY = '_web_stories_is_poster'; /** * Init. From e2035640c68842f84707fa76c9e823fd4f0c881b Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 14:49:44 +0100 Subject: [PATCH 02/11] Rename potentially used filter --- includes/Story_Post_Type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index 95791aaecb81..e54cc277d1d4 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -274,7 +274,7 @@ public static function admin_enqueue_scripts( $hook ) { * * @param array Allowed video mime types. */ - $allowed_video_mime_types = apply_filters( 'amp_story_allowed_video_types', [ 'video/mp4' ] ); + $allowed_video_mime_types = apply_filters( 'web_stories_allowed_video_types', [ 'video/mp4' ] ); // If `$allowed_video_mime_types` doesn't have valid data or is empty add default supported type. if ( ! is_array( $allowed_video_mime_types ) || empty( $allowed_video_mime_types ) ) { From f851182ed10c9af7c2c80bfae9f13abd4c37915f Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 14:49:51 +0100 Subject: [PATCH 03/11] Remove unused filter --- includes/Story_Post_Type.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index e54cc277d1d4..7787e4e40f95 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -284,29 +284,6 @@ public static function admin_enqueue_scripts( $hook ) { // Only add currently supported mime types. $allowed_video_mime_types = array_values( array_intersect( $allowed_video_mime_types, wp_get_mime_types() ) ); - /** - * Filters the list of allowed post types for use in page attachments. - * - * @since 1.3 - * - * @param array Allowed post types. - */ - $page_attachment_post_types = apply_filters( - 'amp_story_allowed_page_attachment_post_types', - [ - 'page', - 'post', - ] - ); - $post_types = []; - foreach ( $page_attachment_post_types as $post_type ) { - $post_type_object = get_post_type_object( $post_type ); - - if ( $post_type_object ) { - $post_types[ $post_type ] = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; - } - } - $post = get_post(); $story_id = ( $post ) ? $post->ID : null; $post_type_object = get_post_type_object( self::POST_TYPE_SLUG ); @@ -322,7 +299,6 @@ public static function admin_enqueue_scripts( $hook ) { 'id' => 'edit-story', 'config' => [ 'allowedVideoMimeTypes' => $allowed_video_mime_types, - 'allowedPageAttachmentPostTypes' => $post_types, 'postType' => self::POST_TYPE_SLUG, 'postThumbnails' => $post_thumbnails, 'storyId' => $story_id, From 429ddc79e35184c875e29a569387f0c203f2f39a Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 15:09:46 +0100 Subject: [PATCH 04/11] Hardcode kses list --- includes/Story_Post_Type.php | 120 +++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 20 deletions(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index 7787e4e40f95..a7f351443a44 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -447,28 +447,108 @@ public static function admin_body_class( $class ) { * @return array Allowed tags. */ public static function filter_kses_allowed_html( $allowed_tags ) { - if ( ! class_exists( '\AMP_Allowed_Tags_Generated' ) ) { - return $allowed_tags; - } - $story_components = [ - 'amp-story', - 'amp-story-page', - 'amp-story-grid-layer', - 'amp-story-cta-layer', - 'amp-story-page-attachment', - 'amp-img', - 'amp-video', - 'img', + 'amp-story' => [ + 'background-audio' => true, + 'live-story' => true, + 'live-story-disabled' => true, + 'poster-landscape-src' => true, + 'poster-portrait-src' => true, + 'poster-square-src' => true, + 'publisher' => true, + 'publisher-logo-src' => true, + 'standalone' => true, + 'supports-landscape' => true, + 'title' => true, + ], + 'amp-story-page' => [ + 'auto-advance-after' => true, + 'background-audio' => true, + 'id' => true, + ], + 'amp-story-page-attachment' => [ + 'theme' => true, + ], + 'amp-story-grid-layer' => [ + 'position' => true, + 'template' => true, + ], + 'amp-story-cta-layer' => [], + 'amp-img' => [ + 'alt' => true, + 'attribution' => true, + 'data-amp-bind-alt' => true, + 'data-amp-bind-attribution' => true, + 'data-amp-bind-src' => true, + 'data-amp-bind-srcset' => true, + 'lightbox' => true, + 'lightbox-thumbnail-id' => true, + 'media' => true, + 'noloading' => true, + 'object-fit' => true, + 'object-position' => true, + 'placeholder' => true, + 'src' => true, + 'srcset' => true, + ], + 'amp-video' => [ + 'album' => true, + 'alt' => true, + 'artist' => true, + 'artwork' => true, + 'attribution' => true, + 'autoplay' => true, + 'controls' => true, + 'controlslist' => true, + 'crossorigin' => true, + 'data-amp-bind-album' => true, + 'data-amp-bind-alt' => true, + 'data-amp-bind-artist' => true, + 'data-amp-bind-artwork' => true, + 'data-amp-bind-attribution' => true, + 'data-amp-bind-controls' => true, + 'data-amp-bind-controlslist' => true, + 'data-amp-bind-loop' => true, + 'data-amp-bind-poster' => true, + 'data-amp-bind-preload' => true, + 'data-amp-bind-src' => true, + 'data-amp-bind-title' => true, + 'disableremoteplayback' => true, + 'dock' => true, + 'lightbox' => true, + 'lightbox-thumbnail-id' => true, + 'loop' => true, + 'media' => true, + 'muted' => true, + 'noaudio' => true, + 'noloading' => true, + 'object-fit' => true, + 'object-position' => true, + 'placeholder' => true, + 'poster' => true, + 'preload' => true, + 'rotate-to-fullscreen' => true, + 'src' => true, + ], + 'img' => [ + 'alt' => true, + 'attribution' => true, + 'border' => true, + 'decoding' => true, + 'height' => true, + 'importance' => true, + 'intrinsicsize' => true, + 'ismap' => true, + 'loading' => true, + 'longdesc' => true, + 'sizes' => true, + 'src' => true, + 'srcset' => true, + 'srcwidth' => true, + ], ]; - foreach ( $story_components as $story_component ) { - $attributes = array_fill_keys( array_keys( \AMP_Allowed_Tags_Generated::get_allowed_attributes() ), true ); - $rule_specs = \AMP_Allowed_Tags_Generated::get_allowed_tag( $story_component ); - foreach ( $rule_specs as $rule_spec ) { - $attributes = array_merge( $attributes, array_fill_keys( array_keys( $rule_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] ), true ) ); - } - $allowed_tags[ $story_component ] = $attributes; - } + + array_merge( $allowed_tags, $story_components ); foreach ( $allowed_tags as &$allowed_tag ) { $allowed_tag['animate-in'] = true; From ad22313a64d0a2e508c348a2973751dc04a23ce0 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 15:09:50 +0100 Subject: [PATCH 05/11] lint fixes --- includes/Story_Post_Type.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index a7f351443a44..cf1862bcf75e 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -298,12 +298,12 @@ public static function admin_enqueue_scripts( $hook ) { [ 'id' => 'edit-story', 'config' => [ - 'allowedVideoMimeTypes' => $allowed_video_mime_types, - 'postType' => self::POST_TYPE_SLUG, - 'postThumbnails' => $post_thumbnails, - 'storyId' => $story_id, - 'previewLink' => get_preview_post_link( $story_id ), - 'api' => [ + 'allowedVideoMimeTypes' => $allowed_video_mime_types, + 'postType' => self::POST_TYPE_SLUG, + 'postThumbnails' => $post_thumbnails, + 'storyId' => $story_id, + 'previewLink' => get_preview_post_link( $story_id ), + 'api' => [ 'stories' => sprintf( '/wp/v2/%s', $rest_base ), 'media' => '/wp/v2/media', 'users' => '/wp/v2/users', From 36cc547e9c70f39bff778aaa7a4383a743a8edb7 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 28 Jan 2020 15:32:50 +0100 Subject: [PATCH 06/11] Handle structured data and fallback images --- assets/images/fallback-poster.jpg | Bin 0 -> 21897 bytes .../fallback-wordpress-publisher-logo.png | Bin 0 -> 7939 bytes includes/Story_Post_Type.php | 99 +++++++++++++++++- includes/templates/single-web-story.php | 12 ++- 4 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 assets/images/fallback-poster.jpg create mode 100644 assets/images/fallback-wordpress-publisher-logo.png diff --git a/assets/images/fallback-poster.jpg b/assets/images/fallback-poster.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5132a1761e1b4f74142dbb655889260fb9eb7d48 GIT binary patch literal 21897 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 M0{^!Y0PKwXKk~kfzyJUM literal 0 HcmV?d00001 diff --git a/assets/images/fallback-wordpress-publisher-logo.png b/assets/images/fallback-wordpress-publisher-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..65ed1497f6adcad4dfd40dbca62f5ad2e369acba GIT binary patch literal 7939 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, true ); @@ -379,7 +380,7 @@ public static function load_fonts( $post ) { /** * Load font in admin from story data. * - * @param \WP_Post $post Post Object. + * @param WP_Post $post Post Object. */ public static function load_admin_fonts( $post ) { $post_story_data = json_decode( $post->post_content_filtered, true ); @@ -575,4 +576,94 @@ public static function filter_template_include( $template ) { return $template; } + + /** + * Get the publisher logo. + * + * @link https://developers.google.com/search/docs/data-types/article#logo-guidelines + * @link https://amp.dev/documentation/components/amp-story/#publisher-logo-src-guidelines + * + * @return string Publisher logo image URL. WordPress logo if no site icon or custom logo defined, and no logo provided via 'amp_site_icon_url' filter. + */ + private static function get_publisher_logo() { + $logo_image_url = null; + + // This should be square, at least 96px in width/height. The 512 is used because the site icon would have this size generated. + $logo_width = 512; + $logo_height = 512; + + // Use the Custom Logo if set, but only if it is square. + $custom_logo_id = get_theme_mod( 'custom_logo' ); + if ( has_custom_logo() && $custom_logo_id ) { + $custom_logo_img = wp_get_attachment_image_src( $custom_logo_id, [ $logo_width, $logo_height ], false ); + if ( $custom_logo_img && ( $custom_logo_img[2] === $custom_logo_img[1] ) ) { + $logo_image_url = $custom_logo_img[0]; + } + } + + // Try Site Icon, though it is not ideal for non-Story because it should be square. + $site_icon_id = get_option( 'site_icon' ); + if ( empty( $logo_image_url ) && $site_icon_id ) { + $site_icon_src = wp_get_attachment_image_src( $site_icon_id, [ $logo_width, $logo_height ], false ); + if ( ! empty( $site_icon_src ) ) { + $logo_image_url = $site_icon_src[0]; + } + } + + // Fallback to serving the WordPress logo. + if ( empty( $logo_image_url ) ) { + $logo_image_url = plugin_dir_url( WEBSTORIES_PLUGIN_FILE ) . 'assets/images/fallback-wordpress-publisher-logo.png'; + } + + return $logo_image_url; + } + + /** + * Get schema.org metadata for the current query. + * + * @return array $metadata All schema.org metadata for the post. + */ + public static function get_schemaorg_metadata() { + $metadata = [ + '@context' => 'http://schema.org', + 'publisher' => [ + '@type' => 'Organization', + 'name' => get_bloginfo( 'name' ), + ], + ]; + + $publisher_logo = self::get_publisher_logo(); + + if ( $publisher_logo ) { + $metadata['publisher']['logo'] = $publisher_logo; + } + + $post = get_queried_object(); + + $metadata = array_merge( + $metadata, + [ + '@type' => 'BlogPosting', + 'mainEntityOfPage' => get_permalink(), + 'headline' => get_the_title(), + 'datePublished' => mysql2date( 'c', $post->post_date_gmt, false ), + 'dateModified' => mysql2date( 'c', $post->post_modified_gmt, false ), + ] + ); + + $post_author = get_userdata( $post->post_author ); + + if ( $post_author ) { + $metadata['author'] = [ + '@type' => 'Person', + 'name' => html_entity_decode( $post_author->display_name, ENT_QUOTES, get_bloginfo( 'charset' ) ), + ]; + } + + if ( has_post_thumbnail( $post->ID ) ) { + $metadata['image'] = wp_get_attachment_image_url( get_post_thumbnail_id( $post->ID ), 'full' ); + } + + return $metadata; + } } diff --git a/includes/templates/single-web-story.php b/includes/templates/single-web-story.php index db871c57e0ca..251514f6b4e3 100644 --- a/includes/templates/single-web-story.php +++ b/includes/templates/single-web-story.php @@ -26,8 +26,11 @@ the_post(); +use \Google\Web_Stories\Story_Post_Type; use \Google\Web_Stories\Media; +$metadata = Story_Post_Type::get_schemaorg_metadata(); + ?> > @@ -46,6 +49,7 @@ object-fit: cover; } + - poster-portrait-src="" - + poster-portrait-src="" poster-square-src="" From 5d9988f64b4ad50dc0a0f5a1a9278258a0040650 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 29 Jan 2020 11:50:43 +0100 Subject: [PATCH 07/11] Add filter for publisher logo --- includes/Story_Post_Type.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index 5ed740574f87..cedbef287269 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -615,7 +615,14 @@ private static function get_publisher_logo() { $logo_image_url = plugin_dir_url( WEBSTORIES_PLUGIN_FILE ) . 'assets/images/fallback-wordpress-publisher-logo.png'; } - return $logo_image_url; + /** + * Filters the publisher's logo. + * + * This should point to a square image. + * + * @param string $logo_image_url URL to the publisher's logo. + */ + return apply_filters( 'web_stories_publisher_logo', $logo_image_url ); } /** From a650b41792983ecd2f4aecb5274aa8d704db2866 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 29 Jan 2020 11:54:46 +0100 Subject: [PATCH 08/11] Print schema.org metadata by hooking into header action --- includes/Story_Post_Type.php | 13 +++++++++++++ includes/templates/single-web-story.php | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index cedbef287269..a796f5eb019c 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -161,6 +161,8 @@ static function ( $content ) { 0 ); + add_action( 'web_stories_story_head', [ __CLASS__, 'print_schemaorg_metadata' ] ); + // @todo Check if there's something to skip in the new version. add_action( 'web_stories_story_head', 'rest_output_link_wp_head', 10, 0 ); add_action( 'web_stories_story_head', 'wp_resource_hints', 2 ); @@ -625,6 +627,17 @@ private static function get_publisher_logo() { return apply_filters( 'web_stories_publisher_logo', $logo_image_url ); } + /** + * Prints the schema.org metadata on the single story template. + */ + public static function print_schemaorg_metadata() { + $metadata = self::get_schemaorg_metadata(); + + ?> + + > @@ -49,7 +47,6 @@ object-fit: cover; } - Date: Wed, 29 Jan 2020 11:57:22 +0100 Subject: [PATCH 09/11] Add filter for structured data --- includes/Story_Post_Type.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/includes/Story_Post_Type.php b/includes/Story_Post_Type.php index a796f5eb019c..7a20d02ba606 100644 --- a/includes/Story_Post_Type.php +++ b/includes/Story_Post_Type.php @@ -684,6 +684,12 @@ public static function get_schemaorg_metadata() { $metadata['image'] = wp_get_attachment_image_url( get_post_thumbnail_id( $post->ID ), 'full' ); } - return $metadata; + /** + * Filters the schema.org metadata for a given story. + * + * @param array $metadata The structured data. + * @param WP_Post $post The current post object. + */ + return apply_filters( 'web_stories_story_schema_metadata', $metadata, $post ); } } From 09112acf5058dc6410e5f52bea8471beb4aa8915 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 29 Jan 2020 12:11:20 +0100 Subject: [PATCH 10/11] Retrieve supported mime types from config provider --- .../components/library/mediaLibrary.js | 21 ++---- includes/Story_Post_Type.php | 74 ++++++++++++------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/assets/src/edit-story/components/library/mediaLibrary.js b/assets/src/edit-story/components/library/mediaLibrary.js index b6dedf099beb..581d561e7a1d 100644 --- a/assets/src/edit-story/components/library/mediaLibrary.js +++ b/assets/src/edit-story/components/library/mediaLibrary.js @@ -30,6 +30,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ +import { useConfig } from '../../app/config'; import UploadButton from '../uploadButton'; import useLibrary from './useLibrary'; @@ -124,17 +125,6 @@ const ButtonCSS = css` border-radius: 3px; `; -const SUPPORTED_IMAGE_TYPES = [ - 'image/png', - 'image/jpeg', - 'image/jpg', - 'image/gif', -]; - -const SUPPORTED_VIDEO_TYPES = [ - 'video/mp4', -]; - const FILTERS = [ { filter: '', name: __( 'All', 'web-stories' ) }, { filter: 'image', name: __( 'Images', 'web-stories' ) }, @@ -148,6 +138,7 @@ function MediaLibrary( { onInsert } ) { state: { media, isMediaLoading, isMediaLoaded, mediaType, searchTerm }, actions: { loadMedia, setIsMediaLoading, setIsMediaLoaded, setMediaType, setSearchTerm }, } = useLibrary(); + const { allowedMimeTypes: { image: allowedImageMimeTypes, video: allowedVideoMimeTypes } } = useConfig(); useEffect( loadMedia ); @@ -212,7 +203,7 @@ function MediaLibrary( { onInsert } ) { const { src, mimeType, oWidth, oHeight } = attachment; const origRatio = oWidth / oHeight; const height = width / origRatio; - if ( SUPPORTED_IMAGE_TYPES.includes( mimeType ) ) { + if ( allowedImageMimeTypes.includes( mimeType ) ) { return onInsert( 'image', { src, width, @@ -224,7 +215,7 @@ function MediaLibrary( { onInsert } ) { origWidth: oWidth, origHeight: oHeight, } ); - } else if ( SUPPORTED_VIDEO_TYPES.includes( mimeType ) ) { + } else if ( allowedVideoMimeTypes.includes( mimeType ) ) { return onInsert( 'video', { src, width, @@ -252,7 +243,7 @@ function MediaLibrary( { onInsert } ) { const { src, oWidth, oHeight, mimeType } = mediaEl; const origRatio = oWidth / oHeight; const height = width / origRatio; - if ( SUPPORTED_IMAGE_TYPES.includes( mimeType ) ) { + if ( allowedImageMimeTypes.includes( mimeType ) ) { return ( insertMediaElement( mediaEl, width ) } /> ); - } else if ( SUPPORTED_VIDEO_TYPES.includes( mimeType ) ) { + } else if ( allowedVideoMimeTypes.includes( mimeType ) ) { /* eslint-disable react/jsx-closing-tag-location */ return (