I am developing a simple plugin based custom post type. The post type is registered fine. Now I want to create some meta boxes and pass a few property values via callback arguments. This is what I tried:
function wpcd_add_dealer_meta_boxes() {
add_meta_box(
'dealer_first_name',
'First Name',
array($this, 'wpcd_meta_box_first_name_markup'),
'dealers',
'normal',
'default',
array(
'id' => 'first_name',
'name' => 'first_name',
'type' => 'text',
'placeholder' => 'Enter first name',
'maxlength' => '30',
'spellcheck' => 'true',
'autocomplete' => 'off'
)
);
}
And here is my callback function with an argument:
function wpcd_meta_box_first_name_markup($args) {
$html = '<input ';
$html.= 'type="' . $args->type . '" ';
$html.= 'id="' .$args->id . '" ';
$html.= 'name="' .$args->name . '" ';
if( isset($args->required) && ($args->required == 'true' || $args->required == '1' ) ) {
$html.= 'required ';
}
if( isset($args->placeholder) && $args->placeholder != '' ) {
$html.= 'placeholder="' . esc_attr( $args->placeholder ) . '" ';
}
if( isset($args->maxlength) ) {
$html.= 'maxlength="' . $args->maxlength . '" ';
}
if( isset($args->spellcheck) && ($args->spellcheck == 'true' ) ) {
$html.= 'spellcheck="' . $args->spellcheck . '" ';
}
if( isset($args->autocomplete) && ($args->autocomplete == 'on' ) ) {
$html.= 'autocomplete="' . $args->autocomplete . '" ';
}
$html.= '/>';
echo $html;
}
But I cannot get the values like $args->id, $args->name etc inside the function. To be precise, all the values are empty, where I did not check if(isset(...)). And where I did those are simply ignored.
With my above code I am expecting the following markup as output:
<input type="text" id="first_name" name="last_name" required placeholder="Enter firstname" maxlength="30" autocomplete="off" spellcheck="true" />
while the actual output is
<input type="" id="" name="" />
Attributes type, id and name are not wrapped inside an if(isset()) block so they are being generated (with empty values) and whatever is wrapped inside if(isset()) block, are simply being ignored, as if they are not set at all!
What I am missing or doing wrong?
Any suggestion would be a life saver for me.
If you check the documentation for add_meta_box() carefully, you'll see:
($callback_args (array) (Optional) Data that should be set as the
$args property of the box array (which is the second parameter passed
to your callback).
The first parameter passed to your callback is a WP_Post object. The second is your parameter array. So, try:
function wpcd_meta_box_first_name_markup($post, $args) { ...
And then access your arguments as you'd expect:
$args['type']
Related
How can I create a code which would search by slug(category name) but not by ID. How can I create a customized solution for my client for search within a specific category (without any plugins)?
Explain: I want the code of search to be customized in such a way that the client could search within a specific category without editing any code. Thanks!
is it's still actually, you should to check this tutorial where an author gives a very detailed explanation about the Search function customization.
One of the most interesting parts for a necessary your case:
// meta_query expects nested arrays even if you only have one query
$sm_query = new WP_Query( array( 'post_type' => 'accommodation', 'posts_per_page' => '-1', 'meta_query' => array( array( 'key' => '_sm_accommodation_city' ) ) ) );
// The Loop
if ( $sm_query->have_posts() ) {
$cities = array();
while ( $sm_query->have_posts() ) {
$sm_query->the_post();
$city = get_post_meta( get_the_ID(), '_sm_accommodation_city', true );
// populate an array of all occurrences (non duplicated)
if( !in_array( $city, $cities ) ){
$cities[] = $city;
}
}
}
} else{
echo 'No accommodations yet!';
return;
}
/* Restore original Post Data */
wp_reset_postdata();
if( count($cities) == 0){
return;
}
asort($cities);
$select_city = '<select name="city" style="width: 100%">';
$select_city .= '<option value="" selected="selected">' . __( 'Select city', 'smashing_plugin' ) . '</option>';
foreach ($cities as $city ) {
$select_city .= '<option value="' . $city . '">' . $city . '</option>';
}
$select_city .= '</select>' . "\n";
reset($cities);
hi guys i want to hide a part of shortcode when an attribute value like closebutton is 0.
this is the code that i use
function atalertshortcode($atts, $content = null) {
extract(shortcode_atts(array(
"class" => '',"text" => '',"size" => '',"closebutton" => '',"other" => ''
), $atts));
return '<div class="uk-alert '.$class.' '.$size.'" data-uk-alert="" '.$other.'> '.$text.' </div>';}
i want to hide this part of shortcode when closebutton value is 0
please help me
Here you go:
function atalertshortcode($atts, $content = null) {
extract(shortcode_atts(array(
"class" => '',
"text" => '',
"size" => '',
"closebutton" => '',
"other" => '',
), $atts));
$output = '<div class="uk-alert ' . $class . ' ' . $size . '" data-uk-alert="" ' . $other . '>';
if ($closebutton) {
$output .= '';
}
$output .= ' ' . $text . '</div>';
return $output;
}
This basically requires you to separate the output in several pieces, and wrap the optional portion in an IF block to check the required condition (in this case we're checking if $closebutton does not evaluate to 0 in any way, and if it doesn't, the link is added to the shortcode output).
I'm going to break my brain..
I've created a new metabox for my custom post type "book".
I'm using a lot of different type of fields like input text, checkbox, select, textarea, taxonomy select and repeatable and everything work great!
But now I'd like to do a more difficult step..
Is it possible to do a repeatable field with 2 fields inside it?
I would like have a select and an input text near it.. inside the select admin can choose the shop (es. Ibs or Amazon) and in the input field he can write the url for sell the book.
This is my code:
/* META Book */
function add_mycustom_meta_box() {
add_meta_box(
'custom_meta_box',
'Info book',
'show_custom_meta_box', // $callback
'product',
'normal',
'high');
}
// Field Array
$prefix = 'custom_';
$custom_meta_fields = array(
array(
'label' => 'Link vendita',
'desc' => 'Inserisci l url dei siti esterni',
'id' => $prefix.'repeatable',
'type' => 'repeatable',
'options' => array(
'amazon' => array(
'label' => 'Amazon',
'value' => 'amazon'
),
'ibs' => array(
'label' => 'Ibs',
'value' => 'ibs'
)
)
)
);
// Callback
function show_custom_meta_box() {
global $custom_meta_fields, $post;
// Use nonce for verification
echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Build metabox
echo '<table class="form-table">';
foreach ($custom_meta_fields as $field) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true);
// begin a table row with
echo '<tr>
<th><label for="'.$field['id'].'">'.$field['label'].'</label></th>
<td>';
switch($field['type']) {
// if repeatable
case 'repeatable':
echo '<a class="repeatable-add button" href="#">+</a>
<ul id="'.$field['id'].'-repeatable" class="custom_repeatable">';
$i = 0;
if ($meta) {
foreach($meta as $row) {
echo '<li><span class="sort hndle">|||</span>';
// Select ibis or amazon
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $row == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select>';
// end select
echo '<input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="'.$row.'" size="30" data-shop="'.$option.'" />
<a class="repeatable-remove button" href="#">-</a></li>';
$i++;
}
} else {
echo '<li><span class="sort hndle">|||</span>';
// Select ibis o amazon
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $row == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select>';
// Fine select
echo '<input type="text" name="'.$field['id'].'['.$i.']" id="'.$field['id'].'" value="" size="30" />
<a class="repeatable-remove button" href="#">-</a></li>';
}
echo '</ul>
<span class="description">'.$field['desc'].'</span>';
break;
} //end switch
echo '</td></tr>';
} // end foreach
echo '</table>';
}
// Save the Data
function save_custom_meta($post_id) {
global $custom_meta_fields;
// verify nonce
if (!wp_verify_nonce($_POST['custom_meta_box_nonce'], basename(__FILE__)))
return $post_id;
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// check permissions
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id))
return $post_id;
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
// loop through fields and save the data
foreach ($custom_meta_fields as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
} // end foreach
}
add_action('save_post', 'save_custom_meta');
The repeatable field generate an array and it is ok, but what I can do to store the select value also?
Hope someone can help me
Thanks
I'm sure you can put in dynamic fields into custom Metaboxes inside the edit screen of any post type.
I build this for the Language Field Plugin into the admin page on http://wordpress.org/plugins/language-field/
I was relying on this example
http://www.mustbebuilt.co.uk/2012/07/27/adding-form-fields-dynamically-with-jquery/
Generally take these steps
Add custom Meta box with this example
http://codex.wordpress.org/Function_Reference/add_meta_box#Examples
when it comes to these lines
$mydata = sanitize_text_field( $_POST['myplugin_new_field'] );
// Update the meta field in the database.
update_post_meta( $post_id, '_my_meta_value_key', $mydata );
loop thru the fields created with example above.
I want to show a additional column in the backend of WooCommerce (in Orders overview).
The column should contain a custom field, which i have defined (delivery date).
How to do this?
In case someone still needs it - instructions on how to add new columns in Woocommerce orders list. No need in unsetting the default columns, just add this in your functions.php and your code will be valid for updates.
1. Define columns position and names
add_filter( 'manage_edit-shop_order_columns', 'MY_COLUMNS_FUNCTION' );
function MY_COLUMNS_FUNCTION($columns){
$new_columns = (is_array($columns)) ? $columns : array();
unset( $new_columns['order_actions'] );
//edit this for you column(s)
//all of your columns will be added before the actions column
$new_columns['MY_COLUMN_ID_1'] = 'MY_COLUMN_1_TITLE';
$new_columns['MY_COLUMN_ID_2'] = 'MY_COLUMN_2_TITLE';
//stop editing
$new_columns['order_actions'] = $columns['order_actions'];
return $new_columns;
}
2. For each custom column, show the values
add_action( 'manage_shop_order_posts_custom_column', 'MY_COLUMNS_VALUES_FUNCTION', 2 );
function MY_COLUMNS_VALUES_FUNCTION($column){
global $post;
$data = get_post_meta( $post->ID );
//start editing, I was saving my fields for the orders as custom post meta
//if you did the same, follow this code
if ( $column == 'MY_COLUMN_ID_1' ) {
echo (isset($data['MY_COLUMN_1_POST_META_ID']) ? $data['MY_COLUMN_1_POST_META_ID'] : '');
}
if ( $column == 'MY_COLUMN_ID_2' ) {
echo (isset($data['MY_COLUMN_2_POST_META_ID']) ? $data['MY_COLUMN_2_POST_META_ID'] : '');
}
//stop editing
}
3. (optional) Function to make the columns sortable
add_filter( "manage_edit-shop_order_sortable_columns", 'MY_COLUMNS_SORT_FUNCTION' );
function MY_COLUMNS_SORT_FUNCTION( $columns ) {
$custom = array(
//start editing
'MY_COLUMN_ID_1' => 'MY_COLUMN_1_POST_META_ID',
'MY_COLUMN_ID_2' => 'MY_COLUMN_2_POST_META_ID'
//stop editing
);
return wp_parse_args( $custom, $columns );
}
To add new column coupon in woo-commerce order table and get all coupon code according to order. you need to copy and paste in you function.php.
add_filter('manage_edit-shop_order_columns', 'custom_shop_order_column', 11);
function custom_shop_order_column($columns) {
//add columns
$columns['my-column1'] = __('Coupons Code', 'theme_slug');
return $columns;
}
// adding the data for each orders by column (example)
add_action('manage_shop_order_posts_custom_column', 'cbsp_credit_details', 10, 2);
function cbsp_credit_details($column) {
global $post, $woocommerce, $the_order;
$order_id = $the_order->id;
switch ($column) {
case 'my-column1' :
// $myVarOne = wc_get_order_item_meta( $order_id, 15, true );
if ($the_order->get_used_coupons()) {
$coupons_count = count($the_order->get_used_coupons());
foreach ($the_order->get_used_coupons() as $coupon) {
echo $coupon;
$i++;
}
echo '</p>';
}
// echo $myVarOne;
break;
}
}
Try this, you will get your solution just write below code on your function.php file.
add_filter( 'manage_edit-shop_order_columns','your_function_name',10 );
function your_function_name($columns){
$columns['delivery_date'] = __('Delivery date','textdomain');
return $columns;
}
add_action( 'manage_shop_order_posts_custom_column','your_other_function_name',20 );
function your_other_function_name($column)
{
swith($column)
{
case 'delivery_date': // your custom code here and do what you want.
}
}
The following works for WooCommerce 2.6.2.
You should look into two new hooks:
woocommerce_admin_order_item_headers, invoked once when orders table header is generated
woocommerce_admin_order_item_values, invoked once per every item inside the order
1. Define columns headers
add_filter('woocommerce_admin_order_item_headers', 'so13683162_headers');
function so13683162_headers($order) {
echo "<th>FIELD1</th>";
}
2. Populate values in rows
add_filter('woocommerce_admin_order_item_values', 'so13683162_values');
function so13683162_values($product) {
if (isset($product -> id)) {
$attrs = get_post_meta($product -> id, "_product_attributes", true);
echo "<td>" . $attrs["FIELD1"]["value"] . "</td>";
}
}
I came across Woocommerce now. Have added a custom field Personal Registration Number - and now wanted it to be displayed in the Order overview page.
I've manage to add the column - but still couldn't get the value of the custom field for each order.
Here is what I did:
// Removed Existing Order Page collumns
remove_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
// Added My own filter to Show the PRN - Personal Registration field
add_filter('manage_edit-shop_order_columns', 'omak_edit_order_columns');
// The omak_edit_order_columns definition
/*** Taken from admin/post_types/shop_order.php ***/
function omak_edit_order_columns($columns){
global $woocommerce;
$columns = array();
$columns["cb"] = "<input type=\"checkbox\" />";
$columns["order_status"] = __( 'Status', 'woocommerce' );
$columns["order_title"] = __( 'Order', 'woocommerce' );
$columns["order_prn"] = __( 'PRN', 'woocommerce' ); // This is the line which added the column after the Title Column
$columns["billing_address"] = __( 'Billing', 'woocommerce' );
$columns["shipping_address"] = __( 'Shipping', 'woocommerce' );
$columns["total_cost"] = __( 'Order Total', 'woocommerce' );
$columns["order_comments"] = '<img alt="' . esc_attr__( 'Order Notes', 'woocommerce' ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/order-notes_head.png" class="tips" data-tip="' . __( 'Order Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["note"] = '<img src="' . $woocommerce->plugin_url() . '/assets/images/note_head.png" alt="' . __( 'Customer Notes', 'woocommerce' ) . '" class="tips" data-tip="' . __( 'Customer Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["order_date"] = __( 'Date', 'woocommerce' );
$columns["order_actions"] = __( 'Actions', 'woocommerce' );
return $columns;
}
Let me know if it helps you...
I am left to deal with how to get its values for each Order.
As commented: the function definition exists in shop_order.php in WooCommerce plugin.
Let me know if anybody sorts it out.. or knows how to do it.
Thanks,
(sorry, was busy in something so couldn't read back to check for errors)
I want to add title="icons/icon_cart.gif" for each of the below options in my select list which is rendered using views.
After trying and reading many articles I can't seem to find the way to add this html into my form.
Below is my code.
function customchatter_form_alter(&$form, &$form_state, $form_id) {
$form["tid"]["#options"][1]=t("nooo chatter");
// this works to change the label of the option but how do I add title="icons/icon-
cart.gif" ?
}
My html code:
<select id="edit-tid" name="tid" class="form-select">
<option value="All">- Any -</option>
<option value="1">nooo chatter</option>
<option value="2">Complaints Complaints</option>
<option value="3">Gear & Gadgets</option>
</select>
Cheers,
Vishal
UPDATE
I tried to update the code as per Clive's advice but the values are still not coming up right. Below is my story.
So below is the html output I am able to achieve but the title always seems to be the number 1.
<select id="edit-select" class="form-select" name="select">
<option value="1" title="1">One</option>
<option value="2" title="1">Two</option>
</select>
As you can see title is there but the value is wrong. Below is my form and the functions which I wrote.
My form:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#title' => array(1 => 'One', 2 => 'Two')
// I tried many combinations but nothing seems to work.
);
My Theme functions.
function kt_vusers_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' .
kt_vusers_form_select_options($element) . '</select>';
}
function kt_vusers_form_select_options($element, $choices = NULL) {
if (!isset($choices)) {
$choices = $element['#options'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
// #vishal so there I have declared the variable to accept the values.
$vtitle = isset($element['#title']) || array_key_exists('#title', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
foreach ($choices as $key => $choice) {
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= form_select_options($element, $choice);
$options .= '</optgroup>';
}
elseif (is_object($choice)) {
$options .= form_select_options($element, $choice->option);
}
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// #vishal this is where the variable is being used.
$options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' . $selected .
'>' . check_plain($choice) . '</option>';
}
}
return $options;
}
below is the correct code for the last theme function
function kt_vusers_form_select_options($element, $choices = NULL, $vtitles=NULL) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
if (!isset($choices)) {
$choices = $element['#options'];
$vtitles = array();
$vtitles = $element['#title'];
}
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
// isset() fails in this situation.
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
$value_is_array = $value_valid && is_array($element['#value']);
$options = '';
// print_r($vtitles);
while
(
(list($key, $choice) = each($choices))
&& (list($keytwo, $vtitle) = each($vtitles))
)
{
// printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
if (is_array($choice)) {
$options .= '<optgroup label="' . $key . '">';
$options .= kt_vusers_form_select_options($element, $choice);
$i++;
// $options .= form_select_options($element, $vtitle);
$options .= '</optgroup>';
} // end if if is_array
elseif(is_object($choice)) {
$options .= form_select_options($element, $choice->option);
} // end of else if
else {
$key = (string) $key;
if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key ||
($value_is_array && in_array($key, $element['#value'])))) {
$selected = ' selected="selected"';
}
else {
$selected = '';
}
// $options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' .
$selected . '>' . check_plain($choice) . '</option>';
}
$options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected
.'>'. check_plain($choice) .'</option>';
} // end of choice
return $options;
} // end of function
I'm afraid you're going to have to dig quite far down to do this, the #options array is flattened in form_select_options() and it doesn't currently include any way of adding attributes. This is the code:
$options .= '<option value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>';
As you can see there's simply no scope for attributes in there. You will be able to override this though, but it will involve implementing your own version of theme_select() and your own FAPI property.
I haven't got time to flesh the entire thing out but in your theme file you would be doing something like this:
function MYTHEME_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' . MYTHEME_form_select_options($element) . '</select>';
}
function MYTHEME_form_select_options($element) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
}
Refer to form_select_options for constructing MYTHEME_form_select_options
And your code in the form would be something like:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#extra_option_attributes' => array(
1 => array('title' => 'Test title'), // Attributes for option with key "1",
2 => array('title' => 'Test title'), // Attributes for option with key "2",
)
);
In MYTHEME_form_select_options() you can then inspect the element's #extra_option_attributes key (if one exists) to see if you need to physically add any more attributes in the HTML you create.
Hope that helps, I know it seems like a crazily long-winded way of doing what you need to but as far as I know it's the only way.
Tested
Try:
$form["tid"][1]['#attributes'] = array('title' => t('nooo chatter'));
instead of:
$form["tid"]['#options'][1]['#attributes'] = array('title' => t('nooo chatter'));
It is possible to add arbitrary attributes to elements this way. I discovered this after performing some tests based on this answer.
Also mentioned here and here.
Untested, but have you tried:
$form["tid"]["#options"][1]['#attributes'] = array('title' => t('YOUR NEW TITLE'));
You might need to mess around with the name of the element etc but the #attributes tag should work.
EDIT: As pointed out in Clive's answer, this won't work but I'll leave it up in case anyone wants to know how to add attributes to other fields (textboxes etc).