自定义元框:在一个可重复的字段中存储两个值

时间:2012-05-16 作者:derekshirk

我试图创建一个自定义元框,用户可以根据需要添加字段。我遵循了本教程:http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/

我想扩展本教程,并创建一个允许两个输入的可重复字段。例如:名称和URL。

我怎样才能做到这一点?

我在这里发现了另一个问题:Create more Meta Boxes as needed

我能够将元框示例集成到我的自定义帖子类型中,但我不知道如何将元值输出到我的主题中。下面是我正在使用的代码:

    /*---------------------------*/
    /* Define Metabox Fields
    /*---------------------------*/

    $prefix = \'tz_\';

    $custom_downloads = array(
         \'id\' => \'custom-downloads\',
         \'title\' => __(\'Custom Downloads Downloads (Beta)\'),
         \'page\' => \'categories-supported\',
         \'context\' => \'normal\',
         \'priority\' => \'high\',
         \'fields\' => array(

        array(
            \'name\' => __(\'Add Product Downloads\', \'framework\'),
            \'desc\' => __(\'This meta box is under development\', \'framework\'),
            \'id\' => $prefix . \'custom-downloads\',
            \'type\' => \'text\',
            \'std\' => \'\'
        ),                        
      )
    );

    /*-------------------------------------*/
    /* Add Meta Box to CPT screen 
    /*-------------------------------------*/

    function tz_add_box() {
        global $custom_downloads;

        add_meta_box($custom_downloads[\'id\'], $custom_downloads[\'title\'], \'tz_show_box_custom_dwnld\', $custom_downloads[\'page\'], $custom_downloads[\'context\'], $custom_downloads[\'priority\']);


    }

 }

 add_action(\'admin_menu\', \'tz_add_box\');

    /*------------------------------------------*/
    /* Callback function/show fields in meta box
    This is taken directly from: https://wordpress.stackexchange.com/questions/19838/create-more-meta-boxes-as-needed
    /*------------------------------------------*/


    function tz_show_box_custom_dwnld() {
        global $custom_downloads, $post;
        // Use nonce for verification
        echo \'<input type="hidden" name="tz_meta_box_nonce" value="\', wp_create_nonce(basename(__FILE__)), \'" />\';


        ?>
        <div id="meta_inner">
        <?php

        //get the saved meta as an arry
        $songs = get_post_meta($post->ID,\'songs\',true);

        $c = 0;
        if ( count( $songs ) > 0 ) {
            foreach( $songs as $track ) {
                if ( isset( $track[\'title\'] ) || isset( $track[\'track\'] ) ) {
                    printf( \'<p>Song Title <input type="text" name="songs[%1$s][title]" value="%2$s" /> -- Track number : <input type="text" name="songs[%1$s][track]" value="%3$s" /><span class="remove">%4$s</span></p>\', $c, $track[\'title\'], $track[\'track\'], __( \'Remove Track\' ) );
                    $c = $c +1;
                }
            }
        }

        ?>
        <span id="here"></span>
        <span class="add"><?php _e(\'Add Tracks\'); ?></span>
        <script>
        var $ =jQuery.noConflict();
        $(document).ready(function() {
        var count = <?php echo $c; ?>;
        $(".add").click(function() {
        count = count + 1;

        $(\'#here\').append(\'<p> Song Title <input type="text" name="songs[\'+count+\'][title]" value="" /> -- Track number : <input type="text" name="songs[\'+count+\'][track]" value="" /><span class="remove">Remove Track</span></p>\' );
        return false;
        });
        $(".remove").live(\'click\', function() {
        $(this).parent().remove();
        });
        });
        </script>
        </div>
        <?php

    }

/*-------------------------------------*/
/* Save data when post is edited
/*-------------------------------------*/


function tz_save_data($post_id) {
    global $meta_box, $meta_box_video, $meta_box_video_page, $meta_box_product_tabs, $meta_deployments, $meta_features, $meta_downloads;
    // verify nonce
    if (!wp_verify_nonce($_POST[\'tz_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;
    }


 $songs = $_POST[\'songs\'];
    update_post_meta($post_id,\'songs\',$songs);


}

add_action(\'save_post\', \'tz_save_data\');
使用上述代码,我能够在我的CPT编辑屏幕上生成动态元框,并能够成功地将数据保存在字段中。

我有点不好意思承认,但我不知道如何在我的主题中显示这些字段的信息。通过使用,我能够成功地显示存储在其他字段中的其他自定义元信息

<?php $post_meta_data = get_post_custom($post->ID); ?>
<?php $custom_features = unserialize($post_meta_data[\'tz_features-repeat\'][0]); ?>

<?php echo \'<ul class="deployments">\';
    foreach ($custom_deployments as $string) {
        echo \'<li>\'.$string.\'</li>\';
    }
    echo \'</ul>\';
?>
任何帮助都将不胜感激!

1 个回复
最合适的回答,由SO网友:Chris_O 整理而成

元框保存的序列化数组已变形。我对您的代码做了一些细微的更改以使其正常工作。我创建了一个新帖子,下面是取消序列化后保存的内容。

Note: WordPress将自动取消存储在post\\u meta中的数组序列化。使用online unserializer 如果你想查看内容。

Array
(
[1] => Array
(
[title] => Back in Black
[track] => 1
) [2] => Array
(
[title] => Hells Bells
[track] => 2
) [3] => Array
(
[title] => Hot for Teacher
[track] => 3
) [4] => Array
(
[title] => Rack City Bitch
[track] => 4
) 
)
要在前端输出它,只需调用get\\u post\\u meta()并遍历数组。

add_filter( \'the_content\', \'get_your_track_meta\' );
    function get_your_track_meta( $content ) {
        global $post;
        $metadata = get_post_meta( $post->ID, \'songs\', true );
        $content .= \'<ul>\';
        foreach ( (array) $metadata as $meta) {
            $content .= \'<li>\' . $meta[\'title\'] . \' -- \' . $meta[\'track\'] . \'</li>\';
        }
        $content .= \'</ul>\';
        return $content;
    }
在前端,这为我们提供了一个很好的无序列表,其中包含曲目和标题:

黑色背景——1《地狱钟声》——2《老师热》——3《Rack City婊子》——4《代码更改》:我不得不将您的页面字段更改为post 在你的meta-box定义中,将其加载到一篇文章中,我还将其移动到add\\u meta\\u-box函数中,这样我们就不必处理使其全局化的问题。在show box函数中,我将get\\u post\\u元变量强制转换为一个数组,以消除为Xdebug中的foreach错误提供的无效参数,并修复了计数器。

$songs = get_post_meta( $post->ID, \'songs\', true );
        $c = 0;
        if ( count( $songs ) > 0 ) {
            foreach ( (array)$songs as $track ) {
                if ( isset( $track[\'title\'] ) || isset( $track[\'track\'] ) ) {
                    printf( \'<p>Song Title <input type="text" name="songs[%1$s][title]" value="%2$s" /> -- Track number : <input type="text" name="songs[%1$s][track]" value="%3$s" /><span class="remove">%4$s</span></p>\', $c, $track[\'title\'], $track[\'track\'], __( \'Remove Track\' ) );
                    $c++;
                }
            }
        }

结束

相关推荐

从菜单屏幕中删除Metabox

一直在挖掘WP文件,我想我可能遗漏了一些东西。最终目标是删除Theme Locations 如果某人没有特定功能,则从菜单屏幕中选择metaboxmanage_options. 我知道,在可用性方面有点奇怪,但只有一个菜单,我们正在努力让这更难搞砸;)正在查看/wp-admin/nav-menu.php 绕线383 我明白了wp_nav_menu_setup() 因此,我尝试添加以下内容作为过滤器,但迄今为止没有成功:function roots_remove_nav_menu_metaboxes() {