I am desperately trying to find a solution to add a conditional div class to individual categories when using the Genesis shortcode [post_categories] in the entry-header.
I want to apply unique colors to category titles in the entry header for articles on the home page and on individual posts. www.mic.com has this affect. You will notice that articles under the "World" category have the category text one color, while articles under the "News" category have the category text displayed as a different color.
For example, if the category is "Infrastructure", I'd like there to be a class that wraps around the existing entry-categories class.
I want it to look like this:
<div class="infrastructure section"><span class="entry-categories"></span></div>
If the category is "Elections", I'd like it to show:
<div class="elections section"><span class="entry-categories"></span></div>
The code I need to edit to get this effect is listed below.
add_shortcode( 'post_categories', 'genesis_post_categories_shortcode' );
/**
* Produces the category links list.
*
* Supported shortcode attributes are:
* after (output after link, default is empty string),
* before (output before link, default is 'Tagged With: '),
* sep (separator string between tags, default is ', ').
*
* Output passes through 'genesis_post_categories_shortcode' filter before returning.
*
* #since 1.1.0
*
* #param array|string $atts Shortcode attributes. Empty string if no attributes.
* #return string Shortcode output
*/
function genesis_post_categories_shortcode( $atts ) {
$defaults = array(
'sep' => ', ',
'before' => __( 'Filed Under: ', 'genesis' ),
'after' => '',
);
$atts = shortcode_atts( $defaults, $atts, 'post_categories' );
$cats = get_the_category_list( trim( $atts['sep'] ) . ' ' );
if ( genesis_html5() )
$output = sprintf( '<span %s>', genesis_attr( 'entry-categories' ) ) . $atts['before'] . $cats . $atts['after'] . '</span>';
else
$output = '<span class="categories">' . $atts['before'] . $cats . $atts['after'] . '</span>';
return apply_filters( 'genesis_post_categories_shortcode', $output, $atts );
}
I have tried using the get_the_category_list function to conditionally create the class names, but the command is not completing an action. When viewing my site through firebug, the new class shows the command as text.
$cats = get_the_category_list( trim( $atts['sep'] ) . ' ' );
if ( genesis_html5() )
$output = sprintf( '<div class="<?php echo $cats[0]->cat_name; ?> section"><span %s>', genesis_attr( 'entry-categories' ) ) . $atts['before'] . $cats . $atts['after'] . '</span></div>';
Any ideas on how to achieve this affect?
Thanks so much!
Something like this should work ( but only for html5 ):
function custom_terms_shortcode( $atts ) {
$defaults = array(
'after' => '',
'before' => __( 'Filed Under: ', 'genesis' ),
'sep' => ', ',
'taxonomy' => 'category',
);
$atts = shortcode_atts( $defaults, $atts, 'custom_terms' );
$terms = get_the_terms( get_the_ID(), $atts['taxonomy'] );
if ( is_wp_error( $terms ) )
return;
if ( empty( $terms ) )
return;
if ( genesis_html5() ){
$output .= '<span class="entry-terms">';
$output .= $atts['before'];
foreach ($terms as $term) {
$output = '<div class="'. $term->name .'">';
$output .= ''.$term->name.''.$atts['sep'];
$output .= '</div>';
}
$output = substr($output, 0, -2);
$output .= $atts['after'];
$output .= '</span>';
}
return apply_filters( 'genesis_post_terms_shortcode', $output, $terms, $atts );
}
Related
I am looking to have an action included in my functions.php file that changes the echo array from true to false in the below code:
function wc_display_item_meta( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args(
$args,
array(
'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => true,
'autop' => false,
'label_before' => '<strong class="wc-item-meta-label">',
'label_after' => ':</strong> ',
)
);
The above code is found in the WooCommerce wc-template-functions.php file found on line 3273.
How can I do this?
In includes/wc-template-functions.php, you will see that the function in there is wrapped in a if ( ! function_exists( 'wc_display_item_meta' ) ) { conditional.
So redefine the same function in functions.php file of the active child theme (or active theme) and your custom function will override the existing.
Note: A function can only be reassigned this way once.
So you get:
/**
* Display item meta data.
*
* #since 3.0.0
* #param WC_Order_Item $item Order Item.
* #param array $args Arguments.
* #return string|void
*/
function wc_display_item_meta( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args(
$args,
array(
'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => false,
'autop' => false,
'label_before' => '<strong class="wc-item-meta-label">',
'label_after' => ':</strong> ',
)
);
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
$value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) );
$strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value;
}
if ( $strings ) {
$html = $args['before'] . implode( $args['separator'], $strings ) . $args['after'];
}
$html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args );
if ( $args['echo'] ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $html;
} else {
return $html;
}
}
I'm current building a website for a non-profit, and am using an older edition of the Wordpress theme, Savior.
There is a custom post type of Donations, and it allows the admin to set up different "Causes", each of which is a post with a specific ID.
By default, the theme has a custom Visual Composer element (Screenshot 1 - https://i.stack.imgur.com/cmhTu.png) that allows you to feature the most recent "Cause"; the only customization option you have is for the Title of the VC element.
I'm trying to update this custom VC element so that the admin can specify the exact ID for the "Cause" they would like to feature on a page/post vs. only showing the latest "Cause."
I've adjusted the VC mapping for the cause.php template where commented below:
<?php
class STM_VC_Causes {
function __construct() {
add_action( 'init', array( $this, 'integrateWithVC' ) );
add_shortcode( 'stm_causes', array( $this, 'render' ) );
}
public function integrateWithVC() {
if ( function_exists( 'vc_map' ) ) {
vc_map( array(
'name' => __( 'Causes', STM_DOMAIN ),
'base' => 'stm_causes',
'category' => __( 'STM', STM_DOMAIN ),
'params' => array(
array(
'type' => 'textfield',
'class' => '',
'heading' => __( 'Title', STM_DOMAIN ),
'param_name' => 'title',
'value' => __( 'Our Causes', STM_DOMAIN )
),
/** ========================================
* Qing Custom 8-6-2018
* Allow admin to select Cause to feature
======================================== **/
array(
'type' => 'textfield',
'class' => '',
'heading' => __( 'Cause ID', STM_DOMAIN ),
'param_name' => 'id',
'value' => __( '', STM_DOMAIN )
)
)
) );
}
}
public function render( $atts, $content = null ) {
/** ========================================
* Qing Custom 8-6-2018
* Display selected Cause ID
======================================== **/
$title = '';
$id = '';
extract( shortcode_atts( array(
'title' => '',
'id' => ''
), $atts ) );
$fea_cause = $atts['id'];
$donations = new WP_Query( array( 'post_type' => 'donation', 'posts_per_page' => 1, 'post__in' => $fea_cause ) );
$output = '';
$output .= '<ul class="donation-grid first clearfix">';
while ( $donations->have_posts() ) {
$donations->the_post();
$target_amount = ( get_post_meta( get_the_ID(), 'donation_target', true ) == '' ) ? 0 : get_post_meta( get_the_ID(), 'donation_target', true );
$raised_amount = ( get_post_meta( get_the_ID(), 'donation_raised', true ) == '' ) ? 0 : get_post_meta( get_the_ID(), 'donation_raised', true );
$currency = ( get_post_meta( get_the_ID(), 'donation_currency', true ) == '' ) ? '$' : get_post_meta( get_the_ID(), 'donation_currency', true );
$donors = ( get_post_meta( get_the_ID(), 'donation_donors', true ) == '' ) ? 0 : get_post_meta( get_the_ID(), 'donation_donors', true );
$target_amount_percent = ( $raised_amount / $target_amount ) * 100;
$output .= '<li id="post-' . get_the_ID() . '" class="' . implode( ' ', get_post_class() ) . '">';
$output .= '<div class="donation-thumbnail">';
$output .= '<a href="' . get_the_permalink() . '">';
if ( has_post_thumbnail() ) {
$output .= get_the_post_thumbnail( get_the_ID(), 'thumb-150x150' );
}
$output .= '</a>';
$output .= '</div>';
$output .= '<div class="donation-content">';
$output .= '<h4>' . get_the_title() . '</h4>';
$output .= '<div class="progress_bar"><span style="width: ' . $target_amount_percent . '%;"></span></div>';
$output .= '<div class="donation-stat">';
$output .= '<span><i class="fa fa-child"></i> ' . __( 'Raised', STM_DOMAIN ) . '<br/>' . $currency . $raised_amount . '</span>';
$output .= '<span><i class="fa fa-users"></i> ' . __( 'Donors', STM_DOMAIN ) . '<br/>' . $donors . '</span>';
$output .= '<span><i class="fa fa-thumbs-up"></i> ' . __( 'Goal', STM_DOMAIN ) . '<br/>' . $currency . $target_amount . '</span>';
$output .= '</div>';
$output .= '<div class="donate_now">';
$output .= '' . __( 'DONATE NOW', STM_DOMAIN ) . '';
$output .= '</div>';
$output .= '</div>';
$output .= '</li>';
}
$output .= '</ul>';
wp_reset_query();
return $output;
}
}
if( defined( 'WPB_VC_VERSION' ) ){
new STM_VC_Causes();
}
?>
The custom VC element is showing up correctly for me on the admin backend side of the site (Screenshot 2 - https://i.stack.imgur.com/zKCgs.png), but I cannot figure out how to get the admin-inputted ID to show up on the frontend - no matter what, it still shows the most recent "Cause." Screenshot 3 (https://i.stack.imgur.com/13Qw4.png) is simply an example screenshot of what the individual "Cause" looks like when a page with the custom VC element is pushed live.
I've contacted the support team for the theme, but they only suggested this Post Types Order WP plugin, which only allows you to change the displayed "Cause" across the entire site, instead of allowing you to specify it in a page-by-page/post-by-post basis. I've also scoured Google/StackOverflow and tried various queries in the WP Codex, building out a custom shortcode (the custom VC element itself is a custom shortcode: [stm_causes]), but it just displays the most recent "Cause."
Edit 8/7/18:
I've made several edits to the causes.php template within the Savior theme, but for some reason, the updated WP_Query loop ended up not pulling in any data (Screenshot 3: https://i.stack.imgur.com/JLibO.png ).
The only exception is if I omit any ID in the VC editor backend; If I don't enter an ID, it defaults to the most recent Cause. However, if I enter any ID, even if it's the same ID as the most recent post, nothing shows up...
Any idea what could be wrong with my logic?
Thank you!
render function Fixed!
$fea_cause = $atts['id'];
$donations = new WP_Query( array( 'post_type' => 'donation', 'posts_per_page' => 1, 'post__in' => array($fea_cause )));
Huge props to Nilesh Sanura for his help!
On https://broadly.vice.com/en_us they show a single, primary category, if their post belongs to many categories.
How can you choose, on a post by post basis, what primary category to show in the post_meta in a Genesis Child theme?
Here is simple solution.
Use SEO Yoast free plugin https://wordpress.org/plugins/wordpress-seo/ . Which help you make any category primary when there are multiple categories assigned to a post.
See Plugin's interface for Primary cat selection:
Then in your WP theme have following function in functions file and then you can use to echo the category name anywhere as: <?php echo taxo_primary_term_name; ?>
// wp seo yoast get primary category name
function taxo_primary_term_name($taxo){
$wpseo_primary_term = new WPSEO_Primary_Term($taxo, get_the_ID());
$wpseo_primary_term = $wpseo_primary_term->get_primary_term();
return $wpseo_primary_term = get_term($wpseo_primary_term)->name;
}
As of this post date, install the Trunk version of CMB2 (not the plugin).
See See Gist for a backup of this answer.
Put the following inside your functions.php or, better, your functions plugin. Don't add the opening php. Change yourprefix_ in many locations.
<?php
//don't add
/**
*
* Create Metabox and Primary Category Select Field
* Requires CMB2 TRUNK branch NOT the plugin from the repo
* Install CMB2-trunk.zip via plugin interface or incorporate in your theme, read their docs
* https://github.com/WebDevStudios/CMB2/branches
*
*/
function yourprefix_primary_category_selection() {
$prefix = 'yourprefix_';
$cmb_demo = new_cmb2_box( array(
'id' => $prefix . 'metabox',
'title' => esc_html__( 'Primary Category', 'yourtextdomain' ),
'object_types' => array( 'post', ),
'context' => 'side',
'priority' => 'low',
'show_names' => false,
) );
$cmb_demo->add_field( array(
'name' => esc_html__( 'Choose Primary Category', 'yourtextdomain' ),
'desc' => esc_html__( 'Choose primary category for display in post_meta', 'yourtextdomain' ),
'id' => $prefix . 'category_list',
'taxonomy' => 'category',
'type' => 'taxonomy_select',
) );
}
add_action( 'cmb2_admin_init', 'yourprefix_primary_category_selection' );
/**
*
* Add Primary to [post_categories] shortcode replacing the genesis shortcode of the same name
*
*/
function yourprefix_post_primary_category_shortcode( $atts ) {
//* get our CMB2 field and category stuff
$prefix = 'yourprefix_';
$primary_cat = get_post_meta( get_the_ID(), $prefix . 'category_list', true );
$category_id = get_cat_ID( $primary_cat );
$category_link = get_category_link( $category_id );
$category_name = get_cat_name( $category_id );
$defaults = array(
'sep' => ', ',
'before' => __( 'Filed Under: ', 'yourtextdomain' ),
'after' => '',
);
$atts = shortcode_atts( $defaults, $atts, 'post_categories' );
//* fallback to the standard array if the choice in the primary metabox is not set
if( empty( $primary_cat ) ) {
$cats = get_the_category_list( trim( $atts['sep'] ) . ' ' );
} else {
$cats = '' . $category_name . '';
}
//* Do nothing if no cats
if ( ! $cats ) {
return '';
}
if ( genesis_html5() )
$output = sprintf( '<span %s>', genesis_attr( 'entry-categories' ) ) . $atts['before'] . $cats . $atts['after'] . '</span>';
else
$output = '<span class="categories">' . $atts['before'] . $cats . $atts['after'] . '</span>';
return apply_filters( 'genesis_post_categories_shortcode', $output, $atts );
}
add_shortcode( 'post_categories', 'yourprefix_post_primary_category_shortcode' );
I have this problem: i have made a custom page with his own set of categories. In a shortcode i want to get all the categories and in the categories i want all the post related to that category.
function innovatiewerkplaats_sort($atts, $content = null){
global $post;
$terms = get_terms('innovatiewerkplaats_categories'); // Get all terms of a taxonomy
$nieuws = '';
foreach($terms as $term):
$nieuws .= '<div class="one">
<h2>Thema <strong>'.$term->name.' id='.$term->term_id.'</strong></h2>
<div class="wrapper">';
$category_query_args = array(
'post_type' => 'innovatiewerkplaats',
// 'category' => $term->term_id,
'category_name' => $term->name,
// 'cat' => $term->term_id,
);
query_posts($category_query_args);
if( have_posts() ) : while (have_posts()) : the_post();
$post_home= get_the_post_thumbnail( $page->ID, 'post-home');
$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), '' );
$url = $thumb['0'];
$excerpt = get_the_content();
$excerpta = preg_replace("~(?:\[/?)[^/\]]+/?\]~s", '', $excerpt);
// $ter = wp_trim_words( apply_filters( 'rpwe_excerpt', $excerpta ), $args['length'], '…' );
$nieuws .= ''.$term->term_id.'<span class="img" style="background:url('.$url.') no-repeat center center; background-size:cover;"></span><span class="titel">'.get_the_title().'</span><p></p><span class="more">Lees meer</span>';
endwhile; endif;
$nieuws .='</div></div>';
endforeach;
return $nieuws;
}
Note: Don't use query_post. Use WP_Query or get_posts.
Please take a look discussion When to use WP_query(), query_posts() and pre_get_posts.
Here sample approach related to your issue to generate all posts base on their category, then display via shortcode for later.
Inside a function, you should query all posts first ( use wp_query or get_posts ),
Get related category by post id inside query loop. If term taxonomy, use get_the_terms.
Build an array of query data with key ( in this case, we use term slug ) to grouping posts.
Then take those data for outside loop, and output them with
simple loop.
Build a shortcode by function add_shortcode ( this code use simple shortcode only ).
/** Shortcode [my_shortcode_posts] */
add_shortcode( 'my_shortcode_posts', 'so36133962_get_all_posts_by_category' );
/**
* All posts by category
* build query by get_posts
*
* #return string|null
*/
function so36133962_get_all_posts_by_category( $attr, $content = null )
{
/**
* Build custom query
*
*/
$args = array(
'post_type' => 'your-post-type', // set your custom post type
'post_status' => 'publish',
'posts_per_page' => -1,
/** add more arguments such as taxonomy query i.e:
'tax_query' => array( array(
'taxonomy' => 'genre', // set your taxonomy
'field' => 'slug',
'terms' => array( 'comedy','drama' ) // set your term taxonomy
) )
*/
);
$posts = new WP_Query( $args );
/**
* Prepare Posts
*
*/
$result = array();
// The Loop
if ( $posts->have_posts() )
{
while ( $posts->have_posts() )
{
$posts->the_post();
/**
* Get all item in a term taxonomy
*
*/
$categories = get_the_terms( get_the_ID(), 'your-taxonomy' /* set your term taxonomy */ );
if ( ! $categories )
continue;
foreach ( $categories as $key => $category )
{
$term_name = $category->name;
$term_slug = $category->slug;
$term_id = $category->term_id;
}
/**
* Set thumbnail background cover
* Use Featured Image
*/
$img_cover = '';
if ( has_post_thumbnail() )
{
$image_url = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ) );
if ( ! empty( $image_url[0] ) )
{
$img_cover = '<span class="img" style="background:url( ' . esc_url( $image_url[0] ) . ' ) no-repeat center center; background-size:cover;">';
}
}
/**
* Format html content
*
*/
$format = '%4$s%2$s</span></br><span class="content-%3$s">%5$s</span></br><span class="more">%6$s</span>';
/**
* Formatted string post content
*
*/
$content = sprintf( $format,
get_permalink(),
get_the_title(),
get_the_ID(),
$img_cover,
get_the_excerpt(),
__( 'Read More', 'text-domain' )
);
/**
* Set an array of each post for output loop
*
*/
$result[ $term_slug ][] = array(
'post_id' => get_the_ID(),
'post_content' => $content,
'term_name' => $term_name,
'term_id' => $term_id
);
}
}
wp_reset_postdata(); // post reset
/**
* Check existing output
*
*/
if ( ! $result )
return;
/**
* Output loop
*
*/
$output = '';
foreach ( $result as $slug => $data )
{
$count = count( $data );
for ( $i = 0; $i < $count; $i++ )
{
/**
* Set data as object
*
*/
$post = ( object ) array_map( 'trim', $data[ $i ] );
if ( 0 == $i )
{
/**
* Set category id and name
*
*/
$output .= '<div id="term-category-' . absint( $post->term_id ) . '">';
$output .= '<h3>' . esc_html( $post->term_name ) . '</h3>';
}
/**
* Set post id and content
*
*/
$output .= '<div id="post-' . absint( $post->post_id ) . '"><p>' . $post->post_content . '</p></div>';
}
$output .= '</div>';
}
return $output; // complete
}
You can change element structures as your needs. As note, with this code, no duplicate posts in each category, and make sure you change the values such as post type and taxonomy as commented in code. I hope this helps.
I'm using the Dynamic Menus within WordPress as a widget. I'm trying to filter the output so that I can add a class to the <a> tags (not the parent <li> as is default) without relying on jQuery.
I do not want to filter by theme_location since I am switching the menu depending on page and cannot assign multiple dynamic menus to one location.
I'd like to target these menus by Menu Name.
So far i've come close by realizing what the available arguments are for wp_nav_menu found in the response to this question : https://wordpress.stackexchange.com/questions/53950/add-a-custom-walkter-to-a-menu-created-in-a-widget
The following seems to be working fine:
add_filter('wp_nav_menu_items','replace_class', 10, 2);
function replace_class($items, $args)
{
if ($args->menu->term_id == '27') {
$items = preg_replace('/<a/', '<a class="custom-class"', $items);
}
return $items;
}
However this is only by using the "term_id" for the menu.
Trying to do something like: if ($args->menu == 'menu-services') { for whatever reason does not work. Could I be using the wrong filter?
*UPDATE*
If you want to use your method or function - just add slug
add_filter('wp_nav_menu_items','replace_class', 10, 2);
function replace_class($items, $args)
{
if ($args->menu->slug == 'your-menu-name') {
$items = preg_replace('/<a/', '<a class="custom-class"', $items);
}
return $items;
}
Original Answer:
I answered this yesterday - see my answer here
Based on the link you provided (from wordpress stackexchange)
add this code to add a custom walker to your widget menu:
function widget($args, $instance) {
// Get menu
$nav_menu = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;
if ( !$nav_menu )
return;
$instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
echo $args['before_widget'];
if ( !empty($instance['title']) )
echo $args['before_title'] . $instance['title'] . $args['after_title'];
wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu ) );
echo $args['after_widget'];
}
$defaults = array( 'menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'depth' => 0, 'walker' => '', 'theme_location' => '' );
$args = wp_parse_args( $args, $defaults );
$args = apply_filters( 'wp_nav_menu_args', $args );
$args = (object) $args;
function myplugin_custom_walker( $args ) {
return array_merge( $args, array(
'walker' => new Class_Name_Walker(),
// another setting go here ...
) );
}
add_filter( 'wp_nav_menu_args', 'myplugin_custom_walker' );
then add this walker - which adds the classes to the a
class Class_Name_Walker extends Walker_Nav_Menu
{
/**
* Start the element output.
*
* #param string $output Passed by reference. Used to append additional content.
* #param object $item Menu item data object.
* #param int $depth Depth of menu item. May be used for padding.
* #param array $args Additional strings.
* #return void
*/
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value .'>';
$atts = array();
$atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .$class_names.'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
/**
* #see Walker::end_el()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param object $item Page data object. Not used.
* #param int $depth Depth of page. Not Used.
*/
function end_el( &$output, $item, $depth = 0, $args = array() ) {
$output .= "</li>\n";
}
}
In your admin area go to Appearance > Menus.
On the top right of the screen click on 'Screen Options' on the bottom row - make sure 'CSS Classes' is checked.