From 4bcf9be6158bd23cee28ebd0aadc6d6f75c581ee Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Tue, 4 Feb 2020 20:14:50 +0000 Subject: [PATCH] Block Editor: Include navigation block server logic. Core did not include the navigation block PHP files. This commit fixes the issue referred, and now the navigation block is executed on the frontend. The block still does not work as expected and throws an error during frontend execution. That problem is going to be fixed on the next WordPress package update. This commit adds the file as it is on the npm package used. Props gziolo. Fixes #49348. git-svn-id: https://develop.svn.wordpress.org/trunk@47176 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/blocks/navigation.php | 195 ++++++++++++++++++ src/wp-settings.php | 1 + tests/phpunit/includes/functions.php | 1 + .../tests/rest-api/rest-schema-setup.php | 1 + tests/qunit/fixtures/wp-api-generated.js | 40 ++++ tools/webpack/packages.js | 1 + 6 files changed, 239 insertions(+) create mode 100644 src/wp-includes/blocks/navigation.php diff --git a/src/wp-includes/blocks/navigation.php b/src/wp-includes/blocks/navigation.php new file mode 100644 index 0000000000..13b6df4256 --- /dev/null +++ b/src/wp-includes/blocks/navigation.php @@ -0,0 +1,195 @@ + array(), + 'inline_styles' => '', + ); + + $has_named_text_color = array_key_exists( 'textColor', $attributes ); + $has_custom_text_color = array_key_exists( 'customTextColor', $attributes ); + + // 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', $attributes['textColor'] ); + } elseif ( $has_custom_text_color ) { + // Add the custom color inline style. + $colors['inline_styles'] = sprintf( 'color: %s;', $attributes['customTextColor'] ); + } + + return $colors; +} + +/** + * Build an array with CSS classes and inline styles defining the font sizes + * which will be applied to the navigation markup in the front-end. + * + * @param array $attributes Navigation block attributes. + * @return array Font size CSS classes and inline styles. + */ +function build_css_font_sizes( $attributes ) { + // CSS classes. + $font_sizes = array( + 'css_classes' => array(), + 'inline_styles' => '', + ); + + $has_named_font_size = array_key_exists( 'fontSize', $attributes ); + $has_custom_font_size = array_key_exists( 'customFontSize', $attributes ); + + if ( $has_named_font_size ) { + // Add the font size class. + $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $attributes['fontSize'] ); + } elseif ( $has_custom_font_size ) { + // Add the custom font size inline style. + $font_sizes['inline_styles'] = sprintf( 'font-size: %spx;', $attributes['customFontSize'] ); + } + + return $font_sizes; +} + +/** + * 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. + * + * @return string Returns the post content with the legacy widget added. + */ +function render_block_navigation( $attributes, $content, $block ) { + $colors = build_css_colors( $attributes ); + $font_sizes = build_css_font_sizes( $attributes ); + $classes = array_merge( + $colors['css_classes'], + $font_sizes['css_classes'], + array( 'wp-block-navigation' ), + isset( $attributes['className'] ) ? array( $attributes['className'] ) : array(), + isset( $attributes['itemsJustification'] ) ? array( 'items-justified-' . $attributes['itemsJustification'] ) : array(), + isset( $attributes['align'] ) ? array( 'align' . $attributes['align'] ) : array() + ); + $class_attribute = sprintf( ' class="%s"', esc_attr( implode( ' ', $classes ) ) ); + $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] ) + ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) ) + : ''; + + return sprintf( + '', + $class_attribute, + $style_attribute, + build_navigation_html( $block, $colors, $font_sizes ) + ); +} + +/** + * Walks the inner block structure and returns an HTML list for it. + * + * @param array $block The block. + * @param array $colors Contains inline styles and CSS classes to apply to navigation item. + * @param array $font_sizes Contains inline styles and CSS classes to apply to navigation item. + * + * @return string Returns an HTML list from innerBlocks. + */ +function build_navigation_html( $block, $colors, $font_sizes ) { + $html = ''; + $classes = array_merge( + $colors['css_classes'], + $font_sizes['css_classes'] + ); + $css_classes = implode( ' ', $classes ); + $class_attribute = sprintf( ' class="wp-block-navigation-link__content %s"', esc_attr( trim( $css_classes ) ) ); + $style_attribute = ( $colors['inline_styles'] || $font_sizes['inline_styles'] ) + ? sprintf( ' style="%s"', esc_attr( $colors['inline_styles'] ) . esc_attr( $font_sizes['inline_styles'] ) ) + : ''; + + foreach ( (array) $block['innerBlocks'] as $key => $block ) { + + $html .= ''; + } + return ''; +} + +/** + * Register the navigation block. + * + * @uses render_block_navigation() + * @throws WP_Error An WP_Error exception parsing the block definition. + */ +function register_block_core_navigation() { + + register_block_type( + 'core/navigation', + array( + 'attributes' => array( + 'className' => array( + 'type' => 'string', + ), + 'textColor' => array( + 'type' => 'string', + ), + 'customTextColor' => array( + 'type' => 'string', + ), + 'fontSize' => array( + 'type' => 'string', + ), + 'customFontSize' => array( + 'type' => 'number', + ), + 'itemsJustification' => array( + 'type' => 'string', + ), + ), + + 'render_callback' => 'render_block_navigation', + ) + ); +} +add_action( 'init', 'register_block_core_navigation' ); diff --git a/src/wp-settings.php b/src/wp-settings.php index 13f9bbb3a5..230b54010a 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -263,6 +263,7 @@ require( ABSPATH . WPINC . '/blocks/calendar.php' ); require( ABSPATH . WPINC . '/blocks/categories.php' ); require( ABSPATH . WPINC . '/blocks/latest-comments.php' ); require( ABSPATH . WPINC . '/blocks/latest-posts.php' ); +require( ABSPATH . WPINC . '/blocks/navigation.php' ); require( ABSPATH . WPINC . '/blocks/rss.php' ); require( ABSPATH . WPINC . '/blocks/search.php' ); require( ABSPATH . WPINC . '/blocks/shortcode.php' ); diff --git a/tests/phpunit/includes/functions.php b/tests/phpunit/includes/functions.php index 4fcb1601e3..a69354d9b7 100644 --- a/tests/phpunit/includes/functions.php +++ b/tests/phpunit/includes/functions.php @@ -301,6 +301,7 @@ function _unhook_block_registration() { remove_action( 'init', 'register_block_core_categories' ); remove_action( 'init', 'register_block_core_latest_comments' ); remove_action( 'init', 'register_block_core_latest_posts' ); + remove_action( 'init', 'register_block_core_navigation' ); remove_action( 'init', 'register_block_core_rss' ); remove_action( 'init', 'register_block_core_search' ); remove_action( 'init', 'register_block_core_shortcode' ); diff --git a/tests/phpunit/tests/rest-api/rest-schema-setup.php b/tests/phpunit/tests/rest-api/rest-schema-setup.php index 0aeebb4352..1a207db546 100644 --- a/tests/phpunit/tests/rest-api/rest-schema-setup.php +++ b/tests/phpunit/tests/rest-api/rest-schema-setup.php @@ -126,6 +126,7 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { '/wp/v2/block-renderer/(?Pcore/categories)', '/wp/v2/block-renderer/(?Pcore/latest-comments)', '/wp/v2/block-renderer/(?Pcore/latest-posts)', + '/wp/v2/block-renderer/(?Pcore/navigation)', '/wp/v2/block-renderer/(?Pcore/rss)', '/wp/v2/block-renderer/(?Pcore/search)', '/wp/v2/block-renderer/(?Pcore/shortcode)', diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 9c130539b7..c709db9f6f 100644 --- a/tests/qunit/fixtures/wp-api-generated.js +++ b/tests/qunit/fixtures/wp-api-generated.js @@ -4632,6 +4632,46 @@ mockedApiResponse.Schema = { } ] }, + "/wp/v2/block-renderer/(?Pcore/navigation)": { + "namespace": "wp/v2", + "methods": [ + "GET" + ], + "endpoints": [ + { + "methods": [ + "GET" + ], + "args": { + "name": { + "required": false, + "description": "Unique registered name for the block.", + "type": "string" + }, + "context": { + "required": false, + "default": "view", + "enum": [ + "edit" + ], + "description": "Scope under which the request is made; determines fields present in response.", + "type": "string" + }, + "attributes": { + "required": false, + "default": [], + "description": "Attributes for core/navigation block", + "type": "object" + }, + "post_id": { + "required": false, + "description": "ID of the post context.", + "type": "integer" + } + } + } + ] + }, "/wp/v2/block-renderer/(?Pcore/rss)": { "namespace": "wp/v2", "methods": [ diff --git a/tools/webpack/packages.js b/tools/webpack/packages.js index ab9e2fdef1..a622453126 100644 --- a/tools/webpack/packages.js +++ b/tools/webpack/packages.js @@ -101,6 +101,7 @@ module.exports = function( env = { environment: 'production', watch: false, buil 'categories', 'latest-comments', 'latest-posts', + 'navigation', 'rss', 'search', 'shortcode',