I have 2 custom post types named clients and casestudies. I'm trying to build a meta box on the clients post type that will have a drop down list featuring the titles of all posts from the casestudies post type. This will end up with a page displaying the featured image from the clients post type, then hyperlink off to the relevant casestudies post if a selection is made from the drop down list.
I have followed this tutorial to get a meta box put together: http://code.tutsplus.com/tutorials/how-to-create-custom-wordpress-writemeta-boxes--wp-20336
This is the meta box code I have in my functions.php file:
add_action( 'add_meta_boxes', 'cd_meta_box_add' );
function cd_meta_box_add()
{
add_meta_box( 'my-meta-box-id', 'My First Meta Box', 'cd_meta_box_cb', 'clients', 'side', 'default' );
}
function cd_meta_box_cb( $post )
{
$values = get_post_custom( $post->ID );
$selected = isset( $values['my_meta_box_select'] ) ? esc_attr( $values['my_meta_box_select'][0] ) : ”;
?>
<p>
<label for="my_meta_box_select">Select which case study this logo will link to when it is clicked:<br /><br /></label>
<select name="my_meta_box_select" id="my_meta_box_select" style="width:100%;">
<option value="No case study">No case study</option>
<?php
$casestudies = array( 'post_type' => 'casestudies', 'orderby' => 'title', 'order' => 'asc', );
$casestudiesloop = new WP_Query( $casestudies );
while ( $casestudiesloop->have_posts() ) : $casestudiesloop->the_post();
?> <option value="<?php the_title(); ?>" <?php selected( $selected, $casestudies['the_title'] ); ?> ><?php the_title(); ?></option>
<?php
endwhile;
?>
</select>
</p>
<?php
}
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
if( !current_user_can( 'edit_post', $post_id ) ) return;
if( isset( $_POST['my_meta_box_select'] ) )
update_post_meta( $post_id, 'my_meta_box_select', esc_attr( $_POST['my_meta_box_select'] ) );
}
The meta box displays correctly on the correct post type, but when I update the post it won't save the data.
Thanks.
You don't have nonce hidden field. Save function would return nothing.
<input type="hidden" name="meta_box_nonce" id="meta_box_nonce" value="<?php echo wp_create_nonce( 'my_meta_box_nonce' ); ?>" />
UPDATE:
So your cd_meta_box_cb function would be
<?php
function cd_meta_box_cb( $post )
{
$values = get_post_custom( $post->ID );
$selected = isset( $values['my_meta_box_select'] ) ? esc_attr( $values['my_meta_box_select'][0] ) : ”;
?>
<p>
<label for="my_meta_box_select">Select which case study this logo will link to when it is clicked:<br /><br /></label>
<select name="my_meta_box_select" id="my_meta_box_select" style="width:100%;">
<option value="No case study">No case study</option>
<?php
$casestudies = array( 'post_type' => 'casestudies', 'orderby' => 'title', 'order' => 'asc', );
$casestudiesloop = new WP_Query( $casestudies );
while ( $casestudiesloop->have_posts() ) : $casestudiesloop->the_post();
?> <option value="<?php the_title(); ?>" <?php selected( $selected, $casestudies['the_title'] ); ?> ><?php the_title(); ?></option>
<?php
endwhile;
?>
</select>
</p>
<input type="hidden" name="meta_box_nonce" id="meta_box_nonce" value="<?php echo wp_create_nonce( 'my_meta_box_nonce' ); ?>" />
<?php
}
?>
Related
I am developing a plugin where I need to display some custom select product. So far I can able to make the option field but how can i save them as option field with comma separated product ids like.
45,78,55,48,
here is an example of searchable multiple select option for WooCommerce product.
Here is my code
function crp_select_products() {
global $post, $woocommerce;
$product_ids = array();
?>
<div class="options_group">
<?php if ( $woocommerce->version >= '3.0' ) : ?>
<p class="form-field">
<label for="related_ids"><?php _e( 'Search Products', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="related_ids" name="related_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations">
<?php
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . wp_kses_post( $product->get_formatted_name() ) . '</option>';
}
}
?>
</select> <?php echo wc_help_tip( __( 'Select products are for sale product.', 'woocommerce' ) ); ?>
</p>
<?php endif; ?>
</div>
<?php
}
First, there is something missing in your function, to display the saved data in it.
After, this special field need to be displayed inside a form that will have a submit button. So it depends where you are using your function.
Here below is an example displaying that custom field as a custom product setting, save the data and display the saved data in it:
function crp_get_product_related_ids() {
global $post, $woocommerce;
$product_ids = get_post_meta( $post->ID, '_related_ids', true );
if( empty($product_ids) )
$product_ids = array();
?>
<div class="options_group">
<?php if ( $woocommerce->version >= '3.0' ) : ?>
<p class="form-field">
<label for="related_ids"><?php _e( 'Search Products', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="related_ids" name="related_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations">
<?php
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . wp_kses_post( $product->get_formatted_name() ) . '</option>';
}
}
?>
</select> <?php echo wc_help_tip( __( 'Select products are for sale product.', 'woocommerce' ) ); ?>
</p>
<?php endif; ?>
</div>
<?php
}
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_fied_in_product_general_fields', 20 );
function add_custom_fied_in_product_general_fields() {
global $post, $woocommerce;
crp_get_product_related_ids();
}
add_action( 'woocommerce_process_product_meta', 'process_product_meta_custom_fied', 20, 1 );
function process_product_meta_custom_fied( $product_id ){
if( isset( $_POST['crosssell_ids'] ) ){
update_post_meta( $product_id, '_related_ids', array_map( 'intval', (array) wp_unslash( $_POST['related_ids'] ) ) );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
i've been at this for a couple of evening now, i've tried many different solutions and would rather keep it PHP rather than a jQuery solution or AJAX, here's my code, for some reason the Select Dropdown just won't keep it's value, any advice would be amazing. Thanks in advance.
<?php
$taxonomy = 'accommodation_area';
$args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => true
);
$tax_terms = get_terms( $taxonomy, $args );
?>
<select name="<? echo $taxonomy ?>" id="<? echo $taxonomy ?>" class="postform">
<option>Choose Area</option>
<?php if($tax_terms): ?>
<?php foreach ($tax_terms as $tax_term): ?>
<option value="<?php echo $tax_term->slug; ?>" <?php if ( isset( $_POST[ $taxonomy ] ) && ( $_POST[ $taxonomy ] == $tax_term->slug ) ) echo "selected";?>><?php echo $tax_term->name; ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
im trying to make this work. its theme option page that list categories and allow you to do MULTIPLE select
but something is wrong and it not saving the values and in the end how can i show these selected categories in index?
here is what i found in web and sof
<?php
add_action( 'admin_init', 'theme_options_init' );
add_action( 'admin_menu', 'theme_options_add_page' );
function theme_options_init(){
register_setting( 'sample_options', 'sample_theme_options', 'theme_options_validate' );
}
function theme_options_add_page() {
add_theme_page( __( 'Theme Options', 'sampletheme' ), __( 'Theme Options', 'sampletheme' ), 'edit_theme_options', 'theme_options', 'theme_options_do_page' );
}
function theme_options_do_page() {
global $select_options, $radio_options;
if ( ! isset( $_REQUEST['settings-updated'] ) )
$_REQUEST['settings-updated'] = false;
?>
<div class="wrap">
<?php screen_icon(); echo "<h2>" . get_current_theme() . __( ' Theme Options', 'sampletheme' ) . "</h2>"; ?>
<?php if ( false !== $_REQUEST['settings-updated'] ) : ?>
<div class="updated fade"><p><strong><?php _e( 'Options saved', 'sampletheme' ); ?></strong></p></div>
<?php endif; ?>
<form method="post" action="options.php">
<?php settings_fields( 'sample_options' ); ?>
<?php $options = get_option( 'sample_theme_options' ); ?>
<select multiple="multiple" name="site_options[categorychoice][]">
<?php $option = get_option('site_options'); ?>
<?php
$args = array(
'orderby' => 'name',
'parent' => 0,
'exclude' => 1
);
$categories = get_categories( $args );
foreach ($categories as $category) { ?>
<?php $selected = in_array( $category->cat_ID, $option['categorychoice'] ) ? ' selected="selected" ' : ''; ?>
<option value="<?php echo $category->term_id; ?>" <?php echo $selected; ?> >
<?php echo $category->cat_name . ' (' . $category->category_count .')'; ?>
</option>
<?php } //endforeach ?>
</select>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e( 'Save Options', 'sampletheme' ); ?>" />
</p>
</form>
</div>
<?php
}
function theme_options_validate( $input ) {
global $select_options, $radio_options, $categories;
if ( ! array_key_exists( $input['categorychoice'], $categories ) )
$input['categorychoice'] = NULL;
return $input;
}
I'm trying to save data from dynamically generated checkboxes in Wordpress meta boxes. For now it almost works - but as you can see each checkbox has the same name and ID which is being used later on, so it cannot be like that.
This is how I create checkboxes:
<?php
$args = array( 'post_type' => 'teachers');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<label for="meta-checkbox-two">
<input type="checkbox" name="meta-checkbox-two" id="meta-checkbox-two" value="yes" <?php if ( isset ( $prfx_stored_meta['meta-checkbox-two'] ) ) checked( $prfx_stored_meta['meta-checkbox-two'][0], 'yes' ); ?> />
<?php the_title() ?>
</label>
<?php endwhile; ?>
And here's saving:
// Checks for input and saves
if( isset( $_POST[ 'meta-checkbox-two' ] ) ) {
update_post_meta( $post_id, 'meta-checkbox-two', 'yes' );
} else {
update_post_meta( $post_id, 'meta-checkbox-two', '' );
}
As I said it almost works - it saves everything called "meta-checkbox-two" - meaning everything, which is not the goal.
This is where I'm getting lost. I'm trying to make each name and ID end with the post ID that the loop is retrieving. Here's how the code looks then:
Generating checkboxes:
<?php
$args = array( 'post_type' => 'teachers');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<label for="meta-checkbox-two">
<input type="checkbox" name="meta-checkbox-<?php the_ID() ?>" id="meta-checkbox-<?php the_ID() ?>" value="yes" <?php if ( isset ( $prfx_stored_meta['meta-checkbox-' . the_ID()] ) ) checked( $prfx_stored_meta['meta-checkbox-'] . the_ID(), 'yes' ); ?> />
<?php the_title() ?>
</label>
<?php endwhile; ?>
Saving them:
$args = array( 'post_type' => 'teachers');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
// Checks for input and saves
if( isset( $_POST[ 'meta-checkbox-'.the_ID()] ) ) {
update_post_meta( $post_id, 'meta-checkbox-'.the_ID(), 'yes' );
} else {
update_post_meta( $post_id, 'meta-checkbox-'.the_ID(), '' );
}
endwhile;
But in the second case the data is not saved. What am I doing wrong?
Just try code below - not tested but should work - I just changed input name on array as you can see name="meta-checkbox-two[]" and that is the point also did unique input id like you did.
<?php
$args = array( 'post_type' => 'teachers');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
?>
<label for="meta-checkbox-two">
<input type="checkbox" name="meta-checkbox-two[]" id="meta-checkbox-two-<?php the_ID() ?>" value="yes" <?php if ( isset ( $prfx_stored_meta['meta-checkbox-two'] ) ) checked( $prfx_stored_meta['meta-checkbox-two'][0], 'yes' ); ?> />
<?php the_title() ?>
</label>
<?php
endwhile;
?>
What I'm trying to do is for a dual-language website. This particular language, Papiamento, isn't supported by Wordpress. Therefore, the client had to create two separate pages, in English and Pap. What I did was to code it like that to display English or Pap menu for each page.
Like this, in header.php:
<?php
if( is_page( array('salon-and-spa-pap', 'tocante-nos', 'testimonio', 'tuma-contacto-cu-nos', 'galeria', 'tratamentonan-di-masahe', 'tratamentonan-spa-di-curpa', 'servicionan-di-boda', 'tratamentonan-spa-di-cara', 'wowo-lip-nek', 'cuido-di-man', 'tratamento-di-huna', 'tratamento-di-huna-di-pia', 'cuido-di-pia', 'salon-p', 'spa-etiquette-pap', 'wax-p', 'reserva-un-tratamento')) ) {
wp_nav_menu(array( 'theme_location' => 'menu_top_pap' ) );
} else {
wp_nav_menu(array( 'theme_location' => 'secondary-menu' ) );
}
?>
However, the problem is that the client will have to keep going back to header.php to add another page slug every time she create a new page. Therefore, I created a Metabox plugin for that. I made a Metabox checkbox so that everytime a page is intended for Papiamento language, the client can just check the box and either the page id or slug will be added to the code above.
I found another question (https://wordpress.stackexchange.com/questions/71043/listing-pages-with-checkboxes-in-a-metabox-and-saving-them) that might be similar to what I was looking for but it didn't work for me.
Here's my metabox function based on this article (http://themefoundation.com/wordpress-meta-boxes-guide/).
<?php
function prfx_custom_meta() {
add_meta_box( 'prfx_meta', __( 'Papiamento Page Box', 'prfx-textdomain' ), 'prfx_meta_callback', 'page', 'normal', 'low' );
}
add_action( 'add_meta_boxes', 'prfx_custom_meta' );
function prfx_meta_callback( $post ) {
wp_nonce_field( basename( __FILE__ ), 'prfx_nonce' );
$prfx_stored_meta = get_post_meta( $post->ID );
$checkfield = maybe_unserialize( get_post_meta($post->ID, "checkfield", true) );
?>
<p>
<span class="prfx-row-title"><?php _e( 'Pap Checkbox', 'prfx-textdomain' )?></span>
<div class="prfx-row-content">
<label for="meta-checkbox">
<input type="checkbox" name="checkfield[]" id="page_<?php echo $page->ID; ?>" value="<?php echo $page->ID; ?>" <?php if ( in_array($page->ID, (array) $checkfield) ) { ?> checked <?php } ?>/> <label for="page_<?php echo $page->ID; ?>"><?php echo $page->post_title; ?>
<?php _e( 'Check if this page is Papiamento', 'prfx-textdomain' )?>
</label>
</div>
</p>
<?php
}
/**
* Saves the custom meta input
*/
function prfx_meta_save( $post_id ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'prfx_nonce' ] ) && wp_verify_nonce( $_POST[ 'prfx_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
// Checks for input and sanitizes/saves if needed
// Checks for input and saves
if( isset( $_POST[ 'checkfield' ] ) ) {
update_post_meta($post_id, "checkfield", $_POST['checkfield'] );
}
}
add_action( 'save_post', 'prfx_meta_save' );
and calling the page id in header.php like this:
<?php
if( in_array($page->ID, (array) $checkfield) ) {
wp_nav_menu(array( 'theme_location' => 'menu_top_pap' ) );
} else {
wp_nav_menu(array( 'theme_location' => 'secondary-menu' ) );
}
?>
But it didn't work. Please help!
***************** UPDATE *****************
I've been trying to edit the function prfx_meta_callback( $post ) but with no success. Here's the latest code I'm trying to modify...
function prfx_meta_callback( $post ) {
wp_nonce_field( basename( __FILE__ ), 'prfx_nonce' );
$checkfield = maybe_unserialize( get_post_meta($post->ID, "checkfield", true) );
$page = get_pages();
$prfx_stored_meta = get_post_meta( $post->ID );
?>
<p>
<span class="prfx-row-title"><?php _e( 'Pap Checkbox', 'prfx-textdomain' )?></span>
<div class="prfx-row-content">
<label for="page_<?php echo $page->ID; ?>">
<input id="page_<?php echo $page->ID; ?>" type="checkbox" name="checkfield[]" value="<?php echo $page->ID; ?>" <?php if ( isset($checkfield [ ?>'<?php echo $page->ID; ?>'<?php ] ) ) checked( $checkfield[ ?>'<?php echo $page->ID; ?>'<?php ][0], '<?php echo $page->ID; ?>'); ?>/> <?php _e( 'Check if this page is Papiamento', 'prfx-textdomain' )?></label> <br>
</div>
</p>
<?php
I've been trying to make it like that, if Pap, then checked, but if not Pap, unchecked in every page.
If the metabox is saving the checkbox settings properly, you can use the following code to make the check in header.php:
if ( in_array( get_the_ID(), get_post_meta( get_the_ID(), 'checkfield', true ) ) ) {
wp_nav_menu(array( 'theme_location' => 'menu_top_pap' ) );
} else {
wp_nav_menu(array( 'theme_location' => 'secondary-menu' ) );
}