Skip to content
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

Try/use featured image attribute #39515

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,47 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/block-supports/spacing.php';
require __DIR__ . '/block-supports/dimensions.php';
require __DIR__ . '/block-supports/duotone.php';

/**
* Adds the contextual attributes storage to
* core blocks to be used in the post editor.
*
* @param Array $settings block settings.
*/
function filter_metadata_registration( $settings ) {
$settings['attributes']['contextualAttributes'] = array(
'type' => 'object',
);
return $settings;
};
add_filter( 'block_type_metadata_settings', 'filter_metadata_registration', 10, 2 );

/**
* Keeps blocks bound to featured image
* up to date in case it has been changed outside
* of the block editor
*
* @param string $block_content Block content.
* @param array $block The block instance.
*/
function update_featured_image( $block_content, $block ) {
if ( 'core/image' !== $block['blockName'] ||
'core/cover' !== $block['blockName']
) {
return $block_content;
}

if ( isset( $block['attrs']['contextualAttributes'] ) &&
isset( $block['attrs']['contextualAttributes']['url'] )
) {
$block_content = str_replace(
$block['attrs']['contextualAttributes']['url'],
get_the_post_thumbnail_url(),
$block_content
);
}

return $block_content;
}

add_filter( 'render_block', 'update_featured_image', 10, 2 );
13 changes: 11 additions & 2 deletions packages/block-editor/src/components/block-edit/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
hasBlockSupport,
getBlockType,
} from '@wordpress/blocks';
import { useContext, useMemo } from '@wordpress/element';
import { useContext, useEffect, useMemo } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -31,10 +31,19 @@ import BlockContext from '../block-context';
const DEFAULT_BLOCK_CONTEXT = {};

export const Edit = ( props ) => {
const { attributes = {}, name } = props;
const {
attributesContext = [],
setAttributes,
attributes = {},
name,
} = props;
const blockType = getBlockType( name );
const blockContext = useContext( BlockContext );

useEffect( () => {
setAttributes( attributesContext );
}, [ attributesContext ] );

// Assign context values using the block type's declared context needs.
const context = useMemo( () => {
return blockType && blockType.usesContext
Expand Down
107 changes: 107 additions & 0 deletions packages/edit-post/src/hooks/components/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
/**
* External dependencies
*/
import { has } from 'lodash';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { useEntityProp, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { addFilter } from '@wordpress/hooks';
import { MediaUpload } from '@wordpress/media-utils';
import { createHigherOrderComponent } from '@wordpress/compose';
import { postFeaturedImage } from '@wordpress/icons';
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

const replaceMediaUpload = () => MediaUpload;

Expand All @@ -11,3 +24,97 @@ addFilter(
'core/edit-post/replace-media-upload',
replaceMediaUpload
);

function getMediaSourceUrlBySizeSlug( media, slug ) {
return (
media?.media_details?.sizes?.[ slug ]?.source_url || media?.source_url
);
}

const addFeaturedImageToolbarItem = createHigherOrderComponent(
( BlockEdit ) => {
return ( props ) => {
const { attributes, setAttributes, name: blockName } = props;

const { contextualAttributes = {} } = attributes;

let attributesContext = {};

const [
hasContextualAttribute,
setHasContextualAttribute,
] = useState( has( contextualAttributes, 'url' ) );

const { sizeSlug } = attributes;
const [ featuredImage ] = useEntityProp(
'postType',
'post',
'featured_media'
);

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

const toggleContextualAttributes = ( ctxAttr ) => {
if ( has( ctxAttr, 'url' ) ) {
delete ctxAttr.url;
} else {
ctxAttr.url = mediaUrl;
}

return ctxAttr;
};

if ( hasContextualAttribute ) {
attributesContext = { url: mediaUrl };
}

if (
( 'core/image' !== blockName && 'core/cover' !== blockName ) ||
! mediaUrl
) {
return <BlockEdit { ...props } />;
}
return (
<>
<BlockControls group="other">
<ToolbarButton
icon={ postFeaturedImage /*this is temporary*/ }
label={ __( 'Use featured image' ) }
isPressed={ hasContextualAttribute }
onClick={ () => {
const newContextualAttributes = toggleContextualAttributes(
contextualAttributes
);
setAttributes( {
contextualAttributes: newContextualAttributes,
} );
setHasContextualAttribute(
! hasContextualAttribute
);
} }
/>
</BlockControls>
<BlockEdit
{ ...props }
attributesContext={ attributesContext }
draganescu marked this conversation as resolved.
Show resolved Hide resolved
/>
</>
);
};
},
'addFeaturedImageToolbarItem'
);

addFilter(
'editor.BlockEdit',
'core/edit-post/bind-featured-image',
addFeaturedImageToolbarItem
);