1

我正在尝试创建一个小部件,使用户能够选择将显示哪些类别。以下是我创建的一段代码,但无法保存复选框状态的更改。只有两个值:所选类别的标题和列表。

function form($instance) {
    $instance = (array)$instance;
    if( empty($instance['title']) ) $instance['title'] = 'Category';
    $selected_categories = (array)$instance['category'];
    var_dump($selected_categories); 
    ....
    $categories = get_categories( array('exclude'=> 1) );
    foreach($categories as $category) : ?>
    <div>
        <input type="checkbox" name="<?php echo $this->get_field_name('category'); ?>"
            value="<?php echo $category->cat_ID; ?>"
            <?php echo $category->cat_name; ?>
    </div>
    <?php endforeach; ?>
}

function update($new_instance, $old_instance) {
    $instance = $old_instance;
    $instance['title'] = strip_tags($new_instance['title']);
    $instance['category'] = $new_instance['category'];

    return $instance;
}

我通过 var_dump($selected_categories) 观察变化。该值始终为 array(size=0) 忽略我检查了多少复选框。

我不知道如何在 $instance 变量中传递数组。

提前致谢。

4

3 回答 3

0

我在这个确切的问题上花了很多时间。关于这个主题的在线搜索并不令人满意。我想了解 Widget 扩展 WP_Widget 对象是如何工作的。就像原来的帖子一样,我也想让我的管理员从所有帖子类别的动态检查列表中进行选择。在我的网站上,我用它来做宣传,我希望有很多这只小狗的实例。一个健壮的实例存储系统对我来说是必不可少的。

有几个愚蠢的问题困扰着我。1) =.. 的时髦标签是怎么回事。我在每个在线示例中看到的类别名称/标签。(注意'标签'被左/右符号包围..在这里不能这样做..)这是必需的,还是只是有人复制以前做过的事情(在 WordPress 源代码中的文件 defaults-widgets.php 中) ? 答:完全浪费时间。少即是多,编码正确。

2)我真的很想了解系统如何保存用户选择的机制。后端页面上似乎没有明显的编码来捕获选择。我花了很长时间在这里搜索,包括尝试在调试器上单步执行代码,结果很糟糕。我花了很多时间使用 var_dump($instance) 来了解结果。该系统有效,但我真的不明白为什么。

我让这个系统工作的逻辑是创建一个复选框变量,让它工作。下一步是创建一个复选框变量数组,但只使用其中一个并让它工作。最后利用整个复选框变量数组。成功。

代码摘录如下:

/*Saves the settings. */
function update( $new_instance, $old_instance ){

    $args = array(
        //your selections here.
    ); 
    $categories = get_categories( $args );   // returns an array of category objects
    $arrlength=count($categories);

    for($x=0;$x<$arrlength;$x++){
        $tempArray[$categories[$x]->slug] = '';  
    }
    $instance = $old_instance;       
    $new_instance = wp_parse_args( (array) $new_instance, $tempArray );

    for($x=0;$x<$arrlength;$x++){
        $instance[$categories[$x]->slug] = $new_instance[$categories[$x]->slug] ? 1 : 0;
    }
    return $instance;
}

/*Creates the form for the widget in the admin back-end. */
function form( $instance ){
     echo '<p>Choose your categories of interest. Multiple selections are fine.</p> ';

    $args = array(
         //your selections here.  Use same args as update function, duh.
    ); 
    $categories = get_categories( $args );   // returns an array of category objects
    $arrlength=count($categories);

    for($x=0;$x<$arrlength;$x++){
        $tempArray[$this->get_field_id($categories[$x]->slug)] = '';
    }
    $instance = wp_parse_args( (array) $instance, $tempArray );

    for($x=0;$x<$arrlength;$x++){
        $tempCheckFlag[$categories[$x]->slug] = $instance[$categories[$x]->slug]  ? 'checked="checked"' : '';   
        // could also use 'checked()' function    
        // Yup, this could be combined with the for loop below, 
        // listed here seperately to enhance understanding of what's going on.
    }

    for($x=0;$x<$arrlength;$x++)
    {
        echo '<p><input class ="checkbox" type="checkbox" value="1" id="'.$this->get_field_id($categories[$x]->slug).'" name="'.$this->get_field_name($categories[$x]->slug).'"'.$tempCheckFlag[$categories[$x]->slug].'>'.$categories[$x]->name.'  (Category # '.$categories[$x]->term_id.' )</p>';  
    }
}

当我需要在我的小部件函数中使用选择时,我会从 $instance 变量中检索管理员的选择。

/* Displays the Widget in the front-end */
function widget( $args, $instance ){
    //.... 

    foreach($instance as $key=>$value)
    {
        if ($value){
            $category_array[]=$key;
        }
    }
 // Now I have a simple array of just those categories that had a check mark... 
于 2014-03-01T20:33:54.757 回答
0

如果未设置数组中的值,您是否有一个验证函数来填充它们?这就是小部件的 »update« 方法。也许您应该添加:

'<input name="..." value="..." id="'.$this->get_field_id( 'category' ).'" />';

到您的输入元素。

于 2013-02-21T07:38:25.233 回答
0

这是使用复选框数组的第二种解决方案。我在我的小部件最近更新的帖子小部件的新版本 1.8 中使用复选框数组解决了这个问题。我使用第二种形式的foreach

foreach (array_expression as $key => $value).

$key允许为每个复选框获取一个唯一的 id 。这里 $id 是一个由 foreach 本身递增的数字。

function form($instance) {
$term_taxonomy_id = (isset($instance['term_taxonomy_id']) ? array_map('absint', $instance['term_taxonomy_id']) : array("0"));
<?php       
    $categ = get_categories();
    foreach($categ as $id => $item) :  
?>
<br/>
<input  type="checkbox"
    id="<?php echo $this->get_field_id('term_taxonomy_id') . $id; ?>" 
    name="<?php echo $this->get_field_name('term_taxonomy_id'); ?>[]" 
    <?php   if (isset($item->term_taxonomy_id)) {
                if (in_array($item->term_taxonomy_id,$term_taxonomy_id)) 
                    echo 'checked'; 
                };      
            ?>  
    value="<?php echo $item->term_taxonomy_id; ?>" />
<label for="<?php echo $this->get_field_id('term_taxonomy_id') . $id; ?>" >
<?php echo $item->name ?>
</label>
    <?php endforeach; ?>

我为我的插件存储了 term_taxonomy_id而不是cat_ID,但是您几乎可以存储cat_ID,它也可以工作。

数组数据由 php 函数 array_map() 清理。更新函数为:

 function update($new_instance, $old_instance) {
// Par défaut, aucune catégorie n'est exclue
    $instance['term_taxonomy_id'] =  (isset($new_instance['term_taxonomy_id']) ? array_map( 'absint', $new_instance['term_taxonomy_id']) : array('0'));

为了在 MySQL 查询中使用它们,我将其内爆为一组值:

// écriture de la liste des objects sélectionnées en langage MySQL
    if (isset($instance['term_taxonomy_id'])) 
        $selected_object = "('".implode(array_map( 'absint',$instance['term_taxonomy_id']),"','")."')"; 
    else $selected_object = "('0')";
于 2015-10-25T10:07:57.960 回答