Skip to content

Commit 80cec97

Browse files
committed
add video schema
1 parent a4c9bbd commit 80cec97

File tree

4 files changed

+139
-6
lines changed

4 files changed

+139
-6
lines changed

src/block/video-popup/edit.js

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
InspectorBottomTip,
1818
AdvancedToggleControl,
1919
useBlockCssGenerator,
20+
ControlSeparator,
2021
} from '~stackable/components'
2122
import {
2223
BlockDiv,
@@ -46,6 +47,7 @@ import { InnerBlocks } from '@wordpress/block-editor'
4647
import { __ } from '@wordpress/i18n'
4748
import { addFilter } from '@wordpress/hooks'
4849
import { memo } from '@wordpress/element'
50+
import { DatePicker } from '@wordpress/components'
4951

5052
export const defaultIcon = '<svg data-prefix="fas" data-icon="play" class="svg-inline--fa fa-play fa-w-14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" aria-hidden="true"><path fill="currentColor" d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"></path></svg>'
5153

@@ -104,7 +106,9 @@ const Edit = props => {
104106
setAttributes={ setAttributes }
105107
videoLink={ attributes.videoLink }
106108
videoId={ attributes.videoId }
107-
109+
videoName={ attributes.videoName }
110+
videoUploadDate={ attributes.videoUploadDate }
111+
videoDescription={ attributes.videoDescription }
108112
/>
109113

110114
{ blockCss && <style key="block-css">{ blockCss }</style> }
@@ -136,7 +140,7 @@ const InspectorControls = memo( props => {
136140
<InspectorStyleControls>
137141
<PanelAdvancedSettings
138142
title={ __( 'General', i18n ) }
139-
id="general"
143+
id="video-popup"
140144
initialOpen={ true }
141145
>
142146
<ImageControl2
@@ -146,11 +150,17 @@ const InspectorControls = memo( props => {
146150
onRemove={ () => props.setAttributes( {
147151
videoLink: '',
148152
videoId: '',
153+
videoName: '',
154+
videoDescription: '',
155+
videoUploadDate: '',
149156
} ) }
150157
onChange={ media => {
151158
props.setAttributes( {
152159
videoLink: media.url,
153160
videoId: media.url,
161+
videoName: media.title, // Use title, description and date from media library for video schema
162+
videoDescription: media.description,
163+
videoUploadDate: media.date.toISOString(),
154164
} )
155165
} }
156166
imageId={ urlIsVideo( props.videoLink ) ? props.videoId : '' }
@@ -164,10 +174,16 @@ const InspectorControls = memo( props => {
164174
isFormatType={ false }
165175
placeholder="https://"
166176
value={ ! urlIsVideo( props.videoLink ) ? props.videoLink : '' }
167-
onChange={ videoLink => props.setAttributes( {
168-
videoLink,
169-
videoId: getVideoProviderFromURL( videoLink ).id,
170-
} ) }
177+
onChange={ videoLink => {
178+
const videoProvider = getVideoProviderFromURL( videoLink )
179+
props.setAttributes( {
180+
videoLink,
181+
videoId: videoProvider.id,
182+
videoName: '',
183+
videoDescription: '',
184+
videoUploadDate: '',
185+
} )
186+
} }
171187
/>
172188
{ isVideoFile( props.videoLink ) && <>
173189
<AdvancedToggleControl
@@ -186,6 +202,36 @@ const InspectorControls = memo( props => {
186202
defaultValue={ false }
187203
/>
188204
</> }
205+
{ props.videoLink && <>
206+
<ControlSeparator />
207+
<AdvancedTextControl
208+
label={ __( 'Video name', i18n ) }
209+
value={ props.videoName }
210+
onChange={ videoName => props.setAttributes( { videoName } ) }
211+
/>
212+
<AdvancedTextControl
213+
label={ __( 'Video description', i18n ) }
214+
value={ props.videoDescription }
215+
onChange={ videoDescription => props.setAttributes( { videoDescription } ) }
216+
isMultiline={ true }
217+
/>
218+
<AdvancedTextControl
219+
// The date picker below always highlights a date even if there is no `videoUploadDate` attribute
220+
// This text control allows users to see if a date has been set/removed
221+
className="stk-components-datetime__date-input"
222+
label={ __( 'Video upload date', i18n ) }
223+
value={ props.videoUploadDate ? new Date( props.videoUploadDate ).toISOString().slice( 0, 10 ) : '' }
224+
inputType="date"
225+
readOnly={ true }
226+
/>
227+
<DatePicker
228+
currentDate={ props.videoUploadDate }
229+
onChange={ videoUploadDate => {
230+
props.setAttributes( { videoUploadDate } )
231+
} }
232+
/>
233+
</> }
234+
189235
</PanelAdvancedSettings>
190236

191237
</InspectorStyleControls>

src/block/video-popup/editor.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,21 @@
2828
.editor-styles-wrapper .stk-block-video-popup [data-block] {
2929
max-width: none;
3030
}
31+
.ugb-panel--video-popup .components-datetime__date {
32+
.components-datetime__date__day[aria-label*="Selected" i] {
33+
color: #fff !important;
34+
&:hover {
35+
color: #fff !important;
36+
}
37+
}
38+
:last-child {
39+
row-gap: 8px;
40+
column-gap: 4px;
41+
div:nth-of-type(7) {
42+
justify-self: auto;
43+
}
44+
}
45+
}
46+
.stk-components-datetime__date-input .components-text-control__input {
47+
background-color: #fff;
48+
}

src/block/video-popup/index.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,60 @@ function stackable_load_videopopup_frontend_script() {
1919
}
2020
add_action( 'stackable/video-popup/enqueue_scripts', 'stackable_load_videopopup_frontend_script' );
2121
}
22+
23+
if ( ! class_exists( 'Stackable_Video_Popup_Schema' ) ) {
24+
class Stackable_Video_Popup_Schema {
25+
public $video_entities = [];
26+
27+
function __construct() {
28+
add_filter( 'render_block_stackable/video-popup', array( $this, 'render_block_video_popup_schema' ), 10, 2 );
29+
add_filter( 'wp_footer', array( $this, 'print_video_popup_schema' ) );
30+
}
31+
32+
public function print_video_popup_schema() {
33+
if ( count( $this->video_entities ) ) {
34+
// Compile all video schema entities into a single script
35+
echo '<script type="application/ld+json"> [ ' . implode( ', ', $this->video_entities ) . ' ] </script>';
36+
}
37+
}
38+
39+
public function render_block_video_popup_schema( $block_content, $block ) {
40+
// Initialize video schema
41+
$video_schema = array();
42+
$video_schema[ '@context' ] = 'https://schema.org';
43+
$video_schema[ '@type' ] = 'VideoObject';
44+
45+
// Get video schema properties from block attributes
46+
$attributes = $block[ 'attrs' ];
47+
48+
// Get video name from the title of the post if not set
49+
$name = isset( $attributes[ 'videoName' ] ) ? $attributes[ 'videoName' ] : ( get_the_title() ?? '');
50+
// Get video upload date from the date of the post if not set
51+
$upload_date = isset( $attributes[ 'videoUploadDate' ] ) ? $attributes[ 'videoUploadDate' ] : ( get_the_date( 'c' ) || '');
52+
$description = isset( $attributes[ 'videoDescription' ] ) ? $attributes[ 'videoDescription' ] : '';
53+
$content_url = isset( $attributes[ 'videoLink' ] ) ? $attributes[ 'videoLink' ] : '';
54+
55+
$video_schema[ 'name' ] = $name;
56+
$video_schema[ 'description' ] = $description;
57+
$video_schema[ 'uploadDate' ] = $upload_date;
58+
$video_schema[ 'contentUrl' ] = $content_url;
59+
60+
// Get thumbnail URL from the image block if it exists
61+
if ( isset( $block[ 'innerBlocks' ] )
62+
&& count( $block[ 'innerBlocks' ] ) === 2
63+
&& $block[ 'innerBlocks' ][ 1 ][ 'blockName' ] === 'stackable/image'
64+
) {
65+
$image_attributes = $block[ 'innerBlocks' ][ 1 ][ 'attrs' ];
66+
$thumbnail_url = isset( $image_attributes[ 'imageUrl' ] ) ? $image_attributes[ 'imageUrl' ] : '';
67+
$video_schema[ 'thumbnailUrl' ] = $thumbnail_url;
68+
}
69+
70+
$video_schema_json = json_encode( $video_schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
71+
$this->video_entities[] = $video_schema_json;
72+
73+
return $block_content;
74+
}
75+
}
76+
77+
new Stackable_Video_Popup_Schema();
78+
}

src/block/video-popup/schema.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ export const attributes = ( version = VERSION ) => {
6262
type: 'boolean',
6363
default: false,
6464
},
65+
videoName: {
66+
type: 'string',
67+
default: '',
68+
},
69+
videoDescription: {
70+
type: 'string',
71+
default: '',
72+
},
73+
videoUploadDate: {
74+
type: 'string',
75+
default: '',
76+
},
6577
},
6678
versionAdded: '3.0.0',
6779
versionDeprecated: '',

0 commit comments

Comments
 (0)