Instantly share code, notes, and snippets.
Created
August 5, 2016 10:23
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save rahulsprajapati/72bab405f29ed7b7b1ad19d4328d3073 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Created by PhpStorm. | |
* User: rahul | |
* Date: 5/8/16 | |
* Time: 3:16 PM | |
* | |
* @ref https://gist.github.com/kucrut/3804376 | |
*/ | |
require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; | |
class Nav_Menu_Item_Meta_Fields { | |
/** | |
* @var array $options Fields templates for meta box of menu items | |
*/ | |
static $options = array( | |
'item_tpl' => '<p class="nav-country-meta-field-{name} description description-wide"> | |
<label for="edit-menu-item-{name}-{id}">{label}<br> | |
{tpl_type} | |
</label> | |
</p>', | |
'select_tpl' => '<select name="menu-item-{name}[{id}]" class="widefat"> | |
<option value="">--Select--</option> | |
{options} | |
</select>', | |
'input_tpl' => '<input | |
type="{field_type}" | |
id="edit-menu-item-{name}-{id}" | |
class="widefat edit-menu-item-{name}" | |
name="menu-item-{name}[{id}]" | |
value="{value}">', | |
); | |
/** | |
* Setup all meta fields from $options['fields'] for nav menu items. | |
*/ | |
static function setup() { | |
if ( ! is_admin() ) { | |
return; | |
} | |
$meta_fields = apply_filters( 'nav_menu_item_meta_fields', array() ); | |
if ( empty($meta_fields) ) | |
return; | |
self::$options['fields'] = $meta_fields; | |
add_filter( 'wp_edit_nav_menu_walker', function () { | |
return 'Custom_Fields_Walker_Nav_Menu_Edit'; | |
} ); | |
add_action( 'save_post', array( __CLASS__, '_save_post' ), 10, 2 ); | |
} | |
/** | |
* @param string $name Meta field name | |
* | |
* @return string Nav Menu Item metabox-key ( post-meta key ) | |
*/ | |
static function get_menu_item_postmeta_key($name) { | |
return '_menu_item_' . $name; | |
} | |
/** | |
* @param object $item Menu item data object. | |
* | |
* @return string | |
*/ | |
static function get_field( $item ) { | |
$meta_fields = ''; | |
foreach( self::$options['fields'] as $field ) { | |
$field['value'] = get_post_meta($item->ID, self::get_menu_item_postmeta_key($field['name']), true); | |
$field['id'] = $item->ID; | |
$item_tpl_key = "item_tpl"; | |
$item_field_tpl_key = "input_tpl"; | |
if ( $field[ "field_type" ] == "select" ) { | |
$item_field_tpl_key = "select_tpl"; | |
} | |
$field_tpl = str_replace( | |
'{tpl_type}', | |
self::$options[$item_field_tpl_key], | |
self::$options[$item_tpl_key] | |
); | |
if ( isset( $field[ 'options' ] ) && ! empty( $field[ 'options' ] ) && is_array( $field[ 'options' ] ) ) { | |
$options = ""; | |
foreach ( $field['options'] as $val => $name ) { | |
$selected = ""; | |
if( $field["value"] == $val ) { | |
$selected = "selected=selected"; | |
} | |
$options .= "<option value=$val $selected>$name</option>"; | |
} | |
$field['options'] = $options; | |
} | |
$meta_fields .= str_replace( | |
array_map(function($key){ return '{' . $key . '}'; }, array_keys($field)), | |
array_values(array_map('esc_attr', $field)), | |
$field_tpl | |
); | |
} | |
return html_entity_decode( $meta_fields ); | |
} | |
/** | |
* Save the newly submitted fields | |
* | |
* @hook {action} save_post | |
* | |
* @param int $post_id Menu item id | |
* @param object $post Menu item data object. | |
* | |
* @return mixed | |
*/ | |
static function _save_post( $post_id, $post ) { | |
if ( $post->post_type !== 'nav_menu_item' ) { | |
return $post_id; | |
} | |
foreach( self::$options['fields'] as $field_schema ) { | |
$form_field_name = 'menu-item-' . $field_schema['name']; | |
// @todo FALSE should always be used as the default $value, otherwise we wouldn't be able to clear checkboxes | |
if (isset($_POST[$form_field_name][$post_id])) { | |
$key = self::get_menu_item_postmeta_key($field_schema['name']); | |
$value = stripslashes($_POST[$form_field_name][$post_id]); | |
update_post_meta($post_id, $key, $value); | |
} | |
} | |
} | |
} | |
add_action( 'init', array( 'Nav_Menu_Item_Meta_Fields', 'setup' ) ); | |
class Custom_Fields_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit { | |
/** | |
* Start the element output. | |
* | |
* @ref wp-admin/includes/class-walker-nav-menu-edit.php | |
* | |
* @see Walker_Nav_Menu::start_el() | |
* | |
* | |
* @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. Used for padding. | |
* @param array $args Not used. | |
* @param int $id Not used. | |
*/ | |
function start_el( &$output, $item, $depth, $args, $id = 0 ) { | |
$item_output = ''; | |
parent::start_el( $item_output, $item, $depth, $args, $id ); | |
if ( $meta_fields = Nav_Menu_Item_Meta_Fields::get_field( $item ) ) { | |
// Inject $new_fields before: <div class="menu-item-actions description-wide submitbox"> | |
$item_output = preg_replace( '/(?=<div[^>]+class="[^"]*submitbox)/', $meta_fields, $item_output ); | |
} | |
$output .= $item_output; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add fields using this filter