Editor: Update WordPress packages based based on Gutenberg v13.0 RC3

This is the last step of backports from the Gutenberg plugin for WordPress 6.0 Beta 1 release. It includes all updates WordPress packages published to npm based on the Gutenberg plugin v13.0 RC3 release. This patch also includes all the necessary changes applied to core blocks. New blocks included:

- Avatar
- Comment Author Name
- Comment Content
- Comment Date
- Comment Edit Link
- Comment Rely Link
- Comment Template
- Comments Pagination
- Comments Pagination Next
- Comments Pagination Previous
- Comments Query Loop
- Home Link
- Post Author Biography
- Query No Results
- Read More
See more details in https://github.com/WordPress/wordpress-develop/pull/2564.

Props zieladam, ramonopoly, ocean90.
Fixes #55505.



git-svn-id: https://develop.svn.wordpress.org/trunk@53157 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Greg Ziółkowski 2022-04-12 15:10:30 +00:00
parent ebb9aa01dc
commit bab610091d
151 changed files with 4196 additions and 2860 deletions

3574
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
"@pmmmwh/react-refresh-webpack-plugin": "0.5.5",
"@wordpress/babel-preset-default": "6.8.0",
"@wordpress/dependency-extraction-webpack-plugin": "3.4.1",
"@wordpress/e2e-test-utils": "5.4.10",
"@wordpress/e2e-test-utils": "7.2.0",
"@wordpress/scripts": "22.4.0",
"autoprefixer": "^9.8.8",
"chalk": "4.1.2",
@ -76,59 +76,60 @@
"webpack-livereload-plugin": "3.0.2"
},
"dependencies": {
"@wordpress/a11y": "3.2.4",
"@wordpress/annotations": "2.2.9",
"@wordpress/api-fetch": "5.2.6",
"@wordpress/autop": "3.2.3",
"@wordpress/blob": "3.2.2",
"@wordpress/block-directory": "3.0.27",
"@wordpress/block-editor": "8.0.17",
"@wordpress/block-library": "6.0.26",
"@wordpress/block-serialization-default-parser": "4.2.3",
"@wordpress/blocks": "11.1.5",
"@wordpress/components": "19.2.3",
"@wordpress/compose": "5.0.7",
"@wordpress/core-data": "4.0.10",
"@wordpress/customize-widgets": "2.0.27",
"@wordpress/data": "6.1.5",
"@wordpress/data-controls": "2.2.8",
"@wordpress/date": "4.2.3",
"@wordpress/deprecated": "3.2.3",
"@wordpress/dom": "3.2.7",
"@wordpress/dom-ready": "3.2.3",
"@wordpress/edit-post": "5.0.27",
"@wordpress/edit-site": "3.0.27",
"@wordpress/edit-widgets": "3.1.22",
"@wordpress/editor": "12.0.21",
"@wordpress/element": "4.0.4",
"@wordpress/escape-html": "2.2.3",
"@wordpress/format-library": "3.0.23",
"@wordpress/hooks": "3.2.2",
"@wordpress/html-entities": "3.2.3",
"@wordpress/i18n": "4.2.4",
"@wordpress/icons": "6.1.1",
"@wordpress/interface": "4.1.18",
"@wordpress/is-shallow-equal": "4.2.1",
"@wordpress/keyboard-shortcuts": "3.0.7",
"@wordpress/keycodes": "3.2.4",
"@wordpress/list-reusable-blocks": "3.0.20",
"@wordpress/media-utils": "3.0.5",
"@wordpress/notices": "3.2.8",
"@wordpress/nux": "5.0.20",
"@wordpress/plugins": "4.0.7",
"@wordpress/primitives": "3.0.4",
"@wordpress/priority-queue": "2.2.3",
"@wordpress/redux-routine": "4.2.2",
"@wordpress/reusable-blocks": "3.0.23",
"@wordpress/rich-text": "5.0.8",
"@wordpress/server-side-render": "3.0.20",
"@wordpress/shortcode": "3.2.3",
"@wordpress/token-list": "2.2.2",
"@wordpress/url": "3.3.1",
"@wordpress/viewport": "4.0.7",
"@wordpress/warning": "2.2.2",
"@wordpress/widgets": "2.0.23",
"@wordpress/wordcount": "3.2.3",
"@wordpress/a11y": "3.6.0",
"@wordpress/annotations": "2.6.0",
"@wordpress/api-fetch": "6.3.0",
"@wordpress/autop": "3.6.0",
"@wordpress/blob": "3.6.0",
"@wordpress/block-directory": "3.4.1",
"@wordpress/block-editor": "8.5.1",
"@wordpress/block-library": "7.3.1",
"@wordpress/block-serialization-default-parser": "4.6.0",
"@wordpress/blocks": "11.5.1",
"@wordpress/components": "19.8.0",
"@wordpress/compose": "5.4.0",
"@wordpress/core-data": "4.4.1",
"@wordpress/customize-widgets": "3.3.1",
"@wordpress/data": "6.6.0",
"@wordpress/data-controls": "2.6.0",
"@wordpress/date": "4.6.0",
"@wordpress/deprecated": "3.6.0",
"@wordpress/dom": "3.6.0",
"@wordpress/dom-ready": "3.6.0",
"@wordpress/edit-post": "6.3.1",
"@wordpress/edit-site": "4.3.1",
"@wordpress/edit-widgets": "4.3.1",
"@wordpress/editor": "12.5.1",
"@wordpress/element": "4.4.0",
"@wordpress/escape-html": "2.6.0",
"@wordpress/format-library": "3.4.1",
"@wordpress/hooks": "3.6.0",
"@wordpress/html-entities": "3.6.0",
"@wordpress/i18n": "4.6.0",
"@wordpress/icons": "8.2.0",
"@wordpress/interface": "4.5.0",
"@wordpress/is-shallow-equal": "4.6.0",
"@wordpress/keyboard-shortcuts": "3.4.0",
"@wordpress/keycodes": "3.6.0",
"@wordpress/list-reusable-blocks": "3.4.0",
"@wordpress/media-utils": "3.4.0",
"@wordpress/notices": "3.6.0",
"@wordpress/nux": "5.4.0",
"@wordpress/plugins": "4.4.0",
"@wordpress/preferences": "1.2.0",
"@wordpress/primitives": "3.4.0",
"@wordpress/priority-queue": "2.6.0",
"@wordpress/redux-routine": "4.6.0",
"@wordpress/reusable-blocks": "3.4.1",
"@wordpress/rich-text": "5.4.0",
"@wordpress/server-side-render": "3.4.1",
"@wordpress/shortcode": "3.6.0",
"@wordpress/token-list": "2.6.0",
"@wordpress/url": "3.7.0",
"@wordpress/viewport": "4.4.0",
"@wordpress/warning": "2.6.0",
"@wordpress/widgets": "2.4.1",
"@wordpress/wordcount": "3.6.0",
"backbone": "1.4.0",
"clipboard": "2.0.8",
"core-js-url-browser": "3.6.4",
@ -145,8 +146,8 @@
"moment": "2.29.1",
"objectFitPolyfill": "2.3.5",
"polyfill-library": "3.105.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"regenerator-runtime": "0.13.9",
"twemoji": "14.0.2",
"underscore": "1.13.1",

File diff suppressed because one or more lines are too long

View File

@ -16,21 +16,21 @@
*/
function render_block_core_archives( $attributes ) {
$show_post_count = ! empty( $attributes['showPostCounts'] );
$class = '';
$type = isset( $attributes['type'] ) ? $attributes['type'] : 'monthly';
$class = '';
if ( ! empty( $attributes['displayAsDropdown'] ) ) {
$class .= ' wp-block-archives-dropdown';
$dropdown_id = esc_attr( uniqid( 'wp-block-archives-' ) );
$dropdown_id = wp_unique_id( 'wp-block-archives-' );
$title = __( 'Archives' );
/** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */
$dropdown_args = apply_filters(
'widget_archives_dropdown_args',
array(
'type' => 'monthly',
'type' => $type,
'format' => 'option',
'show_post_count' => $show_post_count,
)
@ -62,11 +62,9 @@ function render_block_core_archives( $attributes ) {
break;
}
$label = esc_html( $label );
$block_content = '<label for="' . $dropdown_id . '">' . $title . '</label>
<select id="' . $dropdown_id . '" name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
<option value="">' . $label . '</option>' . $archives . '</select>';
$block_content = '<label for="' . esc_attr( $dropdown_id ) . '">' . esc_html( $title ) . '</label>
<select id="' . esc_attr( $dropdown_id ) . '" name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
<option value="">' . esc_html( $label ) . '</option>' . $archives . '</select>';
return sprintf(
'<div %1$s>%2$s</div>',
@ -81,7 +79,7 @@ function render_block_core_archives( $attributes ) {
$archives_args = apply_filters(
'widget_archives_args',
array(
'type' => 'monthly',
'type' => $type,
'show_post_count' => $show_post_count,
)
);
@ -90,9 +88,7 @@ function render_block_core_archives( $attributes ) {
$archives = wp_get_archives( $archives_args );
$classnames = esc_attr( $class );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $class ) );
if ( empty( $archives ) ) {
return sprintf(

View File

@ -1,9 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/archives",
"title": "Archives",
"category": "widgets",
"description": "Display a monthly archive of your posts.",
"description": "Display a date archive of your posts.",
"textdomain": "default",
"attributes": {
"displayAsDropdown": {
@ -13,6 +14,10 @@
"showPostCounts": {
"type": "boolean",
"default": false
},
"type": {
"type": "string",
"default": "monthly"
}
},
"supports": {

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/audio",
"title": "Audio",

View File

@ -0,0 +1,146 @@
<?php
/**
* Server-side rendering of the `core/avatar` block.
*
* @package WordPress
*/
/**
* Renders the `core/avatar` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the avatar.
*/
function render_block_core_avatar( $attributes, $content, $block ) {
$size = isset( $attributes['size'] ) ? $attributes['size'] : 96;
$wrapper_attributes = get_block_wrapper_attributes();
$image_styles = array();
// Add border width styles.
$has_border_width = ! empty( $attributes['style']['border']['width'] );
if ( $has_border_width ) {
$border_width = $attributes['style']['border']['width'];
$image_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
}
// Add border radius styles.
$has_border_radius = ! empty( $attributes['style']['border']['radius'] );
if ( $has_border_radius ) {
$border_radius = $attributes['style']['border']['radius'];
if ( is_array( $border_radius ) ) {
// Apply styles for individual corner border radii.
foreach ( $border_radius as $key => $value ) {
if ( null !== $value ) {
$name = _wp_to_kebab_case( $key );
// Add shared styles for individual border radii.
$border_style = sprintf(
'border-%s-radius: %s;',
esc_attr( $name ),
esc_attr( $value )
);
$image_styles[] = $border_style;
}
}
} else {
$border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
$image_styles[] = $border_style;
}
}
// Add border color styles.
$has_border_color = ! empty( $attributes['style']['border']['color'] );
if ( $has_border_color ) {
$border_color = $attributes['style']['border']['color'];
$image_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
}
// Add border style (solid, dashed, dotted ).
$has_border_style = ! empty( $attributes['style']['border']['style'] );
if ( $has_border_style ) {
$border_style = $attributes['style']['border']['style'];
$image_styles[] = sprintf( 'border-style: %s;', esc_attr( $border_style ) );
}
// Add border classes to the avatar image for both custom colors and palette colors.
$image_classes = '';
if ( $has_border_color || isset( $attributes['borderColor'] ) ) {
$image_classes .= 'has-border-color';
}
if ( isset( $attributes['borderColor'] ) ) {
$image_classes .= ' has-' . $attributes['borderColor'] . '-border-color';
}
if ( ! isset( $block->context['commentId'] ) ) {
$author_id = isset( $attributes['userId'] ) ? $attributes['userId'] : get_post_field( 'post_author', $block->context['postId'] );
$author_name = get_the_author_meta( 'display_name', $author_id );
// translators: %s is the Author name.
$alt = sprintf( __( '%s Avatar' ), $author_name );
$avatar_block = get_avatar(
$author_id,
$size,
'',
$alt,
array(
'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '',
'class' => "wp-block-avatar__image $image_classes ",
)
);
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
$label = '';
if ( '_blank' === $attributes['linkTarget'] ) {
// translators: %s is the Author name.
$label = 'aria-label="' . sprintf( esc_attr__( '(%s author archive, opens in a new tab)' ), $author_name ) . '"';
}
// translators: %1$s: Author archive link. %2$s: Link target. %3$s Aria label. %4$s Avatar image.
$avatar_block = sprintf( '<a href="%1$s" target="%2$s" %3$s class="wp-block-avatar__link">%4$s</a>', get_author_posts_url( $author_id ), esc_attr( $attributes['linkTarget'] ), $label, $avatar_block );
}
return sprintf( '<div %1s>%2s</div>', $wrapper_attributes, $avatar_block );
}
$comment = get_comment( $block->context['commentId'] );
/* translators: %s is the Comment Author name */
$alt = sprintf( __( '%s Avatar' ), $comment->comment_author );
if ( ! $comment ) {
return '';
}
$avatar_block = get_avatar(
$comment,
$size,
'',
$alt,
array(
'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '',
'class' => "wp-block-avatar__image $image_classes",
)
);
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] && isset( $comment->comment_author_url ) && '' !== $comment->comment_author_url ) {
$label = '';
if ( '_blank' === $attributes['linkTarget'] ) {
// translators: %s is the Comment Author name.
$label = 'aria-label="' . sprintf( esc_attr__( '(%s website link, opens in a new tab)' ), $comment->comment_author ) . '"';
}
// translators: %1$s: Comment Author website link. %2$s: Link target. %3$s Aria label. %4$s Avatar image.
$avatar_block = sprintf( '<a href="%1$s" target="%2$s" %3$s class="wp-block-avatar__link">%4$s</a>', $comment->comment_author_url, esc_attr( $attributes['linkTarget'] ), $label, $avatar_block );
}
return sprintf( '<div %1s>%2s</div>', $wrapper_attributes, $avatar_block );
}
/**
* Registers the `core/avatar` block on the server.
*/
function register_block_core_avatar() {
register_block_type_from_metadata(
__DIR__ . '/avatar',
array(
'render_callback' => 'render_block_core_avatar',
)
);
}
add_action( 'init', 'register_block_core_avatar' );

View File

@ -0,0 +1,53 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/avatar",
"title": "Avatar",
"category": "theme",
"description": "Add a user's avatar.",
"textdomain": "default",
"attributes": {
"userId": {
"type": "number"
},
"size": {
"type": "number",
"default": 96
},
"isLink": {
"type": "boolean",
"default": false
},
"linkTarget": {
"type": "string",
"default": "_self"
}
},
"usesContext": [ "postType", "postId", "commentId" ],
"supports": {
"html": false,
"align": true,
"alignWide": false,
"spacing": {
"margin": true
},
"__experimentalBorder": {
"__experimentalSkipSerialization": true,
"radius": true,
"width": true,
"color": true,
"style": true,
"__experimentalDefaultControls": {
"radius": true
}
},
"color": {
"text": false,
"background": false,
"__experimentalDuotone": "img"
}
},
"editorStyle": "wp-block-avatar",
"style": "wp-block-avatar"
}

View File

@ -42,9 +42,14 @@ function render_block_core_block( $attributes ) {
$seen_refs[ $attributes['ref'] ] = true;
$result = do_blocks( $reusable_block->post_content );
// Handle embeds for reusable blocks.
global $wp_embed;
$content = $wp_embed->run_shortcode( $reusable_block->post_content );
$content = $wp_embed->autoembed( $content );
$content = do_blocks( $content );
unset( $seen_refs[ $attributes['ref'] ] );
return $result;
return $content;
}
/**

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/block",
"title": "Reusable block",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/button",
"title": "Button",
@ -59,7 +60,11 @@
"alignWide": false,
"color": {
"__experimentalSkipSerialization": true,
"gradients": true
"gradients": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,
@ -78,7 +83,10 @@
},
"__experimentalBorder": {
"radius": true,
"__experimentalSkipSerialization": true
"__experimentalSkipSerialization": true,
"__experimentalDefaultControls": {
"radius": true
}
},
"__experimentalSelector": ".wp-block-button__link"
},

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/buttons",
"title": "Buttons",
@ -12,7 +13,7 @@
"__experimentalExposeControlsToChildren": true,
"spacing": {
"blockGap": true,
"margin": ["top", "bottom" ],
"margin": [ "top", "bottom" ],
"__experimentalDefaultControls": {
"blockGap": true
}

View File

@ -107,51 +107,47 @@ function block_core_calendar_update_has_published_posts() {
return $has_published_posts;
}
/**
* Handler for updating the has published posts flag when a post is deleted.
*
* @param int $post_id Deleted post ID.
*/
function block_core_calendar_update_has_published_post_on_delete( $post_id ) {
if ( is_multisite() ) {
return;
// We only want to register these functions and actions when
// we are on single sites. On multi sites we use `post_count` option.
if ( ! is_multisite() ) {
/**
* Handler for updating the has published posts flag when a post is deleted.
*
* @param int $post_id Deleted post ID.
*/
function block_core_calendar_update_has_published_post_on_delete( $post_id ) {
$post = get_post( $post_id );
if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) {
return;
}
block_core_calendar_update_has_published_posts();
}
$post = get_post( $post_id );
/**
* Handler for updating the has published posts flag when a post status changes.
*
* @param string $new_status The status the post is changing to.
* @param string $old_status The status the post is changing from.
* @param WP_Post $post Post object.
*/
function block_core_calendar_update_has_published_post_on_transition_post_status( $new_status, $old_status, $post ) {
if ( $new_status === $old_status ) {
return;
}
if ( ! $post || 'publish' !== $post->post_status || 'post' !== $post->post_type ) {
return;
if ( 'post' !== get_post_type( $post ) ) {
return;
}
if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
return;
}
block_core_calendar_update_has_published_posts();
}
block_core_calendar_update_has_published_posts();
add_action( 'delete_post', 'block_core_calendar_update_has_published_post_on_delete' );
add_action( 'transition_post_status', 'block_core_calendar_update_has_published_post_on_transition_post_status', 10, 3 );
}
/**
* Handler for updating the has published posts flag when a post status changes.
*
* @param string $new_status The status the post is changing to.
* @param string $old_status The status the post is changing from.
* @param WP_Post $post Post object.
*/
function block_core_calendar_update_has_published_post_on_transition_post_status( $new_status, $old_status, $post ) {
if ( is_multisite() ) {
return;
}
if ( $new_status === $old_status ) {
return;
}
if ( 'post' !== get_post_type( $post ) ) {
return;
}
if ( 'publish' !== $new_status && 'publish' !== $old_status ) {
return;
}
block_core_calendar_update_has_published_posts();
}
add_action( 'delete_post', 'block_core_calendar_update_has_published_post_on_delete' );
add_action( 'transition_post_status', 'block_core_calendar_update_has_published_post_on_transition_post_status', 10, 3 );

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/calendar",
"title": "Calendar",

View File

@ -31,7 +31,7 @@ function render_block_core_categories( $attributes ) {
$id = 'wp-block-categories-' . $block_id;
$args['id'] = $id;
$args['show_option_none'] = __( 'Select Category' );
$wrapper_markup = '<div %1$s><label class="screen-reader-text" for="' . $id . '">' . __( 'Categories' ) . '</label>%2$s</div>';
$wrapper_markup = '<div %1$s><label class="screen-reader-text" for="' . esc_attr( $id ) . '">' . __( 'Categories' ) . '</label>%2$s</div>';
$items_markup = wp_dropdown_categories( $args );
$type = 'dropdown';

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/categories",
"title": "Categories",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/code",
"title": "Code",
@ -14,7 +15,6 @@
},
"supports": {
"anchor": true,
"__experimentalSelector": ".wp-block-code > code",
"typography": {
"fontSize": true,
"lineHeight": true,
@ -34,12 +34,20 @@
"radius": true,
"color": true,
"width": true,
"style": true
"style": true,
"__experimentalDefaultControls": {
"width": true,
"color": true
}
},
"color": {
"text": true,
"background": true,
"gradients": true
"gradients": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
}
},
"style": "wp-block-code"

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/column",
"title": "Column",
@ -27,13 +28,19 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"spacing": {
"blockGap": true,
"padding": true,
"__experimentalDefaultControls": {
"padding": true
}
}
},
"__experimentalLayout": true
}
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/columns",
"title": "Columns",
@ -20,14 +21,40 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"spacing": {
"blockGap": true,
"margin": [ "top", "bottom" ],
"padding": true,
"__experimentalDefaultControls": {
"padding": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"allowEditing": false,
"default": {
"type": "flex",
"flexWrap": "nowrap"
}
},
"__experimentalBorder": {
"color": true,
"radius": true,
"style": true,
"width": true,
"__experimentalDefaultControls": {
"color": true,
"radius": true,
"style": true,
"width": true
}
}
},
"editorStyle": "wp-block-columns-editor",

View File

@ -0,0 +1,60 @@
<?php
/**
* Server-side rendering of the `core/comment-author-name` block.
*
* @package WordPress
*/
/**
* Renders the `core/comment-author-name` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the post comment's author.
*/
function render_block_core_comment_author_name( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) ) {
return '';
}
$comment = get_comment( $block->context['commentId'] );
if ( empty( $comment ) ) {
return '';
}
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . esc_attr( $attributes['textAlign'] );
}
if ( isset( $attributes['fontSize'] ) ) {
$classes .= 'has-' . esc_attr( $attributes['fontSize'] ) . '-font-size';
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
$comment_author = get_comment_author( $comment );
$link = get_comment_author_url( $comment );
if ( ! empty( $attributes['isLink'] ) && ! empty( $attributes['linkTarget'] ) ) {
$comment_author = sprintf( '<a rel="external nofollow ugc" href="%1s" target="%2s" >%3s</a>', esc_url( $link ), esc_attr( $attributes['linkTarget'] ), $comment_author );
}
return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$comment_author
);
}
/**
* Registers the `core/comment-author-name` block on the server.
*/
function register_block_core_comment_author_name() {
register_block_type_from_metadata(
__DIR__ . '/comment-author-name',
array(
'render_callback' => 'render_block_core_comment_author_name',
)
);
}
add_action( 'init', 'register_block_core_comment_author_name' );

View File

@ -0,0 +1,53 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-author-name",
"title": "Comment Author Name",
"category": "theme",
"ancestor": [ "core/comment-template" ],
"description": "Displays the name of the author of the comment.",
"textdomain": "default",
"attributes": {
"isLink": {
"type": "boolean",
"default": true
},
"linkTarget": {
"type": "string",
"default": "_self"
},
"textAlign": {
"type": "string"
},
"fontSize": {
"type": "string",
"default": "small"
}
},
"usesContext": [ "commentId" ],
"supports": {
"html": false,
"spacing": {
"margin": true,
"padding": true
},
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true
}
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Server-side rendering of the `core/comment-content` block.
*
* @package WordPress
*/
/**
* Renders the `core/comment-content` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the post comment's content.
*/
function render_block_core_comment_content( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) ) {
return '';
}
$comment = get_comment( $block->context['commentId'] );
if ( empty( $comment ) ) {
return '';
}
$comment_text = get_comment_text( $comment );
if ( ! $comment_text ) {
return '';
}
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . $attributes['textAlign'];
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$comment_text
);
}
/**
* Registers the `core/comment-content` block on the server.
*/
function register_block_core_comment_content() {
register_block_type_from_metadata(
__DIR__ . '/comment-content',
array(
'render_callback' => 'render_block_core_comment_content',
)
);
}
add_action( 'init', 'register_block_core_comment_content' );

View File

@ -0,0 +1,42 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-content",
"title": "Comment Content",
"category": "theme",
"ancestor": [ "core/comment-template" ],
"description": "Displays the contents of a comment.",
"textdomain": "default",
"usesContext": [ "commentId" ],
"attributes": {
"textAlign": {
"type": "string"
}
},
"supports": {
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true
},
"spacing": {
"padding": [ "horizontal", "vertical" ],
"__experimentalDefaultControls": {
"padding": true
}
},
"html": false
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Server-side rendering of the `core/comment-date` block.
*
* @package WordPress
*/
/**
* Renders the `core/comment-date` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the post comment's date.
*/
function render_block_core_comment_date( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) ) {
return '';
}
$comment = get_comment( $block->context['commentId'] );
if ( empty( $comment ) ) {
return '';
}
$classes = '';
if ( isset( $attributes['fontSize'] ) ) {
$classes .= 'has-' . esc_attr( $attributes['fontSize'] ) . '-font-size';
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
$formatted_date = get_comment_date(
isset( $attributes['format'] ) ? $attributes['format'] : '',
$comment
);
$link = get_comment_link( $comment );
if ( ! empty( $attributes['isLink'] ) ) {
$formatted_date = sprintf( '<a href="%1s">%2s</a>', esc_url( $link ), $formatted_date );
}
return sprintf(
'<div %1$s><time datetime="%2$s">%3$s</time></div>',
$wrapper_attributes,
esc_attr( get_comment_date( 'c', $comment ) ),
$formatted_date
);
}
/**
* Registers the `core/comment-date` block on the server.
*/
function register_block_core_comment_date() {
register_block_type_from_metadata(
__DIR__ . '/comment-date',
array(
'render_callback' => 'render_block_core_comment_date',
)
);
}
add_action( 'init', 'register_block_core_comment_date' );

View File

@ -0,0 +1,48 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-date",
"title": "Comment Date",
"category": "theme",
"ancestor": [ "core/comment-template" ],
"description": "Displays the date on which the comment was posted.",
"textdomain": "default",
"attributes": {
"format": {
"type": "string"
},
"isLink": {
"type": "boolean",
"default": true
},
"fontSize": {
"type": "string",
"default": "small"
}
},
"usesContext": [ "commentId" ],
"supports": {
"html": false,
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Server-side rendering of the `core/comment-edit-link` block.
*
* @package WordPress
*/
/**
* Renders the `core/comment-edit-link` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string Return the post comment's date.
*/
function render_block_core_comment_edit_link( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) || ! current_user_can( 'edit_comment', $block->context['commentId'] ) ) {
return '';
}
$edit_comment_link = get_edit_comment_link( $block->context['commentId'] );
$link_atts = '';
if ( ! empty( $attributes['linkTarget'] ) ) {
$link_atts .= sprintf( 'target="%s"', esc_attr( $attributes['linkTarget'] ) );
}
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . esc_attr( $attributes['textAlign'] );
}
if ( isset( $attributes['fontSize'] ) ) {
$classes .= 'has-' . esc_attr( $attributes['fontSize'] ) . '-font-size';
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
return sprintf(
'<div %1$s><a href="%2$s" %3$s>%4$s</a></div>',
$wrapper_attributes,
esc_url( $edit_comment_link ),
$link_atts,
esc_html__( 'Edit' )
);
}
/**
* Registers the `core/comment-edit-link` block on the server.
*/
function register_block_core_comment_edit_link() {
register_block_type_from_metadata(
__DIR__ . '/comment-edit-link',
array(
'render_callback' => 'render_block_core_comment_edit_link',
)
);
}
add_action( 'init', 'register_block_core_comment_edit_link' );

View File

@ -0,0 +1,45 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-edit-link",
"title": "Comment Edit Link",
"category": "theme",
"ancestor": [ "core/comment-template" ],
"description": "Displays a link to edit the comment in the WordPress Dashboard. This link is only visible to users with the edit comment capability.",
"textdomain": "default",
"usesContext": [ "commentId" ],
"attributes": {
"linkTarget": {
"type": "string",
"default": "_self"
},
"textAlign": {
"type": "string"
},
"fontSize": {
"type": "string",
"default": "small"
}
},
"supports": {
"html": false,
"color": {
"link": true,
"gradients": true,
"text": false,
"__experimentalDefaultControls": {
"background": true,
"link": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true
}
}
}

View File

@ -0,0 +1,83 @@
<?php
/**
* Server-side rendering of the `core/comment-reply-link` block.
*
* @package WordPress
*/
/**
* Renders the `core/comment-reply-link` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Return the post comment's reply link.
*/
function render_block_core_comment_reply_link( $attributes, $content, $block ) {
if ( ! isset( $block->context['commentId'] ) ) {
return '';
}
$thread_comments = get_option( 'thread_comments' );
if ( ! $thread_comments ) {
return '';
}
$comment = get_comment( $block->context['commentId'] );
if ( empty( $comment ) ) {
return '';
}
$depth = 1;
$max_depth = get_option( 'thread_comments_depth' );
$parent_id = $comment->comment_parent;
// Compute comment's depth iterating over its ancestors.
while ( ! empty( $parent_id ) ) {
$depth++;
$parent_id = get_comment( $parent_id )->comment_parent;
}
$comment_reply_link = get_comment_reply_link(
array(
'depth' => $depth,
'max_depth' => $max_depth,
),
$comment
);
// Render nothing if the generated reply link is empty.
if ( empty( $comment_reply_link ) ) {
return;
}
$classes = '';
if ( isset( $attributes['textAlign'] ) ) {
$classes .= 'has-text-align-' . esc_attr( $attributes['textAlign'] );
}
if ( isset( $attributes['fontSize'] ) ) {
$classes .= 'has-' . esc_attr( $attributes['fontSize'] ) . '-font-size';
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes ) );
return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$comment_reply_link
);
}
/**
* Registers the `core/comment-reply-link` block on the server.
*/
function register_block_core_comment_reply_link() {
register_block_type_from_metadata(
__DIR__ . '/comment-reply-link',
array(
'render_callback' => 'render_block_core_comment_reply_link',
)
);
}
add_action( 'init', 'register_block_core_comment_reply_link' );

View File

@ -0,0 +1,41 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-reply-link",
"title": "Comment Reply Link",
"category": "theme",
"ancestor": [ "core/comment-template" ],
"description": "Displays a link to reply to a comment.",
"textdomain": "default",
"usesContext": [ "commentId" ],
"attributes": {
"textAlign": {
"type": "string"
},
"fontSize": {
"type": "string",
"default": "small"
}
},
"supports": {
"color": {
"gradients": true,
"link": true,
"text": false,
"__experimentalDefaultControls": {
"background": true,
"link": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true
},
"html": false
}
}

View File

@ -0,0 +1,98 @@
<?php
/**
* Server-side rendering of the `core/comment-template` block.
*
* @package WordPress
*/
/**
* Function that recursively renders a list of nested comments.
*
* @param WP_Comment[] $comments The array of comments.
* @param WP_Block $block Block instance.
* @return string
*/
function block_core_comment_template_render_comments( $comments, $block ) {
$content = '';
foreach ( $comments as $comment ) {
$block_content = ( new WP_Block(
$block->parsed_block,
array(
'commentId' => $comment->comment_ID,
)
) )->render( array( 'dynamic' => false ) );
$children = $comment->get_children();
// If the comment has children, recurse to create the HTML for the nested
// comments.
if ( ! empty( $children ) ) {
$inner_content = block_core_comment_template_render_comments(
$children,
$block
);
$block_content .= sprintf( '<ol>%1$s</ol>', $inner_content );
}
$content .= '<li>' . $block_content . '</li>';
}
return $content;
}
/**
* Renders the `core/comment-template` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string Returns the HTML representing the comments using the layout
* defined by the block's inner blocks.
*/
function render_block_core_comment_template( $attributes, $content, $block ) {
// Bail out early if the post ID is not set for some reason.
if ( empty( $block->context['postId'] ) ) {
return '';
}
$comment_query = new WP_Comment_Query(
build_comment_query_vars_from_block( $block )
);
// Get an array of comments for the current post.
$comments = $comment_query->get_comments();
if ( count( $comments ) === 0 ) {
return '';
}
$comment_order = get_option( 'comment_order' );
if ( 'desc' === $comment_order ) {
$comments = array_reverse( $comments );
}
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<ol %1$s>%2$s</ol>',
$wrapper_attributes,
block_core_comment_template_render_comments( $comments, $block )
);
}
/**
* Registers the `core/comment-template` block on the server.
*/
function register_block_core_comment_template() {
register_block_type_from_metadata(
__DIR__ . '/comment-template',
array(
'render_callback' => 'render_block_core_comment_template',
'skip_inner_blocks' => true,
)
);
}
add_action( 'init', 'register_block_core_comment_template' );

View File

@ -0,0 +1,17 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comment-template",
"title": "Comment Template",
"category": "design",
"parent": [ "core/comments-query-loop" ],
"description": "Contains the block elements used to display a comment, like the title, date, author, avatar and more.",
"textdomain": "default",
"usesContext": [ "postId" ],
"supports": {
"reusable": false,
"html": false,
"align": true
},
"style": "wp-block-comment-template"
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Server-side rendering of the `core/comments-pagination-next` block.
*
* @package WordPress
*/
/**
* Renders the `core/comments-pagination-next` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string Returns the next comments link for the query pagination.
*/
function render_block_core_comments_pagination_next( $attributes, $content, $block ) {
// Bail out early if the post ID is not set for some reason.
if ( empty( $block->context['postId'] ) ) {
return '';
}
$comment_vars = build_comment_query_vars_from_block( $block );
$max_page = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages;
$default_label = __( 'Newer Comments' );
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
$pagination_arrow = get_comments_pagination_arrow( $block, 'next' );
$filter_link_attributes = function() {
return get_block_wrapper_attributes();
};
add_filter( 'next_comments_link_attributes', $filter_link_attributes );
if ( $pagination_arrow ) {
$label .= $pagination_arrow;
}
$next_comments_link = get_next_comments_link( $label, $max_page );
remove_filter( 'next_posts_link_attributes', $filter_link_attributes );
if ( ! isset( $next_comments_link ) ) {
return '';
}
return $next_comments_link;
}
/**
* Registers the `core/comments-pagination-next` block on the server.
*/
function register_block_core_comments_pagination_next() {
register_block_type_from_metadata(
__DIR__ . '/comments-pagination-next',
array(
'render_callback' => 'render_block_core_comments_pagination_next',
)
);
}
add_action( 'init', 'register_block_core_comments_pagination_next' );

View File

@ -0,0 +1,38 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-pagination-next",
"title": "Next Page",
"category": "theme",
"parent": [ "core/comments-pagination" ],
"description": "Displays the next comment's page link.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string"
}
},
"usesContext": [ "postId", "comments/paginationArrow" ],
"supports": {
"reusable": false,
"html": false,
"color": {
"gradients": true,
"text": false,
"__experimentalDefaultControls": {
"background": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* Server-side rendering of the `core/comments-pagination-numbers` block.
*
* @package WordPress
*/
/**
* Renders the `core/comments-pagination-numbers` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string Returns the pagination numbers for the comments.
*/
function render_block_core_comments_pagination_numbers( $attributes, $content, $block ) {
// Bail out early if the post ID is not set for some reason.
if ( empty( $block->context['postId'] ) ) {
return '';
}
$comment_vars = build_comment_query_vars_from_block( $block );
$total = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages;
$current = ! empty( $comment_vars['paged'] ) ? $comment_vars['paged'] : null;
// Render links.
$content = paginate_comments_links(
array(
'total' => $total,
'current' => $current,
'prev_next' => false,
'echo' => false,
)
);
if ( empty( $content ) ) {
return '';
}
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
$content
);
}
/**
* Registers the `core/comments-pagination-numbers` block on the server.
*/
function register_block_core_comments_pagination_numbers() {
register_block_type_from_metadata(
__DIR__ . '/comments-pagination-numbers',
array(
'render_callback' => 'render_block_core_comments_pagination_numbers',
)
);
}
add_action( 'init', 'register_block_core_comments_pagination_numbers' );

View File

@ -0,0 +1,15 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-pagination-numbers",
"title": "Page Numbers",
"category": "theme",
"parent": [ "core/comments-pagination" ],
"description": "Displays a list of page numbers for comments pagination.",
"textdomain": "default",
"usesContext": [ "postId" ],
"supports": {
"reusable": false,
"html": false
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Server-side rendering of the `core/comments-pagination-previous` block.
*
* @package WordPress
*/
/**
* Renders the `core/comments-pagination-previous` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
*
* @return string Returns the previous posts link for the comments pagination.
*/
function render_block_core_comments_pagination_previous( $attributes, $content, $block ) {
$default_label = __( 'Older Comments' );
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
$pagination_arrow = get_comments_pagination_arrow( $block, 'previous' );
if ( $pagination_arrow ) {
$label = $pagination_arrow . $label;
}
$filter_link_attributes = function() {
return get_block_wrapper_attributes();
};
add_filter( 'previous_comments_link_attributes', $filter_link_attributes );
$previous_comments_link = get_previous_comments_link( $label );
remove_filter( 'previous_comments_link_attributes', $filter_link_attributes );
if ( ! isset( $previous_comments_link ) ) {
return '';
}
return $previous_comments_link;
}
/**
* Registers the `core/comments-pagination-previous` block on the server.
*/
function register_block_core_comments_pagination_previous() {
register_block_type_from_metadata(
__DIR__ . '/comments-pagination-previous',
array(
'render_callback' => 'render_block_core_comments_pagination_previous',
)
);
}
add_action( 'init', 'register_block_core_comments_pagination_previous' );

View File

@ -0,0 +1,38 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-pagination-previous",
"title": "Previous Page",
"category": "theme",
"parent": [ "core/comments-pagination" ],
"description": "Displays the previous comment's page link.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string"
}
},
"usesContext": [ "postId", "comments/paginationArrow" ],
"supports": {
"reusable": false,
"html": false,
"color": {
"gradients": true,
"text": false,
"__experimentalDefaultControls": {
"background": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* Server-side rendering of the `core/comments-pagination` block.
*
* @package WordPress
*/
/**
* Renders the `core/comments-pagination` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
*
* @return string Returns the wrapper for the Comments pagination.
*/
function render_block_core_comments_pagination( $attributes, $content ) {
if ( empty( trim( $content ) ) ) {
return '';
}
return sprintf(
'<div %1$s>%2$s</div>',
get_block_wrapper_attributes(),
$content
);
}
/**
* Registers the `core/comments-pagination` block on the server.
*/
function register_block_core_comments_pagination() {
register_block_type_from_metadata(
__DIR__ . '/comments-pagination',
array(
'render_callback' => 'render_block_core_comments_pagination',
)
);
}
add_action( 'init', 'register_block_core_comments_pagination' );

View File

@ -0,0 +1,42 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-pagination",
"title": "Comments Pagination",
"category": "theme",
"parent": [ "core/comments-query-loop" ],
"description": "Displays a paginated navigation to next/previous set of comments, when applicable.",
"textdomain": "default",
"attributes": {
"paginationArrow": {
"type": "string",
"default": "none"
}
},
"providesContext": {
"comments/paginationArrow": "paginationArrow"
},
"supports": {
"align": true,
"reusable": false,
"html": false,
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"default": {
"type": "flex"
}
}
},
"editorStyle": "wp-block-comments-pagination-editor",
"style": "wp-block-comments-pagination"
}

View File

@ -0,0 +1,29 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/comments-query-loop",
"title": "Comments Query Loop",
"category": "theme",
"description": "An advanced block that allows displaying post comments using different visual configurations.",
"textdomain": "default",
"attributes": {
"tagName": {
"type": "string",
"default": "div"
}
},
"supports": {
"align": [ "wide", "full" ],
"html": false,
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
}
},
"editorStyle": "wp-block-comments-editor"
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/cover",
"title": "Cover",
@ -9,6 +10,10 @@
"url": {
"type": "string"
},
"useFeaturedImage": {
"type": "boolean",
"default": false
},
"id": {
"type": "number"
},
@ -71,6 +76,7 @@
"enum": [ "all", "insert", false ]
}
},
"usesContext": [ "postId", "postType" ],
"supports": {
"anchor": true,
"align": true,

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/embed",
"title": "Embed",

View File

@ -8,8 +8,8 @@
/**
* When the `core/file` block is rendering, check if we need to enqueue the `'wp-block-file-view` script.
*
* @param array $attributes The block attributes.
* @param array $content The block content.
* @param array $attributes The block attributes.
* @param string $content The block content.
*
* @return string Returns the block content.
*/

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/file",
"title": "File",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/freeform",
"title": "Classic",

View File

@ -32,18 +32,53 @@ function block_core_gallery_data_id_backcompatibility( $parsed_block ) {
add_filter( 'render_block_data', 'block_core_gallery_data_id_backcompatibility' );
/**
* Adds a style tag for the --wp--style--unstable-gallery-gap var.
*
* The Gallery block needs to recalculate Image block width based on
* the current gap setting in order to maintain the number of flex columns
* so a css var is added to allow this.
*
* @param array $attributes Attributes of the block being rendered.
* @param string $content Content of the block being rendered.
* @return string The content of the block being rendered.
*/
function block_core_gallery_render( $attributes, $content ) {
$gap = _wp_array_get( $attributes, array( 'style', 'spacing', 'blockGap' ) );
// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
// because we only want to match against the value, not the CSS attribute.
$gap = preg_match( '%[\\\(&=}]|/\*%', $gap ) ? null : $gap;
$class = wp_unique_id( 'wp-block-gallery-' );
$content = preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . $class . ' ',
$content,
1
);
// --gallery-block--gutter-size is deprecated. --wp--style--gallery-gap-default should be used by themes that want to set a default
// gap on the gallery.
$gap_value = $gap ? $gap : 'var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) )';
$style = '.' . $class . '{ --wp--style--unstable-gallery-gap: ' . $gap_value . '; gap: ' . $gap_value . '}';
// Ideally styles should be loaded in the head, but blocks may be parsed
// after that, so loading in the footer for now.
// See https://core.trac.wordpress.org/ticket/53494.
add_action(
'wp_footer',
function () use ( $style ) {
echo '<style> ' . $style . '</style>';
}
);
return $content;
}
/**
* Registers the `core/gallery` block on server.
* This render callback needs to be here
* so that the gallery styles are loaded in block-based themes.
*/
function register_block_core_gallery() {
register_block_type_from_metadata(
__DIR__ . '/gallery',
array(
'render_callback' => function ( $attributes, $content ) {
return $content;
},
'render_callback' => 'block_core_gallery_render',
)
);
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/gallery",
"title": "Gallery",
@ -105,7 +106,24 @@
},
"supports": {
"anchor": true,
"align": true
"align": true,
"html": false,
"units": [ "px", "em", "rem", "vh", "vw" ],
"spacing": {
"blockGap": true,
"__experimentalSkipSerialization": [ "blockGap" ],
"__experimentalDefaultControls": {
"blockGap": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"allowEditing": false,
"default": {
"type": "flex"
}
}
},
"editorStyle": "wp-block-gallery-editor",
"style": "wp-block-gallery"

View File

@ -1,9 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/group",
"title": "Group",
"category": "design",
"description": "Combine blocks into a group.",
"description": "Gather blocks in a layout container.",
"keywords": [ "container", "wrapper", "row", "section" ],
"textdomain": "default",
"attributes": {
@ -22,9 +23,14 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"spacing": {
"margin": [ "top", "bottom" ],
"padding": true,
"blockGap": true,
"__experimentalDefaultControls": {
@ -36,7 +42,24 @@
"color": true,
"radius": true,
"style": true,
"width": true
"width": true,
"__experimentalDefaultControls": {
"color": true,
"radius": true,
"style": true,
"width": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontStyle": true,
"__experimentalFontWeight": true,
"__experimentalLetterSpacing": true,
"__experimentalTextTransform": true,
"__experimentalDefaultControls": {
"fontSize": true
}
},
"__experimentalLayout": true
},

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/heading",
"title": "Heading",
@ -30,7 +31,11 @@
"anchor": true,
"className": false,
"color": {
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"spacing": {
"margin": true

View File

@ -0,0 +1,162 @@
<?php
/**
* Server-side rendering of the `core/home-link` block.
*
* @package WordPress
*/
/**
* Build an array with CSS classes and inline styles defining the colors
* which will be applied to the home link markup in the front-end.
*
* @param array $context home link block context.
* @return array Colors CSS classes and inline styles.
*/
function block_core_home_link_build_css_colors( $context ) {
$colors = array(
'css_classes' => array(),
'inline_styles' => '',
);
// Text color.
$has_named_text_color = array_key_exists( 'textColor', $context );
$has_custom_text_color = isset( $context['style']['color']['text'] );
// If has text color.
if ( $has_custom_text_color || $has_named_text_color ) {
// Add has-text-color class.
$colors['css_classes'][] = 'has-text-color';
}
if ( $has_named_text_color ) {
// Add the color class.
$colors['css_classes'][] = sprintf( 'has-%s-color', $context['textColor'] );
} elseif ( $has_custom_text_color ) {
// Add the custom color inline style.
$colors['inline_styles'] .= sprintf( 'color: %s;', $context['style']['color']['text'] );
}
// Background color.
$has_named_background_color = array_key_exists( 'backgroundColor', $context );
$has_custom_background_color = isset( $context['style']['color']['background'] );
// If has background color.
if ( $has_custom_background_color || $has_named_background_color ) {
// Add has-background class.
$colors['css_classes'][] = 'has-background';
}
if ( $has_named_background_color ) {
// Add the background-color class.
$colors['css_classes'][] = sprintf( 'has-%s-background-color', $context['backgroundColor'] );
} elseif ( $has_custom_background_color ) {
// Add the custom background-color inline style.
$colors['inline_styles'] .= sprintf( 'background-color: %s;', $context['style']['color']['background'] );
}
return $colors;
}
/**
* Build an array with CSS classes and inline styles defining the font sizes
* which will be applied to the home link markup in the front-end.
*
* @param array $context Home link block context.
* @return array Font size CSS classes and inline styles.
*/
function block_core_home_link_build_css_font_sizes( $context ) {
// CSS classes.
$font_sizes = array(
'css_classes' => array(),
'inline_styles' => '',
);
$has_named_font_size = array_key_exists( 'fontSize', $context );
$has_custom_font_size = isset( $context['style']['typography']['fontSize'] );
if ( $has_named_font_size ) {
// Add the font size class.
$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
} elseif ( $has_custom_font_size ) {
// Add the custom font size inline style.
$font_sizes['inline_styles'] = sprintf( 'font-size: %s;', $context['style']['typography']['fontSize'] );
}
return $font_sizes;
}
/**
* Builds an array with classes and style for the li wrapper
*
* @param array $context Home link block context.
* @return array The li wrapper attributes.
*/
function block_core_home_link_build_li_wrapper_attributes( $context ) {
$colors = block_core_home_link_build_css_colors( $context );
$font_sizes = block_core_home_link_build_css_font_sizes( $context );
$classes = array_merge(
$colors['css_classes'],
$font_sizes['css_classes']
);
$style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
$css_classes = trim( implode( ' ', $classes ) ) . ' wp-block-navigation-item';
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => $css_classes,
'style' => $style_attribute,
)
);
return $wrapper_attributes;
}
/**
* Renders the `core/home-link` block.
*
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param WP_Block $block The parsed block.
*
* @return string Returns the post content with the home url added.
*/
function render_block_core_home_link( $attributes, $content, $block ) {
if ( empty( $attributes['label'] ) ) {
return '';
}
$wrapper_attributes = block_core_home_link_build_li_wrapper_attributes( $block->context );
$aria_current = is_home() || ( is_front_page() && 'page' === get_option( 'show_on_front' ) ) ? ' aria-current="page"' : '';
$html = '<li ' . $wrapper_attributes . '><a class="wp-block-home-link__content wp-block-navigation-item__content" rel="home"' . $aria_current;
// Start appending HTML attributes to anchor tag.
$html .= ' href="' . esc_url( home_url() ) . '"';
// End appending HTML attributes to anchor tag.
$html .= '>';
if ( isset( $attributes['label'] ) ) {
$html .= wp_kses_post( $attributes['label'] );
}
$html .= '</a></li>';
return $html;
}
/**
* Register the home block
*
* @uses render_block_core_home_link()
* @throws WP_Error An WP_Error exception parsing the block definition.
*/
function register_block_core_home_link() {
register_block_type_from_metadata(
__DIR__ . '/home-link',
array(
'render_callback' => 'render_block_core_home_link',
)
);
}
add_action( 'init', 'register_block_core_home_link' );

View File

@ -0,0 +1,30 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/home-link",
"category": "design",
"parent": [ "core/navigation" ],
"title": "Home Link",
"description": "Create a link that always points to the homepage of the site. Usually not necessary if there is already a site title link present in the header.",
"textdomain": "default",
"attributes": {
"label": {
"type": "string"
}
},
"usesContext": [
"textColor",
"customTextColor",
"backgroundColor",
"customBackgroundColor",
"fontSize",
"customFontSize",
"style"
],
"supports": {
"reusable": false,
"html": false
},
"editorStyle": "wp-block-home-link-editor",
"style": "wp-block-home-link"
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/html",
"title": "Custom HTML",

View File

@ -9,8 +9,8 @@
* Renders the `core/image` block on the server,
* adding a data-id attribute to the element if core/gallery has added on pre-render.
*
* @param array $attributes The block attributes.
* @param array $content The block content.
* @param array $attributes The block attributes.
* @param string $content The block content.
* @return string Returns the block content with the data-id attribute added.
*/
function render_block_core_image( $attributes, $content ) {
@ -20,7 +20,7 @@ function render_block_core_image( $attributes, $content ) {
// which now wraps Image Blocks within innerBlocks.
// The data-id attribute is added in a core/gallery `render_block_data` hook.
$data_id_attribute = 'data-id="' . esc_attr( $attributes['data-id'] ) . '"';
if ( ! strpos( $content, $data_id_attribute ) ) {
if ( false === strpos( $content, $data_id_attribute ) ) {
$content = str_replace( '<img', '<img ' . $data_id_attribute . ' ', $content );
}
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/image",
"title": "Image",
@ -83,7 +84,10 @@
"background": false
},
"__experimentalBorder": {
"radius": true
"radius": true,
"__experimentalDefaultControls": {
"radius": true
}
}
},
"styles": [

View File

@ -7,11 +7,23 @@
// Include files required for core blocks registration.
require ABSPATH . WPINC . '/blocks/archives.php';
require ABSPATH . WPINC . '/blocks/avatar.php';
require ABSPATH . WPINC . '/blocks/block.php';
require ABSPATH . WPINC . '/blocks/calendar.php';
require ABSPATH . WPINC . '/blocks/categories.php';
require ABSPATH . WPINC . '/blocks/comment-author-name.php';
require ABSPATH . WPINC . '/blocks/comment-content.php';
require ABSPATH . WPINC . '/blocks/comment-date.php';
require ABSPATH . WPINC . '/blocks/comment-edit-link.php';
require ABSPATH . WPINC . '/blocks/comment-reply-link.php';
require ABSPATH . WPINC . '/blocks/comment-template.php';
require ABSPATH . WPINC . '/blocks/comments-pagination-next.php';
require ABSPATH . WPINC . '/blocks/comments-pagination-numbers.php';
require ABSPATH . WPINC . '/blocks/comments-pagination-previous.php';
require ABSPATH . WPINC . '/blocks/comments-pagination.php';
require ABSPATH . WPINC . '/blocks/file.php';
require ABSPATH . WPINC . '/blocks/gallery.php';
require ABSPATH . WPINC . '/blocks/home-link.php';
require ABSPATH . WPINC . '/blocks/image.php';
require ABSPATH . WPINC . '/blocks/latest-comments.php';
require ABSPATH . WPINC . '/blocks/latest-posts.php';
@ -22,6 +34,7 @@ require ABSPATH . WPINC . '/blocks/navigation-submenu.php';
require ABSPATH . WPINC . '/blocks/navigation.php';
require ABSPATH . WPINC . '/blocks/page-list.php';
require ABSPATH . WPINC . '/blocks/pattern.php';
require ABSPATH . WPINC . '/blocks/post-author-biography.php';
require ABSPATH . WPINC . '/blocks/post-author.php';
require ABSPATH . WPINC . '/blocks/post-comments.php';
require ABSPATH . WPINC . '/blocks/post-content.php';
@ -32,12 +45,14 @@ require ABSPATH . WPINC . '/blocks/post-navigation-link.php';
require ABSPATH . WPINC . '/blocks/post-template.php';
require ABSPATH . WPINC . '/blocks/post-terms.php';
require ABSPATH . WPINC . '/blocks/post-title.php';
require ABSPATH . WPINC . '/blocks/query-no-results.php';
require ABSPATH . WPINC . '/blocks/query-pagination-next.php';
require ABSPATH . WPINC . '/blocks/query-pagination-numbers.php';
require ABSPATH . WPINC . '/blocks/query-pagination-previous.php';
require ABSPATH . WPINC . '/blocks/query-pagination.php';
require ABSPATH . WPINC . '/blocks/query-title.php';
require ABSPATH . WPINC . '/blocks/query.php';
require ABSPATH . WPINC . '/blocks/read-more.php';
require ABSPATH . WPINC . '/blocks/rss.php';
require ABSPATH . WPINC . '/blocks/search.php';
require ABSPATH . WPINC . '/blocks/shortcode.php';

View File

@ -30,7 +30,7 @@ function wp_latest_comments_draft_or_post_title( $post = 0 ) {
if ( empty( $title ) ) {
$title = __( '(no title)' );
}
return esc_html( $title );
return $title;
}
/**

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/latest-comments",
"title": "Latest Comments",

View File

@ -60,6 +60,11 @@ function render_block_core_latest_posts( $attributes ) {
foreach ( $recent_posts as $post ) {
$post_link = esc_url( get_permalink( $post ) );
$title = get_the_title( $post );
if ( ! $title ) {
$title = __( '(no title)' );
}
$list_items_markup .= '<li>';
@ -81,30 +86,27 @@ function render_block_core_latest_posts( $attributes ) {
$post,
$attributes['featuredImageSizeSlug'],
array(
'style' => $image_style,
'style' => esc_attr( $image_style ),
)
);
if ( $attributes['addLinkToFeaturedImage'] ) {
$featured_image = sprintf(
'<a href="%1$s">%2$s</a>',
$post_link,
'<a href="%1$s" aria-label="%2$s">%3$s</a>',
esc_url( $post_link ),
esc_attr( $title ),
$featured_image
);
}
$list_items_markup .= sprintf(
'<div class="%1$s">%2$s</div>',
$image_classes,
esc_attr( $image_classes ),
$featured_image
);
}
$title = get_the_title( $post );
if ( ! $title ) {
$title = __( '(no title)' );
}
$list_items_markup .= sprintf(
'<a href="%1$s">%2$s</a>',
$post_link,
'<a class="wp-block-latest-posts__post-title" href="%1$s">%2$s</a>',
esc_url( $post_link ),
$title
);
@ -117,7 +119,7 @@ function render_block_core_latest_posts( $attributes ) {
if ( ! empty( $author_display_name ) ) {
$list_items_markup .= sprintf(
'<div class="wp-block-latest-posts__post-author">%1$s</div>',
esc_html( $byline )
$byline
);
}
}
@ -126,7 +128,7 @@ function render_block_core_latest_posts( $attributes ) {
$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 ) )
get_the_date( '', $post )
);
}
@ -148,7 +150,7 @@ function render_block_core_latest_posts( $attributes ) {
if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
&& isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) {
$post_content = wp_kses_post( html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ) );
$post_content = html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) );
if ( post_password_required( $post ) ) {
$post_content = __( 'This content is password protected.' );
@ -156,7 +158,7 @@ function render_block_core_latest_posts( $attributes ) {
$list_items_markup .= sprintf(
'<div class="wp-block-latest-posts__post-full-content">%1$s</div>',
$post_content
wp_kses_post( $post_content )
);
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/latest-posts",
"title": "Latest Posts",

View File

@ -24,21 +24,9 @@ function render_block_core_legacy_widget( $attributes ) {
return '';
}
$id_base = $attributes['idBase'];
if ( method_exists( $wp_widget_factory, 'get_widget_key' ) && method_exists( $wp_widget_factory, 'get_widget_object' ) ) {
$widget_key = $wp_widget_factory->get_widget_key( $id_base );
$widget_object = $wp_widget_factory->get_widget_object( $id_base );
} else {
/*
* This file is copied from the published @wordpress/widgets package when WordPress
* Core is built. Because the package is a dependency of both WordPress Core and the
* Gutenberg plugin where the block editor is developed, this fallback condition is
* required until the minimum required version of WordPress for the plugin is raised
* to 5.8.
*/
$widget_key = gutenberg_get_widget_key( $id_base );
$widget_object = gutenberg_get_widget_object( $id_base );
}
$id_base = $attributes['idBase'];
$widget_key = $wp_widget_factory->get_widget_key( $id_base );
$widget_object = $wp_widget_factory->get_widget_object( $id_base );
if ( ! $widget_key || ! $widget_object ) {
return '';

View File

@ -0,0 +1,26 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/list-item",
"title": "List item",
"category": "text",
"parent": [ "core/list" ],
"description": "Create a list item.",
"textdomain": "default",
"attributes": {
"placeholder": {
"type": "string"
},
"content": {
"type": "string",
"source": "html",
"selector": "li",
"default": "",
"__experimentalRole": "content"
}
},
"supports": {
"className": false,
"__experimentalSelector": "li"
}
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/list",
"title": "List",
@ -51,7 +52,11 @@
},
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"__unstablePasteTextInline": true,
"__experimentalSelector": "ol,ul",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/loginout",
"title": "Login/out",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/media-text",
"title": "Media & Text",
@ -91,7 +92,11 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
}
},
"editorStyle": "wp-block-media-text-editor",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/missing",
"title": "Unsupported",

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/more",
"title": "More",

View File

@ -110,15 +110,15 @@ function block_core_navigation_link_build_css_font_sizes( $context ) {
* @return string
*/
function block_core_navigation_link_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
/**
* Renders the `core/navigation-link` block.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param WP_Block $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
@ -193,37 +193,26 @@ function render_block_core_navigation_link( $attributes, $content, $block ) {
'<span class="wp-block-navigation-item__label">';
if ( isset( $attributes['label'] ) ) {
$html .= wp_kses(
$attributes['label'],
array(
'code' => array(),
'em' => array(),
'img' => array(
'scale' => array(),
'class' => array(),
'style' => array(),
'src' => array(),
'alt' => array(),
),
's' => array(),
'span' => array(
'style' => array(),
),
'strong' => array(),
)
);
$html .= wp_kses_post( $attributes['label'] );
}
$html .= '</span>';
// Add description if available.
if ( ! empty( $attributes['description'] ) ) {
$html .= '<span class="wp-block-navigation-item__description">';
$html .= wp_kses_post( $attributes['description'] );
$html .= '</span>';
}
$html .= '</a>';
// End anchor tag content.
if ( isset( $block->context['showSubmenuIcon'] ) && $block->context['showSubmenuIcon'] && $has_submenu ) {
// The submenu icon can be hidden by a CSS rule on the Navigation Block.
$html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_link_render_submenu_icon() . '</span>';
}
$html .= '</a>';
// End anchor tag content.
if ( $has_submenu ) {
$inner_blocks_html = '';
foreach ( $block->inner_blocks as $inner_block ) {

View File

@ -1,11 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/navigation-link",
"title": "Custom Link",
"category": "design",
"parent": [
"core/navigation"
],
"parent": [ "core/navigation" ],
"description": "Add a page, link, or another item to your navigation.",
"textdomain": "default",
"attributes": {
@ -53,6 +52,7 @@
"fontSize",
"customFontSize",
"showSubmenuIcon",
"maxNestingLevel",
"style"
],
"supports": {

View File

@ -110,15 +110,15 @@ function block_core_navigation_submenu_build_css_font_sizes( $context ) {
* @return string
*/
function block_core_navigation_submenu_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
/**
* Renders the `core/navigation-submenu` block.
*
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param object $block The parsed block.
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param WP_Block $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
@ -167,25 +167,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
$label = '';
if ( isset( $attributes['label'] ) ) {
$label .= wp_kses(
$attributes['label'],
array(
'code' => array(),
'em' => array(),
'img' => array(
'scale' => array(),
'class' => array(),
'style' => array(),
'src' => array(),
'alt' => array(),
),
's' => array(),
'span' => array(
'style' => array(),
),
'strong' => array(),
)
);
$label .= wp_kses_post( $attributes['label'] );
}
$aria_label = sprintf(
@ -199,9 +181,9 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
// If Submenus open on hover, we render an anchor tag with attributes.
// If submenu icons are set to show, we also render a submenu button, so the submenu can be opened on click.
if ( ! $open_on_click ) {
$item_url = isset( $attributes['url'] ) ? esc_url( $attributes['url'] ) : '';
$item_url = isset( $attributes['url'] ) ? $attributes['url'] : '';
// Start appending HTML attributes to anchor tag.
$html .= '<a class="wp-block-navigation-item__content" href="' . $item_url . '"';
$html .= '<a class="wp-block-navigation-item__content" href="' . esc_url( $item_url ) . '"';
if ( $is_active ) {
$html .= ' aria-current="page"';
@ -232,11 +214,11 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
if ( $show_submenu_indicators ) {
// The submenu icon is rendered in a button here
// so that there's a clickable element to open the submenu.
$html .= '<button aria-label="' . $aria_label . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
$html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
}
} else {
// If menus open on click, we render the parent as a button.
$html .= '<button aria-label="' . $aria_label . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
$html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
// Wrap title with span to isolate it from submenu icon.
$html .= '<span class="wp-block-navigation-item__label">';
@ -245,10 +227,10 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
$html .= '</span>';
$html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_submenu_render_submenu_icon() . '</span>';
$html .= '</button>';
$html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_submenu_render_submenu_icon() . '</span>';
}
if ( $has_submenu ) {

View File

@ -1,11 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/navigation-submenu",
"title": "Submenu",
"category": "design",
"parent": [
"core/navigation"
],
"parent": [ "core/navigation" ],
"description": "Add a submenu to your navigation.",
"textdomain": "default",
"attributes": {
@ -53,6 +52,7 @@
"fontSize",
"customFontSize",
"showSubmenuIcon",
"maxNestingLevel",
"openSubmenusOnClick",
"style"
],

View File

@ -245,7 +245,7 @@ function block_core_navigation_build_css_font_sizes( $attributes ) {
* @return string
*/
function block_core_navigation_render_submenu_icon() {
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
}
@ -343,6 +343,8 @@ function block_core_navigation_get_fallback_blocks() {
* To customise the blocks provided return an array of blocks - these should be valid
* children of the `core/navigation` block.
*
* @since 5.9.0
*
* @param array[] default fallback blocks provided by the default block mechanic.
*/
return apply_filters( 'block_core_navigation_render_fallback', $fallback_blocks );
@ -351,18 +353,22 @@ function block_core_navigation_get_fallback_blocks() {
/**
* Renders the `core/navigation` block on server.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param WP_Block $block The parsed block.
*
* @return string Returns the post content with the legacy widget added.
*/
function render_block_core_navigation( $attributes, $content, $block ) {
static $seen_menu_names = array();
// Flag used to indicate whether the rendered output is considered to be
// a fallback (i.e. the block has no menu associated with it).
$is_fallback = false;
$nav_menu_name = '';
/**
* Deprecated:
* The rgbTextColor and rgbBackgroundColor attributes
@ -426,6 +432,14 @@ function render_block_core_navigation( $attributes, $content, $block ) {
return '';
}
$nav_menu_name = $navigation_post->post_title;
if ( isset( $seen_menu_names[ $nav_menu_name ] ) ) {
++$seen_menu_names[ $nav_menu_name ];
} else {
$seen_menu_names[ $nav_menu_name ] = 1;
}
$parsed_blocks = parse_blocks( $navigation_post->post_content );
// 'parse_blocks' includes a null block with '\n\n' as the content when
@ -472,6 +486,10 @@ function render_block_core_navigation( $attributes, $content, $block ) {
$layout_class .= ' no-wrap';
}
// Manually add block support text decoration as CSS class.
$text_decoration = _wp_array_get( $attributes, array( 'style', 'typography', 'textDecoration' ), null );
$text_decoration_class = sprintf( 'has-text-decoration-%s', $text_decoration );
$colors = block_core_navigation_build_css_colors( $attributes );
$font_sizes = block_core_navigation_build_css_font_sizes( $attributes );
$classes = array_merge(
@ -479,7 +497,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
$font_sizes['css_classes'],
$is_responsive_menu ? array( 'is-responsive' ) : array(),
$layout_class ? array( $layout_class ) : array(),
$is_fallback ? array( 'is-fallback' ) : array()
$is_fallback ? array( 'is-fallback' ) : array(),
$text_decoration ? array( $text_decoration_class ) : array()
);
$inner_blocks_html = '';
@ -506,14 +525,22 @@ function render_block_core_navigation( $attributes, $content, $block ) {
$block_styles = isset( $attributes['styles'] ) ? $attributes['styles'] : '';
// If the menu name has been used previously then append an ID
// to the name to ensure uniqueness across a given post.
if ( isset( $seen_menu_names[ $nav_menu_name ] ) && $seen_menu_names[ $nav_menu_name ] > 1 ) {
$count = $seen_menu_names[ $nav_menu_name ];
$nav_menu_name = $nav_menu_name . ' ' . ( $count );
}
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => implode( ' ', $classes ),
'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'],
'class' => implode( ' ', $classes ),
'style' => $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'],
'aria-label' => $nav_menu_name,
)
);
$modal_unique_id = uniqid();
$modal_unique_id = wp_unique_id( 'modal-' );
// Determine whether or not navigation elements should be wrapped in the markup required to make it responsive,
// return early if they don't.
@ -537,26 +564,31 @@ function render_block_core_navigation( $attributes, $content, $block ) {
$is_hidden_by_default ? 'always-shown' : '',
);
$toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
$should_display_icon_label = isset( $attributes['hasIcon'] ) && true === $attributes['hasIcon'];
$toggle_button_content = $should_display_icon_label ? $toggle_button_icon : 'Menu';
$responsive_container_markup = sprintf(
'<button aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="modal-%1$s"><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg></button>
<div class="%5$s" style="%7$s" id="modal-%1$s">
'<button aria-haspopup="true" aria-label="%3$s" class="%6$s" data-micromodal-trigger="%1$s">%9$s</button>
<div class="%5$s" style="%7$s" id="%1$s">
<div class="wp-block-navigation__responsive-close" tabindex="-1" data-micromodal-close>
<div class="wp-block-navigation__responsive-dialog" aria-label="%8$s">
<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" role="img" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
<div class="wp-block-navigation__responsive-container-content" id="modal-%1$s-content">
<button aria-label="%4$s" data-micromodal-close class="wp-block-navigation__responsive-container-close"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg></button>
<div class="wp-block-navigation__responsive-container-content" id="%1$s-content">
%2$s
</div>
</div>
</div>
</div>',
$modal_unique_id,
esc_attr( $modal_unique_id ),
$inner_blocks_html,
__( 'Open menu' ), // Open button label.
__( 'Close menu' ), // Close button label.
implode( ' ', $responsive_container_classes ),
implode( ' ', $open_button_classes ),
$colors['overlay_inline_styles'],
__( 'Menu' )
esc_attr( implode( ' ', $responsive_container_classes ) ),
esc_attr( implode( ' ', $open_button_classes ) ),
safecss_filter_attr( $colors['overlay_inline_styles'] ),
__( 'Menu' ),
$toggle_button_content
);
return sprintf(
@ -569,8 +601,8 @@ function render_block_core_navigation( $attributes, $content, $block ) {
/**
* Register the navigation block.
*
* @throws WP_Error An WP_Error exception parsing the block definition.
* @uses render_block_core_navigation()
* @throws WP_Error An WP_Error exception parsing the block definition.
*/
function register_block_core_navigation() {
register_block_type_from_metadata(

View File

@ -1,14 +1,11 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/navigation",
"title": "Navigation",
"category": "theme",
"description": "A collection of blocks that allow visitors to get around your site.",
"keywords": [
"menu",
"navigation",
"links"
],
"keywords": [ "menu", "navigation", "links" ],
"textdomain": "default",
"attributes": {
"ref": {
@ -44,6 +41,10 @@
"type": "string",
"default": "mobile"
},
"hasIcon": {
"type": "boolean",
"default": true
},
"__unstableLocation": {
"type": "string"
},
@ -58,6 +59,10 @@
},
"customOverlayTextColor": {
"type": "string"
},
"maxNestingLevel": {
"type": "number",
"default": 5
}
},
"usesContext": [ "navigationArea" ],
@ -75,13 +80,11 @@
"showSubmenuIcon": "showSubmenuIcon",
"openSubmenusOnClick": "openSubmenusOnClick",
"style": "style",
"orientation": "orientation"
"orientation": "orientation",
"maxNestingLevel": "maxNestingLevel"
},
"supports": {
"align": [
"wide",
"full"
],
"align": [ "wide", "full" ],
"anchor": true,
"html": false,
"inserter": true,
@ -92,16 +95,23 @@
"__experimentalFontWeight": true,
"__experimentalTextTransform": true,
"__experimentalFontFamily": true,
"__experimentalTextDecoration": true,
"__experimentalSkipSerialization": [ "textDecoration" ],
"__experimentalDefaultControls": {
"fontSize": true
}
},
"spacing": {
"units": [ "px", "em", "rem", "vh", "vw" ]
"blockGap": true,
"units": [ "px", "em", "rem", "vh", "vw" ],
"__experimentalDefaultControls": {
"blockGap": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"allowVerticalAlignment": false,
"default": {
"type": "flex"
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/nextpage",
"title": "Page Break",

View File

@ -178,26 +178,26 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click,
$css_class .= ' menu-item-home';
}
$title = wp_kses( $page['title'], wp_kses_allowed_html( 'post' ) );
$title = wp_kses_post( $page['title'] );
$aria_label = sprintf(
/* translators: Accessibility text. %s: Parent page title. */
__( '%s submenu' ),
wp_strip_all_tags( $title )
);
$markup .= '<li class="wp-block-pages-list__item' . $css_class . '"' . $style_attribute . '>';
$markup .= '<li class="wp-block-pages-list__item' . esc_attr( $css_class ) . '"' . $style_attribute . '>';
if ( isset( $page['children'] ) && $is_navigation_child && $open_submenus_on_click ) {
$markup .= '<button aria-label="' . $aria_label . '" class="' . $navigation_child_content_class . ' wp-block-navigation-submenu__toggle" aria-expanded="false">' . $title . '<span class="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg></span>' .
'</button>';
$markup .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="' . esc_attr( $navigation_child_content_class ) . ' wp-block-navigation-submenu__toggle" aria-expanded="false">' . esc_html( $title ) .
'</button>' . '<span class="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg></span>';
} else {
$markup .= '<a class="wp-block-pages-list__item__link' . $navigation_child_content_class . '" href="' . esc_url( $page['link'] ) . '"' . $aria_current . '>' . $title . '</a>';
$markup .= '<a class="wp-block-pages-list__item__link' . esc_attr( $navigation_child_content_class ) . '" href="' . esc_url( $page['link'] ) . '"' . $aria_current . '>' . $title . '</a>';
}
if ( isset( $page['children'] ) ) {
if ( $is_navigation_child && $show_submenu_icons && ! $open_submenus_on_click ) {
$markup .= '<button aria-label="' . $aria_label . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">';
$markup .= '<span class="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" role="img" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg></span>';
$markup .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">';
$markup .= '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
$markup .= '</button>';
}
$markup .= '<ul class="submenu-container';
@ -235,9 +235,9 @@ function block_core_page_list_nest_pages( $current_level, $children ) {
/**
* Renders the `core/page-list` block on server.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
* @param array $attributes The block attributes.
* @param string $content The saved content.
* @param WP_Block $block The parsed block.
*
* @return string Returns the page list markup.
*/
@ -252,7 +252,7 @@ function render_block_core_page_list( $attributes, $content, $block ) {
)
);
// If thare are no pages, there is nothing to show.
// If there are no pages, there is nothing to show.
if ( empty( $all_pages ) ) {
return;
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/page-list",
"title": "Page List",
@ -7,6 +8,9 @@
"keywords": [ "menu", "navigation" ],
"textdomain": "default",
"attributes": {
"__unstableMaxPages": {
"type": "number"
}
},
"usesContext": [
"textColor",

View File

@ -1,9 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/paragraph",
"title": "Paragraph",
"category": "text",
"description": "Start with the building block of all narrative.",
"description": "Start with the basic building block of all narrative.",
"keywords": [ "text" ],
"textdomain": "default",
"attributes": {
@ -33,7 +34,11 @@
"anchor": true,
"className": false,
"color": {
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/pattern",
"title": "Pattern",

View File

@ -0,0 +1,48 @@
<?php
/**
* Server-side rendering of the `core/post-author-biography` block.
*
* @package WordPress
*/
/**
* Renders the `core/post-author-biography` block on the server.
*
* @param array $attributes Block attributes.
* @param string $content Block default content.
* @param WP_Block $block Block instance.
* @return string Returns the rendered post author biography block.
*/
function render_block_core_post_author_biography( $attributes, $content, $block ) {
if ( ! isset( $block->context['postId'] ) ) {
return '';
}
$author_id = get_post_field( 'post_author', $block->context['postId'] );
if ( empty( $author_id ) ) {
return '';
}
$author_biography = get_the_author_meta( 'description', $author_id );
if ( empty( $author_biography ) ) {
return '';
}
$align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );
return sprintf( '<div %1$s>', $wrapper_attributes ) . $author_biography . '</div>';
}
/**
* Registers the `core/post-author-biography` block on the server.
*/
function register_block_core_post_author_biography() {
register_block_type_from_metadata(
__DIR__ . '/post-author-biography',
array(
'render_callback' => 'render_block_core_post_author_biography',
)
);
}
add_action( 'init', 'register_block_core_post_author_biography' );

View File

@ -0,0 +1,41 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-author-biography",
"title": "Post Author Biography",
"category": "theme",
"description": "The author biography.",
"textdomain": "default",
"attributes": {
"textAlign": {
"type": "string"
}
},
"usesContext": [ "postType", "postId" ],
"supports": {
"spacing": {
"margin": true,
"padding": true
},
"color": {
"gradients": true,
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,
"lineHeight": true,
"__experimentalFontFamily": true,
"__experimentalFontWeight": true,
"__experimentalFontStyle": true,
"__experimentalTextTransform": true,
"__experimentalLetterSpacing": true,
"__experimentalDefaultControls": {
"fontSize": true
}
}
}
}

View File

@ -30,7 +30,6 @@ function render_block_core_post_author( $attributes, $content, $block ) {
$byline = ! empty( $attributes['byline'] ) ? $attributes['byline'] : false;
$classes = array_merge(
isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(),
isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array(),
isset( $attributes['textAlign'] ) ? array( 'has-text-align-' . $attributes['textAlign'] ) : array()
);
@ -40,7 +39,7 @@ function render_block_core_post_author( $attributes, $content, $block ) {
return sprintf( '<div %1$s>', $wrapper_attributes ) .
( ! empty( $attributes['showAvatar'] ) ? '<div class="wp-block-post-author__avatar">' . $avatar . '</div>' : '' ) .
'<div class="wp-block-post-author__content">' .
( ! empty( $byline ) ? '<p class="wp-block-post-author__byline">' . $byline . '</p>' : '' ) .
( ! empty( $byline ) ? '<p class="wp-block-post-author__byline">' . esc_html( $byline ) . '</p>' : '' ) .
'<p class="wp-block-post-author__name">' . get_the_author_meta( 'display_name', $author_id ) . '</p>' .
( ! empty( $attributes['showBio'] ) ? '<p class="wp-block-post-author__bio">' . get_the_author_meta( 'user_description', $author_id ) . '</p>' : '' ) .
'</div>' .

View File

@ -1,9 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-author",
"title": "Post Author",
"category": "theme",
"description": "Add the author of this post.",
"description": "Display post author details such as name, avatar, and bio.",
"textdomain": "default",
"attributes": {
"textAlign": {
@ -45,7 +46,11 @@
"color": {
"gradients": true,
"link": true,
"__experimentalDuotone": ".wp-block-post-author__avatar img"
"__experimentalDuotone": ".wp-block-post-author__avatar img",
"__experimentalDefaultControls": {
"background": true,
"text": true
}
}
},
"editorStyle": "wp-block-post-author-editor",

View File

@ -1,9 +1,10 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-comments",
"title": "Post Comments",
"title": "Post Comments (deprecated)",
"category": "theme",
"description": "Display a post's comments.",
"description": "This block is deprecated. Please use the Comments Query Loop block instead.",
"textdomain": "default",
"attributes": {
"textAlign": {
@ -27,8 +28,13 @@
},
"color": {
"gradients": true,
"link": true
}
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"inserter": false
},
"style": [
"wp-block-post-comments",

View File

@ -45,7 +45,7 @@ function render_block_core_post_content( $attributes, $content, $block ) {
// When inside the main loop, we want to use queried object
// so that `the_preview` for the current post can apply.
// We force this behavior by omitting the third argument (post ID) from the `get_the_content`.
$content = get_the_content( null, false );
$content = get_the_content();
// Check for nextpage to display page links for paginated posts.
if ( has_block( 'core/nextpage' ) ) {
$content .= wp_link_pages( array( 'echo' => 0 ) );

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-content",
"title": "Post Content",

View File

@ -21,7 +21,7 @@ function render_block_core_post_date( $attributes, $content, $block ) {
$post_ID = $block->context['postId'];
$align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );
$formatted_date = get_the_date( isset( $attributes['format'] ) ? $attributes['format'] : '', $post_ID );
$formatted_date = get_the_date( empty( $attributes['format'] ) ? '' : $attributes['format'], $post_ID );
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
$formatted_date = sprintf( '<a href="%1s">%2s</a>', get_the_permalink( $post_ID ), $formatted_date );
}
@ -29,7 +29,7 @@ function render_block_core_post_date( $attributes, $content, $block ) {
return sprintf(
'<div %1$s><time datetime="%2$s">%3$s</time></div>',
$wrapper_attributes,
get_the_date( 'c', $post_ID ),
esc_attr( get_the_date( 'c', $post_ID ) ),
$formatted_date
);
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-date",
"title": "Post Date",
@ -22,7 +23,12 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"typography": {
"fontSize": true,

View File

@ -24,7 +24,7 @@ function render_block_core_post_excerpt( $attributes, $content, $block ) {
return '';
}
$more_text = ! empty( $attributes['moreText'] ) ? '<a class="wp-block-post-excerpt__more-link" href="' . esc_url( get_the_permalink( $block->context['postId'] ) ) . '">' . $attributes['moreText'] . '</a>' : '';
$more_text = ! empty( $attributes['moreText'] ) ? '<a class="wp-block-post-excerpt__more-link" href="' . esc_url( get_the_permalink( $block->context['postId'] ) ) . '">' . wp_kses_post( $attributes['moreText'] ) . '</a>' : '';
$filter_excerpt_more = function( $more ) use ( $more_text ) {
return empty( $more_text ) ? $more : '';
};

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-excerpt",
"title": "Post Excerpt",
@ -22,7 +23,12 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"spacing": {
"margin": true,

View File

@ -19,7 +19,9 @@ function render_block_core_post_featured_image( $attributes, $content, $block )
}
$post_ID = $block->context['postId'];
$featured_image = get_the_post_thumbnail( $post_ID );
$size_slug = isset( $attributes['sizeSlug'] ) ? $attributes['sizeSlug'] : 'post-thumbnail';
$post_title = trim( strip_tags( get_the_title( $post_ID ) ) );
$featured_image = get_the_post_thumbnail( $post_ID, $size_slug, array( 'alt' => $post_title ) );
if ( ! $featured_image ) {
return '';
}
@ -43,7 +45,7 @@ function render_block_core_post_featured_image( $attributes, $content, $block )
if ( ! empty( $attributes['scale'] ) ) {
$image_styles .= "object-fit:{$attributes['scale']};";
}
$featured_image = str_replace( 'src=', "style='$image_styles' src=", $featured_image );
$featured_image = str_replace( 'src=', 'style="' . esc_attr( $image_styles ) . '" src=', $featured_image );
}
return "<figure $wrapper_attributes>$featured_image</figure>";

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-featured-image",
"title": "Post Featured Image",
@ -19,13 +20,16 @@
"scale": {
"type": "string",
"default": "cover"
},
"sizeSlug": {
"type": "string"
}
},
"usesContext": [ "postId", "postType", "queryId" ],
"supports": {
"align": [ "left", "right", "center", "wide", "full" ],
"color": {
"__experimentalDuotone": "img",
"__experimentalDuotone": "img, .wp-block-post-featured-image__placeholder, .components-placeholder__illustration, .components-placeholder::before",
"text": false,
"background": false
},

View File

@ -18,7 +18,7 @@ function render_block_core_post_navigation_link( $attributes, $content ) {
return '';
}
// Get the nagigation type to show the proper link. Available options are `next|previous`.
// Get the navigation type to show the proper link. Available options are `next|previous`.
$navigation_type = isset( $attributes['type'] ) ? $attributes['type'] : 'next';
// Allow only `next` and `previous` in `$navigation_type`.
if ( ! in_array( $navigation_type, array( 'next', 'previous' ), true ) ) {
@ -49,13 +49,13 @@ function render_block_core_post_navigation_link( $attributes, $content ) {
*/
if ( ! $attributes['linkLabel'] ) {
if ( $label ) {
$format = '<span class="post-navigation-link__label">' . $label . '</span> %link';
$format = '<span class="post-navigation-link__label">' . wp_kses_post( $label ) . '</span> %link';
}
$link = '%title';
} elseif ( isset( $attributes['linkLabel'] ) && $attributes['linkLabel'] ) {
// If the label link option is enabled and there is a custom label, display it before the title.
if ( $label ) {
$link = '<span class="post-navigation-link__label">' . $label . '</span> <span class="post-navigation-link__title">%title</title>';
$link = '<span class="post-navigation-link__label">' . wp_kses_post( $label ) . '</span> <span class="post-navigation-link__title">%title</span>';
} else {
/*
* If the label link option is enabled and there is no custom label,
@ -64,7 +64,7 @@ function render_block_core_post_navigation_link( $attributes, $content ) {
$label = 'next' === $navigation_type ? _x( 'Next:', 'label before the title of the next post' ) : _x( 'Previous:', 'label before the title of the previous post' );
$link = sprintf(
'<span class="post-navigation-link__label">%1$s</span> <span class="post-navigation-link__title">%2$s</span>',
$label,
wp_kses_post( $label ),
'%title'
);
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-navigation-link",
"title": "Post Navigation Link",

View File

@ -61,8 +61,8 @@ function render_block_core_post_template( $attributes, $content, $block ) {
)
)
)->render( array( 'dynamic' => false ) );
$post_classes = esc_attr( implode( ' ', get_post_class( 'wp-block-post' ) ) );
$content .= '<li class="' . $post_classes . '">' . $block_content . '</li>';
$post_classes = implode( ' ', get_post_class( 'wp-block-post' ) );
$content .= '<li class="' . esc_attr( $post_classes ) . '">' . $block_content . '</li>';
}
wp_reset_postdata();

View File

@ -1,8 +1,9 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-template",
"title": "Post Template",
"category": "design",
"category": "theme",
"parent": [ "core/query" ],
"description": "Contains the block elements used to render a post, like the title, date, featured image, content or excerpt, and more.",
"textdomain": "default",

View File

@ -40,7 +40,7 @@ function render_block_core_post_terms( $attributes, $content, $block ) {
$block->context['postId'],
$attributes['term'],
"<div $wrapper_attributes>",
'<span class="wp-block-post-terms__separator">' . $separator . '</span>',
'<span class="wp-block-post-terms__separator">' . esc_html( $separator ) . '</span>',
'</div>'
);
}

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-terms",
"title": "Post Terms",
@ -22,7 +23,12 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"typography": {
"lineHeight": true,

View File

@ -34,7 +34,7 @@ function render_block_core_post_title( $attributes, $content, $block ) {
}
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
$title = sprintf( '<a href="%1$s" target="%2$s" rel="%3$s">%4$s</a>', get_the_permalink( $post_ID ), $attributes['linkTarget'], $attributes['rel'], $title );
$title = sprintf( '<a href="%1$s" target="%2$s" rel="%3$s">%4$s</a>', get_the_permalink( $post_ID ), esc_attr( $attributes['linkTarget'] ), esc_attr( $attributes['rel'] ), $title );
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) );

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/post-title",
"title": "Post Title",
@ -33,7 +34,12 @@
"html": false,
"color": {
"gradients": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true,
"link": true
}
},
"spacing": {
"margin": true

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/preformatted",
"title": "Preformatted",
@ -18,7 +19,11 @@
"supports": {
"anchor": true,
"color": {
"gradients": true
"gradients": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,

View File

@ -1,4 +1,5 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/pullquote",
"title": "Pullquote",
@ -30,7 +31,11 @@
"color": {
"gradients": true,
"background": true,
"link": true
"link": true,
"__experimentalDefaultControls": {
"background": true,
"text": true
}
},
"typography": {
"fontSize": true,
@ -48,7 +53,13 @@
"color": true,
"radius": true,
"style": true,
"width": true
"width": true,
"__experimentalDefaultControls": {
"color": true,
"radius": true,
"style": true,
"width": true
}
}
},
"editorStyle": "wp-block-pullquote-editor",

Some files were not shown because too many files have changed in this diff Show More