为什么我的Metabox数据不会保存?

时间:2011-07-18 作者:gillespieza

我有一个自定义帖子,里面有很多元框。我最近尝试添加一些动态元数据库,使用以下问题:Create more Meta Boxes as needed

我设法让元盒添加得很好,jquery工作得很好,除了save\\u post操作之外,其他一切都工作得很好——“评论”保存得很好,但“筛选”没有。我在代码中做错了什么?我肯定我忽略了一些非常简单的东西,也许是用nonces?

Edit: 我知道我可以用一个save_post, 如果我只有这些动态元盒中的一个,那么这是可行的,但如果我添加了第二个(或更多)动态元盒部分,则不会保存数据。

Edit: 如果需要,我可以发布我的全部自定义帖子。php函数文件粘贴到pastebin或其他东西,但为了简洁起见,我刚刚在这里包含了我认为相关的代码片段

Edit: 更新的代码。。。

<?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


?>

2 个回复
最合适的回答,由SO网友:Hameedullah Khan 整理而成

以下是阻止在两个保存函数中保存元数据的问题。

1. Incorrect post_type checking.您正在保存功能中选中“页面”的帖子类型,其中元框显示在自定义的“电影”帖子类型上。

您的代码:

if ( \'page\' == $_POST[\'post_type\'] ) { if ( !current_user_can( \'edit_page\', $post_id )) { return $post_id; }}
它应该是:

if ( \'film\' == $_POST[\'post_type\'] ) { if ( !current_user_can( \'edit_page\', $post_id )) { return $post_id; }}
2. Incorrect nonce field name.正如@tollmanz指出的,在检查nonce时,您正在检查不正确的字段名。保存函数中的字段名称应与打印元框函数中的输入字段名称匹配。

您的代码:

if (isset($_POST[\'reviews-nonce\'])){
    if ( !wp_verify_nonce( $_POST[\'reviews-nonce\'], \'reviews-nonce\' ) )
        return;
}else{return;}
它应该是:

if (isset($_POST[\'reviews_noncename\'])){
    if ( !wp_verify_nonce( $_POST[\'reviews_noncename\'], \'reviews-nonce\' ) )
        return;
}else{return;}
要立即筛选您的代码:

if (isset($_POST[\'screenings-nonce\'])){
    if ( !wp_verify_nonce( $_POST[\'screenings-nonce\'], \'screenings-nonce\' ) )
        return;
}else{return;}
它应该是:

if (isset($_POST[\'screenings_noncename\'])){
    if ( !wp_verify_nonce( $_POST[\'screenings_noncename\'], \'screenings-nonce\' ) )
        return;
}else{return;}
3. Incorrectly saving the meta values.您正在使用update\\u post\\u meta存储元值。

4. Inoccrectly getting meta values.您在get\\u post\\u meta调用中使用了第三个参数,即指定仅获取单个meta值,在您的情况下,您需要获取所有meta值。

您的代码:

$reviews = get_post_meta($post->ID,\'reviews\',true); //get any previously saved meta as an array so we can display it
它应该是:

$reviews = get_post_meta($post->ID,\'reviews\'); //get any previously saved meta as an array so we can display it
您的筛选代码:

$reviews = get_post_meta($post->ID,\'screenings\',true); //get any previously saved meta as an array so we can display it
它应该是:

$reviews = get_post_meta($post->ID,\'screenings\',true); //get any previously saved meta as an array so we can display it
Below is the correct code. 下面的代码应该适合您,因为我已经对其进行了测试,并且运行良好。如果由于某种原因无法正常工作,我需要查看您的完整代码。

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

SO网友:tollmanz

我认为问题在于以下代码:

if (isset($_POST[\'reviews-nonce\'])){
    if ( !wp_verify_nonce( $_POST[\'reviews-nonce\'], \'reviews-nonce\' ) )
        return;
}else{return;}
做好临时检查工作;但是,nonce名称不正确。在HTML表单中,可以指定:

echo \'<input type="hidden" name="reviews_noncename" id="reviews_noncename" value="\' . wp_create_nonce( \'reviews-nonce\' ) . \'" />\';
nonce字段的名称为reviews_noncenamereviews-nonce. 因此,我相信您可以将save函数中的代码更正为:

if (isset($_POST[\'reviews_noncename\'])){
    if ( !wp_verify_nonce( $_POST[\'reviews_noncename\'], \'reviews-nonce\' ) )
        return;
}else{return;}
我想这会解决你的问题。

结束

相关推荐

后端中的分类下拉Metabox

我创建了名为Brands 并将其分级,以便我可以在其中添加汽车品牌和车型,并保持它们之间的关系,如下所示:福特(Ford)野马(Mustang)蒙迪欧(Mondeo)的问题是,这个列表可能很长,每个帖子只需要一个品牌和一个车型,所以复选框会产生误导。我正在考虑将metabox拆分为两个(一个用于品牌,一个用于模型),并将其下拉列表。因此,当在第一个下拉列表中选择品牌时,第二个下拉列表将仅显示与该品牌相关的型号。但我不知道如何编码。也许有人能给我举个例子?