wp/wp-includes/blocks/page-list.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     6  */
     6  */
     7 
     7 
     8 /**
     8 /**
     9  * Build an array with CSS classes and inline styles defining the colors
     9  * Build an array with CSS classes and inline styles defining the colors
    10  * which will be applied to the pages markup in the front-end when it is a descendant of navigation.
    10  * which will be applied to the pages markup in the front-end when it is a descendant of navigation.
       
    11  *
       
    12  * @since 5.8.0
    11  *
    13  *
    12  * @param  array $attributes Block attributes.
    14  * @param  array $attributes Block attributes.
    13  * @param  array $context    Navigation block context.
    15  * @param  array $context    Navigation block context.
    14  * @return array Colors CSS classes and inline styles.
    16  * @return array Colors CSS classes and inline styles.
    15  */
    17  */
    99 
   101 
   100 /**
   102 /**
   101  * Build an array with CSS classes and inline styles defining the font sizes
   103  * Build an array with CSS classes and inline styles defining the font sizes
   102  * which will be applied to the pages markup in the front-end when it is a descendant of navigation.
   104  * which will be applied to the pages markup in the front-end when it is a descendant of navigation.
   103  *
   105  *
       
   106  * @since 5.8.0
       
   107  *
   104  * @param  array $context Navigation block context.
   108  * @param  array $context Navigation block context.
   105  * @return array Font size CSS classes and inline styles.
   109  * @return array Font size CSS classes and inline styles.
   106  */
   110  */
   107 function block_core_page_list_build_css_font_sizes( $context ) {
   111 function block_core_page_list_build_css_font_sizes( $context ) {
   108 	// CSS classes.
   112 	// CSS classes.
   117 	if ( $has_named_font_size ) {
   121 	if ( $has_named_font_size ) {
   118 		// Add the font size class.
   122 		// Add the font size class.
   119 		$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
   123 		$font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
   120 	} elseif ( $has_custom_font_size ) {
   124 	} elseif ( $has_custom_font_size ) {
   121 		// Add the custom font size inline style.
   125 		// Add the custom font size inline style.
   122 		$font_sizes['inline_styles'] = sprintf( 'font-size: %s;', $context['style']['typography']['fontSize'] );
   126 		$font_sizes['inline_styles'] = sprintf(
       
   127 			'font-size: %s;',
       
   128 			wp_get_typography_font_size_value(
       
   129 				array(
       
   130 					'size' => $context['style']['typography']['fontSize'],
       
   131 				)
       
   132 			)
       
   133 		);
   123 	}
   134 	}
   124 
   135 
   125 	return $font_sizes;
   136 	return $font_sizes;
   126 }
   137 }
   127 
   138 
   128 /**
   139 /**
   129  * Outputs Page list markup from an array of pages with nested children.
   140  * Outputs Page list markup from an array of pages with nested children.
       
   141  *
       
   142  * @since 5.8.0
   130  *
   143  *
   131  * @param boolean $open_submenus_on_click Whether to open submenus on click instead of hover.
   144  * @param boolean $open_submenus_on_click Whether to open submenus on click instead of hover.
   132  * @param boolean $show_submenu_icons Whether to show submenu indicator icons.
   145  * @param boolean $show_submenu_icons Whether to show submenu indicator icons.
   133  * @param boolean $is_navigation_child If block is a child of Navigation block.
   146  * @param boolean $is_navigation_child If block is a child of Navigation block.
   134  * @param array   $nested_pages The array of nested pages.
   147  * @param array   $nested_pages The array of nested pages.
       
   148  * @param boolean $is_nested Whether the submenu is nested or not.
   135  * @param array   $active_page_ancestor_ids An array of ancestor ids for active page.
   149  * @param array   $active_page_ancestor_ids An array of ancestor ids for active page.
   136  * @param array   $colors Color information for overlay styles.
   150  * @param array   $colors Color information for overlay styles.
   137  * @param integer $depth The nesting depth.
   151  * @param integer $depth The nesting depth.
   138  *
   152  *
   139  * @return string List markup.
   153  * @return string List markup.
   140  */
   154  */
   141 function block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $nested_pages, $active_page_ancestor_ids = array(), $colors = array(), $depth = 0 ) {
   155 function block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $nested_pages, $is_nested, $active_page_ancestor_ids = array(), $colors = array(), $depth = 0 ) {
   142 	if ( empty( $nested_pages ) ) {
   156 	if ( empty( $nested_pages ) ) {
   143 		return;
   157 		return;
   144 	}
   158 	}
   145 	$markup = '';
   159 	$front_page_id = (int) get_option( 'page_on_front' );
       
   160 	$markup        = '';
   146 	foreach ( (array) $nested_pages as $page ) {
   161 	foreach ( (array) $nested_pages as $page ) {
   147 		$css_class       = $page['is_active'] ? ' current-menu-item' : '';
   162 		$css_class       = $page['is_active'] ? ' current-menu-item' : '';
   148 		$aria_current    = $page['is_active'] ? ' aria-current="page"' : '';
   163 		$aria_current    = $page['is_active'] ? ' aria-current="page"' : '';
   149 		$style_attribute = '';
   164 		$style_attribute = '';
   150 
   165 
   164 		}
   179 		}
   165 
   180 
   166 		$navigation_child_content_class = $is_navigation_child ? ' wp-block-navigation-item__content' : '';
   181 		$navigation_child_content_class = $is_navigation_child ? ' wp-block-navigation-item__content' : '';
   167 
   182 
   168 		// If this is the first level of submenus, include the overlay colors.
   183 		// If this is the first level of submenus, include the overlay colors.
   169 		if ( 1 === $depth && isset( $colors['overlay_css_classes'], $colors['overlay_inline_styles'] ) ) {
   184 		if ( ( ( 0 < $depth && ! $is_nested ) || $is_nested ) && isset( $colors['overlay_css_classes'], $colors['overlay_inline_styles'] ) ) {
   170 			$css_class .= ' ' . trim( implode( ' ', $colors['overlay_css_classes'] ) );
   185 			$css_class .= ' ' . trim( implode( ' ', $colors['overlay_css_classes'] ) );
   171 			if ( '' !== $colors['overlay_inline_styles'] ) {
   186 			if ( '' !== $colors['overlay_inline_styles'] ) {
   172 				$style_attribute = sprintf( ' style="%s"', esc_attr( $colors['overlay_inline_styles'] ) );
   187 				$style_attribute = sprintf( ' style="%s"', esc_attr( $colors['overlay_inline_styles'] ) );
   173 			}
   188 			}
   174 		}
   189 		}
   175 
   190 
   176 		$front_page_id = (int) get_option( 'page_on_front' );
       
   177 		if ( (int) $page['page_id'] === $front_page_id ) {
   191 		if ( (int) $page['page_id'] === $front_page_id ) {
   178 			$css_class .= ' menu-item-home';
   192 			$css_class .= ' menu-item-home';
   179 		}
   193 		}
   180 
   194 
   181 		$title      = wp_kses_post( $page['title'] );
   195 		$title      = wp_kses_post( $page['title'] );
   187 
   201 
   188 		$markup .= '<li class="wp-block-pages-list__item' . esc_attr( $css_class ) . '"' . $style_attribute . '>';
   202 		$markup .= '<li class="wp-block-pages-list__item' . esc_attr( $css_class ) . '"' . $style_attribute . '>';
   189 
   203 
   190 		if ( isset( $page['children'] ) && $is_navigation_child && $open_submenus_on_click ) {
   204 		if ( isset( $page['children'] ) && $is_navigation_child && $open_submenus_on_click ) {
   191 			$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 ) .
   205 			$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 ) .
   192 			'</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>';
   206 			'</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>';
   193 		} else {
   207 		} else {
   194 			$markup .= '<a class="wp-block-pages-list__item__link' . esc_attr( $navigation_child_content_class ) . '" href="' . esc_url( $page['link'] ) . '"' . $aria_current . '>' . $title . '</a>';
   208 			$markup .= '<a class="wp-block-pages-list__item__link' . esc_attr( $navigation_child_content_class ) . '" href="' . esc_url( $page['link'] ) . '"' . $aria_current . '>' . $title . '</a>';
   195 		}
   209 		}
   196 
   210 
   197 		if ( isset( $page['children'] ) ) {
   211 		if ( isset( $page['children'] ) ) {
   198 			if ( $is_navigation_child && $show_submenu_icons && ! $open_submenus_on_click ) {
   212 			if ( $is_navigation_child && $show_submenu_icons && ! $open_submenus_on_click ) {
   199 				$markup .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">';
   213 				$markup .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">';
   200 				$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>';
   214 				$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>';
   201 				$markup .= '</button>';
   215 				$markup .= '</button>';
   202 			}
   216 			}
   203 			$markup .= '<ul class="submenu-container';
   217 			$markup .= '<ul class="wp-block-navigation__submenu-container">';
   204 			// Extra classname is added when the block is a child of Navigation.
   218 			$markup .= block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $page['children'], $is_nested, $active_page_ancestor_ids, $colors, $depth + 1 );
   205 			if ( $is_navigation_child ) {
   219 			$markup .= '</ul>';
   206 				$markup .= ' wp-block-navigation__submenu-container';
       
   207 			}
       
   208 			$markup .= '">' . block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $page['children'], $active_page_ancestor_ids, $colors, $depth + 1 ) . '</ul>';
       
   209 		}
   220 		}
   210 		$markup .= '</li>';
   221 		$markup .= '</li>';
   211 	}
   222 	}
   212 	return $markup;
   223 	return $markup;
   213 }
   224 }
   214 
   225 
   215 /**
   226 /**
   216  * Outputs nested array of pages
   227  * Outputs nested array of pages
       
   228  *
       
   229  * @since 5.8.0
   217  *
   230  *
   218  * @param array $current_level The level being iterated through.
   231  * @param array $current_level The level being iterated through.
   219  * @param array $children The children grouped by parent post ID.
   232  * @param array $children The children grouped by parent post ID.
   220  *
   233  *
   221  * @return array The nested array of pages.
   234  * @return array The nested array of pages.
   233 }
   246 }
   234 
   247 
   235 /**
   248 /**
   236  * Renders the `core/page-list` block on server.
   249  * Renders the `core/page-list` block on server.
   237  *
   250  *
       
   251  * @since 5.8.0
       
   252  *
   238  * @param array    $attributes The block attributes.
   253  * @param array    $attributes The block attributes.
   239  * @param string   $content    The saved content.
   254  * @param string   $content    The saved content.
   240  * @param WP_Block $block      The parsed block.
   255  * @param WP_Block $block      The parsed block.
   241  *
   256  *
   242  * @return string Returns the page list markup.
   257  * @return string Returns the page list markup.
   243  */
   258  */
   244 function render_block_core_page_list( $attributes, $content, $block ) {
   259 function render_block_core_page_list( $attributes, $content, $block ) {
   245 	static $block_id = 0;
   260 	static $block_id = 0;
   246 	$block_id++;
   261 	++$block_id;
       
   262 
       
   263 	$parent_page_id = $attributes['parentPageID'];
       
   264 	$is_nested      = $attributes['isNested'];
   247 
   265 
   248 	$all_pages = get_pages(
   266 	$all_pages = get_pages(
   249 		array(
   267 		array(
   250 			'sort_column' => 'menu_order,post_title',
   268 			'sort_column' => 'menu_order,post_title',
   251 			'order'       => 'asc',
   269 			'order'       => 'asc',
   262 	$pages_with_children = array();
   280 	$pages_with_children = array();
   263 
   281 
   264 	$active_page_ancestor_ids = array();
   282 	$active_page_ancestor_ids = array();
   265 
   283 
   266 	foreach ( (array) $all_pages as $page ) {
   284 	foreach ( (array) $all_pages as $page ) {
   267 		$is_active = ! empty( $page->ID ) && ( get_the_ID() === $page->ID );
   285 		$is_active = ! empty( $page->ID ) && ( get_queried_object_id() === $page->ID );
   268 
   286 
   269 		if ( $is_active ) {
   287 		if ( $is_active ) {
   270 			$active_page_ancestor_ids = get_post_ancestors( $page->ID );
   288 			$active_page_ancestor_ids = get_post_ancestors( $page->ID );
   271 		}
   289 		}
   272 
   290 
   273 		if ( $page->post_parent ) {
   291 		if ( $page->post_parent ) {
   274 			$pages_with_children[ $page->post_parent ][ $page->ID ] = array(
   292 			$pages_with_children[ $page->post_parent ][ $page->ID ] = array(
   275 				'page_id'   => $page->ID,
   293 				'page_id'   => $page->ID,
   276 				'title'     => $page->post_title,
   294 				'title'     => $page->post_title,
   277 				'link'      => get_permalink( $page->ID ),
   295 				'link'      => get_permalink( $page ),
   278 				'is_active' => $is_active,
   296 				'is_active' => $is_active,
   279 			);
   297 			);
   280 		} else {
   298 		} else {
   281 			$top_level_pages[ $page->ID ] = array(
   299 			$top_level_pages[ $page->ID ] = array(
   282 				'page_id'   => $page->ID,
   300 				'page_id'   => $page->ID,
   283 				'title'     => $page->post_title,
   301 				'title'     => $page->post_title,
   284 				'link'      => get_permalink( $page->ID ),
   302 				'link'      => get_permalink( $page ),
   285 				'is_active' => $is_active,
   303 				'is_active' => $is_active,
   286 			);
   304 			);
   287 
   305 
   288 		}
   306 		}
   289 	}
   307 	}
   297 	$style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
   315 	$style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
   298 	$css_classes     = trim( implode( ' ', $classes ) );
   316 	$css_classes     = trim( implode( ' ', $classes ) );
   299 
   317 
   300 	$nested_pages = block_core_page_list_nest_pages( $top_level_pages, $pages_with_children );
   318 	$nested_pages = block_core_page_list_nest_pages( $top_level_pages, $pages_with_children );
   301 
   319 
   302 	// Limit the number of items to be visually displayed.
   320 	if ( 0 !== $parent_page_id ) {
   303 	if ( ! empty( $attributes['__unstableMaxPages'] ) ) {
   321 		// If the parent page has no child pages, there is nothing to show.
   304 		$nested_pages = array_slice( $nested_pages, 0, $attributes['__unstableMaxPages'] );
   322 		if ( ! array_key_exists( $parent_page_id, $pages_with_children ) ) {
       
   323 			return;
       
   324 		}
       
   325 
       
   326 		$nested_pages = block_core_page_list_nest_pages(
       
   327 			$pages_with_children[ $parent_page_id ],
       
   328 			$pages_with_children
       
   329 		);
   305 	}
   330 	}
   306 
   331 
   307 	$is_navigation_child = array_key_exists( 'showSubmenuIcon', $block->context );
   332 	$is_navigation_child = array_key_exists( 'showSubmenuIcon', $block->context );
   308 
   333 
   309 	$open_submenus_on_click = array_key_exists( 'openSubmenusOnClick', $block->context ) ? $block->context['openSubmenusOnClick'] : false;
   334 	$open_submenus_on_click = array_key_exists( 'openSubmenusOnClick', $block->context ) ? $block->context['openSubmenusOnClick'] : false;
   310 
   335 
   311 	$show_submenu_icons = array_key_exists( 'showSubmenuIcon', $block->context ) ? $block->context['showSubmenuIcon'] : false;
   336 	$show_submenu_icons = array_key_exists( 'showSubmenuIcon', $block->context ) ? $block->context['showSubmenuIcon'] : false;
   312 
   337 
   313 	$wrapper_markup = '<ul %1$s>%2$s</ul>';
   338 	$wrapper_markup = $is_nested ? '%2$s' : '<ul %1$s>%2$s</ul>';
   314 
   339 
   315 	$items_markup = block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $nested_pages, $active_page_ancestor_ids, $colors );
   340 	$items_markup = block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $nested_pages, $is_nested, $active_page_ancestor_ids, $colors );
   316 
   341 
   317 	$wrapper_attributes = get_block_wrapper_attributes(
   342 	$wrapper_attributes = get_block_wrapper_attributes(
   318 		array(
   343 		array(
   319 			'class' => $css_classes,
   344 			'class' => $css_classes,
   320 			'style' => $style_attribute,
   345 			'style' => $style_attribute,
   326 		$wrapper_attributes,
   351 		$wrapper_attributes,
   327 		$items_markup
   352 		$items_markup
   328 	);
   353 	);
   329 }
   354 }
   330 
   355 
   331 	/**
   356 /**
   332 	 * Registers the `core/pages` block on server.
   357  * Registers the `core/pages` block on server.
   333 	 */
   358  *
       
   359  * @since 5.8.0
       
   360  */
   334 function register_block_core_page_list() {
   361 function register_block_core_page_list() {
   335 	register_block_type_from_metadata(
   362 	register_block_type_from_metadata(
   336 		__DIR__ . '/page-list',
   363 		__DIR__ . '/page-list',
   337 		array(
   364 		array(
   338 			'render_callback' => 'render_block_core_page_list',
   365 			'render_callback' => 'render_block_core_page_list',
   339 		)
   366 		)
   340 	);
   367 	);
   341 }
   368 }
   342 	add_action( 'init', 'register_block_core_page_list' );
   369 add_action( 'init', 'register_block_core_page_list' );