Adding custom <li> to Wordpress navigation menu - php

I just cant fully understand how custom walkers work in worpress:
Code in theme's home.php (actually all code is included from other file to not mess HTML) looks like this:
/**
* Contains wordpress function with array with parameters
* #return string HTML output
*/
function show_main_navigation() {
return wp_nav_menu(
array(
'theme_location' => 'header-menu',
'echo' => false,
'depth' => '-1',
'walker' => new Last_Item_Walker()
)
);
}
Walker looks like this:
class Last_Item_Walker extends Walker_Nav_Menu {
function end_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat("\t", $depth);
$output .= '<li class="spec">title</li>'; // my custom <li>
$output .= "$indent</ul>\n";
}
}
Overwritten method just does not work.
If I try to overwrite another method, for example:
class Last_Item_Walker extends Walker_Nav_Menu {
function end_el( &$output, $item, $depth = 0, $args = array() ) {
$output .= "<br>"; // for demonstration
$output .= "</li>\n";
}
}
This one works, adds br tag but this is not what i want, i want to customize last li before /ul.
Can somebody help me with this?

Ok it was easier to do with filters.
/**
* Hardcodes shop item in navigation
* #param string $items HTML with navigation items
* #param object $args navigation menu arguments
* #return string all navigation items HTML
*/
function new_nav_menu_items($items, $args) {
if($args->theme_location == 'header-menu'){
$shop_item = '<li class="spec">title</li>';
$items = $items . $shop_item;
}
return $items;
}
add_filter('wp_nav_menu_items', 'new_nav_menu_items', 10, 2);

If you're not too worried about IE8 and less, you can use the :last-child selector.
li.spec:last-child{
color: red;
}
If you are bothered about IE8 and less you can use a polyfill to make it work.

Related

How can i create a shortcode in wordpress?

I have the code below and i want it to display content on implementation using
[insert_dos]*Content for dos here*[/insert_dos]
[insert_donts]*Content for dos here*[/insert_donts]
Dos
Content for dos here
Don'ts
Content for don'ts here
The code am trying to use
// Shortcode for dos
function insert_dos_func( $atts,$content ) {
extract( shortcode_atts( array(
'content' => 'Hello World',
), $atts ) );
return '<h2>DOs</h2>';
return '<div>' . $content . '</div>';
}
add_shortcode( 'insert_dos', 'insert_dos_func' );
// Shortcode for don'ts
function insert_donts_func( $atts ) {
extract( shortcode_atts( array(
'content' => 'Hello World',
), $atts ) );
return "<h2>DON'Ts</h2>";
return "<div>" . $content . "</div>";
}
add_shortcode( 'insert_donts', 'insert_donts_func' );
The first issue you're going to face is the use of multiple return statements inside a single function. Anything after the first return won't be executed.
The second issue is the way you're passing in content. There's an element in your attributes array named content. If you run extract on that array it's going to override the $content argument of your shortcode callback.
function insert_dos_func( $atts, $content ) {
/**
* This is going to get attributes and set defaults.
*
* Example of a shortcode attribute:
* [insert_dos my_attribute="testing"]
*
* In the code below, if my_attribute isn't set on the shortcode
* it's going to default to Hello World. Extract will make it
* available as $my_attribute instead of $atts['my_attribute'].
*
* It's here purely as an example based on the code you originally
* posted. $my_attribute isn't actually used in the output.
*/
extract( shortcode_atts( array(
'my_attribute' => 'Hello World',
), $atts ) );
// All content is going to be appended to a string.
$output = '';
$output .= '<h2>DOs</h2>';
$output .= '<div>' . $content . '</div>';
// Once we've built our output string, we're going to return it.
return $output;
}
add_shortcode( 'insert_dos', 'insert_dos_func' );

Custom walker decorator

I need add to my menu extra icon before text. So I read in documentation that I need implement custom Walker_Nav_Menu. After some analyzing, I recognize I could implement my custom walker accord with decorator pattern. I have very small expirience in php especially wordpress. My code works weird. Look at it:
class Walker_nav_menu_Decorator extends Walker_Nav_Menu{
public $menu;
public static $index = 0;
function __construct() {
$menu = new Walker_Nav_Menu();
}
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
if($item->title == "Main Menu"){
$args->before = "TEST";
}
echo $index;
$index+=1;
parent::start_el($output, $item, $depth, $args, $id);
}
}
It doesn't echo $index at all oO. Additionally add extra "TEST" word before each menu item. How should I do it properly and why this version doesn't work?
My class is in my functions.php file and I'm calling my menu here:
wp_nav_menu( array( 'theme_location' => 'main_menu', 'container' => 'nav' ,'container_class' => 'menu', 'walker' => new Walker_nav_menu_Decorator() ) );
your $index is static so don't call it directly but by
echo self::$index;
self::$index+=1;

Override Menu CSS Wordpress with Functions.php

I am using the following override in my functions.php
function wp_nav_menu_attributes_filter($var) {
return is_array($var) ? array_intersect($var, array('current-menu-item')) : '';
}
add_filter('nav_menu_css_class', 'wp_nav_menu_attributes_filter', 100, 1);
add_filter('nav_menu_item_id', 'wp_nav_menu_attributes_filter', 100, 1);
add_filter('page_css_class', 'wp_nav_menu_attributes_filter', 100, 1);
This removes the class tag that wordpress adds to a menu item. Now what I need to do is actually put in my own class name into the li tag instead, can anyone fill me in quickly on how to do that, I have scoured google and maybe I am searching for it wrong or what not or I just cannot understand the hook system with the functions.php file....
Using the above make my html output as...
<ul id="menu-homemenu" class="list-group special">
<li>Biography</li>
<li>Selected Works</li>
<li>Contact Us</li>
</ul>
Of course after I posted a comment I figured it out...sigh hate when this takes all evening to get it...this question pointed me in the right direction - How to add custom HTML to wp_nav_menu?
I added this class..
class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$output .= "<li class='list-group-item'>".esc_attr($item->title)."";
}
function end_el( &$output, $item, $depth = 0, $args = array() ) {
$output .= "</li>\n";
}
}
Then added this to my array where I called my nav inside my template...
<?php wp_nav_menu(array('menu' => 'HomeMenu','menu_class' => 'list-group special','menu_id' => '','walker' => new Custom_Walker_Nav_Menu)); ?>

How to add classes to images based on their categories?

I need to be able to: 1.) assign categories to images and 2.) add classes to all images that correspond to their assigned categories.
I was able to add categories to images with the following:
function ug_add_categories_to_attachments() {
register_taxonomy_for_object_type( 'category', 'attachment' );
}
add_action( 'init' , 'ug_add_categories_to_attachments' );
And I found a function to add a class to images as so:
function add_image_class($class){
$class .= ' additional-class';
return $class;
}
add_filter('get_image_tag_class','add_image_class');
But I'm not advanced enough with php to take it much further. I tried this
function ug_add_image_class($class){
foreach(get_the_category() as $cat) { $class .= ' category-'.$cat->slug; };
return $class;
}
add_filter('get_image_tag_class','ug_add_image_class');
but no love...
Help? Ideas? Please? and Happy Friday!
Much thanks to birgire at the referenced url for the answer:
/**
* Append the image categories to the current image class.
*
* #see http://wordpress.stackexchange.com/a/156576/26350
*/
add_filter( 'get_image_tag_class',
function( $class, $id, $align, $size )
{
foreach( (array) get_the_category( $id ) as $cat )
{
$class .= ' category-' . $cat->slug;
}
return $class;
}
, 10, 4 );

WordPress: add HTML to a specific nav menu

add_filter('wp_nav_menu_items', 'add_custom', 10, 2);
function add_custom($items, $args) {
if ($args->theme_location == 'primary') {
$items .= '<li class="custom"></li>';
}
return $items;
}
which produces:
<ul id="menu-top">
<li></li>
<li></li>
<li></li>
<li class="custom"></li> /* added custom HTML */
<ul>
but what if my WP menu doesn't have a "theme_location"? Can I target my menu by id/class instead of "theme_location", or how else can I add HTML to one specific menu?
Can you use jQuery?
jQuery(document).ready(function($) {
$('#menu-top').append('<li class="custom"></li>');
});
Or PHP + CSS - with this solution, you add it to every menu and hide it if need be via CSS.
add_filter('wp_nav_menu_items', 'add_custom', 10, 2);
function add_custom($items, $args) {
$items .= '';
return $items;
}
li.custom { display:none; } // hide originally
ul#menu-top li.custom { display:inline; } // or whatever styles
When there is no theme_location, then I guess, it falls back to wp_page_menu. So, in theory, you could filter into wp_page_menu and modify the output.
<?php
//Use this filter to modify the complete output
//You can get an argument to optionally check for the right menu
add_filter( 'wp_page_menu', 'my_page_menu', 10, 2 );
/**
* Modify page menu
* #param string $menu HTML output of the menu
* #param array $args Associative array of wp_page_menu arguments
* #see http://codex.wordpress.org/Function_Reference/wp_page_menu
* #return string menu HTML
*/
function my_page_menu( $menu, $args ) {
//see the arguments
//Do something with $menu
return $menu;
}
//Use this filter to alter the menu argument altogether
//It is fired before creating any menu html
add_filter( 'wp_page_menu_args', 'my_page_menu_pre_arg', 10, 1 );
/**
* Modify page menu arguments
* #param array $args Associative array of wp_page_menu arguments
* #see http://codex.wordpress.org/Function_Reference/wp_page_menu
* #return array modified arguments
*/
function my_page_menu_pre_arg( $args ) {
//Do something with $args
return $args;
}
Hope it helps.

Categories