在自定义元数据框中保存多个字段(下拉列表和文本)

时间:2020-07-08 作者:wp_dev99

我见过很多人问这个问题,但似乎什么都不管用。我在CPT中有一个简单的metabox,需要保存两个值。它需要保存页面下拉列表和url文本字段。我可以获取要保存和显示的文本字段,但不能获取下拉列表。初始化时正在调用我的类。我想这和$dropdown_args 变量,但我不太确定。我可以在数据库中看到它正在保存,但保存后它不会显示所选内容。描述元框保存并显示良好,这是需要帮助的登录页。我已经发布了我所有的代码,任何帮助都将不胜感激。

    class description_meta {

    public $dropdown_args = array();

    /**
     * Constructor.
     */
    public function __construct() {
        if ( is_admin() ) {
            add_action( \'load-post.php\',     array( $this, \'init_metabox\' ) );
            add_action( \'load-post-new.php\', array( $this, \'init_metabox\' ) );            
        }

        $this->dropdown_args = [
            \'show_option_none\' => \'- select a page -\',
            \'option_none_value\' => \'no page selected\',
            \'id\'               => \'landing_page\',
            \'name\'             => \'landing_page\',
            \'value_field\'      => \'landing_page\',
            \'selected\'         => $landing_page
        ];

    }

    /**
     * Meta box initialization.
     */
    public function init_metabox() {
        add_action( \'add_meta_boxes\', array( $this, \'add_metabox\'  )        );
        add_action( \'save_post\',      array( $this, \'save_metabox\' ), 10, 2 );
    }

    public function register() {
        add_action( \'save_post\',      array( $this, \'save_metabox\' ), 10, 2 );
    }

    /**
     * Adds the meta box.
     */
    public function add_metabox() {
        add_meta_box(
            \'description\',
            \'Description\',
            array( $this, \'render_description\' ),
            \'funnels\',
            \'advanced\',
            \'default\'
            );

         add_meta_box(
            \'landing_page\',
            \'Landing Page\',
            array( $this, \'render_landing\' ),
            \'funnels\',
            \'advanced\',
            \'default\'
            );
    }

    /**
     * Renders the meta box.
     */
    public function render_description( $post ) {
        // Add nonce for security and authentication.
        wp_nonce_field( \'update_post\', \'funnel_nonce\' );

        // Use get_post_meta to retrieve an existing value from the database.
        $description = get_post_meta( $post->ID, \'description\', true );

        // Display the form, using the current value.
       ?>
       <input type="text" class="widefat" placeholder="Enter description..." id="description" name="description" value="<?php echo esc_attr( $description ); ?>">
       <?php 
   }

   public function render_landing( $post ) {
        wp_nonce_field( \'update_post\', \'funnel_nonce\' );

        $landing_page = get_post_meta( $post->ID, \'landing_page\', true );
        $landing_link = get_post_meta( $post->ID, \'landing_link\', true );


        ?>
        <h4 style="display: inline-block;">Select a page:</h4>
        <?php wp_dropdown_pages($this->dropdown_args); ?>
        <br>
        <h4 style="display: inline-block;">Enter the success link:</h4>
        <input style="width: 600px;" type="url" value="<?php echo esc_attr( $landing_link ); ?>" name="landing_link" id="landing_link" placeholder="Enter success link...">
        <br>
        <br>

        <div class="meta_links" id="meta_links">
            <a href="#">Meta link 1</a>
            <a href="#">Meta link 2</a>
            <a href="#">Meta link 3</a>
        </div> 
        <?
        
   }

    /**
     * Handles saving the meta box.
     *
     * @param int     $post_id Post ID.
     * @param WP_Post $post    Post object.
     * @return null
     */
    public function save_metabox( $post_id, $post ) {

        // Add nonce for security and authentication.
        $nonce_name   = isset( $_POST[\'funnel_nonce\'] ) ? $_POST[\'funnel_nonce\'] : \'\';
        $nonce_action = \'update_post\';


        // Check if nonce is valid.
        if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) ) {
            return;
        }

        // Check if user has permissions to save data.
        if ( ! current_user_can( \'edit_post\', $post_id ) ) {
            return;
        }

        // Check if not an autosave.
        if ( wp_is_post_autosave( $post_id ) ) {
            return;
        }

        // Check if not a revision.
        if ( wp_is_post_revision( $post_id ) ) {
            return;
        }

        $fields = [
            \'landing_page\' => \'landing_page\',
            \'landing_link\' => \'landing_link\',
            \'description\' => \'description\'
        ];

        foreach ( $fields as $posted_key => $post_meta_key ) {
            $posted_value = \'\';

            if ( isset( $_POST[ $posted_key ] ) ) {
                $posted_value = sanitize_text_field( wp_unslash( $_POST[ $posted_key ] ) );
            }

            if ( ! empty( $posted_value ) ) {
                update_post_meta( $post_id, $post_meta_key, $posted_value );
            } 

            else {
                delete_post_meta( $post_id, $posted_key );
            }
        }
    }
}

new description_meta();

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

您用来设置所选项目的变量似乎未在该范围内定义。

在构造函数中:

    public function __construct() {
        if ( is_admin() ) {
            add_action( \'load-post.php\',     array( $this, \'init_metabox\' ) );
            add_action( \'load-post-new.php\', array( $this, \'init_metabox\' ) );            
        }

        $this->dropdown_args = [
            \'show_option_none\' => \'- select a page -\',
            \'option_none_value\' => \'no page selected\',
            \'id\'               => \'landing_page\',
            \'name\'             => \'landing_page\',
            \'value_field\'      => \'landing_page\',
            \'selected\'         => $landing_page
        ];
    }
$landing_page 此处未定义。

我并不完全熟悉您的所有代码,但对于您使用的其他字段get_post_meta( $post->ID, \'description\', true ) 获取该字段的当前值。

$post 在构造函数中不可用您需要正确设置selected 中的参数render_landing(). 可能类似于:

替换:

    <?php wp_dropdown_pages($this->dropdown_args); ?>
使用:

    <?php 
    $args = $this->dropdown_args; 
    $args[\'selected\'] = get_post_meta( $post->ID, \'landing_page\', true );
    wp_dropdown_pages($args);
    ?>
由于您的代码很好而且干净,我想您应该整理一下构造函数,这样它就不会将所选字段设置为空值,并且可以生成字符串landing_page 一个类级变量或常量,这样它就不会在不同的地方重复。

如果有效,请告诉我