是的,我认为应该可以通过编程方式添加和删除nav菜单项。您可以使用wp_nav_menu_objects
或wp_nav_menu_items
筛选以编辑导航菜单。或者如果您可以编辑menu walker
, 您可以在其中添加事件项。
使用您可以使用的第一个过滤器wp_update_nav_menu_item
创建新菜单项并将其保存到数据库。您应该能够使用删除菜单项wp_delete_post
. 对于后者,您将处理nav菜单的html,因此您可以将html字符串附加到菜单中。
如果事件日期存储为post meta,则可以使用custom field WP_Query
获取具有未来日期的事件。
下面是一个非常粗略的示例wp_nav_menu_objects
这是我根据法典和代码参考而想到的。希望您可以将此作为创建工作解决方案的起点<这绝不是一个有效的代码示例,需要调整、微调,也许还需要一些排版
add_filter( \'wp_nav_menu_objects\', \'prefix_wp_nav_menu_objects\', 10, 2 );
function prefix_wp_nav_menu_objects( $menu_items, $args ) {
// Check if correct menu
if ( \'my-theme-location\' === $args[\'theme_location\'] ) {
// Loop items
$time_now = time();
foreach ( $menu_items as $key => $menu_item ) {
// Add new items to correct submenu
if ( $add_item_logic === $menu_item->property_to_compare ) { // add applicable logic
$new_items = prefix_add_items_menu( $menu_item, $args );
$menu_items = $menu_items + $new_items; // add new items to the menu item array
} else if ( $remove_item_logic === $menu_item->property_to_compare ) { // add applicable logic
$event_date = get_post_meta( $menu_item->db_id, \'event_date\', true );
if ( $event_date && strtotime( $event_date ) < $time_now ) {
// Delete menu item permanently
wp_delete_post( $menu_item->db_id ); // check if property is correct
// Remove from menu item array
unset( $menu_items[$key] );
}
}
}
}
return $menu_items;
}
function prefix_add_items_menu( $menu_item, $menu_args ) {
$new_items = array();
$query_args = array(
\'post_type\' => \'my_cpt_slug\', // add correct cpt slug
\'posts_per_page\' => 10, // adjust as needed
\'meta_key\' => \'event_date\', // add correct meta key if date saved in post meta
\'meta_value\' => date( "Ymd" ), // change to how "event date" is stored
\'meta_compare\' => \'>=\' // change comparison methof if needed
);
$query = new WP_Query( $query_args );
if ( $query->posts ) {
foreach ( $query->posts as $event ) {
// If you want to create menu items
wp_update_nav_menu_item( $menu_args[\'menu_id\'], 0, array(
\'menu-item-title\' => $event->post_title,
\'menu-item-object-id\' => $event->ID,
\'menu-item-object\' => $event->post_type,
\'menu-item-parent-id\' => $menu_item->ID, // not sure if property is correct, please check it yourself
));
// And / or push posts to menu items
$new_items[] = array(
\'menu-item-title\' => $event->post_title,
\'menu-item-object-id\' => $event->ID,
\'menu-item-object\' => $event->post_type,
\'menu-item-parent-id\' => $menu_item->ID, // not sure if property is correct, please check it yourself
);
}
}
return $new_items;
}
您还可以查看相关的WPSE Q&;A关于这件事,
Add items to a menu dynamically
Programmatically add a Navigation menu and menu items
Add items to a menu dynamically
Remove a menu item in menu
EDIT 1实际上,您可以在上更新菜单
save_post
, 发布新事件时也是如此。这可能是更好的方式来更新菜单,因为我现在想得更多。发布新帖子时进行更新意味着更新功能的运行频率较低,从而降低了网站的总体负担。
要从菜单中删除过去的事件,可以考虑添加一个每天运行一次的自定义wp cront事件。
function prefix_update_menu( $post_id, $post ) {
// New post only
if ( $post->post_date !== $post->post_modified ) {
return;
}
// Get main menu items
$main_menu_items = wp_get_nav_menu_items( \'menu-id-slug-name-or-object\' );
if ( ! $main_menu_items ) {
return;
}
// 1. foreach Loop menu items
// 2. when correct submenu is matched add new menu item with wp_update_nav_menu_item
// 3. optionally also remove passed events while doing the foreach loop
// get post id from menu item with get_post_meta( $item->ID, \'_menu_item_object_id\', true );
// then get event end date and current date for comparison
// remove menu item with delete_postw p_delete_post( $item->ID );
}
add_action( \'save_post\', \'prefix_update_menu\', 10, 2 );