Pre-popularea meniurilor în WordPress

De multe ori se întâmplă să fie nevoie să am meniurile gata pregătite în WP. Să fac un fel de seed la DB. Cum procedez?

În primul rând, facem un array cu elementele de meniu. Majoritatea sunt doar pagini, dar sunt situații în care vrem ceva mai… custom. De exemplu, vrem să adăugăm o anumită clasă pentru un element al meniului:

$menus = [
  'primary' => ['About', 'Stories', 'Community', 'Resources', 'Pet Supplies', 'Subscribe',
    [
      'menu-item-title' => 'Pet Portal',
      'menu-item-classes' => 'button button-hollow',
    ],

    [
      'menu-item-title' => 'Donate',
      'menu-item-classes' => 'button',
    ],
  ],
  'secondary1' => ['Adoption', 'Pet Care', 'Training', 'Youth Programs'],
  'secondary2' => ['Give', 'Take Action', 'Outreach', 'Sponsor'],
  'footer' => ['Contact', 'Careers', 'Articles', 'Events', 'Results'],
];

Cheile array-ului coincid cu meniurile înregistrate deja (să zicem în functions.php):

add_action('after_setup_theme', function () {
  register_nav_menus([
    'primary' => __('Primary Menu (top)'),
    'secondary1' => __('Secondary Menu (top left)'),
    'secondary2' => __('Secondary Menu (top right)'),
    'footer' => __('Footer Menu'),
  ]);
});

Când avem structura dorită, generăm meniurile și adăugăm elementele în meniu:

$locations = get_nav_menu_locations();
foreach ($menus as $menu => $items) {

  $menuID = isset($locations[$menu]) ? $locations[$menu] : wp_create_nav_menu($menu);
  $locations[$menu] = $menuID;

  $existingItems = wp_list_pluck(wp_get_nav_menu_items($menuID), 'title');

  if (is_wp_error($menuID)) {
    continue;
  }

  foreach ($items as $item) {
    $newMenuArgs = [
      'menu-item-object' => 'page',
      'menu-item-status' => 'publish',
      'menu-item-type' => 'post_type',
    ];

    if (is_array($item)) {
      $newMenuArgs = array_merge($newMenuArgs, $item);
    } else {
      $newMenuArgs['menu-item-title'] = $item;
    }

    $menuPage = get_page_by_title($newMenuArgs['menu-item-title']);

    if (!$menuPage) {
      $menuPageID = wp_insert_post([
        'post_title' => $newMenuArgs['menu-item-title'],
        'post_type' => 'page',
        'post_status' => 'publish',
      ]);
    } else {
      $menuPageID = $menuPage->ID;
    }

    if (is_wp_error($menuPage)) {
      continue;
    }

    $newMenuArgs['menu-item-object-id'] = $menuPageID;

    if (!in_array($newMenuArgs['menu-item-title'], $existingItems)) {
      wp_update_nav_menu_item($menuID, 0, $newMenuArgs);
    }
  }
}

set_theme_mod('nav_menu_locations', $locations);

Câteva note:

  1. Paginile sunt verificate după titlu. Dacă o pagină există, nu mai este adăugată;
  2. Verificarea asta se face inclusiv pentru paginile care sunt în trash!
  3. Meniurile sunt și ele verificate: dacă există deja un element cu titlul ăla, nu mai este adăugat încă unul;
  4. Meniurile se pot șterge rapid folosind array_walk($locations, 'wp_delete_nav_menu'); set_theme_mod('nav_menu_locations', []);.

Publicat de

Ionuț Staicu

este frontend & WordPress developer, iar în timpul liber administrează DevForum.