J'ai un message personnalisé avec beaucoup de boîtes de méta. J'ai récemment essayé d'ajouter des métaboxes dynamiques en utilisant cette question: Créez plus de méta-boîtes si nécessaire
J'ai réussi à faire bien ajouter les métaboxes, jquery fonctionne, tout fonctionne sauf l'action save_post - les "Commentaires" enregistrent joliment, mais les "Screenings" ne le font pas. Qu'est-ce que j'ai mal fait dans mon code? Je suis sûr que ce doit être quelque chose de très simple que je néglige, peut-être avec les nonces?
Edit : Je sais que je peux faire tout cela avec un save_post
, et cela fonctionne si je n’ai qu’un de ces métabox dynamiques, mais si j’ajoute une deuxième section (ou plus) de métabox dynamique, ces données ne pas sauver.
Edit : Si nécessaire, je peux poster tout mon fichier de fonction custom-posts.php sur Pastebin ou quelque chose du genre, mais je viens d'inclure ce que je pense être l'extrait pertinent ici par souci de brièveté.
Edit : Code mis à jour ...
<?php
add_action('save_post', 'save_postdata'); // saves post data from another function earlier on
add_action('save_post', 'save_postdata_dynamic_reviews_metabox' );
add_meta_box("film-reviews", "Reviews", "print_dynamic_reviews_metabox", "film", "normal", "low");
add_action('save_post', 'save_postdata_dynamic_screenings_metabox' );
add_meta_box("film-screenings", "Screenings", "print_dynamic_screenings_metabox", "film", "normal", "low");
/* Prints the box content */
function print_dynamic_reviews_metabox() {
global $post;
// Use nonce for verification
echo '<input type="hidden" name="reviews_noncename" id="reviews_noncename" value="' . wp_create_nonce( 'reviews-nonce' ) . '" />';
echo '<div id="meta_inner-reviews">';
echo '<ol id="reviews-meta">';
$reviews = get_post_meta($post->ID,'reviews',true); //get any previously saved meta as an array so we can display it
// print_r($reviews);
$c = 0;
if( is_array($reviews) ) {
foreach($reviews as $review ) {
if (isset($review['review-name']) || isset($review['review-link']) ) {
echo '
<li><span class="remove-review" title="Delete">Remove</span>
<label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name saveddata" name="reviews['.$c.'][review-name]" value="'.$review['review-name'].'" /></label>
<label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url saveddata" name="reviews['.$c.'][review-url]" value="'.$review['review-url'].'" /></label>';
echo '<span class="remove-review" title="Delete">Remove</span></li>';
$c = $c +1;
} // ends if isset $award[album]
} // ends foreach
} // ends if (is_array)
echo '</ol>';
echo '<span class="add-review">Add New Review</span>';
?>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
var count = <?php echo $c; ?>;
$(".add-review").click(function() {
count = count + 1;
$('#reviews-meta').append('<li><span class="remove-review" title="Delete">Remove</span> <label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name" name="reviews['+count+'][review-name]" value="" /></label> <label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url" name="reviews['+count+'][review-url]" value="" /></label></li> <span class="remove-review" title="Delete">Remove</span>');
return false;
});
$(".remove-review").live('click', function() {
$(this).parent().remove();
});
});
</script>
<?php
echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_reviews_metabox()
function save_postdata_dynamic_reviews_metabox( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return;
}
// 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;}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if (isset($_POST['reviews_noncename'])){
if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
return;
}else{return;}
// OK, we're authenticated: we need to find and save the data
$reviews = $_POST['reviews'];
update_post_meta($post_id,'reviews',$reviews);
} // ends function save_postdata_dynamic_reviews_metabox
/* Prints the box content */
function print_dynamic_screenings_metabox() {
global $post;
// Use nonce for verification
echo '<input type="hidden" name="screenings_noncename" id="screenings_noncename" value="' . wp_create_nonce( 'screenings-nonce' ) . '" />';
echo '<div id="meta_inner-screenings">';
echo '<ol id="screenings-meta">';
$screenings= get_post_meta($post->ID,'screenings',true); //get any previously saved meta as an array so we can display it
// print_r($screenings);
$c = 0;
if( is_array($screenings) ) {
foreach($screenings as $screening ) {
if (isset($screening['screening-festival-name']) || isset($screening['screening-festival-date']) ) {
echo '
<li><span class="remove-screening" title="Delete">Remove</span>
<label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name saveddata" name="screenings['.$c.'][screening-festival-name]" value="'.$screening['screening-festival-name'].'" /></label>
<label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date saveddata" name="screenings['.$c.'][screening-festival-date]" value="'.$screening['screening-festival-date'].'" /></label>';
echo '<span class="remove-screening" title="Delete">Remove</span></li>';
$c = $c +1;
} // ends if isset $award[album]
} // ends foreach
} // ends if (is_array)
echo '</ol>';
echo '<span class="add-screening">Add New Screening</span>';
?>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
var count = <?php echo $c; ?>;
$(".add-screening").click(function() {
count = count + 1;
$('#screenings-meta').append('<li><span class="remove-screening" title="Delete">Remove</span> <label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name" name="screenings['+count+'][screening-festival-name]" value="" /></label> <label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date" name="screenings['+count+'][screening-festival-date]" value="" /></label> <span class="remove-screening" title="Delete">Remove</span>');
return false;
});
$(".remove-screening").live('click', function() {
$(this).parent().remove();
});
});
</script>
<?php
echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_screenings_metabox()
function save_postdata_dynamic_screenings_metabox( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return;
}
// 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;}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if (isset($_POST['screenings_noncename'])){
if ( !wp_verify_nonce( $_POST['screenings_noncename'], 'screenings-nonce' ) )
return;
}else{return;}
// OK, we're authenticated: we need to find and save the data
$screenings= $_POST['screenings'];
update_post_meta($post_id,'screenings',$screenings);
} // ends function save_postdata_dynamic_screenings_metabox
?>
Voici les problèmes qui empêchaient que les méta-valeurs soient enregistrées dans vos deux fonctions de sauvegarde.
1. Vérification de post_type incorrecte. Vous vérifiez que le type de message est de "page" dans votre fonction de sauvegarde, alors que vos méta-boîtes sont affichées sur votre type de message personnalisé de "film".
Votre code:
if ( 'page' == $_POST['post_type'] ) { if ( !current_user_can( 'edit_page', $post_id )) { return $post_id; }}
CA devrait etre:
if ( 'film' == $_POST['post_type'] ) { if ( !current_user_can( 'edit_page', $post_id )) { return $post_id; }}
2. Nom de champ nonce incorrect. Comme @tollmanz l'a fait remarquer, vous vérifiez les noms de champs incorrects lors de la vérification des nonces. Le nom du champ dans les fonctions de sauvegarde doit correspondre au nom du champ de saisie dans les fonctions de la boîte méta d'impression.
Votre code:
if (isset($_POST['reviews-nonce'])){
if ( !wp_verify_nonce( $_POST['reviews-nonce'], 'reviews-nonce' ) )
return;
}else{return;}
CA devrait etre:
if (isset($_POST['reviews_noncename'])){
if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
return;
}else{return;}
Pour filtrer votre code:
if (isset($_POST['screenings-nonce'])){
if ( !wp_verify_nonce( $_POST['screenings-nonce'], 'screenings-nonce' ) )
return;
}else{return;}
CA devrait etre:
if (isset($_POST['screenings_noncename'])){
if ( !wp_verify_nonce( $_POST['screenings_noncename'], 'screenings-nonce' ) )
return;
}else{return;}
3. Sauvegarde incorrecte des méta-valeurs. Vous utilisiez update_post_meta pour stocker les méta-valeurs.
4. Obtention inattendue de méta-valeurs. Vous utilisiez un troisième paramètre dans vos appels get_post_meta, qui consiste à spécifier de n'extraire qu'une seule méta-valeur. Dans ce cas, vous devez extraire toutes les méta-valeurs.
Votre code:
$reviews = get_post_meta($post->ID,'reviews',true); //get any previously saved meta as an array so we can display it
CA devrait etre:
$reviews = get_post_meta($post->ID,'reviews'); //get any previously saved meta as an array so we can display it
Votre code pour les projections:
$reviews = get_post_meta($post->ID,'screenings',true); //get any previously saved meta as an array so we can display it
CA devrait etre:
$reviews = get_post_meta($post->ID,'screenings',true); //get any previously saved meta as an array so we can display it
Voici le code correct. Le code ci-dessous devrait fonctionner pour vous car je l'ai testé et tout a bien fonctionné. Si cela ne fonctionne pas pour une raison quelconque, je devrai consulter votre code complet.
add_action('save_post', 'save_postdata_dynamic_reviews_metabox' );
add_meta_box("film-reviews", "Reviews", "print_dynamic_reviews_metabox", "film", "normal", "low");
add_action('save_post', 'save_postdata_dynamic_screenings_metabox' );
add_meta_box("film-screenings", "Reviews", "print_dynamic_screenings_metabox", "film", "normal", "low");
/* Prints the box content */
function print_dynamic_reviews_metabox() {
global $post;
// Use nonce for verification
echo '<input type="hidden" name="reviews_noncename" id="reviews_noncename" value="' . wp_create_nonce( 'reviews-nonce' ) . '" />';
echo '<div id="meta_inner-reviews">';
echo '<ol id="reviews-meta">';
$reviews = get_post_meta($post->ID,'reviews'); //get any previously saved meta as an array so we can display it
// print_r($reviews);
$c = 0;
if( is_array($reviews) ) {
foreach($reviews as $review ) {
if (isset($review['review-name']) || isset($review['review-link']) ) {
echo '
<li><span class="remove-review" title="Delete">Remove</span>
<label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name saveddata" name="reviews['.$c.'][review-name]" value="'.$review['review-name'].'" /></label>
<label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url saveddata" name="reviews['.$c.'][review-url]" value="'.$review['review-url'].'" /></label>';
echo '<span class="remove-review" title="Delete">Remove</span></li>';
$c = $c +1;
} // ends if isset $award[album]
} // ends foreach
} // ends if (is_array)
echo '</ol>';
echo '<span class="add-review">Add New Review</span>';
?>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
var count = <?php echo $c; ?>;
$(".add-review").click(function() {
count = count + 1;
$('#reviews-meta').append('<li><span class="remove-review" title="Delete">Remove</span> <label><strong>Review Name/Title:</strong> <input type="text" class="meta-review-name" name="reviews['+count+'][review-name]" value="" /></label> <label><strong>Review URL:</strong> (don\'t forget the http://) <input type="text" class="meta-review-url" name="reviews['+count+'][review-url]" value="" /></label></li> <span class="remove-review" title="Delete">Remove</span>');
return false;
});
$(".remove-review").live('click', function() {
$(this).parent().remove();
});
});
</script>
<?php
echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_reviews_metabox()
function save_postdata_dynamic_reviews_metabox( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return;
}
// Check permissions
if ( 'film' == $_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;}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if (isset($_POST['reviews_noncename'])){
if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
return;
}else{return;}
delete_post_meta( $post_id, 'reviews' );
// OK, we're authenticated: we need to find and save the data
$reviews = $_POST['reviews'];
foreach ( $reviews as $review ) {
add_post_meta($post_id,'reviews',$review);
}
} // ends function save_postdata_dynamic_reviews_metabox
/* Prints the box content */
function print_dynamic_screenings_metabox() {
global $post;
// Use nonce for verification
echo '<input type="hidden" name="screenings_noncename" id="screenings_noncename" value="' . wp_create_nonce( 'screenings-nonce' ) . '" />';
echo '<div id="meta_inner-screenings">';
echo '<ol id="screenings-meta">';
$reviews = get_post_meta($post->ID,'screenings'); //get any previously saved meta as an array so we can display it
// print_r($reviews);
$c = 0;
if( is_array($screenings) ) {
foreach($screenings as $screening ) {
if (isset($screening['screening-festival-name']) || isset($screening['screening-festival-date']) ) {
echo '
<li><span class="remove-screening" title="Delete">Remove</span>
<label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name saveddata" name="screenings['.$c.'][screening-festival-name]" value="'.$screening['screening-festival-name'].'" /></label>
<label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date saveddata" name="screenings['.$c.'][screening-festival-date]" value="'.$screening['screening-festival-date'].'" /></label>';
echo '<span class="remove-screening" title="Delete">Remove</span></li>';
$c = $c +1;
} // ends if isset $award[album]
} // ends foreach
} // ends if (is_array)
echo '</ol>';
echo '<span class="add-screening">Add New Screening</span>';
?>
<script>
var $ =jQuery.noConflict();
$(document).ready(function() {
var count = <?php echo $c; ?>;
$(".add-screening").click(function() {
count = count + 1;
$('#screenings-meta').append('<li><span class="remove-screening" title="Delete">Remove</span> <label><strong>Festival Name:</strong> <input type="text" class="meta-screening-festival-name" name="screenings['+count+'][screening-festival-name]" value="" /></label> <label><strong>Festival Date:</strong> <input type="text" class="meta-screening-festival-date" name="screenings['+count+'][screening-festival-date]" value="" /></label> <span class="remove-screening" title="Delete">Remove</span>');
return false;
});
$(".remove-screening").live('click', function() {
$(this).parent().remove();
});
});
</script>
<?php
echo '</div>'; // ends div#meta_inner
} // ends function print_dynamic_screenings_metabox()
function save_postdata_dynamic_screenings_metabox( $post_id ) {
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return;
}
// Check permissions
if ( 'film' == $_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;}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if (isset($_POST['screenings_noncename'])){
if ( !wp_verify_nonce( $_POST['screenings_noncename'], 'screenings-nonce' ) )
return;
}else{return;}
delete_post_meta( $post_id, 'screenings' );
// OK, we're authenticated: we need to find and save the data
$screenings = $_POST['screenings'];
foreach ( $screenings as $screening ) {
add_post_meta($post_id,'screenings',$screening);
}
} // ends function save_postdata_dynamic_reviews_metabox
Je crois que le problème réside dans le code suivant:
if (isset($_POST['reviews-nonce'])){
if ( !wp_verify_nonce( $_POST['reviews-nonce'], 'reviews-nonce' ) )
return;
}else{return;}
Bon travail de vérification pour le nonce; Cependant, le nom nonce est incorrect. Dans le formulaire HTML, vous spécifiez:
echo '<input type="hidden" name="reviews_noncename" id="reviews_noncename" value="' . wp_create_nonce( 'reviews-nonce' ) . '" />';
Le nom du champ nonce est reviews_noncename
et non reviews-nonce
. Donc, je crois que vous pouvez corriger le code dans la fonction de sauvegarde pour:
if (isset($_POST['reviews_noncename'])){
if ( !wp_verify_nonce( $_POST['reviews_noncename'], 'reviews-nonce' ) )
return;
}else{return;}
Je pense que cela résoudra votre problème.