* Server-side rendering of the `core/categories` block.
* Renders the `core/categories` block on server.
* @param array $attributes The block attributes.
* @return string Returns the categories list/dropdown markup.
function render_block_core_categories( $attributes ) {
'hierarchical' => ! empty( $attributes['showHierarchy'] ),
'show_count' => ! empty( $attributes['showPostCounts'] ),
if ( ! empty( $attributes['displayAsDropdown'] ) ) {
$id = 'wp-block-categories-' . $block_id;
$args['show_option_none'] = __( 'Select Category' );
$wrapper_markup = '<div %1$s>%2$s</div>';
$items_markup = wp_dropdown_categories( $args );
// Inject the dropdown script immediately after the select dropdown.
$items_markup = preg_replace(
build_dropdown_script_block_core_categories( $id ),
$wrapper_markup = '<ul %1$s>%2$s</ul>';
$items_markup = wp_list_categories( $args );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => "wp-block-categories-{$type}" ) );
* Generates the inline script for a categories dropdown field.
* @param string $dropdown_id ID of the dropdown field.
* @return string Returns the dropdown onChange redirection script.
function build_dropdown_script_block_core_categories( $dropdown_id ) {
<script type='text/javascript'>
var dropdown = document.getElementById( '<?php echo esc_js( $dropdown_id ); ?>' );
if ( dropdown.options[ dropdown.selectedIndex ].value > 0 ) {
location.href = "<?php echo home_url(); ?>/?cat=" + dropdown.options[ dropdown.selectedIndex ].value;
dropdown.onchange = onCatChange;
* Registers the `core/categories` block on server.
function register_block_core_categories() {
register_block_type_from_metadata(
'render_callback' => 'render_block_core_categories',
add_action( 'init', 'register_block_core_categories' );