feat(menu): list regions and cities in the header menu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,5 +54,12 @@ function hoho_nav_fallback() {
|
|||||||
echo '<ul class="nav__list">';
|
echo '<ul class="nav__list">';
|
||||||
echo '<li><a class="nav__link" href="' . esc_url( home_url( '/' ) ) . '">' . esc_html__( 'Home', 'hoponhopoff' ) . '</a></li>';
|
echo '<li><a class="nav__link" href="' . esc_url( home_url( '/' ) ) . '">' . esc_html__( 'Home', 'hoponhopoff' ) . '</a></li>';
|
||||||
echo '<li><a class="nav__link" href="' . esc_url( $archive ) . '">' . esc_html__( 'Tours', 'hoponhopoff' ) . '</a></li>';
|
echo '<li><a class="nav__link" href="' . esc_url( $archive ) . '">' . esc_html__( 'Tours', 'hoponhopoff' ) . '</a></li>';
|
||||||
|
// Regions + cities from the Viator Collector structure, when active.
|
||||||
|
if ( class_exists( 'VC_Menu' ) ) {
|
||||||
|
$items = VC_Menu::items();
|
||||||
|
if ( $items ) {
|
||||||
|
echo walk_nav_menu_tree( $items, 2, (object) array( 'walker' => new Hoho_Nav_Walker() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||||
|
}
|
||||||
|
}
|
||||||
echo '</ul>';
|
echo '</ul>';
|
||||||
}
|
}
|
||||||
|
|||||||
88
viator-collector/includes/class-vc-menu.php
Normal file
88
viator-collector/includes/class-vc-menu.php
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the Viator Structure regions (each with a dropdown of its cities)
|
||||||
|
* to the theme's header menu, so the menu follows the structure without
|
||||||
|
* hand-editing Appearance → Menus.
|
||||||
|
*/
|
||||||
|
class VC_Menu {
|
||||||
|
const LOCATION = 'hoho_primary';
|
||||||
|
|
||||||
|
public static function init() {
|
||||||
|
add_filter( 'wp_nav_menu_objects', array( __CLASS__, 'append' ), 10, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function append( $items, $args ) {
|
||||||
|
if ( empty( $args->theme_location ) || self::LOCATION !== $args->theme_location ) {
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
$order = count( $items );
|
||||||
|
$extra = self::items();
|
||||||
|
foreach ( $extra as $item ) {
|
||||||
|
$item->menu_order = ++$order;
|
||||||
|
}
|
||||||
|
return array_merge( $items, $extra );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu-item objects for the walker. The theme walker turns a parent with
|
||||||
|
* children into a toggle button (no link), so a region's dropdown starts
|
||||||
|
* with an "All of {region}" link to the region page itself.
|
||||||
|
*
|
||||||
|
* @return object[]
|
||||||
|
*/
|
||||||
|
public static function items() {
|
||||||
|
$items = array();
|
||||||
|
$n = 0;
|
||||||
|
foreach ( VC_Structure::get() as $region ) {
|
||||||
|
$term = $region['term_id'] ? get_term( (int) $region['term_id'], 'viator_destination' ) : null;
|
||||||
|
if ( ! $term instanceof WP_Term ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$region_url = get_term_link( $term );
|
||||||
|
if ( is_wp_error( $region_url ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$parent = self::item( ++$n, 0, $term->name, $region_url );
|
||||||
|
$items[] = $parent;
|
||||||
|
if ( ! $region['cities'] ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* translators: %s: region name. */
|
||||||
|
$items[] = self::item( ++$n, $parent->db_id, sprintf( __( 'All of %s', 'viator-collector' ), $term->name ), $region_url );
|
||||||
|
foreach ( $region['cities'] as $city ) {
|
||||||
|
$items[] = self::item( ++$n, $parent->db_id, $city['name'], home_url( '/' . $city['slug'] . '/' ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function item( $n, $parent_id, $title, $url ) {
|
||||||
|
$id = -1000 - $n;
|
||||||
|
$item = new stdClass();
|
||||||
|
|
||||||
|
$item->ID = $id;
|
||||||
|
$item->db_id = $id;
|
||||||
|
$item->menu_item_parent = (string) $parent_id;
|
||||||
|
$item->object_id = (string) $id;
|
||||||
|
$item->object = 'custom';
|
||||||
|
$item->type = 'custom';
|
||||||
|
$item->type_label = '';
|
||||||
|
$item->title = $title;
|
||||||
|
$item->url = $url;
|
||||||
|
$item->target = '';
|
||||||
|
$item->attr_title = '';
|
||||||
|
$item->description = '';
|
||||||
|
$item->classes = array( 'menu-item', 'vc-structure-item' );
|
||||||
|
$item->xfn = '';
|
||||||
|
$item->status = 'publish';
|
||||||
|
$item->post_parent = 0;
|
||||||
|
$item->menu_order = $n;
|
||||||
|
$item->current = false;
|
||||||
|
$item->current_item_ancestor = false;
|
||||||
|
$item->current_item_parent = false;
|
||||||
|
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ final class VC_Plugin {
|
|||||||
VC_Settings::init();
|
VC_Settings::init();
|
||||||
VC_Structure_Admin::init();
|
VC_Structure_Admin::init();
|
||||||
VC_Routing::init();
|
VC_Routing::init();
|
||||||
|
VC_Menu::init();
|
||||||
VC_Cron::init();
|
VC_Cron::init();
|
||||||
VC_Display::init();
|
VC_Display::init();
|
||||||
VC_Sections::init();
|
VC_Sections::init();
|
||||||
@@ -39,6 +40,7 @@ final class VC_Plugin {
|
|||||||
'includes/class-vc-settings.php',
|
'includes/class-vc-settings.php',
|
||||||
'includes/class-vc-structure-admin.php',
|
'includes/class-vc-structure-admin.php',
|
||||||
'includes/class-vc-routing.php',
|
'includes/class-vc-routing.php',
|
||||||
|
'includes/class-vc-menu.php',
|
||||||
'includes/class-vc-display.php',
|
'includes/class-vc-display.php',
|
||||||
'includes/class-vc-sections.php',
|
'includes/class-vc-sections.php',
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user