You are here

latest-posts.php in Gutenberg 8.2

Same filename and directory in other branches
  1. 8 vendor/gutenberg/block-library/blocks/latest-posts.php

File

vendor/gutenberg/block-library/blocks/latest-posts.php
View source
<?php

/**
 * Server-side rendering of the `core/latest-posts` block.
 *
 * @package WordPress
 */

/**
 * 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 gutenberg_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.
 *
 * @return string Returns the post content with latest posts added.
 */
function gutenberg_render_block_core_latest_posts($attributes) {
  global $post, $block_core_latest_posts_excerpt_length;
  $args = array(
    'posts_per_page' => $attributes['postsToShow'],
    'post_status' => 'publish',
    'order' => $attributes['order'],
    'orderby' => $attributes['orderBy'],
    'suppress_filters' => false,
  );
  $block_core_latest_posts_excerpt_length = $attributes['excerptLength'];
  add_filter('excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20);
  if (isset($attributes['categories'])) {
    $args['category__in'] = array_column($attributes['categories'], 'id');
  }
  if (isset($attributes['selectedAuthor'])) {
    $args['author'] = $attributes['selectedAuthor'];
  }
  $recent_posts = get_posts($args);
  $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('<a href="%1$s">%2$s</a>', 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('<div class="wp-block-latest-posts__post-author">%1$s</div>', esc_html($byline));
      }
    }
    if (isset($attributes['displayPostDate']) && $attributes['displayPostDate']) {
      $list_items_markup .= sprintf('<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>', esc_attr(get_the_date('c', $post)), esc_html(get_the_date('', $post)));
    }
    if (isset($attributes['displayPostContent']) && $attributes['displayPostContent'] && isset($attributes['displayPostContentRadio']) && 'excerpt' === $attributes['displayPostContentRadio']) {
      $trimmed_excerpt = get_the_excerpt($post);
      $list_items_markup .= sprintf('<div class="wp-block-latest-posts__post-excerpt">%1$s</div>', $trimmed_excerpt);
    }
    if (isset($attributes['displayPostContent']) && $attributes['displayPostContent'] && isset($attributes['displayPostContentRadio']) && 'full_post' === $attributes['displayPostContentRadio']) {
      $list_items_markup .= sprintf('<div class="wp-block-latest-posts__post-full-content">%1$s</div>', wp_kses_post(html_entity_decode($post->post_content, ENT_QUOTES, get_option('blog_charset'))));
    }
    $list_items_markup .= "</li>\n";
  }
  remove_filter('excerpt_length', 'gutenberg_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'];
  }
  if (isset($attributes['postLayout']) && 'grid' === $attributes['postLayout']) {
    $class .= ' is-grid';
  }
  if (isset($attributes['columns']) && 'grid' === $attributes['postLayout']) {
    $class .= ' columns-' . $attributes['columns'];
  }
  if (isset($attributes['displayPostDate']) && $attributes['displayPostDate']) {
    $class .= ' has-dates';
  }
  if (isset($attributes['displayAuthor']) && $attributes['displayAuthor']) {
    $class .= ' has-author';
  }
  if (isset($attributes['className'])) {
    $class .= ' ' . $attributes['className'];
  }
  return sprintf('<ul class="%1$s">%2$s</ul>', esc_attr($class), $list_items_markup);
}

/**
 * Registers the `core/latest-posts` block on server.
 */
function gutenberg_register_block_core_latest_posts() {
  register_block_type_from_metadata(__DIR__ . '/latest-posts', array(
    'render_callback' => 'gutenberg_render_block_core_latest_posts',
  ));
}
add_action('init', 'gutenberg_register_block_core_latest_posts', 20);

/**
 * 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 gutenberg_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', 'gutenberg_block_core_latest_posts_migrate_categories');

Functions

Namesort descending Description
gutenberg_block_core_latest_posts_get_excerpt_length Callback for the excerpt_length filter used by the Latest Posts block at render time.
gutenberg_block_core_latest_posts_migrate_categories Handles outdated versions of the `core/latest-posts` block by converting attribute `categories` from a numeric string to an array with key `id`.
gutenberg_register_block_core_latest_posts Registers the `core/latest-posts` block on server.
gutenberg_render_block_core_latest_posts Renders the `core/latest-posts` block on server.