Skip to content

Instantly share code, notes, and snippets.

@kasparsd
Created April 22, 2025 07:54
Show Gist options
  • Save kasparsd/1b8bb79da29b115da632d0277ae210ec to your computer and use it in GitHub Desktop.
Save kasparsd/1b8bb79da29b115da632d0277ae210ec to your computer and use it in GitHub Desktop.

Revisions

  1. kasparsd created this gist Apr 22, 2025.
    75 changes: 75 additions & 0 deletions navigation-item.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    <?php
    /**
    * Plugin Name: Navigation Item Ancestors
    */

    namespace Config\Navigation_Item;

    function get_post_children_ids(): array {
    static $children_ids;

    if ( ! isset( $children_ids ) ) {
    $children_ids = [];

    // Get all posts with a parent set.
    $query = new \WP_Query(
    [
    'post_type' => 'any',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'fields' => 'id=>parent',
    'post_parent__not_in' => [ 0 ], // Exclude posts without parents.
    'no_found_rows' => true,
    'cache_results' => true,
    'update_post_term_cache' => false,
    'update_post_meta_cache' => false,
    ]
    );

    if ( ! empty( $query->posts ) ) {
    $children_ids = array_reduce(
    $query->posts,
    function ( $carry, $post ) {
    $carry[ $post->post_parent ][] = $post->ID;

    return $carry;
    },
    []
    );

    // Now collect all ancestry.
    foreach ( $children_ids as $parent_id => $child_ids ) {
    foreach ( $child_ids as $child_id ) {
    if ( isset( $children_ids[ $child_id ] ) ) {
    $children_ids[ $parent_id ] = array_merge( $children_ids[ $parent_id ], $children_ids[ $child_id ] );
    }
    }
    }
    }
    }

    return $children_ids;
    }

    add_filter(
    'render_block',
    function ( $block_content, $block ) {
    if ( ! empty( $block['attrs']['id'] ) && str_starts_with( $block['blockName'], 'core/navigation-' ) && is_singular() ) {
    $children_ids = get_post_children_ids();
    $current_post_id = get_queried_object_id();
    $menu_link_post_id = (int) $block['attrs']['id'];

    if ( isset( $children_ids[ $menu_link_post_id ] ) && in_array( $current_post_id, $children_ids[ $menu_link_post_id ], true ) ) {
    return str_replace(
    ' wp-block-navigation-item',
    ' wp-block-navigation-item current-menu-ancestor',
    $block_content
    );
    }
    }

    return $block_content;
    },
    10,
    2
    );