I am trying to pull in some dynamic (non-WP) content to populate a menu in WordPress. For this I’ve extended the Walker Class as shown here:
http://www.kriesi.at/archives/improve-your-wordpress-navigation-menu-output
So my Menu would look like
- Home
- Blog
- News
- Features
- competitions –
- Comp1
- Comp2
Where Comp1 and Comp2 are pulled from a DB on a seperate site. They are just links to an external site, so the only relevant value is the ‘Comp Title’ and ‘Comp URL’
The main method within my class is :
function start_el(&$output, $item, $depth, $args)
{
global $wp_query;
$indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="'. esc_attr( $class_names ) . '"';
$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
$prepend = '<strong>';
$append = '</strong>';
$description = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : '';
if($depth != 0)
{
$description = $append = $prepend = "";
}
if($item->title == 'Competitions')
{
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
$item_output .= $description.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
$this->loopComps($output , $args);
}
else
{
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
$item_output .= $description.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
and then the loopComps method is:
(getGalleryComps() pulls in the dynamic content)
function loopComps($output , $args)
{
$openComps = $this->getGalleryComps();
foreach($openComps as $comp)
{
$item = new StdClass;
$item->ID = 9999;
$item->post_author = 5;
$item->post_date = '2012-11-16 10:48:44';
$item->post_date_gmt = '2012-11-16 10:48:44';
$item->title = $comp['competition_name'];
$item->post_type = 'nav_menu_item';
$item->post_name = $comp['competition_name'];
$item->post_title = $comp['competition_name'];
$item->post_excerpt = $comp['competition_name'];
$item->guid = $comp['competition_name'];
$item->url = 'http://www.mycomps';
$item->post_status = 'publish';
$item->post_parent = 0;
$item->filter = 'raw';
$item->menu_item_parent = '6845';
$item->object_id = '99999';
$item->object = 'custom';
$item->type = 'custom';
$item->classes = array(null , 'menu-item' , 'menu-item-type-custom' , 'menu-item-object-custom');
$item->menu_order = 6;
return $this->start_el($output, $item, 1, $args);
}
}
This all seems to work fine , expect the $item is never attached to the actual menu. If I print out the $items during the nav menu loop, I can see my dynamic content which I’ve created a ‘psuedo Post’ is there , it just never gets attached to the menu.
Is there an easier way of injecting menu items?
UPDATE 1:
I’ve adjusted loopComps method to be:
function loopComps($output)
{
$openComps = $this->getGalleryComps();
$output .= '<ul>';
foreach( $openComps as $openComp )
{
$output .= '<li><a href='.$openComp->url.'>'.$openComp['competition_name]'].'</a></li>';
}
$output .= '</ul>';
return $output;
}
As this does make much more sense , but doesn’t solve the issue, the data is there, but is never shown in the menu.
I’m not sure if I understood your question properly but since you asked
Is there an easier way of injecting menu items?
, so I think you can add extra menu items easily usingwp_nav_menu_items
hook likeJust paste the code in your
functions.php
and replace your menu title and link with yours.You should just have to append the HTML for the menu items for the competitions to
$output
, e.g.,That’s why $output is passed by reference (‘&’) to
start_el()
.This example is probably simplistic, because you’ll have to adjust it to whatever prototype your WP-generated menu items follow, but it illustrates the principle. Creating mock WordPress items and trying to trick WordPress into doing the work for you, doesn’t seem like the right approach.
After review of question and answer i have added ‘GOOGLE’ sub menu item under the ‘Competitions’ parent menu so here is complete solution for editing menu bar.
1
First put this code where menu bar is called mostly it should be in header.php and change your custom menu which i have mentioned in comment
call the wp_nav_menu and pass custom walker object which we have just created.
wp_nav_menu( array(
'container' =>false,
'menu_class' => 'menuPrincipal',
'echo' => true,
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'depth' => 0,
'walker' => new description_walker())
);
it will add GOOGLE sub menu under Competitions menu
First answer is correct but the class member output could not set by loopComps and also we should not return output just to set output member so we just set direct sub menu to the walker.