Nav menu current item not highlihting - php

I was working on a site with categories as primary menu .I have a new post type and added an archive content as menu item with label 'City Guide'.Now when I on City Guide page the menu item is not highlighting.Or with code the class 'current' is not printing in the menu item class.Here is my code:
<?php
$menu_name = PRIMARY_NAVIGATION_NAME;
$menu_items = array();
if( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ){
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menu_items = $menu ? wp_get_nav_menu_items($menu->term_id) : array();
}
?>
<nav class="visible-sm visible-md visible-lg" role="navigation">
<ul id="menu-primary-navigation" class="main-navigation">
<?php if( !empty($menu_items) ): ?>
<?php
$current_category_object = null;
if( !empty($wp_query->query_vars['category_name']) ){
$category_name = $wp_query->query_vars['category_name'];
$current_category_object = get_category_by_slug($wp_query->query_vars['category_name']);
}
?>
<?php foreach( $menu_items as $item): ?>
<?php
$active_class = false;
if ($item->object == 'category' && !empty($current_category_object) ){
$cat_object = get_category($item->object_id);
if ($cat_object->term_id == $current_category_object->term_id || $cat_object->term_id == $current_category_object->parent) {
$active_class = true;
}
}
?>
<li class="<?php echo sanitize_title($item->title); ?><?php echo ' menu-item-object-category'; if ($active_class) echo ' current'?>">
<a href="<?php echo $item->url; ?>" class="main-category"<?php if( $item->target) echo ' target="' . $item->target . '"'; ?>><?php echo $item->title ?></a>
<?php if( $item->object == 'category'): ?>
<?php
$sub_categories = get_terms( array('category'), array('child_of' => $item->object_id, 'hide_empty' => 0) );
if (count($sub_categories) <= 4) {
include(locate_template('partials/sub-menu-two-featured.php'));
} else {
include(locate_template('partials/sub-menu-one-featured.php'));
}
?>
<?php endif; ?>
<?php if ($item->title == 'City Guide'): ?>
<?php include(locate_template('partials/sub-menu-city-guide.php')); ?>
<?php endif; ?>
</li>
<?php wp_reset_query(); ?>
<?php endforeach; ?>
<?php endif; ?>
</ul>
</nav>
How can i implement it into it using a condition to add current for my archive page menu item in the above code .
I tried
<?php if ($item->title == 'City Guide'): ?>
but it was echoing in all instance not when the menu is active.
Please help.

One possible solution is to use get_queried_object() function for this.
Codex says
if you're on a single post, it will return the post object
if you're on a page, it will return the page object
if you're on an archive page, it will return the post type object
if you're on a category archive, it will return the category object
if you're on an author archive, it will return the author object
If you start using $qo = get_queried_object() then no need to use this code
if( !empty( $wp_query->query_vars['category_name'] ) ){
$category_name = $wp_query->query_vars['category_name'];
$current_category_object = get_category_by_slug(
$wp_query->query_vars['category_name']
);
}
because:
If you are in category-archive page, $qo will contain category object, and $qo->term_id and $qo->parent will be available.
If you are in CPT archive page, then $qo will contain CPT object, and properties like CPT name, query_var, label and so on will be available.
So when you have custom queried object and with the help of some conditional tags like is_tax(), is_tag(), is_category(), is_post_type_archive() you will be able to determine exactly where you are.
P.S. You must check the codex first, because there have some notes for precedence when using get_queried_object()

<?php
$active_class = false;
$this_category = get_queried_object();
$this_category->name;
if ($this_category->name == 'city-guide' ){
$active_class = true;
} ?>
<li class="<?php echo sanitize_title($item->title); ?><?php echo ' menu-item-object-category'; if ($active_class ==1 && sanitize_title($item->title) =='city-guide') echo ' current'; ?>">
this worked thanks #pgk for pointing me out

Related

WordPress Menu: On click of parent menu item, only display sub navigation children of that link

I am having some trouble with my WordPress navigation functionality. I have the following function that pulls menu items from the admin:
function cr_get_menu_items($menu_location)
{
$locations = get_nav_menu_locations();
$menu = get_term($locations[$menu_location], 'nav_menu');
return wp_get_nav_menu_items($menu->term_id);
}
In my navigation template, I use this function to pull in only parent items like this:
<?php $nav = cr_get_menu_items('navigation_menu') ?>
<?php foreach ($nav as $link):
if ($link->menu_item_parent == 0) : ?>
<a class="main-nav" href="<?= $link->url ?>"><?= $link->title ?></a>
<?php endif; endforeach; ?>
I tried to make a sub navigation that shows children items like this:
<?php $nav = cr_get_menu_items('navigation_menu') ?>
<?php foreach ($nav as $link):
if ($link->menu_item_parent !== 0) : ?>
<?= $link->title ?>
<?php endif; endforeach; ?>
This pulls in ALL children menu items. The way the navigation I am building should work is: you click on a parent menu item and the sub navigation displays all child menu items for that parent. The hide/display functionality is all JS.
Is there a way to alter the function I have to pull in only children for a specific parent menu item? Any help/guidance is appreciated.
Is there a way to alter the function I have to pull in only children
for a specific parent menu item?
For that purpose, yes, there is.
Try the following function (replace the existing cr_get_menu_items() function):
function cr_get_menu_items($menu_location, $parent = -1)
{
$locations = get_nav_menu_locations();
$menu = get_term($locations[$menu_location], 'nav_menu');
$items = wp_get_nav_menu_items($menu->term_id);
if ( is_numeric( $parent ) && $parent >= 0 ) {
$_id = (int) $parent;
foreach ( $items as $i => $item ) {
if ( $_id !== (int) $item->menu_item_parent ) {
unset( $items[ $i ] );
}
}
}
return $items;
}
Usage examples:
$nav = cr_get_menu_items( 'navigation_menu' ); // Get all menu items.
$nav = cr_get_menu_items( 'navigation_menu', 0 ); // Get menu items whose parent ID is 0
UPDATE
After I re-read your question, this is the function that you likely need:
// $items is the menu items array that you retrieved using `cr_get_menu_items()`,
// or other functions which return valid `nav_menu` items.
function cr_get_submenu_items( array $items, $parent ) {
$parent = (int) $parent;
$list = [];
foreach ( $items as $item ) {
if ( $parent === (int) $item->menu_item_parent ) {
$list[] = $item;
}
}
return $list;
}
UPDATE #2
Here's how you would/could use cr_get_menu_items() along with cr_get_submenu_items():
<?php $nav = cr_get_menu_items('navigation_menu') ?>
<!-- Display parent items. -->
<?php $nav = cr_get_menu_items('navigation_menu') ?>
<?php foreach ($nav as $link):
if ($link->menu_item_parent == 0) : ?>
<a class="main-nav" href="<?= $link->url ?>"><?= $link->title ?></a>
<?php endif; endforeach; ?>
<!-- Display children items. (in its own wrapper `div`/`ul`/etc.) -->
<?php $_ids = []; ?>
<?php foreach ($nav as $link):
$parent = (int) $link->menu_item_parent;
if ( 0 !== $parent && ! in_array( $parent, $_ids ) ) : ?>
<!-- This `div` is just an example wrapper. -->
<div class="menu-<?= $parent ?>-subnav">
<?php foreach ( cr_get_submenu_items( $nav, $parent ) as $clink ): ?>
<?= $clink->title ?>
<?php endforeach; ?>
<?php $_ids[] = $link->menu_item_parent; ?>
</div>
<?php endif; endforeach; ?>

Get only categories from a specific custom post type

I am trying to get categories from a specific post type : member .
I am using this code
<?php
$taxonomy = 'category';
$terms = get_terms($taxonomy);
if ( $terms && !is_wp_error( $terms ) ) :
?>
<ul>
<?php foreach ( $terms as $term ) { ?>
<li><?php echo $term->name; ?></li>
<?php } ?>
</ul>
But the problem is : when i am adding a category to member then it is also added to post type : post and when deleted it also deleted from both post type.
What can i do now?
try this way this will display categories from specific post and retrieve the terms for a post.
<?php
$postArg = array('post_type'=>'post',
'posts_per_page'=>-1,
'order'=>'desc',
);
$getPost = new wp_query($postArg);
global $post;
if($getPost->have_posts()){
echo '<ul>';
while ( $getPost->have_posts()):$getPost->the_post();
echo "<h2>".$post->post_title."</h2>";
$terms = get_the_terms($post->ID, 'category' );
foreach ($terms as $term) {
echo "<li>".$term_name = $term->name.'</li>';
}
endwhile;
echo '</ul>';
}
?>
Second way
<?php
$category = get_terms('category');//custom category name
foreach ($category as $catVal) {
echo '<h2>'.$catVal->name.'</h2>';
}
?>

inserting ads between every 7th post of homepage and category wordpress page

I am trying to insert google ads between every 7th posts in my wordpress site with infinite scroll. i searched and found results but that didn't worked for me because the WordPress theme i am using is little complex. the result i found was to add this code
<?php $postnum++; if($postnum%5 == 0) { ?>
YOUR AD CODE HERE
<?php } ?>
after <?php endwhile; ?> in index.php, but in my case the loop is different from the general wordpress theme. the loop i have is like this and i want to know how can i implement the above code in my case.
loop code
static function loop( $template ) {
global $wp_query;
echo '<input type="hidden" id="query-' . $template . '" value="' . urlencode( json_encode( $wp_query -> query ) ) . '" />';
if ( count( $wp_query->posts) > 0 ) {
if( self::is_grid( $template ) ){
?>
<div class="loop-container-view grid">
<?php self::loop_switch( $template , 1 ); ?>
</div>
<?php
}else{
?>
<div class="loop-container-view list" id="contloop">
<?php self::loop_switch( $template , 0 ); ?>
</div>
<?php
}
get_template_part('pagination');
} else {
get_template_part('loop', '404');
}
}
which then call this code, i made it a little shorter
static function get( $post , $template = 'blog_page' ){
$meta = meta::get_meta( $post -> ID , 'settings' );
if( isset( $meta['safe'] ) ){
if( meta::logic( $post , 'settings' , 'safe' ) ){
$classes = ' nsfw';
}else{
$classes = ' ';
}
}else{
$classes = ' ';
}
?>
<!-- post -->
<article id="post-<?php echo $post -> ID; ?>" <?php post_class( 'post ' . $classes , $post -> ID ); ?>>
</article>
<?php
}
loop switch function
static function loop_switch( $template = '' , $grid = 1 ) {
global $wp_query;
if ( !empty( $template ) ) {
$ajax = false;
} else {
$query = array();
$template = isset( $_POST['template'] ) && strlen( $_POST['template'] ) ? $_POST['template'] : exit();
$query = isset( $_POST['query'] ) && !empty( $_POST['query'] ) ? (array)json_decode( urldecode( $_POST['query'] ) ) : exit();
$query['post_status'] = 'publish';
$wp_query = new WP_Query( $query );
$grid = isset($_POST['grid']) ? (int)$_POST['grid'] : 1;
$ajax = true;
}
$template = str_replace( array( '_hot' , '_new' , '_like' ) , '' , $template );
if( $grid == 1 ){
$k = 1;
$i = 1;
$nr = $wp_query->post_count;
if (layout::get_length(0, $template) == 940 ) {
$div = 3;
} else {
$div = 2;
}
foreach ($wp_query->posts as $post) {
$wp_query->the_post();
if ($i == 1) {
if (( $nr - $k ) < $div) {
$classes = 'class="last"';
} else {
$classes = '';
}
echo '<div ' . $classes . '>';
}
self::grid( $post, $template );
if ($i % $div == 0) {
echo '</div>';
$i = 0;
}
$i++;
$k++;
}
if ($i > 1) {
echo '</div>';
}
}else{
foreach( $wp_query->posts as $index => $post ) {
$wp_query->the_post();
if ($index > 0) {
?><!--<p class="delimiter"> </p>--><?php
}
self::get( $post, $template );
}
}
if( $ajax ){
exit();
}
}
and post is called here in front-page.php file
<?php
$wp_query = new WP_Query(array( 'page_id' => options::get_value( 'front_page' , 'page' ) ) );
if( $wp_query -> post_count > 0 ){
foreach( $wp_query -> posts as $post ){
$wp_query -> the_post();
$post_id = $post -> ID;
?>
<article id="post-<?php the_ID(); ?>" <?php post_class() ?>>
<header class="entry-header">
<h1 class="entry-title"><?php the_title(); ?></h1>
<!-- post meta top -->
<?php
if( meta::logic( $post , 'settings' , 'meta' ) ){
get_template_part( 'post-meta-top' );
}
?>
</header>
<div class="entry-content">
<?php
/* if show featured image */
if( options::logic( 'blog_post' , 'show_featured' ) ){
if( has_post_thumbnail ( $post -> ID ) ){
$src = wp_get_attachment_image_src( get_post_thumbnail_id( $post -> ID ) , 'full' );
?>
<div class="featimg circle">
<div class="img">
<?php
ob_start();
ob_clean();
get_template_part( 'caption' );
$caption = ob_get_clean();
?>
<?php the_post_thumbnail( '600x200' ); ?>
<?php
if( strlen( trim( $caption) ) ){
?>
<p class="wp-caption-text"><?php echo $caption; ?></p>
<?php
}
?>
</div>
</div>
<?php
}
}
?>
</div>
<footer class="entry-footer">
<div class="share">
<?php get_template_part( 'social-sharing' ); ?>
</div>
<div class="excerpt">
<?php the_content(); ?>
<?php wp_link_pages(); ?>
</div>
</footer>
</article>
<?php
}
}else{
/* not found page */
get_template_part( 'loop' , '404' );
}
Try this in front-page.php. You may have to adjust it to add after correct number of posts.
if( $wp_query -> post_count > 0 ){
$postnum = 0;
foreach( $wp_query -> posts as $post ){
$postnum++;
if( $postnum%5 == 0 ) {
echo '<p> ---- insert ad here ---- </p>';
}
$wp_query -> the_post();
$post_id = $post -> ID;
?>
it should replace this bit of code
if( $wp_query -> post_count > 0 ){
foreach( $wp_query -> posts as $post ){
$wp_query -> the_post();
$post_id = $post -> ID;
?>

Can't Echo Custom Field In Widget

I'm trying to display a custom field in a widget I'm customizing but I can't get the custom field to display. I think it has something to do with the variable I'm using to get the post ID in the loop because when I change it to the standard the_title function, the widget works, so it has something to do with how I'm calling the custom field.
I know the key to the custom field is "wpcf-promo-title" but no matter what I've tried, the custom field (which holds a shortened version of the post title for the sidebar) just won't display. This code results in the thumbnails showing, but not the promo title. You can see this in action at http://www.cantstopshipping.com
Here's my code, including the query and the front end of the widget.
function widget($args, $instance) {
extract( $args );
$title = apply_filters( 'widget_title', empty($instance['title']) ? 'Recent Posts' : $instance['title'], $instance, $this->id_base);
$show_date = isset( $instance['show_date'] ) ? $instance['show_date'] : false;
if ( ! $number = absint( $instance['number'] ) ) $number = 5;
if( ! $cats = $instance["cats"] ) $cats='';
// array to call recent posts.
$crpw_args=array(
'showposts' => $number,
'category__in'=> $cats,
);
$crp_widget = null;
$crp_widget = new WP_Query($crpw_args);
echo $before_widget;
// Widget title
echo $before_title;
echo $instance["title"];
echo $after_title;
// Post list in widget
echo "<ul>\n";
while ( $crp_widget->have_posts() )
{
$crp_widget->the_post();
?>
<li class="crpw-item">
<p style="float:left">
<?php the_post_thumbnail('sidebar-small'); ?>
</p>
<?php $promotitle = get_post_meta($post->ID, 'wpcf-promo-title', true); ?>
<p style="float:right; width:200px">
<?php echo $promotitle; ?>
</p>
<?php if ( $show_date ) : ?>
<span class="crpw-date"><?php echo "("; ?><?php echo get_the_date(); ?><?php echo ")"; ?></span>
<?php endif; ?>
</li>
<?php
}
wp_reset_query();
echo "<div class=\"fix\"></div>";
echo "</ul>\n";
echo $after_widget;
}
It looks like your global $post is missing.
But you could try get_the_ID() instead of $post->ID.
You should also consider getting rid of extract(), it's now considered a "bad" practice.
Another thing is that you should use wp_reset_postdata() to restore the global $post object. The wp_reset_query() call should be used with the query_posts() call.

Don´t display list if subcategory has only 1 item

I´m displaying a menu with this code:
<!-- Subcategory menu from current category -->
<ul class="sub-menu">
<?php
if (is_home()) {
wp_list_categories('orderby=id&title_li=&depth=1');
}
else{
$category = get_the_category();
$cat_term_id = $category[0]->term_id;
$cat_category_parent = $category[0]->category_parent;
$listcat = wp_list_categories('echo=0&child_of='.$cat_category_parent.'&title_li=&orderby=order&order=ASC');
$listcat = str_replace("cat-item-".$cat_term_id, "cat-item-".$cat_term_id." current-cat", $listcat);
if ( in_category( $cat_term_id ) || post_is_in_descendant_category( $cat_term_id )) {
echo $listcat;
}
}
?>
and each li of that menu display post titles using this:
<!-- Post list from current category -->
<div class="menu_list">
<ul id="submenu_productos" class="clearfix">
<?php
$IDOutsideLoop = $post->ID;
while( have_posts() ) {
the_post();
foreach( ( get_the_category() ) as $category )
$my_query = new WP_Query('category_name=' . $category->category_nicename . '&orderby=date&order=DESC&showposts=100');
if( $my_query ) {
while ( $my_query->have_posts() ) {
$my_query->the_post(); ?>
<!-- this line to hightlight current post in the category page -->
<li<?php if ( $post->ID == $wp_query->post->ID ) { echo ' class="test"'; } else {} ?>>
<?php the_title(); ?>
</li>
<?php
}
}
}
?>
</ul>
</div>
The menu works well and it shows like this:
The problem is that when I have one post that belongs to that category/subcategory it is also displayed on the list... I want to hide it when it´s only one item:
Is there any way to hide it when the subcategory has only one post?
PD: PLEASE avoid telling me to put this on wordpress.stackexchange.com, I always post there with no answer and here people always help me...
You can count the number of item in your sub menu using :
$count = $my_query->post_count;
I'll suggest to add it in your if condition:
if( $my_query && $my_query->post_count > 1)
That should work

Categories