diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/blocks/latest-posts.php --- a/wp/wp-includes/blocks/latest-posts.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/blocks/latest-posts.php Tue Dec 15 13:49:49 2020 +0100 @@ -6,6 +6,26 @@ */ /** + * The excerpt length set by the Latest Posts core block + * set at render time and used by the block itself. + * + * @var int + */ +$block_core_latest_posts_excerpt_length = 0; + +/** + * Callback for the excerpt_length filter used by + * the Latest Posts block at render time. + * + * @return int Returns the global $block_core_latest_posts_excerpt_length variable + * to allow the excerpt_length filter respect the Latest Block setting. + */ +function block_core_latest_posts_get_excerpt_length() { + global $block_core_latest_posts_excerpt_length; + return $block_core_latest_posts_excerpt_length; +} + +/** * Renders the `core/latest-posts` block on server. * * @param array $attributes The block attributes. @@ -13,6 +33,8 @@ * @return string Returns the post content with latest posts added. */ function render_block_core_latest_posts( $attributes ) { + global $post, $block_core_latest_posts_excerpt_length; + $args = array( 'posts_per_page' => $attributes['postsToShow'], 'post_status' => 'publish', @@ -21,8 +43,14 @@ 'suppress_filters' => false, ); + $block_core_latest_posts_excerpt_length = $attributes['excerptLength']; + add_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 ); + if ( isset( $attributes['categories'] ) ) { - $args['category'] = $attributes['categories']; + $args['category__in'] = array_column( $attributes['categories'], 'id' ); + } + if ( isset( $attributes['selectedAuthor'] ) ) { + $args['author'] = $attributes['selectedAuthor']; } $recent_posts = get_posts( $args ); @@ -30,16 +58,60 @@ $list_items_markup = ''; foreach ( $recent_posts as $post ) { + + $list_items_markup .= '
  • '; + + 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( + '
    %2$s
    ', + $image_classes, + get_the_post_thumbnail( + $post, + $attributes['featuredImageSizeSlug'], + array( + 'style' => $image_style, + ) + ) + ); + } + $title = get_the_title( $post ); if ( ! $title ) { - $title = __( '(Untitled)' ); + $title = __( '(no title)' ); } $list_items_markup .= sprintf( - '
  • %2$s', + '%2$s', esc_url( get_permalink( $post ) ), $title ); + if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) { + $author_display_name = get_the_author_meta( 'display_name', $post->post_author ); + + /* translators: byline. %s: current author. */ + $byline = sprintf( __( 'by %s' ), $author_display_name ); + + if ( ! empty( $author_display_name ) ) { + $list_items_markup .= sprintf( + '
    %1$s
    ', + esc_html( $byline ) + ); + } + } + if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) { $list_items_markup .= sprintf( '', @@ -48,10 +120,31 @@ ); } + if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] + && isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) { + + $trimmed_excerpt = get_the_excerpt( $post ); + + $list_items_markup .= sprintf( + '
    %1$s
    ', + $trimmed_excerpt + ); + } + + if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] + && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) { + $list_items_markup .= sprintf( + '
    %1$s
    ', + wp_kses_post( html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ) ) + ); + } + $list_items_markup .= "
  • \n"; } - $class = 'wp-block-latest-posts'; + remove_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 ); + + $class = 'wp-block-latest-posts wp-block-latest-posts__list'; if ( isset( $attributes['align'] ) ) { $class .= ' align' . $attributes['align']; } @@ -68,64 +161,61 @@ $class .= ' has-dates'; } + if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) { + $class .= ' has-author'; + } + if ( isset( $attributes['className'] ) ) { $class .= ' ' . $attributes['className']; } - $block_content = sprintf( + return sprintf( '', esc_attr( $class ), $list_items_markup ); - - return $block_content; } /** * Registers the `core/latest-posts` block on server. */ function register_block_core_latest_posts() { - register_block_type( - 'core/latest-posts', + register_block_type_from_metadata( + __DIR__ . '/latest-posts', array( - 'attributes' => array( - 'categories' => array( - 'type' => 'string', - ), - 'className' => array( - 'type' => 'string', - ), - 'postsToShow' => array( - 'type' => 'number', - 'default' => 5, - ), - 'displayPostDate' => array( - 'type' => 'boolean', - 'default' => false, - ), - 'postLayout' => array( - 'type' => 'string', - 'default' => 'list', - ), - 'columns' => array( - 'type' => 'number', - 'default' => 3, - ), - 'align' => array( - 'type' => 'string', - ), - 'order' => array( - 'type' => 'string', - 'default' => 'desc', - ), - 'orderBy' => array( - 'type' => 'string', - 'default' => 'date', - ), - ), 'render_callback' => 'render_block_core_latest_posts', ) ); } +add_action( 'init', 'register_block_core_latest_posts' ); -add_action( 'init', 'register_block_core_latest_posts' ); +/** + * Handles outdated versions of the `core/latest-posts` block by converting + * attribute `categories` from a numeric string to an array with key `id`. + * + * This is done to accommodate the changes introduced in #20781 that sought to + * add support for multiple categories to the block. However, given that this + * block is dynamic, the usual provisions for block migration are insufficient, + * as they only act when a block is loaded in the editor. + * + * TODO: Remove when and if the bottom client-side deprecation for this block + * is removed. + * + * @param array $block A single parsed block object. + * + * @return array The migrated block object. + */ +function block_core_latest_posts_migrate_categories( $block ) { + if ( + 'core/latest-posts' === $block['blockName'] && + ! empty( $block['attrs']['categories'] ) && + is_string( $block['attrs']['categories'] ) + ) { + $block['attrs']['categories'] = array( + array( 'id' => absint( $block['attrs']['categories'] ) ), + ); + } + + return $block; +} +add_filter( 'render_block_data', 'block_core_latest_posts_migrate_categories' );