Skip to content

Commit

Permalink
Makes cover block dynamic and adds featured image binding (#39658)
Browse files Browse the repository at this point in the history
* adds featured image support to the cover block

* don't check for featured image if the flag is on as the cover block works great without one
  • Loading branch information
draganescu authored Apr 4, 2022
1 parent 2e4e079 commit 395aea4
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 44 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Add an image or video with a text overlay — great for headers. ([Source](https
- **Name:** core/cover
- **Category:** media
- **Supports:** align, anchor, color (~~background~~, ~~text~~), spacing (padding), ~~html~~
- **Attributes:** allowedBlocks, alt, backgroundType, contentPosition, customGradient, customOverlayColor, dimRatio, focalPoint, gradient, hasParallax, id, isDark, isRepeated, minHeight, minHeightUnit, overlayColor, templateLock, url
- **Attributes:** allowedBlocks, alt, backgroundType, contentPosition, customGradient, customOverlayColor, dimRatio, focalPoint, gradient, hasParallax, id, isDark, isRepeated, minHeight, minHeightUnit, overlayColor, templateLock, url, useFeaturedImage

## Embed

Expand Down
1 change: 1 addition & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ function gutenberg_reregister_core_block_types() {
'block.php' => 'core/block',
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
'cover.php' => 'core/cover',
'comment-author-avatar.php' => 'core/comment-author-avatar',
'comment-author-name.php' => 'core/comment-author-name',
'comment-content.php' => 'core/comment-content',
Expand Down
5 changes: 5 additions & 0 deletions packages/block-library/src/cover/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"url": {
"type": "string"
},
"useFeaturedImage": {
"type": "boolean",
"default": false
},
"id": {
"type": "number"
},
Expand Down Expand Up @@ -72,6 +76,7 @@
"enum": [ "all", "insert", false ]
}
},
"usesContext": [ "postId", "postType" ],
"supports": {
"anchor": true,
"align": true,
Expand Down
106 changes: 77 additions & 29 deletions packages/block-library/src/cover/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import namesPlugin from 'colord/plugins/names';
/**
* WordPress dependencies
*/
import { useEntityProp, store as coreStore } from '@wordpress/core-data';
import {
Fragment,
useEffect,
Expand All @@ -28,6 +29,7 @@ import {
Spinner,
TextareaControl,
ToggleControl,
ToolbarButton,
__experimentalUseCustomUnits as useCustomUnits,
__experimentalBoxControl as BoxControl,
__experimentalToolsPanelItem as ToolsPanelItem,
Expand All @@ -54,7 +56,7 @@ import {
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { cover as icon } from '@wordpress/icons';
import { postFeaturedImage, cover as icon } from '@wordpress/icons';
import { isBlobURL } from '@wordpress/blob';
import { store as noticesStore } from '@wordpress/notices';

Expand Down Expand Up @@ -298,11 +300,12 @@ function CoverEdit( {
setAttributes,
setOverlayColor,
toggleSelection,
context: { postId, postType },
} ) {
const {
contentPosition,
id,
backgroundType,
useFeaturedImage,
dimRatio,
focalPoint,
hasParallax,
Expand All @@ -311,11 +314,35 @@ function CoverEdit( {
minHeight,
minHeightUnit,
style: styleAttribute,
url,
alt,
allowedBlocks,
templateLock,
} = attributes;

const [ featuredImage ] = useEntityProp(
'postType',
postType,
'featured_media',
postId
);

const media = useSelect(
( select ) =>
featuredImage &&
select( coreStore ).getMedia( featuredImage, { context: 'view' } ),
[ featuredImage ]
);
const mediaUrl = media?.source_url;

// instead of destructuring the attributes
// we define the url and background type
// depending on the value of the useFeaturedImage flag
// to preview in edit the dynamic featured image
const url = useFeaturedImage ? mediaUrl : attributes.url;
const backgroundType = useFeaturedImage
? IMAGE_BACKGROUND_TYPE
: attributes.backgroundType;

const { __unstableMarkNextChangeAsNotPersistent } = useDispatch(
blockEditorStore
);
Expand Down Expand Up @@ -374,6 +401,13 @@ function CoverEdit( {
} );
};

const toggleUseFeaturedImage = () => {
setAttributes( {
useFeaturedImage: ! useFeaturedImage,
dimRatio: dimRatio === 100 ? 50 : dimRatio,
} );
};

const onUploadError = ( message ) => {
createErrorNotice( Array.isArray( message ) ? message[ 2 ] : message, {
type: 'snackbar',
Expand Down Expand Up @@ -458,14 +492,22 @@ function CoverEdit( {
/>
</BlockControls>
<BlockControls group="other">
<MediaReplaceFlow
mediaId={ id }
mediaURL={ url }
allowedTypes={ ALLOWED_MEDIA_TYPES }
accept="image/*,video/*"
onSelect={ onSelectMedia }
name={ ! url ? __( 'Add Media' ) : __( 'Replace' ) }
<ToolbarButton
icon={ postFeaturedImage }
label={ __( 'Use featured image' ) }
isPressed={ useFeaturedImage }
onClick={ toggleUseFeaturedImage }
/>
{ ! useFeaturedImage && (
<MediaReplaceFlow
mediaId={ id }
mediaURL={ url }
allowedTypes={ ALLOWED_MEDIA_TYPES }
accept="image/*,video/*"
onSelect={ onSelectMedia }
name={ ! url ? __( 'Add Media' ) : __( 'Replace' ) }
/>
) }
</BlockControls>
<InspectorControls>
{ !! url && (
Expand Down Expand Up @@ -499,27 +541,32 @@ function CoverEdit( {
}
/>
) }
{ url && isImageBackground && isImgElement && (
<TextareaControl
label={ __( 'Alt text (alternative text)' ) }
value={ alt }
onChange={ ( newAlt ) =>
setAttributes( { alt: newAlt } )
}
help={
<>
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
{ ! useFeaturedImage &&
url &&
isImageBackground &&
isImgElement && (
<TextareaControl
label={ __(
'Alt text (alternative text)'
) }
value={ alt }
onChange={ ( newAlt ) =>
setAttributes( { alt: newAlt } )
}
help={
<>
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
{ __(
'Describe the purpose of the image'
) }
</ExternalLink>
{ __(
'Describe the purpose of the image'
'Leave empty if the image is purely decorative.'
) }
</ExternalLink>
{ __(
'Leave empty if the image is purely decorative.'
) }
</>
}
/>
) }
</>
}
/>
) }
<PanelRow>
<Button
variant="secondary"
Expand All @@ -533,6 +580,7 @@ function CoverEdit( {
focalPoint: undefined,
hasParallax: undefined,
isRepeated: undefined,
useFeaturedImage: false,
} )
}
>
Expand Down
85 changes: 85 additions & 0 deletions packages/block-library/src/cover/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/**
* Server-side rendering of the `core/cover` block.
*
* @package WordPress
*/

/**
* Renders the `core/cover` block on server.
*
* @param array $attributes The block attributes.
* @param array $content The block rendered content.
*
* @return string Returns the cover block markup, if useFeaturedImage is true.
*/
function render_block_core_cover( $attributes, $content ) {
if ( false === $attributes['useFeaturedImage'] ) {
return $content;
}

$current_featured_image = get_the_post_thumbnail_url();

if ( false === $current_featured_image ) {
return $content;
}

$is_img_element = ! ( $attributes['hasParallax'] || $attributes['isRepeated'] );
$is_image_background = 'image' === $attributes['backgroundType'];

if ( $is_image_background && ! $is_img_element ) {
$content = preg_replace(
'/class=\".*?\"/',
'${0} style="background-image:url(' . esc_url( $current_featured_image ) . ')"',
$content,
1
);
}

if ( $is_image_background && $is_img_element ) {
$object_position = '';
if ( isset( $attributes['focalPoint'] ) ) {
$object_position = round( $attributes['focalPoint']['x'] * 100 ) . '%' . ' ' .
round( $attributes['focalPoint']['x'] * 100 ) . '%';
}

$image_template = '<img
class="wp-block-cover__image-background"
alt="%s"
src="%s"
style="object-position: %s"
data-object-fit="cover"
data-object-position="%s"
/>';

$image = sprintf(
$image_template,
esc_attr( get_the_post_thumbnail_caption() ),
esc_url( $current_featured_image ),
esc_attr( $object_position ),
esc_attr( $object_position )
);

$content = str_replace(
'</span><div',
'</span>' . $image . '<div',
$content
);

}

return $content;
}

/**
* Registers the `core/cover` block renderer on server.
*/
function register_block_core_cover() {
register_block_type_from_metadata(
__DIR__ . '/cover',
array(
'render_callback' => 'render_block_core_cover',
)
);
}
add_action( 'init', 'register_block_core_cover' );
32 changes: 18 additions & 14 deletions packages/block-library/src/cover/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default function save( { attributes } ) {
customOverlayColor,
dimRatio,
focalPoint,
useFeaturedImage,
hasParallax,
isDark,
isRepeated,
Expand All @@ -60,7 +61,7 @@ export default function save( { attributes } ) {
const isImgElement = ! ( hasParallax || isRepeated );

const style = {
...( isImageBackground && ! isImgElement
...( isImageBackground && ! isImgElement && ! useFeaturedImage
? backgroundImageStyles( url )
: {} ),
minHeight: minHeight || undefined,
Expand Down Expand Up @@ -113,19 +114,22 @@ export default function save( { attributes } ) {
style={ bgStyle }
/>

{ isImageBackground && isImgElement && url && (
<img
className={ classnames(
'wp-block-cover__image-background',
id ? `wp-image-${ id }` : null
) }
alt={ alt }
src={ url }
style={ { objectPosition } }
data-object-fit="cover"
data-object-position={ objectPosition }
/>
) }
{ ! useFeaturedImage &&
isImageBackground &&
isImgElement &&
url && (
<img
className={ classnames(
'wp-block-cover__image-background',
id ? `wp-image-${ id }` : null
) }
alt={ alt }
src={ url }
style={ { objectPosition } }
data-object-fit="cover"
data-object-position={ objectPosition }
/>
) }
{ isVideoBackground && url && (
<video
className={ classnames(
Expand Down
1 change: 1 addition & 0 deletions test/integration/fixtures/blocks/core__cover.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"isValid": true,
"attributes": {
"url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=",
"useFeaturedImage": false,
"alt": "",
"hasParallax": false,
"isRepeated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"name": "core/cover",
"isValid": true,
"attributes": {
"useFeaturedImage": false,
"alt": "",
"hasParallax": false,
"isRepeated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"isValid": true,
"attributes": {
"url": "data:image/jpeg;base64,/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=",
"useFeaturedImage": false,
"alt": "",
"hasParallax": false,
"isRepeated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"isValid": true,
"attributes": {
"url": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=",
"useFeaturedImage": false,
"alt": "",
"hasParallax": false,
"isRepeated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"name": "core/cover",
"isValid": true,
"attributes": {
"useFeaturedImage": false,
"alt": "",
"hasParallax": false,
"isRepeated": false,
Expand Down
Loading

0 comments on commit 395aea4

Please sign in to comment.