Reputation: 497
First of all 90% of this code is working just need a little push :D
Everything is done inside functions.php
I'm adding an item to my header menu, where it needs to display dynamically some posts inside a specific category.
I'm getting the posts using the function below which was taken and modified for my needs from here
function get_latest_post_thumbnails_urls() {
// Set an empty variable which will hold our array of URL's
$output = [];
// Set our query args
$args = [
'posts_per_page' => 3,
'fields' => 'ids', // Only get post ID's
'meta_query' => [ // Get posts which has thumbnails only
[
'key' => '_thumbnail_id',
'compare' => 'EXISTS'
]
],
'cat' => '5'
// Any additional parameters you might need
];
$q = get_posts( $args );
// ALWAYS make sure we have posts, else return $output
if ( !$q )
return $output;
// Ok, we have posts, lets loop through them and create an array of URL's
foreach ( $q as $id )
$output[] = wp_get_attachment_url( get_post_thumbnail_id( $id ) );
// Return our array
return $output;
}
Then I use the function below to add the menu item (adapted from here), but the variable is not displaying in the correct place during the loop. The <li>
needs to be inside the <ul>
.
add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);
function add_admin_link($items, $args){
if( $args->theme_location == 'main_menu' ){
$items .= '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children dropdown menu-item-1441">
<a class="sf-with-ul" title="Eventos" href="/eventos/"><span class="link-inner">EVENTOS <span class="nav-arrow top-level fa fa-angle-down"></span></span></a>
<ul class="sub-menu" style="display: none;">'.
$urls = get_latest_post_thumbnails_urls();
if ( $urls ) {
foreach ( $urls as $url ) {
// Do something with your thumbnail url
echo '<li>'. $url .'</li>';// For testing, remove this
}
}
'</ul>
</li>';
}
return $items;
}
As you can see in the image, the function is getting all of the correct information, but it is displaying it before the menu item.
//////////////// NEW CODE HELP //////////////////
add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);
function add_admin_link($items, $args){
if( $args->theme_location == 'main_menu' ){
//add your first few elements to the $items variable
$items .= '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children dropdown menu-item-1441">';
$items .= '<a class="sf-with-ul" title="Eventos" href="/eventos/"><span class="link-inner">EVENTOS <span class="nav-arrow top-level fa fa-angle-down"></span></span></a>';
$items .= '<ul class="sub-menu" style="display: none;">';
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'cat' => '5'
);
$post_query = new WP_Query($args);
if($post_query->have_posts() ) {
while($post_query->have_posts() ) {
$post_query->the_post();
$items .= '<h2>'. the_title() .'</h2>';
}
};
//close the dom elements
$items .= '</ul>';
$items .= '</li>';
}
//return the final product
Upvotes: 1
Views: 392
Reputation: 497
Function to loop post fields ID
function get_latest_post_thumbnails_urls()
{
// Set an empty variable which will hold our array of URL's
$output = [];
// Set our query args
$args = [
'posts_per_page' => -1,
'fields' => 'ids', // Only get post ID's
'meta_query' => [ // Get posts which has thumbnails only
[
'key' => '_thumbnail_id',
'compare' => 'EXISTS'
]
],
'cat' => '5'
// Any additional parameters you might need
];
$q = get_posts( $args );
// ALWAYS make sure we have posts, else return $output
if ( !$q )
return $output;
// Ok, we have posts, lets loop through them and create an array of URL's
foreach ( $q as $id )
$output[] = $id;
// Return our array
return $output;
}
Function to display my menu item
function add_admin_link($items, $args){
if( $args->theme_location == 'main_menu' ){
//add your first few elements to the $items variable
$items .= '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children dropdown menu-item-1441">';
$items .= '<a class="sf-with-ul" title="Eventos" href="/eventos/"><span class="link-inner">EVENTOS <span class="nav-arrow top-level fa fa-angle-down"></span></span></a>';
$items .= '<ul class="sub-menu" style="display: none;">';
$urls = get_latest_post_thumbnails_urls();
if ( $urls ) {
//loop through your url's
foreach ( $urls as $url ) {
//add each url onto the $items variable
$items .= '<li><a href="'. get_permalink($url) .'"><span class="link-inner">'. get_the_title($url) .'</span></a></li>';
}
}
//close the dom elements
$items .= '</ul>';
$items .= '</li>';
}
//return the final product
return $items;
}
Function to position the menu item in the menu
add_filter( 'wp_nav_menu_objects', 'restructure_menu_links', 10, 2 );
function restructure_menu_links( $reorgitems, $args ) {
$new_links = array();
$label = add_admin_link($items, $args); // add your custom menu item content here
// Create a nav_menu_item object
$item = array(
'title' => $label,
'menu_item_parent' => 0,
'ID' => 'hidden',
'db_id' => '',
'url' => $link,
'classes' => array( 'menu-item' )
);
$new_links[] = (object) $item; // Add the new menu item to our array
// insert item
$location = 2; // insert at 3rd place
array_splice( $reorgitems, $location, 0, $new_links );
return $reorgitems;
}
I know this isn't perfect but I thank @Frits for the help I finaly got it working my way _:)
And your wellcome to make it better ;)
Upvotes: 1
Reputation: 7614
The error you are dealing with is happening because you are echoing your $url
variables before you return the menu items.
To resolve this, instead of echoing the urls inside your loop, add them to the $items
variable (using .=
like you did before) as well and then return the $items
like you were already doing.
add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);
function add_admin_link($items, $args){
if( $args->theme_location == 'main_menu' ){
//add your first few elements to the $items variable
$items .= '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children dropdown menu-item-1441">';
$items .= '<a class="sf-with-ul" title="Eventos" href="/eventos/"><span class="link-inner">EVENTOS <span class="nav-arrow top-level fa fa-angle-down"></span></span></a>';
$items .= '<ul class="sub-menu" style="display: none;">';
$urls = get_latest_post_thumbnails_urls();
if ( $urls ) {
//loop through your url's
foreach ( $urls as $url ) {
//add each url onto the $items variable
$items .= '<li>'. $url .'</li>';
}
}
//close the dom elements
$items .= '</ul>';
$items .= '</li>';
}
//return the final product
return $items;
}
You can also combine both of your functions into a singular function by running your WP_Query inside the menu filter.
Doing it this way will make it easier to add additional post information into your menu items.
Here's an example that adds the featured image, wrapped in a link to the post, with the post title added as a title attribute of the link:
add_filter('wp_nav_menu_items', 'add_admin_link', 10, 2);
function add_admin_link($items, $args){
if( $args->theme_location == 'main_menu' ){
//add your first few elements to the $items variable
$items .= '<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children dropdown menu-item-1441">';
$items .= '<a class="sf-with-ul" title="Eventos" href="/eventos/"><span class="link-inner">EVENTOS <span class="nav-arrow top-level fa fa-angle-down"></span></span></a>';
$items .= '<ul class="sub-menu" style="display: none;">';
$urls = get_latest_post_thumbnails_urls();
//build you arguments for the wp query
$args = array(
'post_type' => 'post',
'posts_per_page'=> -1,
'tax_query' => array( //only get posts in category 5
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => 5,
),
),
'meta_query' => array( //only get posts that have a thumbnail
array(
'key' => '_thumbnail_id',
'compare' => 'EXISTS'
),
)
);
//create the query and loop through it
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts()) {
$query->the_post();
$thumbnail_id = get_post_thumbnail_id(); //get the thumbnail id
$image_src = wp_get_attachment_image_src($thumbnail_id, 'full')[0]; //you can use either full/large/medium/thumbnail
$items .= '<li><a href="'.get_the_permalink().'" title="'.get_the_title().'"><img src="'.$image_src.'"></a></a></li>';
}
}
wp_reset_postdata();
//close the dom elements
$items .= '</ul>';
$items .= '</li>';
}
//return the final product
return $items;
}
Upvotes: 2