自定义元盒数据数组:Foreach无法正常工作?

时间:2018-09-18 作者:Yvonne

我编写了一个插件来创建一个名为gardener, 并添加了一个名为region, 除了一个包含多个字段的元框_gardener_address. The last is where the problem lies.

你看,我使用了https://gist.github.com/cferdinandi/46aca88d6d142791a32a9d30017f1cd8 为了创建我的元框,虽然在管理方面一切都很好,但当我尝试在帖子上实际显示元数据时,我遇到了一个大问题。

创建自定义帖子类型、分类法和元框的代码如下:

if ( ! function_exists(\'gardeners_post_type\') ) {

if ( ! function_exists( \'region_taxonomy\' ) ) {

// Register Custom Taxonomy
function region_taxonomy() {

    $labels = array(
        \'name\'                       => _x( \'Regio\\\'s\', \'Taxonomy General Name\', \'text_domain\' ),
        \'singular_name\'              => _x( \'Regio\', \'Taxonomy Singular Name\', \'text_domain\' ),
        \'menu_name\'                  => __( \'Regio\\\'s\', \'text_domain\' ),
        \'all_items\'                  => __( \'Alle Regio\\\'s\', \'text_domain\' ),
        \'parent_item\'                => __( \'Provincie\', \'text_domain\' ),
        \'parent_item_colon\'          => __( \'Provincie:\', \'text_domain\' ),
        \'new_item_name\'              => __( \'Nieuwe regio\', \'text_domain\' ),
        \'add_new_item\'               => __( \'Nieuwe regio\', \'text_domain\' ),
        \'edit_item\'                  => __( \'Wijzig regio\', \'text_domain\' ),
        \'update_item\'                => __( \'Update regio\', \'text_domain\' ),
        \'view_item\'                  => __( \'Bekijk regio\', \'text_domain\' ),
        \'separate_items_with_commas\' => __( \'Afzonderlijke regio\\\'s scheiden met komma\\\'s\', \'text_domain\' ),
        \'add_or_remove_items\'        => __( \'Toevoegen of verwijderen regio\\\'s\', \'text_domain\' ),
        \'choose_from_most_used\'      => __( \'Kies uit de meest gebruikte regio\\\'s\', \'text_domain\' ),
        \'popular_items\'              => __( \'Populaire regio\\\'s\', \'text_domain\' ),
        \'search_items\'               => __( \'Zoek regio\', \'text_domain\' ),
        \'not_found\'                  => __( \'Regio niet gevonden\', \'text_domain\' ),
        \'no_terms\'                   => __( \'Geen regio beschikbaar\', \'text_domain\' ),
        \'items_list\'                 => __( \'Regio-overzicht\', \'text_domain\' ),
        \'items_list_navigation\'      => __( \'Regio-overzicht navigatie\', \'text_domain\' ),
    );
    $args = array(
        \'labels\'                     => $labels,
        \'hierarchical\'               => false,
        \'public\'                     => true,
        \'show_ui\'                    => true,
        \'show_admin_column\'          => true,
        \'show_in_nav_menus\'          => true,
        \'show_tagcloud\'              => true,
        \'show_in_rest\'               => true,
    );
    register_taxonomy( \'region\', array( \'gardener\' ), $args );

}
add_action( \'init\', \'region_taxonomy\', 0 );

}


 // Register Custom Post Type
function gardeners_post_type() {

    $labels = array(
        \'name\'                  => _x( \'Hoveniers\', \'Post Type General Name\', \'text_domain\' ),
        \'singular_name\'         => _x( \'Hovenier\', \'Post Type Singular Name\', \'text_domain\' ),
        \'menu_name\'             => __( \'Hoveniers\', \'text_domain\' ),
        \'name_admin_bar\'        => __( \'Hovenier\', \'text_domain\' ),
        \'archives\'              => __( \'Hovenieroverzicht\', \'text_domain\' ),
        \'attributes\'            => __( \'Hovenier eigenschappen\', \'text_domain\' ),
        \'parent_item_colon\'     => __( \'Hoofdhovenier:\', \'text_domain\' ),
        \'all_items\'             => __( \'Alle hoveniers\', \'text_domain\' ),
        \'add_new_item\'          => __( \'Nieuwe hovenier\', \'text_domain\' ),
        \'add_new\'               => __( \'Nieuwe hovenier\', \'text_domain\' ),
        \'new_item\'              => __( \'Nieuwe hovenier\', \'text_domain\' ),
        \'edit_item\'             => __( \'Wijzig hovenier\', \'text_domain\' ),
        \'update_item\'           => __( \'Update hovenier\', \'text_domain\' ),
        \'view_item\'             => __( \'Bekijk hovenier\', \'text_domain\' ),
        \'view_items\'            => __( \'Bekijk hoveniers\', \'text_domain\' ),
        \'search_items\'          => __( \'Zoek hovenier\', \'text_domain\' ),
        \'not_found\'             => __( \'Hovenier niet gevonden\', \'text_domain\' ),
        \'not_found_in_trash\'    => __( \'Hovenier niet gevonden in Prullenbak\', \'text_domain\' ),
        \'featured_image\'        => __( \'Uitgelichte afbeelding\', \'text_domain\' ),
        \'set_featured_image\'    => __( \'Stel uitgelichte afbeelding in\', \'text_domain\' ),
        \'remove_featured_image\' => __( \'Verwijder uitgelichte afbeelding\', \'text_domain\' ),
        \'use_featured_image\'    => __( \'Gebruik als uitgelichte afbeelding\', \'text_domain\' ),
        \'insert_into_item\'      => __( \'Invoegen bij hovenier\', \'text_domain\' ),
        \'uploaded_to_this_item\' => __( \'Geüploadet naar deze hovenier\', \'text_domain\' ),
        \'items_list\'            => __( \'Hovenieroverzicht\', \'text_domain\' ),
        \'items_list_navigation\' => __( \'Hovenieroverzichtsmenu\', \'text_domain\' ),
        \'filter_items_list\'     => __( \'Filter hoveniers\', \'text_domain\' ),
    );
    $rewrite = array(
        \'slug\'                  => \'hovenier\',
        \'with_front\'            => true,
        \'pages\'                 => true,
        \'feeds\'                 => false,
    );
    $args = array(
        \'label\'                 => __( \'Hovenier\', \'text_domain\' ),
        \'description\'           => __( \'Overzicht van hoveniers\', \'text_domain\' ),
        \'labels\'                => $labels,
        \'supports\'              => array( \'title\', \'editor\', \'thumbnail\', \'revisions\' ),
        \'taxonomies\'            => array( \'region\' ),
        \'hierarchical\'          => false,
        \'public\'                => true,
        \'show_ui\'               => true,
        \'show_in_menu\'          => true,
        \'menu_position\'         => 70,
        \'menu_icon\'             => \'dashicons-groups\',
        \'show_in_admin_bar\'     => true,
        \'show_in_nav_menus\'     => true,
        \'can_export\'            => true,
        \'has_archive\'           => true,
        \'exclude_from_search\'   => false,
        \'publicly_queryable\'    => true,
        \'rewrite\'               => $rewrite,
        \'capability_type\'       => \'page\',
        \'show_in_rest\'          => true,

    );
    register_post_type( \'gardener\', $args );

}

add_action( \'init\', \'gardeners_post_type\', 0 );



// CUSTOM META BOX ---------------------------------------------
//
// Create Metabox
//
/**
 * Create the metabox
 * @link https://developer.wordpress.org/reference/functions/add_meta_box/
 https://gist.github.com/cferdinandi/46aca88d6d142791a32a9d30017f1cd8
 */
function _gardener_address_create_metabox() {
    // Can only be used on a single post type (ie. page or post or a custom post type).
    // Must be repeated for each post type you want the metabox to appear on.
    add_meta_box(
        \'_gardener_address_metabox\', // Metabox ID
        \'Contactinformatie\', // Title to display
        \'_gardener_address_render_metabox\', // Function to call that contains the metabox content
        \'gardener\', // Post type to display metabox on
        \'normal\', // Where to put it (normal = main colum, side = sidebar, etc.)
        \'high\' // Priority relative to other metaboxes
    );
}
add_action( \'add_meta_boxes\', \'_gardener_address_create_metabox\' );

/**
 * Create the metabox default values
 * This allows us to save multiple values in an array, reducing the size of our database.
 * Setting defaults helps avoid "array key doesn\'t exit" issues.
 * @todo
 */
function _gardener_address_metabox_defaults() {
    return array(
        \'street\'     => \'\',
        \'zip\'        => \'\',
        \'city\'       => \'\',
        \'tel1\'       => \'\',
        \'tel2\'       => \'\',
        \'email\'      => \'\',
        \'url\'        => \'\',
        \'fb\'         => \'\',
        \'twitter\'    => \'\',
        \'linkedin\'   => \'\',
        \'insta\'      => \'\',
        \'pint\'       => \'\',
    );
}

/**
 * Render the metabox markup
 * This is the function called in `_gardener_address_create_metabox()`
 */
function _gardener_address_render_metabox() {
    // Variables
    global $post; // Get the current post data
    $saved = get_post_meta( $post->ID, \'_gardener_address\', true ); // Get the saved values
    $defaults = _gardener_address_metabox_defaults(); // Get the default values
    $details = wp_parse_args( $saved, $defaults ); // Merge the two in case any fields don\'t exist in the saved data
    ?>

    <style>

        #_gardener_address_metabox .inside {
            display:flex;
            align-items:flex-start;
            justify-content: space-between;
        }

        .gardener_address_fieldset div {
            display:flex;
            align-items: center;
            justify-content: space-between;
            width:100%;
        }

        .gardener_address_fieldset legend {
            font-weight:600;
            margin-bottom:1rem;
        }

        .gardener_address_fieldset label {
            margin-right:1rem;
        }

        .gardener_address_fieldset input {

        }
    </style>

    <fieldset class="gardener_address_fieldset">
        <legend>Adresgegevens</legend>
        <div>
            <label for="_gardener_address_custom_metabox_street">
                    <?php
                        // This runs the text through a translation and echoes it (for internationalization)
                        _e( \'Straat\', \'_gardener_address\' );
                    ?>
                </label>
            <?php
                // It\'s important that the `name` is an array. This let\'s us
                // easily loop through all fields later when we go to save
                // our submitted data.
                //
                // The `esc_attr()` function here escapes the data for
                // HTML attribute use to avoid unexpected issues
            ?>
            <input type="text" name="_gardener_address_custom_metabox[street]" id="_gardener_address_custom_metabox_street" value="<?php echo esc_attr( $details[\'street\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_zip">
                    <?php
                        _e( \'Postcode\', \'_gardener_address\' );
                    ?>
                </label>
                <input type="text" name="_gardener_address_custom_metabox[zip]" id="_gardener_address_custom_metabox_zip" value="<?php echo esc_attr( $details[\'zip\'] ); ?>">
        </div>

                    <div>
            <label for="_gardener_address_custom_metabox_city">
                    <?php
                        _e( \'Plaats\', \'_gardener_address\' );
                    ?>
                </label>
                <input type="text" name="_gardener_address_custom_metabox[city]" id="_gardener_address_custom_metabox_city" value="<?php echo esc_attr( $details[\'city\'] ); ?>">
        </div>
    </fieldset>

    <fieldset class="gardener_address_fieldset">
        <legend>Telefoonnummers</legend>
        <div>
            <label for="_gardener_address_custom_metabox_tel1">
            <?php _e( \'Telefoon\', \'_gardener_address\' ); ?>
        </label>
            <input type="tel" name="_gardener_address_custom_metabox[tel1]" id="_gardener_address_custom_metabox_tel1" value="<?php echo esc_attr( $details[\'tel1\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_tel2">
            <?php _e( \'Telefoon\', \'_gardener_address\' ); ?>
        </label>
            <input type="tel" name="_gardener_address_custom_metabox[tel2]" id="_gardener_address_custom_metabox_tel2" value="<?php echo esc_attr( $details[\'tel2\'] ); ?>">
        </div>
    </fieldset>

    <fieldset class="gardener_address_fieldset">
        <legend>Web</legend>
        <div>
            <label for="_gardener_address_custom_metabox_email">
            <?php _e( \'E-mail\', \'_gardener_address\' ); ?>
        </label>
            <input type="email" name="_gardener_address_custom_metabox[email]" id="_gardener_address_custom_metabox_email" value="<?php echo esc_attr( $details[\'email\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_url">
            <?php _e( \'Website\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[url]" id="_gardener_address_custom_metabox_url" value="<?php echo esc_attr( $details[\'url\'] ); ?>">
        </div>
    </fieldset>

    <fieldset class="gardener_address_fieldset">
        <legend>Sociale media</legend>
        <div>
            <label for="_gardener_address_custom_metabox_fb">
            <?php _e( \'Facebook\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[fb]" id="_gardener_address_custom_metabox_fb" value="<?php echo esc_attr( $details[\'fb\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_twitter">
            <?php _e( \'Twitter\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[twitter]" id="_gardener_address_custom_metabox_twitter" value="<?php echo esc_attr( $details[\'twitter\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_linkedin">
            <?php _e( \'LinkedIn\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[linkedin]" id="_gardener_address_custom_metabox_linkedin" value="<?php echo esc_attr( $details[\'linkedin\'] ); ?>">
        </div>

        <div>
            <label for="_gardener_address_custom_metabox_insta">
            <?php _e( \'Instagram\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[insta]" id="_gardener_address_custom_metabox_insta" value="<?php echo esc_attr( $details[\'insta\'] ); ?>">
        </div>


        <div>
            <label for="_gardener_address_custom_metabox_pint">
            <?php _e( \'Pinterest\', \'_gardener_address\' ); ?>
        </label>
            <input type="url" name="_gardener_address_custom_metabox[pint]" id="_gardener_address_custom_metabox_pint" value="<?php echo esc_attr( $details[\'pint\'] ); ?>">
        </div>
    </fieldset>

<?php
    // Security field
    // This validates that submission came from the
    // actual dashboard and not the front end or
    // a remote server.
    wp_nonce_field( \'_gardener_address_form_metabox_nonce\', \'_gardener_address_form_metabox_process\' );
}

//
// Save our data
//
/**
 * Save the metabox
 * @param  Number $post_id The post ID
 * @param  Array  $post    The post data
 */
function _gardener_address_save_metabox( $post_id, $post ) {
    // Verify that our security field exists. If not, bail.
    if ( !isset( $_POST[\'_gardener_address_form_metabox_process\'] ) ) return;

    // Verify data came from edit/dashboard screen
    if ( !wp_verify_nonce( $_POST[\'_gardener_address_form_metabox_process\'], \'_gardener_address_form_metabox_nonce\' ) ) {
        return $post->ID;
    }

    // Verify user has permission to edit post
    if ( !current_user_can( \'edit_post\', $post->ID )) {
        return $post->ID;
    }

    // Check that our custom fields are being passed along
    // This is the `name` value array. We can grab all
    // of the fields and their values at once.
    if ( !isset( $_POST[\'_gardener_address_custom_metabox\'] ) ) {
        return $post->ID;
    }

    /**
     * Sanitize all data
     * This keeps malicious code out of our database.
     */

    // Set up an empty array
    $sanitized = array();
    // Loop through each of our fields

    foreach ( $_POST[\'_gardener_address_custom_metabox\'] as $key => $detail ) {
        // Sanitize the data and push it to our new array
        // `wp_filter_post_kses` strips our dangerous server values
        // and allows through anything you can include a post.
        $sanitized[$key] = wp_filter_post_kses( $detail );
    }
    // Save our submissions to the database
    update_post_meta( $post->ID, \'_gardener_address\', $sanitized );
}
add_action( \'save_post\', \'_gardener_address_save_metabox\', 1, 2 );

//
// Save a copy to our revision history
// This is optional, and potentially undesireable for certain data types.
// Restoring a a post to an old version will also update the metabox.
/**
 * Save events data to revisions
 * @param  Number $post_id The post ID
 */
function _gardener_address_save_revisions( $post_id ) {
    // Check if it\'s a revision
    $parent_id = wp_is_post_revision( $post_id );

    // If is revision
    if ( $parent_id ) {
        // Get the saved data
        $parent = get_post( $parent_id );
        $details = get_post_meta( $parent->ID, \'_gardener_address\', true );
        // If data exists and is an array, add to revision

        if ( !empty( $details ) && is_array( $details ) ) {
            // Get the defaults
            $defaults = _gardener_address_metabox_defaults();
            // For each default item
            foreach ( $defaults as $key => $value ) {
                // If there\'s a saved value for the field, save it to the version history
                if ( array_key_exists( $key, $details ) ) {
                    add_metadata( \'post\', $post_id, \'_gardener_address_\' . $key, $details[$key] );
                }
            }
        }
    }
}

add_action( \'save_post\', \'_gardener_address_save_revisions\' );

/**
 * Restore events data with post revisions
 * @param  Number $post_id     The post ID
 * @param  Number $revision_id The revision ID
 */
function _gardener_address_restore_revisions( $post_id, $revision_id ) {

    // Variables
    $post = get_post( $post_id ); // The post
    $revision = get_post( $revision_id ); // The revision
    $defaults = _gardener_address_metabox_defaults(); // The default values
    $details = array(); // An empty array for our new metadata values
    // Update content
    // For each field

    foreach ( $defaults as $key => $value ) {
        // Get the revision history version
        $detail_revision = get_metadata( \'post\', $revision->ID, \'_gardener_address_\' . $key, true );
        // If a historic version exists, add it to our new data

        if ( isset( $detail_revision ) ) {
            $details[$key] = $detail_revision;
        }
    }
    // Replace our saved data with the old version
    update_post_meta( $post_id, \'_gardener_address\', $details );
}

add_action( \'wp_restore_post_revision\', \'_gardener_address_restore_revisions\', 10, 2 );

/**
 * Get the data to display on the revisions page
 * @param  Array $fields The fields
 * @return Array The fields
 */
function _gardener_address_get_revisions_fields( $fields ) {
    // Get our default values
    $defaults = _gardener_address_metabox_defaults();
    // For each field, use the key as the title
    foreach ( $defaults as $key => $value ) {
        $fields[\'_gardener_address_\' . $key] = ucfirst( $key );
    }
    return $fields;
}
add_filter( \'_wp_post_revision_fields\', \'_gardener_address_get_revisions_fields\' );

/**
 * Display the data on the revisions page
 * @param  String|Array $value The field value
 * @param  Array        $field The field
 */
function _gardener_address_display_revisions_fields( $value, $field ) {
    global $revision;
    return get_metadata( \'post\', $revision->ID, $field, true );
}

add_filter( \'_wp_post_revision_field_my_meta\', \'_gardener_address_display_revisions_fields\', 10, 2 );

}
我试图在single-gardener.php 通过使用

<ul>
<?php 

    $custom_fields = get_post_custom( get_the_ID() );
    $my_custom_field = $custom_fields[\'_gardener_address\'];
    foreach ( $my_custom_field as $key => $value ) {
    echo "<li>" . $key . " => " . $value . "</li>";
    }
?>
</ul>
然而,我得到的只是一根长字符串

0=>a:12:{s:6:“街道”;s:8:“街道1”;s:3:“邮编”;s:7:“1234 AB”;s:4:“城市”;s:4:“tel1”;s:0:;s:4:“tel2”;s:0:;s:5:“电子邮件”;s:0:;s:3:“url”;s:16:http://test.com/“s:2:“fb”;s:0:;s:7:“twitter”;s:0:;s:8:“linkedin”;s:0:;s:5:“insta”;s:0:;s:4:“品脱”;s:0:;”

我基本上是一个PHP初学者,老实说,我不知道为什么我的数据会作为一个长字符串进行响应,而不是将每个值单独列出。。。有谁能指引我正确的方向吗?

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

get_post_custom() 是一种非常过时的获取post meta的方法。要正确获取帖子元,您应该使用get_post_meta():

$my_custom_field = get_post_meta( get_the_ID(), \'_gardener_address\', true );
foreach ( $my_custom_field as $key => $value ) {
echo "<li>" . $key . " => " . $value . "</li>";
}

结束

相关推荐

如何在编辑或添加帖子屏幕上添加Metabox来拉取自定义帖子列表(任意两个)?

我想将metabox添加到自定义帖子列表中,并在编辑或添加帖子屏幕上选择任意两个。最后,当文章发布时,将其显示在单个文章页面上。请帮帮我!任何帮助都将不胜感激。。。。 add_action( \'add_meta_boxes\', function () { add_meta_box( \'yourcustom_sectionid\', __( \' Custom Offer Section\', \'yourtextdomain\'