Add `active` class to li of current single page wordpress - php

Looking for your help and advices.
I have a list of links to single in Wordpress. I need to place class active only to li of active page.
Should be like on this image
But it is:
My wp-code:
<ul class="inline-list medium-6 large-4 skill-items">
<?php
$id = get_the_ID();
// echo $id;
$class;
$skills = new WP_Query( array(
'post_type' => 'skills',
'order' => 'ASC'
));
if ($skills->have_posts()) : while ($skills->have_posts()) : $skills->the_post();
// echo $post->ID;
if( $id == $post->ID) {$class = 'active';} else {$class = '';}
?>
<li class="<?php echo $class; ?>"><?php the_title(); ?></li>
<?php endwhile; endif; wp_reset_query();
?>
</ul>

That's not the proper way to do a menu in Wordpress. You should use wp_nav_menu instead of doing a custom WP_Query.
First, in functions.php add the following to register a new menu:
add_action('after_setup_theme', 'register_my_menu');
function register_my_menu() {
register_nav_menu('skills_menu', __( 'Skills menu', 'your-theme-name' ));
}
Then log in your administration, you will see that new menu placement under Appearance > Menu. Create a new menu for that placement - you have the possibility to automatically add top level new pages to this menu.
Then in your template add the following in order to display the menu:
<?php wp_nav_menu(array('theme_location' => 'skills_menu')); ?>
Wordpress will automatically handle the active class by adding current-menu-item to the appropriate li. No need for any filter for that.

Found an answer for my question using Javascript/jQuery
jQuery(document).ready(function($){
var pgurl = window.location.href;
$("ul.skill-items li").each(function(){
if($(this).find('a').attr("href") == pgurl || $(this).find('a').attr("href") == '' )
$(this).addClass("active");
})
});
pgurl contains your current url. After that for each item we are looking for anchor and its link. Then we are comapring those links, and if their are equal, we add class active to li

You may try this:
function my_alter_classes_on_li( $classes, $item ){
global $post;
if( in_array( $post->post_type, $classes ) ) $classes[] = 'current-menu-item';
return $classes;
}
add_filter( 'nav_menu_css_class', 'my_alter_classes_on_li', 10, 2 );

Related

WordPress how to add <span> after main navigation dropdown

I like to add an empty 'span' in the main navigation li element which has a specific class.
Here is the desired look:
<ul>
<li class="menu-item"></li>
<li class="menu-item"></li>
<li class="menu-item has-childern"><span></span></li>
</ul>
I have a code that adds the span after every nav link:
add_filter('nav_menu_item_args', function ($args, $item, $depth) {
if ( $args -> theme_location == 'primary') {
$args -> link_after = '<span></span>';
}
return $args;
}, 10, 3);
How can I achieve to add the 'span' only in the 'li' element which has the 'has-children' class? Thank you for the help!
You could use nav_menu_link_attributes filter hook to get access to the nav attributes.
From Documentation
nav_menu_link_attributes
'after'
(string) Text after the link markup.
'link_after'
(string) Text after the link text.
So you could set it up in multiple ways, for example you could do something like this:
add_filter('nav_menu_link_attributes', 'your_theme_custom_html_element', 10, 3);
function your_theme_custom_html_element($atts, $item, $args)
{
if ($args->theme_location == 'primary' && (strpos($atts['class'], 'has-childern') !== false)) {
$args->after = '<span></span>';
}
return $atts;
}
Just tested on my own website and it works seamlessly fine!

Wordpress - How to get the information of a widget instance

I wanted to know how to get the information of a widget instance, to be able to get all its information from another widget. Try the Get Widget ID plugin but it returns "temp" as a result and I also tried with this code block:
https://wordpress.stackexchange.com/questions/240327/how-to-access-widget-data-from-outside-widget
But I still get the same result.
My idea is the following:
I am modifying a Wordpress widget so that it selects a static post in order to fulfill the function of a featured post in a digital newspaper ... The widget has already been modified and is already working. That same widget is repeated in several places on my website, that is, I use it several times (each with a different selected post).
My idea is to show the featured posts with that widget (those selected by the editor) and modify another widget, that shows me all the posts except the ones that are selected in those widgets. For that I want to know how to get the instance of said widgets that select the featured post, to be able to get the ID of the selected post in each widget and show all the posts except those that are already as featured posts.
In summary ... I just want to see no news that is selected as featured again.
Clarification: This is not a widget written by me, it is a template that I bought and since it did not have this functionality, I am trying to create it.
I leave the code of my widget, in case it is of any use:
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
add_action('widgets_init', 'seleccion_subtitulo');
function seleccion_subtitulo() {
register_widget('seleccion_subtitulo');
}
class seleccion_subtitulo extends WP_Widget {
/*-----------------------------------------------------------------------------------*/
/* Widget Setup
/*-----------------------------------------------------------------------------------*/
public function __construct() {
$widget_ops = array(
'classname' => 'seleccion_subtitulo',
'description' => esc_html__('Seleccionar noticia con titulo y subtitulo', 'disto')
);
parent::__construct('seleccion_subtitulo', esc_html__('Noticias: Noticia titulo + subtitulo [Estilo 1]', 'disto'), $widget_ops);
}
/*-----------------------------------------------------------------------------------*/
/* Display Widget
/*-----------------------------------------------------------------------------------*/
function widget($args, $instance) {
extract($args);
$featured_post = isset($instance["featured_post"]) ? $instance["featured_post"] : '';
$posts = null;
$args = array(
'p' => $featured_post,
'posts_per_page' => 1,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'ignore_sticky_posts' => true
);
$posts_query = new WP_Query;
$posts = $posts_query->query($args);
$unique_block_id = rand(10000, 900000);
echo '<div class="jl_large_builder jl_nonav_margin jelly_homepage_builder jl-post-block-'.esc_html($unique_block_id).'">';
if (!empty($instance['titles'])) {?>
<div class="homepage_builder_title">
<h2 class="builder_title_home_page">
<?php echo esc_attr($instance["titles"]);?>
</h2>
</div>
<?php }?>
<?php
while ($posts_query->have_posts()) {
$post_id = get_the_ID();
$posts_query->the_post();
$categories = get_the_category(get_the_ID());
?>
<div class="jl_post_title_top jl_large_format">
<h3 class="image-post-title"><a href="<?php the_permalink(); ?>">
<?php the_title()?></a></h3>
</div>
<div class="post-entry-content">
<div class="post-entry-content-wrapper">
<div class="large_post_content">
<p>
<?php echo wp_trim_words( get_the_content(), 34, '...' );?>
</p>
<!-- <div class="jl_large_sw">
<?php echo esc_html__('Read More', 'disto')?>
<?php if(function_exists('disto_share_footer_link')){echo disto_share_footer_link(get_the_ID());}?>
</div> -->
</div>
</div>
</div>
<div class="box jl_grid_layout1 blog_large_post_style">
<?php if ( has_post_thumbnail()) {?>
<div class="jl_front_l_w">
<?php $slider_large_thumb_id = get_post_thumbnail_id();
$slider_large_image_header = wp_get_attachment_image_src( $slider_large_thumb_id, 'disto_slider_grid_large', true ); ?>
<?php if($slider_large_thumb_id){?>
<span class="image_grid_header_absolute" style="background-image: url('<?php echo esc_url($slider_large_image_header[0]); ?>')"></span>
<?php }else{?>
<span class="image_grid_header_absolute"></span>
<?php }?>
<?php if(get_theme_mod('disable_post_category') !=1){
$categories = get_the_category(get_the_ID());
if ($categories) {
echo '<span class="meta-category-small">';
foreach( $categories as $tag) {
$tag_link = get_category_link($tag->term_id);
$title_bg_Color = get_term_meta($tag->term_id, "category_color_options", true);
$title_reactions = get_term_meta($tag->term_id, "disto_cat_reactions", true);
if($title_reactions){}else{echo '<a class="post-category-color-text" style="background:'.$title_bg_Color.'" href="'.esc_url($tag_link).'">'.$tag->name.'</a>';}
}echo "</span>";}}?>
<?php echo disto_post_type();?>
</div>
<?php }?>
<div class="jl_post_title_top jl_large_format">
<?php echo disto_single_post_meta(get_the_ID()); ?>
</div>
</div>
<?php }
if($post_loadmore == 1){echo '<div class="jl-loadmore-btn-w">'.esc_html__('Load more', 'disto').'</div>';
wp_add_inline_script( 'disto-custom', "(function($){ $(document).ready(function() {'use strict'; var current_page_".esc_js($unique_block_id)." = 1; $('.jl-post-block-".esc_js($unique_block_id)." .jl_btn_load').click(function(e){ e.preventDefault(); e.stopPropagation(); var button = $(this), data = {'action': 'jl_post_more','query': ".json_encode( $posts_query->query_vars , true).",'page' : current_page_".esc_js($unique_block_id).",'cat' : '".esc_js($cats)."','jl_layout' : 'postslarge'}; var button_default_text = button.text(); $.ajax({ url : '".esc_url(site_url())."/wp-admin/admin-ajax.php', data : data, type : 'POST', beforeSend : function ( xhr ) {button.text('');button.addClass('btn-loading'); }, success : function( data ){ if( data ) { button.text( button_default_text ); button.removeClass('btn-loading'); $('.jl-post-block-".esc_js($unique_block_id)." .jl-loadmore-btn-w').before(data); current_page_".esc_js($unique_block_id)."++; if ( current_page_".esc_js($unique_block_id)." == ".esc_js($posts_query->max_num_pages)." ) button.remove(); }else {button.remove();}}});});});})(jQuery);");
}
wp_reset_postdata();
?>
</div>
<?php }
/*-----------------------------------------------------------------------------------*/
/* Update Widget
/*-----------------------------------------------------------------------------------*/
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['featured_post'] = $new_instance['featured_post'];
return $instance;
}
/*-----------------------------------------------------------------------------------*/
/* Widget Settings (Displays the widget settings controls on the widget panel)
/*-----------------------------------------------------------------------------------*/
function form( $instance ) {?>
<h2>Elige una de las ultimas 20 noticias para establecerla como portada secundaria.</h2>
<div class="container">
<p>
<label>
<strong> <?php esc_html_e('Seleccionar noticia destacada:', 'disto');?></strong>
</label>
</p>
<p>
<select id="<?php echo esc_attr( $this->get_field_id( 'featured_post' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'featured_post' ) ); ?>">
<?php
$posts_args = array('posts_per_page' => 20,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'ignore_sticky_posts' => true);
$last_entries = get_posts($posts_args);
foreach ($last_entries as $entry) {
?>
<option value="<?php echo $entry->ID; ?>" <?php if($instance['featured_post']==$entry->ID){ echo 'selected="selected"'; } ?> ><?php echo $entry->post_title; ?></option>
<?php
}
?>
</select>
</p>
</div>
<?php
}
}
?>
If I do var_dump ($instance) it shows me the following:
array(3) { ["featured_post"]=> string(4) "2970" ["so_sidebar_emulator_id"]=> string(29) "seleccion_subtitulo-421210000" ["option_name"]=> string(26) "widget_seleccion_subtitulo" }
I estimate that the following value tells me the ID of my widget instance:
["so_sidebar_emulator_id"] => string (29) "seleccion_subtitulo-421210000"
but I don't know how to invoke it from another widget, to get the information from it.
When obtaining that information, I try the following code to see what I get (I saw this code in the link that happens first):
$widget_name = 'seleccion_subtitulo';
$widget_instance = '421210000';
$widget_instances = get_option('widget_' . $widget_name);
$data = $widget_instances[$widget_instance];
var_dump($widget_instances);
If I do var_dump($data); I get NULL
If I do var_dump($widget_instances); I get:
array(1) { ["_multiwidget"]=> int(1) }
Lets rephrase your question into 2 parts:
"How to get a widgets settings"
"How to get the list of featured posts as used by that widget for purpose of excluding them from another list of posts"
1. Widget settings:
Widget settings are stored in the database in the wp_options table. If you do a search in phpmyadmin using widget% wildcard in the option name field you will see all widgets and their serialised data arrays.
You may note that they all have a subarray called "_multiwidget" which will contain the instances and their settings. In your example above you dumped this ["_multiwidget"]=> int(1)
This shows that nothing has yet been stored for that widget. The widget is not in a sidebar and/or no featured posts have been defined for that widget.
If the widget had been saved to a sidebar with some settings we would be seeing more details here.
Setup some widget instances so you can see the saved data structures. Then you will be able to see the widget details (either via phpmyadmin or by dumping as before)
2. Get list of featured posts out of a set of widget instances in order to exclude them from a query (in another widget)
For the widget you looking at we would probably see an array of settings one of which would be called "featured_post".
Once the widget has been dragged to some sidebars and has some featured posts defined in a few instances, you can then in your new widget do something like (pseudo code):
$widget_name = 'seleccion_subtitulo'; //if that's the widget name in the db.
$widget_settings = get_option('widget_' . $widget_name);
$featured_posts = array();
if (!empty($widget_settings)) {
if (!empty($widget_settings["_multiwidget"])) {
$instances = $widget_settings["_multiwidget"];
foreach ( $instances as $wid => $instance) {
$featured_posts[] = $instance['featured_post']; // if that is how it is stored in the widget details
}
}
}
You can then use https://developer.wordpress.org/reference/functions/get_posts/ and pass the array $featured_posts
in the argument array as
'exclude' => $featured_posts
Note that It is not necessary to know the 'instance' or the 'widget id' for what you say to want to achieve, one simply has to loop through all the instances for that widget.

wordpress custom menu for different page

I am trying to use a custom menu on my landingpage.
I used this code:
<?php
function change_wp_nav_menu_args($args = ''){
$pageID = get_the_id();
if($pageID == '63') //custom menu for site with id 63
{
$args['menu'] = 'homepage';
}
return $args;
}
add_filter( 'wp_nav_menu_args', 'change_wp_nav_menu_args' );
?>
It works fine, but not only the main menu changes.
The footer menu changes also.
But the footer menu should be the same on every page.
How can I affect this?
This code fixed my problem:
<?php
add_filter( 'wp_nav_menu_args', 'bb_wp_nav_menu_args' );
function bb_wp_nav_menu_args( $args = '' ) {
// change the menu in the Header menu position
if( $args['theme_location'] == 'primary' && is_page('63') ) {
$args['menu'] = '6'; // 32 is the ID of the menu we want to use here
}
return $args;
}
?>
Its great that you find your answer, but it's a suggestion to make the code dynamic rather set the menu value as static [ $args['menu']='6' ].
Suggestion :
Create a Meta Box [ Dropdown with list of menu ] for Page with the Label Menu. And use the Menu Id for the wp_nav_menu .
For Dropdown [ listing Menus ]
function your_menus()
{
$menu_arr=NULL;
$menus=get_terms( 'nav_menu', array( 'hide_empty' => true ) );
$menu_arr['your-nomenu']='Default';
foreach ( $menus as $menu ){
$menu_arr[$menu->slug]=$menu->name;
}
return $menu_arr;
}//end of function
For Nav Menus : [ _your_page_menu : meta name ]. You can place the code inside a function and called it in Header or you can place this code directly into the header.
$page_menu_name=get_post_meta(get_the_ID(),'_your_page_menu',true)==''?'your-nomenu':get_post_meta(get_the_ID(),'_your_page_menu',true);
if($page_menu_name==='your-nomenu')
{
wp_nav_menu(array('theme_location' => 'primary','menu_id'=> 'main-menu','container'=>false,'fallback_cb'=>'','menu_class'=>'main-navigation'));
}
else
{
wp_nav_menu(array('menu_id'=> 'main-menu' , 'container'=>false, 'menu'=>$page_
menu_name,'fallback_cb'=>'','menu_class'=>'main-navigation'));
}
Hope it helps you.

Custom Post Type active link - Wordpress

I have a custom post type named 'schools' on my wordpress site. When you hover over the schools tab a list of schools are shown in the submenu. These are pages I created with different school names. Now when you click on one of the school pages I have a sidebar with all the schools so they can naviate through the different schools from the sidebar rather than using the menu.
I have the sidebar being populated using the following snippet.
while( $shools_loop->have_posts() ) : $schools_loop->the_post();
$content .= '<li class="schools-list">';
$content .= ''.get_the_title().'';
$content .= '</li>';
endwhile;
This works perfectly and I can navigate through all the schools without a problem from my sidebar. I'm trying to find a way to when I view a school via the sidebar or nav that when I'm on the active page I create some css styling to the li of the ACTIVE page. I've already figured out how to do this with the nav menu. But need help on the sidebar menu. Since the sidebar list menu is being populated I'm unsure how to check if the custom post type link is active and corresponds to the /schools/get-title page.
I found something like this online and I've tried editing it, but I'm not sure if this only works for nav menu
add_action( 'init', 'create_post_type' );
function create_post_type() {
register_post_type( 'services',
array(
'labels' => array(
'name' => __( 'Services' ),
'singular_name' => __( 'Services' )
),
'public' => true,
'has_archive' => true,
'rewrite' => array('slug' => 'services'),
)
);
}
// highlight active custom post page in nav
add_filter( 'nav_menu_css_class', 'namespace_menu_classes', 10, 2 );
function namespace_menu_classes( $classes , $item ){
if ( get_post_type() == 'services' ) {
// remove unwanted classes if found
$classes = str_replace( 'current_page_parent', '', $classes );
// find the url you want and add the class you want
if ( $item->url == 'services/physical-therapy-services/' ) {
$classes = str_replace( 'menu-item', 'menu-item current_page_parent', $classes );
}
}
return $classes;
}
Basically need to find a way to check whether the custom post type is active or not.
You can set a global variable in the main template page with the ID of the current post and then in your sidebar loop, you can retrieve that global variable and compare it with current post's ID by using get_the_ID() function and then perform the necessary actions.
Example:
single-cpt.php
// Inside the loop
global $post_id = get_the_ID();
sidebar-cpt.php
$post_id = isset($_GLOBALS['post_id']) ? $_GLOBALS['post_id'] : 0;
while( $shools_loop->have_posts() ) : $schools_loop->the_post();
if($post_id == get_the_ID()){
// This is the active link
$content .= '<li class="schools-list selected">';
} else {
$content .= '<li class="schools-list">';
}
$content .= ''.get_the_title().'';
$content .= '</li>';
endwhile;

Want to apply different classes to each selected menu elements

Hi i am having an issues with the customizing of wordpress menu theme. I want to apply different classes on each of the selected menu.
This is exactly what i want.
<ul>
<li class="item1">Home Page</li>
<li class="item2">About Page</li>
<li class="item3">Contact Page</li>
</ul>
When the menu item is clicked different classes would be applied on each of the selected menu item
For example i want to click menu item1 a class active1 should be added to the selected element simillary if i clicked item2 a class active2 should be added to the selected element
This is how i am trying to achieve this but its not working
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
function special_nav_class($classes, $item){
if ($item == 'Home Page') {
if( in_array('current-menu-item', $classes) ){
$classes[] = 'active1';
}
}
if ($item == 'Home Page') {
if( in_array('current-menu-item', $classes) ){
$classes[] = 'active2';
}
}
return $classes;
}
Can Anyone please help me? Thanks in Advance
This requires some jQuery
PHP
First, let's construct the menu:
$menu = array(
'1' => 'Home',
'2' => 'About',
'3' => 'contact',
);
PHP/HTML
<ul class="menu">
<?php foreach ($menu as $id => $item): ?>
<li><a class="item item-<?= $id; ?>" href="#"><?= $item; ?></a></li>
<?php endforeach; ?>
jQuery
$(document).ready(function() {
$(document).on('click', '.item', function () {
$('.item').removeClass('active');
$(this).addClass('active');
});
});
After reading more closely I see you want to add the class in PHP. In order for me to answer your question, I need to know how the $classes array looks.

Categories