-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add featured image to Media & Text block #51491
Changes from 15 commits
4289a75
1ff701f
9505f7d
f1de86e
c1f8969
e599a7d
b70c2fa
27d42bc
f12bd39
02484dc
38bd0c7
2d1ce2c
ebf6555
87fbd79
d0e6eda
759db59
d7a553e
3a47c7c
9755334
665f068
183fb7a
c916464
4ee5cf3
7e3c6b1
ac0a606
f89e7af
1aa6703
96c3a18
ffdc6f1
4c19b22
f4508d5
04a6d07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,7 @@ import { | |
} from '@wordpress/components'; | ||
import { isBlobURL, getBlobTypeByURL } from '@wordpress/blob'; | ||
import { pullLeft, pullRight } from '@wordpress/icons'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
import { useEntityProp, store as coreStore } from '@wordpress/core-data'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -127,7 +127,12 @@ function attributesFromMedia( { | |
}; | ||
} | ||
|
||
function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | ||
function MediaTextEdit( { | ||
attributes, | ||
isSelected, | ||
setAttributes, | ||
context: { postId, postType }, | ||
} ) { | ||
const { | ||
focalPoint, | ||
href, | ||
|
@@ -145,9 +150,42 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
rel, | ||
verticalAlignment, | ||
allowedBlocks, | ||
useFeaturedImage, | ||
} = attributes; | ||
const mediaSizeSlug = attributes.mediaSizeSlug || DEFAULT_MEDIA_SIZE_SLUG; | ||
|
||
const [ featuredImage ] = useEntityProp( | ||
'postType', | ||
postType, | ||
'featured_media', | ||
postId | ||
); | ||
|
||
const featuredImageMedia = useSelect( | ||
( select ) => | ||
featuredImage && | ||
select( coreStore ).getMedia( featuredImage, { context: 'view' } ), | ||
[ featuredImage ] | ||
); | ||
|
||
const featuredImageURL = useFeaturedImage | ||
? featuredImageMedia?.source_url | ||
: ''; | ||
const featuredImageAlt = useFeaturedImage | ||
? featuredImageMedia?.alt_text | ||
: ''; | ||
|
||
const toggleUseFeaturedImage = () => { | ||
setAttributes( { | ||
imageFill: false, | ||
mediaType: 'image', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we set However, I do know that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By setting We should be able to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you. |
||
mediaId: undefined, | ||
mediaUrl: undefined, | ||
mediaAlt: undefined, | ||
useFeaturedImage: ! useFeaturedImage, | ||
} ); | ||
}; | ||
|
||
const { imageSizes, image } = useSelect( | ||
( select ) => { | ||
const { getSettings } = select( blockEditorStore ); | ||
|
@@ -252,24 +290,30 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
} | ||
/> | ||
) } | ||
{ imageFill && mediaUrl && mediaType === 'image' && ( | ||
<FocalPointPicker | ||
__nextHasNoMarginBottom | ||
label={ __( 'Focal point picker' ) } | ||
url={ mediaUrl } | ||
value={ focalPoint } | ||
onChange={ ( value ) => | ||
setAttributes( { focalPoint: value } ) | ||
} | ||
onDragStart={ imperativeFocalPointPreview } | ||
onDrag={ imperativeFocalPointPreview } | ||
/> | ||
) } | ||
{ mediaType === 'image' && ( | ||
{ imageFill && | ||
( mediaUrl || featuredImageURL ) && | ||
mediaType === 'image' && ( | ||
<FocalPointPicker | ||
__nextHasNoMarginBottom | ||
label={ __( 'Focal point picker' ) } | ||
url={ | ||
useFeaturedImage && featuredImageURL | ||
? featuredImageURL | ||
: mediaUrl | ||
} | ||
value={ focalPoint } | ||
onChange={ ( value ) => | ||
setAttributes( { focalPoint: value } ) | ||
} | ||
onDragStart={ imperativeFocalPointPreview } | ||
onDrag={ imperativeFocalPointPreview } | ||
/> | ||
) } | ||
{ mediaType === 'image' && ( mediaUrl || featuredImageURL ) && ( | ||
<TextareaControl | ||
__nextHasNoMarginBottom | ||
label={ __( 'Alternative text' ) } | ||
value={ mediaAlt } | ||
value={ mediaAlt || featuredImageAlt } | ||
draganescu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
onChange={ onMediaAltChange } | ||
help={ | ||
<> | ||
|
@@ -293,7 +337,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
) } | ||
/> | ||
) } | ||
{ mediaUrl && ( | ||
{ ( mediaUrl || featuredImageURL ) && ( | ||
<RangeControl | ||
__nextHasNoMarginBottom | ||
label={ __( 'Media width' ) } | ||
|
@@ -353,7 +397,11 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
onChangeUrl={ onSetHref } | ||
linkDestination={ linkDestination } | ||
mediaType={ mediaType } | ||
mediaUrl={ image && image.source_url } | ||
mediaUrl={ | ||
useFeaturedImage && featuredImageURL | ||
? featuredImageURL | ||
: image && image.source_url | ||
} | ||
mediaLink={ image && image.link } | ||
linkTarget={ linkTarget } | ||
linkClass={ linkClass } | ||
|
@@ -370,6 +418,7 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
commitWidthChange={ commitWidthChange } | ||
ref={ refMediaContainer } | ||
enableResize={ blockEditingMode === 'default' } | ||
toggleUseFeaturedImage={ toggleUseFeaturedImage } | ||
{ ...{ | ||
focalPoint, | ||
imageFill, | ||
|
@@ -381,6 +430,9 @@ function MediaTextEdit( { attributes, isSelected, setAttributes } ) { | |
mediaType, | ||
mediaUrl, | ||
mediaWidth, | ||
useFeaturedImage, | ||
featuredImageURL, | ||
featuredImageAlt, | ||
} } | ||
/> | ||
{ mediaPosition !== 'right' && <div { ...innerBlocksProps } /> } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
/** | ||
* Server-side rendering of the `core/media-text` block. | ||
* | ||
* @package WordPress | ||
*/ | ||
|
||
/** | ||
* Renders the `core/media-text` block on server. | ||
* | ||
* @param array $attributes The block attributes. | ||
* @param string $content The block rendered content. | ||
* | ||
* @return string Returns the Media & Text block markup, if useFeaturedImage is true. | ||
*/ | ||
function render_block_core_media_text( $attributes, $content ) { | ||
if ( false === $attributes['useFeaturedImage'] ) { | ||
return $content; | ||
} | ||
|
||
if ( in_the_loop() ) { | ||
update_post_thumbnail_cache(); | ||
} | ||
|
||
$current_featured_image = get_the_post_thumbnail_url(); | ||
if ( ! $current_featured_image ) { | ||
return $content; | ||
} | ||
|
||
$processor = new WP_HTML_Tag_Processor( $content ); | ||
if ( isset( $attributes['imageFill'] ) && $attributes['imageFill'] ) { | ||
if ( isset( $attributes['focalPoint'] ) ) { | ||
$position = round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%'; | ||
} else { | ||
$position = '50% 50%'; | ||
} | ||
carolinan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$processor->next_tag( 'figure' ); | ||
$processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $position . ';' ); | ||
} | ||
$processor->next_tag( 'img' ); | ||
$media_size_slug = 'full'; | ||
if ( isset( $attributes['mediaSizeSlug'] ) ) { | ||
$media_size_slug = $attributes['mediaSizeSlug']; | ||
} | ||
$processor->set_attribute( 'src', esc_url( $current_featured_image ) ); | ||
$processor->set_attribute( 'alt', esc_attr( $processor->get_attribute( 'alt' ) ) ); | ||
carolinan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug ); | ||
|
||
$content = $processor->get_updated_html(); | ||
|
||
return $content; | ||
} | ||
|
||
/** | ||
* Registers the `core/media-text` block renderer on server. | ||
*/ | ||
function register_block_core_media_text() { | ||
register_block_type_from_metadata( | ||
__DIR__ . '/media-text', | ||
array( | ||
'render_callback' => 'render_block_core_media_text', | ||
) | ||
); | ||
} | ||
add_action( 'init', 'register_block_core_media_text' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we check for
featuredImageURL
andfeaturedImageAlt
asbool
in many places can we set them tofalse
if they have no value? IMO the way JS saysfalse || ''
isfalse
is better if we default to testing forfalse
? Is there any downside?Alternatively we could make
hasFeaturedImageAlt
andhasFeaturedImageURL
, respectively. set to!== ''
, then use these inbool
checks later?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but it meant that the alt text was set to the string "false" instead of being empty when:
It shows the text "false" inside the alt text option in the editor, and in the attribute.
So this condition on line 316 also needs to be updated.
value={ mediaAlt || featuredImageAlt }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@draganescu I think I did not fully understand what to do here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means we need the empty string, In which case it means we should not check for
value={ mediaAlt || featuredImageAlt }
later but instead forvalue={ mediaAlt || featuredImageAlt !== '' }
. That's it :)