How to custom links aka blogroll widgets? - wordpress

wordpress\wp-includes\default-widgets.php # line 91
/**
* Links widget class
*
* #since 2.8.0
*/
class WP_Widget_Links extends WP_Widget {
function WP_Widget_Links() {
$widget_ops = array('description' => __( "Your blogroll" ) );
$this->WP_Widget('links', __('Links'), $widget_ops);
}
function widget( $args, $instance ) {
extract($args, EXTR_SKIP);
$show_description = isset($instance['description']) ? $instance['description'] : false;
$show_name = isset($instance['name']) ? $instance['name'] : false;
$show_rating = isset($instance['rating']) ? $instance['rating'] : false;
$show_images = isset($instance['images']) ? $instance['images'] : true;
$category = isset($instance['category']) ? $instance['category'] : false;
if ( is_admin() && !$category ) {
// Display All Links widget as such in the widgets screen
echo $before_widget . $before_title. __('All Links') . $after_title . $after_widget;
return;
}
$before_widget = preg_replace('/id="[^"]*"/','id="%id"', $before_widget);
wp_list_bookmarks(apply_filters('widget_links_args', array(
'title_before' => $before_title, 'title_after' => $after_title,
'category_before' => $before_widget, 'category_after' => $after_widget,
'show_images' => $show_images, 'show_description' => $show_description,
'show_name' => $show_name, 'show_rating' => $show_rating,
'category' => $category, 'class' => 'linkcat widget'
)));
}
function update( $new_instance, $old_instance ) {
$new_instance = (array) $new_instance;
$instance = array( 'images' => 0, 'name' => 0, 'description' => 0, 'rating' => 0);
foreach ( $instance as $field => $val ) {
if ( isset($new_instance[$field]) )
$instance[$field] = 1;
}
$instance['category'] = intval($new_instance['category']);
return $instance;
}
function form( $instance ) {
//Defaults
$instance = wp_parse_args( (array) $instance, array( 'images' => true, 'name' => true, 'description' => false, 'rating' => false, 'category' => false ) );
$link_cats = get_terms( 'link_category');
?>
<p>
<label for="<?php echo $this->get_field_id('category'); ?>" class="screen-reader-text"><?php _e('Select Link Category'); ?></label>
<select class="widefat" id="<?php echo $this->get_field_id('category'); ?>" name="<?php echo $this->get_field_name('category'); ?>">
<option value=""><?php _e('All Links'); ?></option>
<?php
foreach ( $link_cats as $link_cat ) {
echo '<option value="' . intval($link_cat->term_id) . '"'
. ( $link_cat->term_id == $instance['category'] ? ' selected="selected"' : '' )
. '>' . $link_cat->name . "</option>\n";
}
?>
</select></p>
<p>
<input class="checkbox" type="checkbox" <?php checked($instance['images'], true) ?> id="<?php echo $this->get_field_id('images'); ?>" name="<?php echo $this->get_field_name('images'); ?>" />
<label for="<?php echo $this->get_field_id('images'); ?>"><?php _e('Show Link Image'); ?></label><br />
<input class="checkbox" type="checkbox" <?php checked($instance['name'], true) ?> id="<?php echo $this->get_field_id('name'); ?>" name="<?php echo $this->get_field_name('name'); ?>" />
<label for="<?php echo $this->get_field_id('name'); ?>"><?php _e('Show Link Name'); ?></label><br />
<input class="checkbox" type="checkbox" <?php checked($instance['description'], true) ?> id="<?php echo $this->get_field_id('description'); ?>" name="<?php echo $this->get_field_name('description'); ?>" />
<label for="<?php echo $this->get_field_id('description'); ?>"><?php _e('Show Link Description'); ?></label><br />
<input class="checkbox" type="checkbox" <?php checked($instance['rating'], true) ?> id="<?php echo $this->get_field_id('rating'); ?>" name="<?php echo $this->get_field_name('rating'); ?>" />
<label for="<?php echo $this->get_field_id('rating'); ?>"><?php _e('Show Link Rating'); ?></label>
</p>
<?php
}
}
How can I construct with this bookmark-template.php so that I can have another custom widgets?
wordpress\wp-includes\bookmark-template.php

Here's a code for styling blogroll links that can go into a text widget:
<style type="text/css">
.bloglist {
padding: 0;
margin: 0;
list-style: none;
font-weight: bold;
}
.bloglist li {
padding: 0;
margin: 0 0 6px 0;
background: #ede;
}
.bloglist li span {
padding: 12px 4px;
display: block;
}
.bloglist li a {
display: block;
}
</style>
<ul class="bloglist">
<?php wp_list_bookmarks('before=<li><span>&after=</span></li>&show_description=1&title_li=&categorize=0'); ?>
</ul>

Related

Search Result shows White Blank Page wordpress

My site link is: https://staging.buellairhorns.com/
When I try the search function, the search result page shows nothing but a white blank page. Can anyone help me figure out what's wrong?
This is my: search.php
<?php
$container_class = apply_filters( 'neve_container_class_filter', 'container', 'blog-archive' );
get_header();
$wrapper_classes = [ 'posts-wrapper' ];
if ( ! neve_is_new_skin() ) {
$wrapper_classes[] = 'row';
}
?>
<div class="<?php echo esc_attr( $container_class ); ?> archive-container">
<div class="row">
<?php do_action( 'neve_do_sidebar', 'blog-archive', 'left' ); ?>
<div class="nv-index-posts search col">
<?php
do_action( 'neve_page_header', 'search' );
if ( have_posts() ) {
/* Start the Loop. */
echo '<div class="' . esc_attr( join( ' ', $wrapper_classes ) ) . '">';
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content' );
}
echo '</div>';
if ( ! is_singular() ) {
do_action( 'neve_do_pagination', 'blog-archive' );
}
} else {
get_template_part( 'template-parts/content', 'none' );
}
?>
<div class="w-100"></div>
</div>
<?php do_action( 'neve_do_sidebar', 'blog-archive', 'right' ); ?>
</div>
</div>
<?php
get_footer();
This is my searchform.php
<?php
$form_classes = [ 'search-form' ];
$placeholder = array_key_exists( 'placeholder', $args ) ? $args['placeholder'] : __( 'Search for...', 'neve' );
if ( array_key_exists( 'additional_form_classes', $args ) && is_array( $args['additional_form_classes'] ) ) {
$form_classes = array_merge( $form_classes, $args['additional_form_classes'] );
}
$value = array_key_exists( 'value', $args ) ? $args['value'] : '';
$placeholder = apply_filters( 'nv_search_placeholder', $placeholder );
$aria_label = __( 'Search', 'neve' );
$home_url = home_url( '/' );
if ( function_exists( 'PLL' ) ) {
$pll_data = PLL();
if ( property_exists( $pll_data, 'links' ) && method_exists( $pll_data->links, 'get_home_url' ) ) {
$home_url = $pll_data->links->get_home_url( null, true );
}
}
?>
<form role="search"
method="get"
class="<?php echo esc_attr( implode( ' ', $form_classes ) ); ?>"
action="<?php echo esc_url( $home_url ); ?>">
<label>
<span class="screen-reader-text"><?php echo esc_html__( 'Search for...', 'neve' ); ?></span>
</label>
<input type="search"
class="search-field"
aria-label="<?php echo esc_attr__( 'Search', 'neve' ); ?>"
placeholder="<?php echo esc_attr( $placeholder ); ?>"
value="<?php echo esc_attr( $value ); ?>"
name="s"/>
<button type="submit"
class="search-submit"
aria-label="<?php echo esc_attr( $aria_label ); ?>">
<span class="nv-search-icon-wrap">
<?php neve_search_icon( false, true ); ?>
</span>
</button>
<?php
if ( array_key_exists( 'post_type', $args ) ) {
echo '<input type="hidden" name="post_type" value="' . esc_attr( $args['post_type'] ) . '"/>';
}
?>
</form>
I'am using neve theme. I created a custom search result page using Elementor Pro but still not working.

Can't display the value in custom metabox textarea wordpress

Well i tried to make custom meta boxes in page and posts...
I do have the have slider heading and content which i need to make on those specific posts and pages..
I did save the value of heading part in input box..
And in content part i have used Textarea where my value doesn't show up at all..
when i printed the variable that needs to be there i find the value is saving but it doesnt show up
For the code:
<?php function xgr_settings() {
add_meta_box(
'extra-slider-settings', // $id
__( 'Extra Slider Settings', 'xgr' ), // $title
'xgr_add_slider_options_callback',// $callback
array('post','page'),
'normal', // $context
'high' // $priority
);
}
add_action( 'add_meta_boxes', 'xgr_settings' );
$xgr_settings = array(
'slider-heading' => array(
'name' => __('Slider Heading','xgr'),
'value' => 'slider-heading',
'id' => 'slider-heading'
),
'slider-content' => array(
'name' => __('Slider Content','xgr'),
'value' => 'slider-content',
'id' => 'slider-content'
),
);
function xgr_add_slider_options_callback($post){
global $post , $xgr_settings;
?>
<div class="metabox">
<div class="row">
<?php foreach($xgr_settings as $field) {
$headings= get_post_meta($post->ID,$field['id'],true);
var_dump($headings);
?>
<?php if(($field['id']) === 'slider-heading') { ?>
<div class="form-group">
<label style="margin-bottom: 9px; font-style: italic; padding: 15px 10px; line-height: 1.3; vertical-align: middle;" class="control-label f13" for="inputDefault"><?php echo esc_attr( $field['name'] ); ?></label>
<input style="width:100%" type="text" class="form-control" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['value'] ); ?>" value="<?php echo $headings ? $headings : '' ?>">
</div>
<?php
} elseif(($field['id']) === 'slider-content'){ ?>
<div class="form-group">
<label style="margin-bottom: 9px; font-style: italic; padding: 15px 10px; line-height: 1.3; vertical-align: middle;" class="control-label f13" for="inputDefault"><?php echo esc_attr( $field['name'] ); ?></label>
<textarea style="width:100%;min-height:200px;" type="textarea" class="form-control" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['value'] ); ?>" value="<?php echo $headings ? $headings : '' ?>"></textarea>
</div>
<?php } } ?>
<br>
</div>
</div>
<?php
wp_nonce_field( 'xgr_nonce', 'xgr_nonce' );
}
function xgr_save_funtions($post_id){
$heading = sanitize_text_field( $_POST['slider-heading']);
$content = sanitize_text_field( $_POST['slider-content']);
if(isset($POST['xgr_nonce']) && wp_verify_nonce( $POST['xgr_nonce'], 'xgr_nonce')){
return;
}
if(isset($_POST['slider-heading'])){
update_post_meta($post_id ,'slider-heading',$heading);
}
if(isset($_POST['slider-content'])){
update_post_meta($post_id ,'slider-content',$content);
}
}
add_action('save_post','xgr_save_funtions');
TextArea Tag doesn't have value="" parameter
use:
<textarea>{YOUR VALUE TO SHOW}</textarea>
<textarea style="width:100%;min-height:200px;" type="textarea" class="form-control" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['value'] ); ?>" ><?php echo $headings ? $headings : '' ?></textarea>

Ajax add to cart not updating cart content untill after refresh

The ajax add to cart function of woocommerce doesn't seem to update the cart untill after I manually refresh the website.
This is the function for the cart widget I edited, and it seems to be working fine. It just doesn't refresh automatically.
class GeminiCart extends WP_Widget {
public function __construct() {
parent::__construct(
'gb_woocommerce_dropdown_cart',
esc_html__('Gemini Bracelet Woocommerce Dropdown Cart', 'depot'),
array( 'description' => esc_html__( 'Display a shop cart icon with a dropdown that shows products that are in the cart', 'depot' ), )
);
$this->setParams();
}
protected function setParams() {
$this->params = array(
array(
'type' => 'textfield',
'name' => 'woocommerce_dropdown_cart_margin',
'title' => esc_html__('Icon Margin', 'depot'),
'description' => esc_html__('Insert margin in format: top right bottom left (e.g. 10px 5px 10px 5px)', 'depot')
),
array(
'type' => 'dropdown',
'name' => 'woocommerce_enable_cart_info',
'title' => esc_html__('Enable Cart Info', 'depot'),
'options' => depot_mikado_get_yes_no_select_array(false),
'description' => esc_html__('Enabling this option will show cart info (products number and price) at the right side of dropdown cart icon', 'depot')
),
);
}
/**
* Generate widget form based on $params attribute
*
* #param array $instance
*
* #return null
*/
public function form($instance) {
if(is_array($this->params) && count($this->params)) {
foreach($this->params as $param_array) {
$param_name = $param_array['name'];
${$param_name} = isset($instance[$param_name]) ? esc_attr($instance[$param_name]) : '';
}
foreach($this->params as $param) {
switch($param['type']) {
case 'textfield':
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id($param['name'])); ?>"><?php echo
esc_html($param['title']); ?>:</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id($param['name'])); ?>" name="<?php echo esc_attr($this->get_field_name($param['name'])); ?>" type="text" value="<?php echo esc_attr(${$param['name']}); ?>"/>
<?php if(!empty($param['description'])) : ?>
<span class="mkd-field-description"><?php echo esc_html($param['description']); ?></span>
<?php endif; ?>
</p>
<?php
break;
case 'dropdown':
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id($param['name'])); ?>"><?php echo
esc_html($param['title']); ?>:</label>
<?php if(isset($param['options']) && is_array($param['options']) && count($param['options'])) { ?>
<select class="widefat" name="<?php echo esc_attr($this->get_field_name($param['name'])); ?>" id="<?php echo esc_attr($this->get_field_id($param['name'])); ?>">
<?php foreach($param['options'] as $param_option_key => $param_option_val) {
$option_selected = '';
if(${$param['name']} == $param_option_key) {
$option_selected = 'selected';
}
?>
<option <?php echo esc_attr($option_selected); ?> value="<?php echo esc_attr($param_option_key); ?>"><?php echo esc_attr($param_option_val); ?></option>
<?php } ?>
</select>
<?php } ?>
<?php if(!empty($param['description'])) : ?>
<span class="mkd-field-description"><?php echo esc_html($param['description']); ?></span>
<?php endif; ?>
</p>
<?php
break;
}
}
} else { ?>
<p><?php esc_html_e('There are no options for this widget.', 'depot'); ?></p>
<?php }
}
/**
* #param array $new_instance
* #param array $old_instance
*
* #return array
*/
public function update($new_instance, $old_instance) {
$instance = array();
foreach($this->params as $param) {
$param_name = $param['name'];
$instance[$param_name] = sanitize_text_field($new_instance[$param_name]);
}
return $instance;
}
public function widget( $args, $instance ) {
extract( $args );
global $woocommerce;
$icon_styles = array();
if ($instance['woocommerce_dropdown_cart_margin'] !== '') {
$icon_styles[] = 'padding: ' . $instance['woocommerce_dropdown_cart_margin'];
}
$icon_class = 'mkd-cart-info-is-disabled';
if (!empty($instance['woocommerce_enable_cart_info']) && $instance['woocommerce_enable_cart_info'] === 'yes') {
$icon_class = 'mkd-cart-info-is-active';
}
$cart_description = depot_mikado_options()->getOptionValue('mkd_woo_dropdown_cart_description');
?>
<div class="mkd-shopping-cart-holder <?php echo esc_html($icon_class); ?>" <?php depot_mikado_inline_style($icon_styles) ?>>
<div class="mkd-shopping-cart-inner">
<?php $cart_is_empty = sizeof( $woocommerce->cart->get_cart() ) <= 0; ?>
<a itemprop="url" class="mkd-header-cart" href="<?php echo esc_url($woocommerce->cart->get_cart_url()); ?>">
<span class="mkd-cart-icon-text"><?php esc_html_e('CART', 'depot'); ?></span>
<span class="mkd-cart-info">
<span class="mkd-cart-info-total">( <?php echo wp_kses($woocommerce->cart->get_cart_contents_count()); ?> )</span>
</span>
</a>
<?php if ( !$cart_is_empty ) : ?>
<div class="mkd-shopping-cart-dropdown">
<ul>
<?php foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $cart_item ) :
$_product = $cart_item['data'];
// Only display if allowed
if ( ! $_product->exists() || $cart_item['quantity'] == 0 ) {
continue;
}
// Get price
if ( version_compare( WOOCOMMERCE_VERSION, '3.0' ) >= 0 ) {
$product_price = get_option( 'woocommerce_tax_display_cart' ) == 'excl' ? wc_get_price_excluding_tax( $_product ) : wc_get_price_including_tax( $_product );
} else {
$product_price = get_option( 'woocommerce_tax_display_cart' ) == 'excl' ? $_product->get_price_excluding_tax() : $_product->get_price_including_tax();
}
?>
<li>
<div class="mkd-item-image-holder">
<a itemprop="url" href="<?php echo esc_url(get_permalink( $cart_item['product_id'] )); ?>">
<?php echo wp_kses($_product->get_image(), array(
'img' => array(
'src' => true,
'width' => true,
'height' => true,
'class' => true,
'alt' => true,
'title' => true,
'id' => true
)
)); ?>
</a>
</div>
<div class="mkd-item-info-holder">
<h5 itemprop="name" class="mkd-product-title"><a itemprop="url" href="<?php echo esc_url(get_permalink( $cart_item['product_id'] )); ?>"><?php echo apply_filters('depot_mikado_woo_widget_cart_product_title', $_product->get_title(), $_product ); ?></a></h5>
<span class="mkd-quantity"><?php echo esc_html($cart_item['quantity']); ?></span>
<?php echo apply_filters( 'depot_mikado_woo_cart_item_price_html', wc_price( $product_price ), $cart_item, $cart_item_key ); ?>
<?php echo apply_filters( 'depot_mikado_woo_cart_item_remove_link', sprintf('<span class="icon-arrows-remove"></span>', esc_url( $woocommerce->cart->get_remove_url( $cart_item_key ) ), esc_html__('Remove this item', 'depot') ), $cart_item_key ); ?>
</div>
</li>
<?php endforeach; ?>
<div class="mkd-cart-bottom">
<div class="mkd-subtotal-holder clearfix">
<span class="mkd-total"><?php esc_html_e( 'TOTAL:', 'depot' ); ?></span>
<span class="mkd-total-amount">
<?php echo wp_kses($woocommerce->cart->get_cart_subtotal(), array(
'span' => array(
'class' => true,
'id' => true
)
)); ?>
</span>
</div>
<?php if(!empty($cart_description)) { ?>
<div class="mkd-cart-description">
<div class="mkd-cart-description-inner">
<span><?php echo esc_html($cart_description); ?></span>
</div>
</div>
<?php } ?>
<div class="mkd-btn-holder clearfix">
<a itemprop="url" href="<?php echo esc_url($woocommerce->cart->get_cart_url()); ?>" class="mkd-view-cart" data-title="<?php esc_html_e('VIEW CART','depot'); ?>"><span><?php esc_html_e('VIEW CART','depot'); ?></span></a>
</div>
<div class="mkd-btn-holder clearfix">
<a itemprop="url" href="<?php echo esc_url($woocommerce->cart->get_checkout_url()); ?>" class="mkd-view-cart" data-title="<?php esc_html_e('CHECKOUT','depot'); ?>"><span><?php esc_html_e('CHECKOUT','depot'); ?></span></a>
</div>
</div>
</ul>
</div>
<?php else : ?>
<div class="mkd-shopping-cart-dropdown">
<ul>
<li class="mkd-empty-cart"><?php esc_html_e( 'No products in the cart.', 'depot' ); ?></li>
</ul>
</div>
<?php endif; ?>
</div>
</div>
<?php
}
}
I already implemented this function to make it update; but it doesn't change anything:
add_filter( 'woocommerce_add_to_cart_fragments', 'iconic_cart_count_fragments', 10, 1 );
function iconic_cart_count_fragments( $fragments ) {
$fragments['mkd-header-cart'] = '<span class="mkd-cart-icon-text"><?php esc_html_e(\'CART\', \'depot\'); ?></span>
<span class="mkd-cart-info">
<span class="mkd-cart-info-total">( <?php echo wp_kses($woocommerce->cart->get_cart_contents_count()); ?> )</span>
</span>';
return $fragments;
}
In wordpress itself I enabled the AJAX add to cart.
The add to cart button also has the class add_to_cart_button
The code that reloads those fragments can be found here: \plugins\woocommerce\assets\js\frontend\cart-fragments.js
To refresh WooCommerce widget you have to copy the code below
var $fragment_refresh = {
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
type: 'POST',
success: function( data ) {
if ( data && data.fragments ) {
$.each( data.fragments, function( key, value ) {
$( key ).replaceWith( value );
});
if ( $supports_html5_storage ) {
sessionStorage.setItem( wc_cart_fragments_params.fragment_name, JSON.stringify( data.fragments ) );
set_cart_hash( data.cart_hash );
if ( data.cart_hash ) {
set_cart_creation_timestamp();
}
}
$( document.body ).trigger( 'wc_fragments_refreshed' );
}
}
};
and to trigger the event you do this: $.ajax( $fragment_refresh ); OR jQuery.ajax( $fragment_refresh );

How to add custom woocommerce admin field type

i has already add one custom field type to woocommerce admin fields, and has worked 100%.
but this code is in the woocommerce plugin (woocommerce/includes/admin/class-wc-admin-settings.php).
My problem now is how to exclude or hook or filter my custom woocommerce admin field type from woocoommerce plugin to my plugin. therefore, my custom field type still exists and worked when update woocommerce.
this is class-wc-admin-settings.php has customized
<?php
...
class WC_Admin_Settings {
...
public static function output_fields( $options ) {
...
switch ( $value['type'] ) {
case 'productcategory' :
$option_value = (array) self::get_option( $value['id'] );
?><tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; ?>
</th>
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
<fieldset>
<ul class="" style="margin:0; padding:0;">
<?php
$args = array(
'orderby' => 'name',
'hide_empty'=> 0,
'taxonomy' => 'product_cat'
);
$all_categories = get_categories( $args );
$index = 0;
$count = count($all_categories);
$numItemsPerRow = ceil($count / 2);
$numItemsOffsetFix = $count % 2 == 1;
echo '<div class="columns" style="width:auto; display:inline-block; height:auto; float:left; padding:0; margin:0 25px 0 0;">';
foreach ($all_categories as $key => $val) {
if ($index > 0 and $index % $numItemsPerRow == 0) {
echo '</div><div class="columns">';
if ($numItemsOffsetFix) {
$numItemsPerRow--;
$numItemsOffsetFix = false;
}
}
//foreach ( $value['options'] as $key => $val ) {
?>
<li style="">
<label><input type="checkbox"
name="<?php echo esc_attr( $value['id'] ); ?>[]"
id="<?php echo esc_attr( $val->term_id )?>"
value="<?php echo esc_attr( $val->term_id )?>"
<?php
if ( in_array( $val->term_id,$option_value ) ) {
echo ' checked="checked"';
}
?>
/> <?php echo $val->name; ?>
</label>
</li>
<?php
$index++;
}
?>
</ul>
</fieldset>
<fieldset>
<?php echo $description; ?>
</fieldset>
</td>
</tr><?php
break;
...
} //end switch
...
} //end output_fields function
public static function save_fields( $options ) {
...
switch ( $option['type'] ) {
...
case 'productcategory':
$value = array_filter( array_map( 'wc_clean', (array) $raw_value ) );
break;
...
}
...
} //end save_fields function
...
} //end class
?>
thanks for advise.
There's a do_action as the default case in the switch statement. Meaning, that if nothing has matched yet in the core code it will see if anything is attached to the action hook. Similarly, you can sanitize via the woocommerce_admin_settings_sanitize_option_$option_name filter
Therefore, here's my best guess:
// handle output of new settings type
add_action( 'woocommerce_admin_field_productcategory', 'output_productcategory_fields' );
function output_productcategory_fields( $value ) {
$option_value = (array) WC_Admin_Settings::get_option( $value['id'] );
?><tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
<?php echo $tooltip_html; ?>
</th>
<td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
<fieldset>
<ul class="" style="margin:0; padding:0;">
<?php
$args = array(
'orderby' => 'name',
'hide_empty'=> 0,
'taxonomy' => 'product_cat'
);
$all_categories = get_categories( $args );
$index = 0;
$count = count($all_categories);
$numItemsPerRow = ceil($count / 2);
$numItemsOffsetFix = $count % 2 == 1;
echo '<div class="columns" style="width:auto; display:inline-block; height:auto; float:left; padding:0; margin:0 25px 0 0;">';
foreach ($all_categories as $key => $val) {
if ($index > 0 and $index % $numItemsPerRow == 0) {
echo '</div><div class="columns">';
if ($numItemsOffsetFix) {
$numItemsPerRow--;
$numItemsOffsetFix = false;
}
}
//foreach ( $value['options'] as $key => $val ) {
?>
<li style="">
<label><input type="checkbox"
name="<?php echo esc_attr( $value['id'] ); ?>[]"
id="<?php echo esc_attr( $val->term_id )?>"
value="<?php echo esc_attr( $val->term_id )?>"
<?php
if ( in_array( $val->term_id,$option_value ) ) {
echo ' checked="checked"';
}
?>
/> <?php echo $val->name; ?>
</label>
</li>
<?php
$index++;
}
?>
</ul>
</fieldset>
<fieldset>
<?php echo $description; ?>
</fieldset>
</td>
</tr><?php
}
// sanitize data for new settings type
add_filter( 'woocommerce_admin_settings_sanitize_option_productcategory', 'sanitize_productcategory_option', 10, 3 );
function sanitize_productcategory_option( $value, $option, $raw_value ){
$value = array_filter( array_map( 'wc_clean', (array) $raw_value ) );
return $value;
}

Add custom fields to nav-menu item

I am trying to add custom data to my menu items (say, for example, data-* attributes) or a dropdown to select the link target, etc.
Through the Screen Options, we have Link Target, Title Attribute, CSS Classes, Link Relationship (XFN) and Description (see screenshot below), but none really offer what I want.
I thought of looking for extensions to Advanced Custom Fields, or something of the sort, but I have not seen anything like it, nor anything through my theme functions.php file.
I finally found a good tutorial with lots of details and explanations as to how to achieve this. The article explains how the WordPress plugin Sweet Custom Menu works, and I've been able to add the functionality to my current theme.
As of today, the plugin hasn't been updated in over two years, but it still does what is expected of it.
You can try Carbon Fields Framework. It provides a custom fields for menu items.
Even if you are using ACF (Advanced Custom Fields) plugin, you still can add the plugin since both can work together.
add_filter( 'wp_edit_nav_menu_walker', 'custom_nav_edit_walker',10,2 );
function custom_nav_edit_walker($walker,$menu_id) {
return 'Walker_Nav_Menu_Edit_Custom';
}
/*
* Saves new field navmenu
*/
add_action('wp_update_nav_menu_item', 'custom_nav_update',10, 3);
function custom_nav_update($menu_id, $menu_item_db_id, $args ) {
if ( is_array($_REQUEST['menu-item-custom']) ) {
$custom_value = $_REQUEST['menu-item-custom'][$menu_item_db_id];
update_post_meta( $menu_item_db_id, '_menu_item_custom', $custom_value );
}
}
/*
* Adds value of new field to Navmenu
*/
add_filter( 'wp_setup_nav_menu_item','custom_nav_item' );
function custom_nav_item($menu_item) {
$menu_item->custom = get_post_meta( $menu_item->ID, '_menu_item_custom', true );
return $menu_item;
}
class Walker_Nav_Menu_Edit_Custom extends Walker_Nav_Menu {
function start_lvl( &$output, $depth = 0, $args = array() ) {}
/**
* Ends the list of after the elements are added.
*
* #see Walker_Nav_Menu::end_lvl()
*
* #since 3.0.0
*
* #param string $output Passed by reference.
* #param int $depth Depth of menu item. Used for padding.
* #param array $args Not used.
*/
function end_lvl( &$output, $depth = 0, $args = array() ) {}
/**
* Start the element output.
*
* #see Walker_Nav_Menu::start_el()
* #since 3.0.0
*
* #global int $_wp_nav_menu_max_depth
*
* #param string $output Used to append additional content (passed by reference).
* #param object $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
* #param array $args Not used.
* #param int $id Not used.
*/
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
global $_wp_nav_menu_max_depth;
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
ob_start();
$item_id = esc_attr( $item->ID );
$removed_args = array(
'action',
'customlink-tab',
'edit-menu-item',
'menu-item',
'page-tab',
'_wpnonce',
);
$original_title = false;
if ( 'taxonomy' == $item->type ) {
$original_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' );
if ( is_wp_error( $original_title ) ) {
$original_title = false;
}
} elseif ( 'post_type' == $item->type ) {
$original_object = get_post( $item->object_id );
$original_title = get_the_title( $original_object->ID );
} elseif ( 'post_type_archive' == $item->type ) {
$original_object = get_post_type_object( $item->object );
if ( $original_object ) {
$original_title = $original_object->labels->archives;
}
}
$classes = array(
'menu-item menu-item-depth-' . $depth,
'menu-item-' . esc_attr( $item->object ),
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive' ),
);
$title = $item->title;
if ( ! empty( $item->_invalid ) ) {
$classes[] = 'menu-item-invalid';
/* translators: %s: title of menu item which is invalid */
$title = sprintf( __( '%s (Invalid)' ), $item->title );
} elseif ( isset( $item->post_status ) && 'draft' == $item->post_status ) {
$classes[] = 'pending';
/* translators: %s: title of menu item in draft status */
$title = sprintf( __( '%s (Pending)' ), $item->title );
}
$title = ( ! isset( $item->label ) || '' == $item->label ) ? $title : $item->label;
$submenu_text = '';
if ( 0 == $depth ) {
$submenu_text = 'style="display: none;"';
}
?>
<li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode( ' ', $classes ); ?>">
<div class="menu-item-bar">
<div class="menu-item-handle">
<span class="item-title"><span class="menu-item-title"><?php echo esc_html( $title ); ?></span> <span class="is-submenu" <?php echo $submenu_text; ?>><?php _e( 'sub item' ); ?></span></span>
<span class="item-controls">
<span class="item-type"><?php echo esc_html( $item->type_label ); ?></span>
<span class="item-order hide-if-js">
<a href="
<?php
echo wp_nonce_url(
add_query_arg(
array(
'action' => 'move-up-menu-item',
'menu-item' => $item_id,
),
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>
" class="item-move-up" aria-label="<?php esc_attr_e( 'Move up' ); ?>">↑</a>
|
<a href="
<?php
echo wp_nonce_url(
add_query_arg(
array(
'action' => 'move-down-menu-item',
'menu-item' => $item_id,
),
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
),
'move-menu_item'
);
?>
" class="item-move-down" aria-label="<?php esc_attr_e( 'Move down' ); ?>">↓</a>
</span>
<a class="item-edit" id="edit-<?php echo $item_id; ?>" href="
<?php
echo ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? admin_url( 'nav-menus.php' ) : add_query_arg( 'edit-menu-item', $item_id, remove_query_arg( $removed_args, admin_url( 'nav-menus.php#menu-item-settings-' . $item_id ) ) );
?>
" aria-label="<?php esc_attr_e( 'Edit menu item' ); ?>"><span class="screen-reader-text"><?php _e( 'Edit' ); ?></span></a>
</span>
</div>
</div>
<div class="menu-item-settings wp-clearfix" id="menu-item-settings-<?php echo $item_id; ?>">
<?php if ( 'custom' == $item->type ) : ?>
<p class="field-url description description-wide">
<label for="edit-menu-item-url-<?php echo $item_id; ?>">
<?php _e( 'URL' ); ?><br />
<input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->url ); ?>" />
</label>
</p>
<?php endif; ?>
<p class="description description-wide">
<label for="edit-menu-item-title-<?php echo $item_id; ?>">
<?php _e( 'Navigation Label' ); ?><br />
<input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->title ); ?>" />
</label>
</p>
<p class="field-title-attribute field-attr-title description description-wide">
<label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
<?php _e( 'Title Attribute' ); ?><br />
<input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->post_excerpt ); ?>" />
</label>
</p>
<p class="field-link-target description">
<label for="edit-menu-item-target-<?php echo $item_id; ?>">
<input type="checkbox" id="edit-menu-item-target-<?php echo $item_id; ?>" value="_blank" name="menu-item-target[<?php echo $item_id; ?>]"<?php checked( $item->target, '_blank' ); ?> />
<?php _e( 'Open link in a new tab' ); ?>
</label>
</p>
<p class="field-css-classes description description-thin">
<label for="edit-menu-item-classes-<?php echo $item_id; ?>">
<?php _e( 'CSS Classes (optional)' ); ?><br />
<input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( implode( ' ', $item->classes ) ); ?>" />
</label>
</p>
<p class="field-xfn description description-thin">
<label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
<?php _e( 'Link Relationship (XFN)' ); ?><br />
<input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->xfn ); ?>" />
</label>
</p>
<p class="field-description description description-wide">
<label for="edit-menu-item-description-<?php echo $item_id; ?>">
<?php _e( 'Description' ); ?><br />
<textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $item->description ); // textarea_escaped ?></textarea>
<span class="description"><?php _e( 'The description will be displayed in the menu if the current theme supports it.' ); ?></span>
</label>
</p>
<p class="field-custom description description-wide">
<label for="edit-menu-item-custom-<?php echo $item_id; ?>">
<?php _e( 'Custom' ); ?><br />
<input type="text" id="edit-menu-item-custom-<?php echo $item_id; ?>" class="widefat code edit-menu-item-custom" name="menu-item-custom[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->custom ); ?>" />
</label>
</p>
<fieldset class="field-move hide-if-no-js description description-wide">
<span class="field-move-visual-label" aria-hidden="true"><?php _e( 'Move' ); ?></span>
<button type="button" class="button-link menus-move menus-move-up" data-dir="up"><?php _e( 'Up one' ); ?></button>
<button type="button" class="button-link menus-move menus-move-down" data-dir="down"><?php _e( 'Down one' ); ?></button>
<button type="button" class="button-link menus-move menus-move-left" data-dir="left"></button>
<button type="button" class="button-link menus-move menus-move-right" data-dir="right"></button>
<button type="button" class="button-link menus-move menus-move-top" data-dir="top"><?php _e( 'To the top' ); ?></button>
</fieldset>
<div class="menu-item-actions description-wide submitbox">
<?php if ( 'custom' != $item->type && $original_title !== false ) : ?>
<p class="link-to-original">
<?php
/* translators: %s: original title */
printf( __( 'Original: %s' ), '' . esc_html( $original_title ) . '' );
?>
</p>
<?php endif; ?>
<a class="item-delete submitdelete deletion" id="delete-<?php echo $item_id; ?>" href="
<?php
echo wp_nonce_url(
add_query_arg(
array(
'action' => 'delete-menu-item',
'menu-item' => $item_id,
),
admin_url( 'nav-menus.php' )
),
'delete-menu_item_' . $item_id
);
?>
"><?php _e( 'Remove' ); ?></a> <span class="meta-sep hide-if-no-js"> | </span> <a class="item-cancel submitcancel hide-if-no-js" id="cancel-<?php echo $item_id; ?>" href="
<?php
echo esc_url(
add_query_arg(
array(
'edit-menu-item' => $item_id,
'cancel' => time(),
),
admin_url( 'nav-menus.php' )
)
);
?>
#menu-item-settings-<?php echo $item_id; ?>"><?php _e( 'Cancel' ); ?></a>
</div>
<input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
<input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object_id ); ?>" />
<input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->object ); ?>" />
<input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_item_parent ); ?>" />
<input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->menu_order ); ?>" />
<input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item->type ); ?>" />
</div><!-- .menu-item-settings-->
<ul class="menu-item-transport"></ul>
<?php
$output .= ob_get_clean();
}
}

Resources