Skip to content

Commit

Permalink
Add featured images to Latest Posts block (#17151)
Browse files Browse the repository at this point in the history
See #1594. This commits builds on #17148 to add featured image to the Latest Posts block. It uses that new ImageSizeControl control and adds an alignment control for image alignment.
  • Loading branch information
ryelle authored Feb 9, 2020
1 parent d98e695 commit 3249ae1
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 7 deletions.
21 changes: 21 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -677,3 +677,24 @@ function gutenberg_extend_block_editor_preload_paths( $preload_paths, $post ) {
return $preload_paths;
}
add_filter( 'block_editor_preload_paths', 'gutenberg_extend_block_editor_preload_paths', 10, 2 );

/**
* Extends block editor settings to include a list of image dimensions per size.
*
* @param array $settings Default editor settings.
*
* @return array Filtered editor settings.
*/
function gutenberg_extend_settings_image_dimensions( $settings ) {
$image_dimensions = array();
$all_sizes = wp_get_registered_image_subsizes();
foreach ( $settings['imageSizes'] as $size ) {
$key = $size['slug'];
if ( isset( $all_sizes[ $key ] ) ) {
$image_dimensions[ $key ] = $all_sizes[ $key ];
}
}
$settings['imageDimensions'] = $image_dimensions;
return $settings;
}
add_filter( 'block_editor_settings', 'gutenberg_extend_settings_image_dimensions' );
147 changes: 141 additions & 6 deletions packages/block-library/src/latest-posts/edit.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/**
* External dependencies
*/
import { isUndefined, pickBy } from 'lodash';
import { get, isUndefined, pickBy } from 'lodash';
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { Component, RawHTML } from '@wordpress/element';
import {
BaseControl,
PanelBody,
Placeholder,
QueryControls,
Expand All @@ -22,7 +23,12 @@ import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';
import { __ } from '@wordpress/i18n';
import { dateI18n, format, __experimentalGetSettings } from '@wordpress/date';
import { InspectorControls, BlockControls } from '@wordpress/block-editor';
import {
InspectorControls,
BlockAlignmentToolbar,
BlockControls,
__experimentalImageSizeControl as ImageSizeControl,
} from '@wordpress/block-editor';
import { withSelect } from '@wordpress/data';

/**
Expand Down Expand Up @@ -63,9 +69,17 @@ class LatestPostsEdit extends Component {
}

render() {
const { attributes, setAttributes, latestPosts } = this.props;
const {
attributes,
setAttributes,
imageSizeOptions,
latestPosts,
defaultImageWidth,
defaultImageHeight,
} = this.props;
const { categoriesList } = this.state;
const {
displayFeaturedImage,
displayPostContentRadio,
displayPostContent,
displayPostDate,
Expand All @@ -76,6 +90,10 @@ class LatestPostsEdit extends Component {
categories,
postsToShow,
excerptLength,
featuredImageAlign,
featuredImageSizeSlug,
featuredImageSizeWidth,
featuredImageSizeHeight,
} = attributes;

const inspectorControls = (
Expand Down Expand Up @@ -130,6 +148,62 @@ class LatestPostsEdit extends Component {
/>
</PanelBody>

<PanelBody title={ __( 'Featured Image Settings' ) }>
<ToggleControl
label={ __( 'Display featured image' ) }
checked={ displayFeaturedImage }
onChange={ ( value ) =>
setAttributes( { displayFeaturedImage: value } )
}
/>
{ displayFeaturedImage && (
<>
<ImageSizeControl
onChange={ ( value ) => {
const newAttrs = {};
if ( value.hasOwnProperty( 'width' ) ) {
newAttrs.featuredImageSizeWidth =
value.width;
}
if ( value.hasOwnProperty( 'height' ) ) {
newAttrs.featuredImageSizeHeight =
value.height;
}
setAttributes( newAttrs );
} }
slug={ featuredImageSizeSlug }
width={ featuredImageSizeWidth }
height={ featuredImageSizeHeight }
imageWidth={ defaultImageWidth }
imageHeight={ defaultImageHeight }
imageSizeOptions={ imageSizeOptions }
onChangeImage={ ( value ) =>
setAttributes( {
featuredImageSizeSlug: value,
featuredImageSizeWidth: undefined,
featuredImageSizeHeight: undefined,
} )
}
/>
<BaseControl>
<BaseControl.VisualLabel>
{ __( 'Image Alignment' ) }
</BaseControl.VisualLabel>
<BlockAlignmentToolbar
value={ featuredImageAlign }
onChange={ ( value ) =>
setAttributes( {
featuredImageAlign: value,
} )
}
controls={ [ 'left', 'center', 'right' ] }
isCollapsed={ false }
/>
</BaseControl>
</>
) }
</PanelBody>

<PanelBody title={ __( 'Sorting and filtering' ) }>
<QueryControls
{ ...{ order, orderBy } }
Expand Down Expand Up @@ -236,12 +310,35 @@ class LatestPostsEdit extends Component {

const excerptElement = document.createElement( 'div' );
excerptElement.innerHTML = excerpt;

excerpt =
excerptElement.textContent ||
excerptElement.innerText ||
'';

const imageSourceUrl = post.featuredImageSourceUrl;

const imageClasses = classnames( {
'wp-block-latest-posts__featured-image': true,
[ `align${ featuredImageAlign }` ]: !! featuredImageAlign,
} );

return (
<li key={ i }>
{ displayFeaturedImage && (
<div className={ imageClasses }>
{ imageSourceUrl && (
<img
src={ imageSourceUrl }
alt=""
style={ {
maxWidth: featuredImageSizeWidth,
maxHeight: featuredImageSizeHeight,
} }
/>
) }
</div>
) }
<a
href={ post.link }
target="_blank"
Expand Down Expand Up @@ -314,8 +411,16 @@ class LatestPostsEdit extends Component {
}

export default withSelect( ( select, props ) => {
const { postsToShow, order, orderBy, categories } = props.attributes;
const { getEntityRecords } = select( 'core' );
const {
featuredImageSizeSlug,
postsToShow,
order,
orderBy,
categories,
} = props.attributes;
const { getEntityRecords, getMedia } = select( 'core' );
const { getSettings } = select( 'core/block-editor' );
const { imageSizes, imageDimensions } = getSettings();
const latestPostsQuery = pickBy(
{
categories,
Expand All @@ -325,7 +430,37 @@ export default withSelect( ( select, props ) => {
},
( value ) => ! isUndefined( value )
);

const posts = getEntityRecords( 'postType', 'post', latestPostsQuery );
const imageSizeOptions = imageSizes
.filter( ( { slug } ) => slug !== 'full' )
.map( ( { name, slug } ) => ( { value: slug, label: name } ) );

return {
latestPosts: getEntityRecords( 'postType', 'post', latestPostsQuery ),
defaultImageWidth: imageDimensions[ featuredImageSizeSlug ].width,
defaultImageHeight: imageDimensions[ featuredImageSizeSlug ].height,
imageSizeOptions,
latestPosts: ! Array.isArray( posts )
? posts
: posts.map( ( post ) => {
if ( post.featured_media ) {
const image = getMedia( post.featured_media );
let url = get(
image,
[
'media_details',
'sizes',
featuredImageSizeSlug,
'source_url',
],
null
);
if ( ! url ) {
url = get( image, 'source_url', null );
}
return { ...post, featuredImageSourceUrl: url };
}
return post;
} ),
};
} )( LatestPostsEdit );
51 changes: 50 additions & 1 deletion packages/block-library/src/latest-posts/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,41 @@ function render_block_core_latest_posts( $attributes ) {
$list_items_markup = '';

foreach ( $recent_posts as $post ) {
$list_items_markup .= '<li>';

if ( $attributes['displayFeaturedImage'] && has_post_thumbnail( $post ) ) {
$image_style = '';
if ( isset( $attributes['featuredImageSizeWidth'] ) ) {
$image_style .= sprintf( 'max-width:%spx;', $attributes['featuredImageSizeWidth'] );
}
if ( isset( $attributes['featuredImageSizeHeight'] ) ) {
$image_style .= sprintf( 'max-height:%spx;', $attributes['featuredImageSizeHeight'] );
}

$image_classes = 'wp-block-latest-posts__featured-image';
if ( isset( $attributes['featuredImageAlign'] ) ) {
$image_classes .= ' align' . $attributes['featuredImageAlign'];
}

$list_items_markup .= sprintf(
'<div class="%1$s">%2$s</div>',
$image_classes,
get_the_post_thumbnail(
$post,
$attributes['featuredImageSizeSlug'],
array(
'style' => $image_style,
)
)
);
}

$title = get_the_title( $post );
if ( ! $title ) {
$title = __( '(no title)' );
}
$list_items_markup .= sprintf(
'<li><a href="%1$s">%2$s</a>',
'<a href="%1$s">%2$s</a>',
esc_url( get_permalink( $post ) ),
$title
);
Expand Down Expand Up @@ -164,6 +193,26 @@ function register_block_core_latest_posts() {
'type' => 'string',
'default' => 'date',
),
'displayFeaturedImage' => array(
'type' => 'boolean',
'default' => false,
),
'featuredImageAlign' => array(
'type' => 'string',
'enum' => array( 'left', 'center', 'right' ),
),
'featuredImageSizeSlug' => array(
'type' => 'string',
'default' => 'thumbnail',
),
'featuredImageSizeWidth' => array(
'type' => 'number',
'default' => null,
),
'featuredImageSizeHeight' => array(
'type' => 'number',
'default' => null,
),
),
'render_callback' => 'render_block_core_latest_posts',
)
Expand Down
23 changes: 23 additions & 0 deletions packages/block-library/src/latest-posts/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
}
&.wp-block-latest-posts__list {
list-style: none;

li {
clear: both;
}
}
&.is-grid {
display: flex;
Expand Down Expand Up @@ -40,3 +44,22 @@
margin-top: $grid-size;
margin-bottom: $grid-size-large;
}

.wp-block-latest-posts__featured-image {
img {
height: auto;
width: auto;
}
&.alignleft {
/*rtl:ignore*/
margin-right: 1em;
}
&.alignright {
/*rtl:ignore*/
margin-left: 1em;
}
&.aligncenter {
margin-bottom: 1em;
text-align: center;
}
}
1 change: 1 addition & 0 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class EditorProvider extends Component {
'hasFixedToolbar',
'hasPermissionsToManageWidgets',
'imageSizes',
'imageDimensions',
'isRTL',
'maxWidth',
'styles',
Expand Down

0 comments on commit 3249ae1

Please sign in to comment.