Skip to content
Open
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
4 changes: 2 additions & 2 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@ Display a list of your most recent posts. ([Source](https://github.com/WordPress

- **Name:** core/latest-posts
- **Category:** widgets
- **Supports:** align, anchor, color (background, gradients, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** addLinkToFeaturedImage, categories, columns, displayAuthor, displayFeaturedImage, displayPostContent, displayPostContentRadio, displayPostDate, excerptLength, featuredImageAlign, featuredImageSizeHeight, featuredImageSizeSlug, featuredImageSizeWidth, order, orderBy, postLayout, postsToShow, selectedAuthor
- **Supports:** align, anchor, color (background, gradients, link, text), interactivity (clientNavigation), layout, spacing (blockGap, margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** addLinkToFeaturedImage, categories, displayAuthor, displayFeaturedImage, displayPostContent, displayPostContentRadio, displayPostDate, excerptLength, featuredImageAlign, featuredImageSizeHeight, featuredImageSizeSlug, featuredImageSizeWidth, order, orderBy, postsToShow, selectedAuthor

## List

Expand Down
17 changes: 8 additions & 9 deletions packages/block-library/src/latest-posts/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,6 @@
"type": "boolean",
"default": false
},
"postLayout": {
"type": "string",
"default": "list"
},
"columns": {
"type": "number",
"default": 3
},
"order": {
"type": "string",
"default": "desc"
Expand Down Expand Up @@ -86,6 +78,7 @@
"anchor": true,
"align": true,
"html": false,
"layout": true,
"color": {
"gradients": true,
"link": true,
Expand All @@ -97,7 +90,13 @@
},
"spacing": {
"margin": true,
"padding": true
"padding": true,
"blockGap": {
"__experimentalDefault": "1.25em"
},
"__experimentalDefaultControls": {
"blockGap": true
}
},
"typography": {
"fontSize": true,
Expand Down
1 change: 0 additions & 1 deletion packages/block-library/src/latest-posts/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export const MIN_EXCERPT_LENGTH = 10;
export const MAX_EXCERPT_LENGTH = 100;
export const MAX_POSTS_COLUMNS = 6;
export const DEFAULT_EXCERPT_LENGTH = 55;
73 changes: 65 additions & 8 deletions packages/block-library/src/latest-posts/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,84 @@
*/
import metadata from './block.json';

const { attributes } = metadata;
const attributes = {
...metadata.attributes,
};

const legacyLayoutAttributes = {
postLayout: {
type: 'string',
default: 'list',
},
columns: {
type: 'number',
default: 3,
},
};

const migrateCategories = ( oldAttributes ) => {
if (
! oldAttributes.categories ||
'string' !== typeof oldAttributes.categories
) {
return oldAttributes;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to add this check because we need to run this before the layout migration, and if we don't check whether categories actually exists it just goes and adds an array of them anyway


// This needs the full category object, not just the ID.
return {
...oldAttributes,
categories: [ { id: Number( oldAttributes.categories ) } ],
};
};

const migratePostLayout = ( oldAttributes ) => {
const { postLayout, columns, ...attributesWithoutLegacyLayout } =
oldAttributes;

if ( ! postLayout ) {
return oldAttributes;
}

return {
...attributesWithoutLegacyLayout,
layout: {
type: postLayout === 'grid' ? 'grid' : 'default',
...( postLayout === 'grid' && columns && { columnCount: columns } ),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does there need to be a default here, or does it flow down from block.json? (column: 3)

E.g., columnCount: columns ?? 3

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be whatever is set on the legacy block, which might be that default from block.json or something else if user has changed it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah actually I think we should ensure the legacy attribs are present in the deprecation, then they can be removed from the block.json

},
};
};

export default [
{
attributes: {
...attributes,
...legacyLayoutAttributes,
categories: {
type: 'string',
type: [ 'array', 'string' ],
},
},
supports: {
align: true,
html: false,
layout: true,
},
migrate: ( oldAttributes ) =>
migratePostLayout( migrateCategories( oldAttributes ) ),
isEligible: ( { postLayout } ) => postLayout,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the migration have to run just for 'grid' or all layouts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all layouts because we're also converting the "list" layout to the "default" type.

save: () => null,
},
{
attributes: {
...attributes,
categories: {
type: 'string',
},
},
migrate: ( oldAttributes ) => {
// This needs the full category object, not just the ID.
return {
...oldAttributes,
categories: [ { id: Number( oldAttributes.categories ) } ],
};
supports: {
align: true,
html: false,
},
migrate: migrateCategories,
isEligible: ( { categories } ) =>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, I haven't had my nose in deprecations for a long time.

Does this deprecation see the original raw attributes or the already-migrated attributes?

Just wondering if this will run on the original attributes and replace the migration result from before. If so maybe a ! postLayout check would stop that?

I don't know! 😄

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it the migrations always run in sequence, so if the block is eligible for the categories migration it'll run that, and if it's eligible for the layout one it'll run categories and then layout on whatever categories spat out. I tested this on blocks with legacy layouts and it seemed to work fine.

categories && 'string' === typeof categories,
save: () => null,
Expand Down
76 changes: 33 additions & 43 deletions packages/block-library/src/latest-posts/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import { createInterpolateElement } from '@wordpress/element';
import {
MIN_EXCERPT_LENGTH,
MAX_EXCERPT_LENGTH,
MAX_POSTS_COLUMNS,
DEFAULT_EXCERPT_LENGTH,
} from './constants';
import { useToolsPanelDropdownMenuProps } from '../utils/hooks';
Expand Down Expand Up @@ -105,7 +104,7 @@ function getCurrentAuthor( post ) {
return post._embedded?.author?.[ 0 ];
}

function Controls( { attributes, setAttributes, postCount } ) {
function Controls( { attributes, setAttributes } ) {
const {
postsToShow,
order,
Expand All @@ -117,8 +116,6 @@ function Controls( { attributes, setAttributes, postCount } ) {
displayPostContent,
displayPostDate,
displayAuthor,
postLayout,
columns,
excerptLength,
featuredImageAlign,
featuredImageSizeSlug,
Expand Down Expand Up @@ -473,7 +470,6 @@ function Controls( { attributes, setAttributes, postCount } ) {
postsToShow: 5,
categories: undefined,
selectedAuthor: undefined,
columns: 3,
} )
}
dropdownMenuProps={ dropdownMenuProps }
Expand Down Expand Up @@ -523,41 +519,16 @@ function Controls( { attributes, setAttributes, postCount } ) {
selectedAuthorId={ selectedAuthor }
/>
</ToolsPanelItem>

{ postLayout === 'grid' && (
<ToolsPanelItem
hasValue={ () => columns !== 3 }
label={ __( 'Columns' ) }
onDeselect={ () =>
setAttributes( {
columns: 3,
} )
}
isShownByDefault
>
<RangeControl
__next40pxDefaultSize
label={ __( 'Columns' ) }
value={ columns }
onChange={ ( value ) =>
setAttributes( { columns: value } )
}
min={ 2 }
max={
! postCount
? MAX_POSTS_COLUMNS
: Math.min( MAX_POSTS_COLUMNS, postCount )
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the old max here so it matches the Post Template controls.

required
/>
</ToolsPanelItem>
) }
</ToolsPanel>
</>
);
}

export default function LatestPostsEdit( { attributes, setAttributes } ) {
export default function LatestPostsEdit( {
attributes,
setAttributes,
__unstableLayoutClassNames,
} ) {
const instanceId = useInstanceId( LatestPostsEdit );

const {
Expand All @@ -571,6 +542,7 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) {
displayPostContent,
displayPostDate,
displayAuthor,
layout,
postLayout,
columns,
excerptLength,
Expand All @@ -580,6 +552,11 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) {
featuredImageSizeHeight,
addLinkToFeaturedImage,
} = attributes;
const { type: savedLayoutType, minimumColumnWidth } = layout || {};
const layoutType =
savedLayoutType || ( postLayout === 'grid' ? 'grid' : 'default' );
const columnCount =
layout?.columnCount ?? ( ! savedLayoutType ? columns : undefined ) ?? 3;
const { latestPosts } = useSelect(
( select ) => {
const { getEntityRecords } = select( coreStore );
Expand Down Expand Up @@ -626,18 +603,20 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) {
<Controls
attributes={ attributes }
setAttributes={ setAttributes }
postCount={ latestPosts?.length ?? 0 }
/>
</InspectorControls>
);

const blockProps = useBlockProps( {
className: clsx( {
className: clsx( __unstableLayoutClassNames, {
'wp-block-latest-posts__list': true,
'is-grid': postLayout === 'grid',
'is-grid': layoutType === 'grid',
'has-dates': displayPostDate,
'has-author': displayAuthor,
[ `columns-${ columns }` ]: postLayout === 'grid',
[ `columns-${ columnCount }` ]:
layoutType === 'grid' && columnCount,
'has-native-responsive-grid':
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block has the same responsive fallback as Post Template so we're adding the same back compat workaround.

layoutType === 'grid' && columnCount && minimumColumnWidth,
} ),
} );

Expand All @@ -662,18 +641,29 @@ export default function LatestPostsEdit( { attributes, setAttributes } ) {
? latestPosts.slice( 0, postsToShow )
: latestPosts;

const setDisplayLayout = ( newDisplayLayout ) =>
setAttributes( {
layout: { ...layout, ...newDisplayLayout },
postLayout: undefined,
columns: undefined,
} );

const layoutControls = [
{
icon: list,
title: _x( 'List view', 'Latest posts block display setting' ),
onClick: () => setAttributes( { postLayout: 'list' } ),
isActive: postLayout === 'list',
onClick: () => setDisplayLayout( { type: 'default' } ),
isActive: layoutType === 'default' || layoutType === 'constrained',
},
{
icon: grid,
title: _x( 'Grid view', 'Latest posts block display setting' ),
onClick: () => setAttributes( { postLayout: 'grid' } ),
isActive: postLayout === 'grid',
onClick: () =>
setDisplayLayout( {
type: 'grid',
columnCount,
} ),
isActive: layoutType === 'grid',
},
];

Expand Down
17 changes: 14 additions & 3 deletions packages/block-library/src/latest-posts/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,23 @@ function render_block_core_latest_posts( $attributes ) {

remove_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 );

$layout = $attributes['layout'] ?? array();
$legacy_layout_type = (
isset( $attributes['postLayout'] ) &&
'grid' === $attributes['postLayout']
) ? 'grid' : 'default';
$layout_type = $layout['type'] ?? $legacy_layout_type;
$column_count = $layout['columnCount'] ?? ( $attributes['columns'] ?? null );

$classes = array( 'wp-block-latest-posts__list' );
if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) {
if ( 'grid' === $layout_type ) {
$classes[] = 'is-grid';
}
if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) {
$classes[] = 'columns-' . $attributes['columns'];
if ( 'grid' === $layout_type && ! empty( $column_count ) ) {
$classes[] = sanitize_title( 'columns-' . $column_count );
}
if ( 'grid' === $layout_type && ! empty( $column_count ) && ! empty( $layout['minimumColumnWidth'] ) ) {
$classes[] = 'has-native-responsive-grid';
}
if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
$classes[] = 'has-dates';
Expand Down
14 changes: 12 additions & 2 deletions packages/block-library/src/latest-posts/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@use "@wordpress/base-styles/breakpoints" as *;
@use "@wordpress/base-styles/mixins" as *;

.wp-block-latest-posts {
Expand All @@ -21,7 +22,9 @@
}
}

&.is-grid {
// These rules no longer apply to blocks using layout support, but should
// be kept for backwards compatibility.
&.is-grid:not(.is-layout-grid) {
display: flex;
flex-wrap: wrap;

Expand All @@ -33,7 +36,7 @@

@include break-small {
@for $i from 2 through 6 {
&.columns-#{ $i } li {
&.columns-#{ $i }:not(.is-layout-grid) li {
width: calc((100% / #{$i}) - 1.25em + (1.25em / #{$i}));

&:nth-child(#{ $i }n) {
Expand All @@ -44,6 +47,13 @@
}
}

@media (max-width: $break-small) {
// Temporary specificity bump until "wp-container" layout specificity is revisited.
.wp-block-latest-posts-is-layout-grid[class*="columns-"]:not(.has-native-responsive-grid) {
grid-template-columns: 1fr;
}
}

:root {
:where(.wp-block-latest-posts.is-grid) {
padding: 0;
Expand Down
Loading
Loading