函数Widget()中的实例为空

时间:2014-12-22 作者:Jamie

我正在为我的主题开发一个小部件。如果我做了

print_r($insance) 
在form函数中,使用正确的数据填充实例数组。我已经检查了数据库,我的小部件的选项表中有正确的信息。

我的问题是,如果我

print_r($instance) 
对于前端,数组是空的,我在小部件函数中得到了未定义的索引。我一直没能弄清楚到底是怎么回事。

 class alliance_post_builder extends WP_Widget {

/**
 * Register widget with WordPress.
 */
function __construct() {
    parent::__construct(
        \'alliance_post_builder\', // Base ID
        __( \'Alliance post builder\', \'alliance\' ), // Name
        array( \'description\' => __( \'A post builder\', \'alliance\' ), ) // Args
    );
}

/**
 * Front-end display of widget.
 *
 * @see WP_Widget::widget()
 *
 * @param array $args     Widget arguments.
 * @param array $instance Saved values from database.
 */
public function widget( $args, $instance ) {
    extract( $args );

    $sectionID = $instance[\'sectionID\'];
    $title = $instance[\'title\'];
    $category = $instance[\'category\'];  

?><section id="<?php echo $sectionID; ?>"><?php
        print_r($instance);
    ?></section><?php
} 

    /**
 * Sanitize widget form values as they are saved.
 *
 * @see WP_Widget::update()
 *
 * @param array $new_instance Values just sent to be saved.
 * @param array $old_instance Previously saved values from database.
 *
 * @return array Updated safe values to be saved.
 */
function update( $new_instance, $old_instance ) {
    $instance = $old_instance;

    /* Strip tags for title and name to remove HTML (important for text inputs). */
    $instance[\'title\'] = strip_tags( $new_instance[\'title\'] );
    $instance[\'sectionID\'] = strip_tags( $new_instance[\'sectionID\'] );
    $instance[\'category\'] = $new_instance[\'category\'];

    return $instance;
}

/** 
 * Back-end widget form.
 *
 * @see WP_Widget::form()
 *
 * @param array $instance Previously saved values from database.
 */
public function form( $instance ) {

$defaults = array( \'title\' => __(\'A new section\', \'alliance\'), \'sectionID\' => __(\'\', \'alliance\'), \'category\' => -1 );
$instance = wp_parse_args( (array) $instance, $defaults ); 

    ?>
    <p>
    <label for="<?php echo $this->get_field_id( \'sectionID\' ); ?>"><?php _e( \'Section Id:\' ); ?></label> 
    <input class="widefat" id="<?php echo $this->get_field_id( \'sectionID\' ); ?>" name="<?php echo $this->get_field_name( \'sectionID\' ); ?>" type="text" value="<?php echo esc_attr( $sectionID ); ?>">
    </p>

    <p>
    <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label> 
    <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
    </p>
    <?php 
        wp_dropdown_categories( array(
        \'name\' => $this->get_field_name( \'category\' ),
        \'selected\' => $instance["category"],
        \'show_option_none\'   => \'None\',
    ) );
}
 }

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

你的小部件确实有很多问题,完全破坏了我在后端小部件页面上的布局。我建议你从Widget API 学习编写小部件的正确方法

以下是我发现的几个问题:

声誉良好的消息来源不应建议甚至使用extract(). 该函数的所有痕迹都已从core中完全删除,只有一个实例(据我从trac记录单中了解)尚未解决。这应该说明了很多关于函数的内容

您的小部件form 是破坏我布局的罪魁祸首。我甚至没有试着去看这个问题,因为这里有两个以上的问题。我刚刚完全改变了这一点get_categories() 正如我之前建议的那样,让下拉菜单正常工作并阻止我的布局被破坏

您的widget 应该输出前端信息的函数缺少许多元素。我不确定你想要的是什么样的布局,也不确定你的计划在使用中是什么,所以我只做了以下几点:(这是你应该拥有的基本必需品)

?><section id="<?php echo $sectionID; ?>"><?php

echo $args[\'before_widget\'];
if ( $title ) {
    echo $args[\'before_title\'] . $title . $args[\'after_title\'];
}               
echo "SOMETHING IS MISSING HERE";

echo $args[\'after_widget\']; 

?></section><?php
根据naming convention section in the coding standards

我还在小部件中添加了一个缓存以加快速度

下面是一个小部件的工作示例。我已经测试过了,它对我来说很有效。我还将在前端获得给定代码的输出,您只需修改此代码并在我声明的地方添加缺少的部分echo "SOMETHING IS MISSING HERE";

/**
 * Alliance_Post_Builder widget class
 *
 * @since 1.0.0
*/
class Alliance_Post_Builder extends WP_Widget {

    public function __construct() {
    parent::__construct(
        \'alliance_post_builder\', // Base ID
        __( \'Alliance post builder\', \'alliance\' ), // Name
        array( \'description\' => __( \'A post builder\', \'alliance\' ), ) // Args
    );
        $this->alt_option_name = \'widget_alliance_posts\';

        add_action( \'save_post\', array($this, \'flush_widget_cache\') );
        add_action( \'deleted_post\', array($this, \'flush_widget_cache\') );
        add_action( \'switch_theme\', array($this, \'flush_widget_cache\') );
    }

    public function widget( $args, $instance ) {
        $cache = array();
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( \'widget_alliance_build_posts\', \'widget\' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = array();
        }

        if ( ! isset( $args[\'widget_id\'] ) ) {
            $args[\'widget_id\'] = $this->id;
        }

        if ( isset( $cache[ $args[\'widget_id\'] ] ) ) {
            echo $cache[ $args[\'widget_id\'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance[\'title\'] ) ) ? $instance[\'title\'] : __( \'A new section\', \'alliance\' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( \'widget_title\', $title, $instance, $this->id_base );
        $sectionID      = ( ! empty( $instance[\'sectionID\'] ) ) ? $instance[\'sectionID\'] : __( \'A new section\', \'alliance\' );
        $category       = $instance[\'category\'];  


        ?><section id="<?php echo $sectionID; ?>"><?php

        echo $args[\'before_widget\'];
        if ( $title ) {
            echo $args[\'before_title\'] . $title . $args[\'after_title\'];
        }               
        echo "SOMETHING IS MISSING HERE";

        echo $args[\'after_widget\']; 

        ?></section><?php

        if ( ! $this->is_preview() ) {
            $cache[ $args[\'widget_id\'] ] = ob_get_flush();
            wp_cache_set( \'widget_alliance_build_posts\', $cache, \'widget\' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) {
        $instance                   = $old_instance;
        $instance[\'title\']          = strip_tags( $new_instance[\'title\'] );
        $instance[\'sectionID\']      = strip_tags( $new_instance[\'sectionID\'] );
        $instance[\'category\']       = $new_instance[\'category\'];
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( \'alloptions\', \'options\' );
        if ( isset($alloptions[\'widget_alliance_posts\']) )
            delete_option(\'widget_alliance_posts\');

        return $instance;
    }

    public function flush_widget_cache() {
        wp_cache_delete(\'widget_alliance_build_posts\', \'widget\');
    }

    public function form( $instance ) {

        $title      = isset( $instance[\'title\'] ) ? esc_attr( $instance[\'title\'] ) : \'\';
        $sectionID  = isset( $instance[\'sectionID\'] ) ? esc_attr( $instance[\'sectionID\'] ) : \'\';
        $category   = isset( $instance[\'category\'] ) ? $instance[\'category\'] : -1;
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( \'sectionID\' ); ?>"><?php _e( \'Section Id:\' ); ?></label> 
            <input class="widefat" id="<?php echo $this->get_field_id( \'sectionID\' ); ?>" name="<?php echo $this->get_field_name( \'sectionID\' ); ?>" type="text" value="<?php echo esc_attr( $sectionID ); ?>">
        </p>

        <p>
            <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( \'title\' ); ?>" name="<?php echo $this->get_field_name( \'title\' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

        <p>
            <label for="<?php echo $this->get_field_id(\'category\'); ?>"><?php _e( \'Category Name:\' )?></label>
            <select id="<?php echo $this->get_field_id(\'category\'); ?>" name="<?php echo $this->get_field_name(\'category\'); ?>">
                <?php 
                $this->categories = get_categories();
                foreach ( $this->categories as $cat ) {
                    $selected = ( $cat->term_id == esc_attr( $category ) ) ? \' selected = "selected" \' : \'\';
                    $option = \'<option \'.$selected .\'value="\' . $cat->term_id;
                    $option = $option .\'">\';
                    $option = $option .$cat->name;
                    $option = $option .\'</option>\';
                    echo $option;
                }
                ?>
            </select>
        </p>

    <?php
    }

}

add_action( \'widgets_init\', function () {
    register_widget( \'Alliance_Post_Builder\' );
}); 

SO网友:Thawdar

我也有同样的问题function widget($args, $instance). 问题是当我调试时var_dump($instance), 它是array{} (空数组)并且小部件设置没有值。

所以我忘了$instance 变量并使用$this->get_settings() 函数检索小部件的设置。现在可以工作了。我讨厌$instance 变量

结束

相关推荐

Multiple widgets in wordpress

我已经创建了一个wordpress小部件。它在小部件选项中有一个下拉列表。下拉列表包含“facebook”和“twitter”。如果管理员选择“twitter”,那么twitter关注者计数将显示在小部件中,与facebook的情况类似。使用jquery,该计数显示在id为“social count”的div中。当页面加载时,jquery ajax将获取计数并将其插入到“社交计数”中。问题是它在单个实例中运行良好。但是,如果在侧栏中添加了2个实例,则在这两个实例中都会显示最新的计数,因为我使用的是$(“.