【问题标题】:How to group an Option group in html select from WordPress values?如何从 WordPress 值中对 html 中的选项组进行分组?
【发布时间】:2015-03-23 18:16:18
【问题描述】:

我有这个 HTML optgroup 选择框,它是根据存储在 WordPress 数据库中的值填充的。

$field_val = get_post_meta($post->ID, $field['id'], true);

echo '<select id="'.$field['id'].'" name="'.$field['id'].'">';
foreach ($field['options'] as $key => $value) {
    $custom_fields = get_post_custom($value);
    $bgtypes = $custom_fields['bgtype'];
    foreach($bgtypes as $bgkey => $type){

        echo '<optgroup label="'.$type.'">';
            echo '<option value="'.$value.'" '.selected($value, $field_val, false).'>'.$key.'</option>';
        echo '</optgroup>';
    }
}
echo '</select>';

它检索所有正确的数据,但是当它打印出未“分组”的值时。

以下是返回结果的示例:

<select id="_wpbp_background" name="_wpbp_background">
  <optgroup label="youtube">
  <option value="2777" >YouTube Playlist video</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2775" >Another Self Hosted Video</option>
  </optgroup>
  <optgroup label="images">
  <option value="2774" >Image Slideshow Main</option>
  </optgroup>
  <optgroup label="pattern">
  <option value="2773" >Carbon Pattern BG</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2772" >Purple Solid BG Color</option>
  </optgroup>
  <optgroup label="audio">
  <option value="2771" >Test Audio File 2</option>
  </optgroup>
  <optgroup label="images">
  <option value="2759" >test image slideshow</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2747"  selected='selected'>Test Hosted Video</option>
  </optgroup>
  <optgroup label="youtube">
  <option value="2736" >YouTube Video 1</option>
  </optgroup>
  <optgroup label="pattern">
  <option value="2718" >Pattern 1</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2711" >test video 1</option>
  </optgroup>
  <optgroup label="audio">
  <option value="2693" >Test audio file 1</option>
  </optgroup>
  <optgroup label="images">
  <option value="2670" >test image</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2669" >Blue Solid Background</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2667" >Red Background</option>
  </optgroup>
</select>

如果您查看返回的结果,您会注意到有许多同名的组。例如“图像”。

有没有一种方法可以修改原始 PHP 代码来对这些选项进行分组,如下所示:

<select id="_wpbp_background" name="_wpbp_background">
  <optgroup label="images">
  <option value="2774" >Image Slideshow Main</option>
  <option value="2759" >test image slideshow</option>
  <option value="2670" >test image</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2669" >Blue Solid Background</option>
  <option value="2667" >Red Background</option>
  </optgroup>
</select>

任何帮助将不胜感激。谢谢

================================================ ======================== 编辑:

这是我调用以获取“背景”自定义帖子类型元素的原始函数:

/**
 * Returns a list of backgrounds
 */
function get_backgrounds(){
    $bgs = get_posts(array(
        'post_type'   => $this->cpt,
        'numberposts' => -1,
        'orderby'     => 'title',
    ));
    $backgrounds = array();
    $backgrounds[__('-- Select Background --', $this->prefix)] = '';
    foreach($bgs as $key => $value){
        $backgrounds[$value->post_title] = $value->ID;
    }
    return $backgrounds;
}

调用时显示上述代码

Array
(
    [-- Select Background --] => 
    [YouTube Video 1] => 2736
    [YouTube Playlist video] => 2777
    [test video 1] => 2711
    [test image slideshow] => 2759
    [test image] => 2670
    [Test Hosted Video] => 2747
    [Test Audio File 2] => 2771
    [Test audio file 1] => 2693
    [Red Background] => 2667
    [Purple Solid BG Color] => 2772
    [Pattern 1] => 2718
    [Image Slideshow Main] => 2774
    [Carbon Pattern BG] => 2773
    [Blue Solid Background] => 2669
    [Another Self Hosted Video] => 2775
)

部分有效的第一个代码块:

// <optgroup> of the previous <option>
$previous = "";

// variable to set the first group
$first_group = true;

foreach ($field['options'] as $key => $value) {
    $custom_fields = get_post_custom($value);

    if (isset($custom_fields['bgtype'][0]) && $custom_fields['bgtype'][0]) {
        $bgtypes = $custom_fields['bgtype'];

        foreach($bgtypes as $typebg){

            if ($typebg != $previous) {
                if (!$first_group) {
                    echo '</optgroup>';
                } else {
                    $first_group = false;
                }
                echo '<optgroup label="'.$typebg.'">';
                $previous = $typebg;
            }

            echo '<option value="'.$value.'" '.selected($value, $field_val, false).'>'.$key.'</option>';
        }
    }
}
echo '</optgroup>';  // close last optgroup
echo '</select>';

第一个代码块的结果:

<select id="_wpbp_background" name="_wpbp_background">
  <optgroup label="youtube">
  <option value="2736" >YouTube Video 1</option>
  <option value="2777" >YouTube Playlist video</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2711" >test video 1</option>
  </optgroup>
  <optgroup label="images">
  <option value="2759" >test image slideshow</option>
  <option value="2670" >test image</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2747"  selected='selected'>Test Hosted Video</option>
  </optgroup>
  <optgroup label="audio">
  <option value="2771" >Test Audio File 2</option>
  <option value="2693" >Test audio file 1</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2667" >Red Background</option>
  <option value="2772" >Purple Solid BG Color</option>
  </optgroup>
  <optgroup label="pattern">
  <option value="2718" >Pattern 1</option>
  </optgroup>
  <optgroup label="images">
  <option value="2774" >Image Slideshow Main</option>
  </optgroup>
  <optgroup label="pattern">
  <option value="2773" >Carbon Pattern BG</option>
  </optgroup>
  <optgroup label="solid">
  <option value="2669" >Blue Solid Background</option>
  </optgroup>
  <optgroup label="videos">
  <option value="2775" >Another Self Hosted Video</option>
  </optgroup>
</select>

如您所见,此代码块按元素的“字节”对元素进行部分分组。它将其中一些分组,但不是全部。我以这种方式分组的方法是将'orderby' =&gt; 'title' 添加到初始函数以显示背景。

**Second code block:**
echo '<select id="'.$field['id'].'" name="'.$field['id'].'">';
foreach ($field['options'] as $key => $value) {
    $custom_fields = get_post_custom($value);

        $bgtypes = $custom_fields['bgtype'];

        foreach($bgtypes as $bgkey => $type){

            if(strpos($type,'images') !== false):

                $images.= '<optgroup label="'.$type.'">'.'<option value="'.$value.'" '.selected($value, $field_val, false).'>'.$key.'</option>'.'</optgroup>';
            elseif(strpos($type,'youtube') !== false):
                $youtube.= '<optgroup label="'.$type.'">'.'<option value="'.$value.'" '.selected($value, $field_val, false).'>'.$key.'</option>'.'</optgroup>';

            else:
                $other.= '<optgroup label="'.$type.'">'.'<option value="'.$value.'" '.selected($value, $field_val, false).'>'.$key.'</option>'.'</optgroup>';

            endif;

        }
}
echo $images;
echo $youtube;
echo $other;
echo '</select>';

在这段代码中,我将 strpos 函数更改为 if(strpos($type,'images') !== false): 以与实际的“bgtype”进行比较,因为 $bgkey 变量对所有结果都返回 0。

不幸的是,这段代码仍然返回未按其“bgtypes”分组的列表。

编辑 3:返回“PostId”、“Post Title”和“BGType”的新代码。

// Get a list of all the created backgrounds
$bgs = get_posts(array(
    'post_type'   => 'wpbp-backgrounds',
    'numberposts' => -1,
    'orderby'     => 'title',
));

foreach($bgs as $key => $value){
    // Post Id
    $cpid =  $value->ID;
    // Post Title
    $cptitle = $value->post_title;
    // BGType
    $custom_fields = get_post_custom($cpid);
    $cpbgtype = $custom_fields['bgtype'];

    if (isset($custom_fields['bgtype'][0]) && $custom_fields['bgtype'][0]) {
        //This is where I would create all the code and group them
    }
}

以上代码使用echo $cpid . ' - ' . $cptitle .' - '.$cpbgtype.'&lt;br&gt;';的结果是:

2736 - YouTube Video 1 - youtube
2777 - YouTube Playlist video - youtube
2711 - test video 1 - videos
2759 - test image slideshow - images
2670 - test image - images
2747 - Test Hosted Video - videos
2771 - Test Audio File 2 - audio
2693 - Test audio file 1 - audio
2667 - Red Background - solid
2772 - Purple Solid BG Color - solid
2718 - Pattern 1 - pattern
2774 - Image Slideshow Main - images
2773 - Carbon Pattern BG - pattern
2669 - Blue Solid Background - solid
2775 - Another Self Hosted Video - videos

上面的代码似乎提供了项目的所有详细信息。我只是不确定如何将它们分组到 optgroup 并在下拉列表中按顺序显示。

编辑 4:var_dump() 的输出 如果我运行此代码:var_dump($cpbgtype); 我会收到此输出:

array(1) {
  [0]=>
  string(7) "youtube"
}
array(1) {
  [0]=>
  string(7) "youtube"
}
array(1) {
  [0]=>
  string(6) "videos"
}
array(1) {
  [0]=>
  string(6) "images"
}
array(1) {
  [0]=>
  string(6) "images"
}
array(1) {
  [0]=>
  string(6) "videos"
}
array(1) {
  [0]=>
  string(5) "audio"
}
array(1) {
  [0]=>
  string(5) "audio"
}
array(1) {
  [0]=>
  string(5) "solid"
}
array(1) {
  [0]=>
  string(5) "solid"
}
array(1) {
  [0]=>
  string(7) "pattern"
}
array(1) {
  [0]=>
  string(6) "images"
}
array(1) {
  [0]=>
  string(7) "pattern"
}
array(1) {
  [0]=>
  string(5) "solid"
}
array(1) {
  [0]=>
  string(6) "videos"
}

但是,如果我运行此代码 var_dump($custom_fields['bgtype'][0]); 我会收到此输出。不知道该调用哪一个,因为这个实际上是我如何引用每个“bgtype”

string(7) "youtube"
string(7) "youtube"
string(6) "videos"
string(6) "images"
string(6) "images"
string(6) "videos"
string(5) "audio"
string(5) "audio"
string(5) "solid"
string(5) "solid"
string(7) "pattern"
string(6) "images"
string(7) "pattern"
string(5) "solid"
string(6) "videos"

编辑 5:var_dump($custom_fields) 的输出

array(14) {
  ["_edit_lock"]=>
  array(1) {
    [0]=>
    string(12) "1421540192:1"
  }
  ["_edit_last"]=>
  array(1) {
    [0]=>
    string(1) "1"
  }
  ["bgtype"]=>
  array(1) {
    [0]=>
    string(7) "youtube"
  }
  ["poster"]=>
  array(1) {
    [0]=>
    string(70) "http://localhost/wordpress-dev/wp-content/uploads/2015/01/mash_ups.png"
  }
  ["volume"]=>
  array(1) {
    [0]=>
    string(2) "10"
  }
  ["mute"]=>
  array(1) {
    [0]=>
    string(4) "true"
  }
  ["showplay"]=>
  array(1) {
    [0]=>
    string(4) "true"
  }
  ["showmute"]=>
  array(1) {
    [0]=>
    string(4) "true"
  }
  ["paused"]=>
  array(1) {
    [0]=>
    string(5) "false"
  }
  ["loopvideo"]=>
  array(1) {
    [0]=>
    string(5) "false"
  }
  ["ytbtnbg"]=>
  array(1) {
    [0]=>
    string(7) "#565656"
  }
  ["ytbtntxt"]=>
  array(1) {
    [0]=>
    string(7) "#ffffff"
  }
  ["video_controls"]=>
  array(1) {
    [0]=>
    string(11) "bottom_left"
  }
  ["playlist"]=>
  array(1) {
    [0]=>
    string(59) "ZKa8OEPCZrg,goKm9Oafs3E,OCHy1nUdfu8,mpCFLr0NPjA,i3WX-VeNKmk"
  }
}

从这个 var_dump() 我在 BGType 之后,在这种情况下是:

["bgtype"]=>
      array(1) {
        [0]=>
        string(7) "youtube"
      }

这是我在循环中调用的每个单独背景返回的内容

【问题讨论】:

    标签: php wordpress select optgroup


    【解决方案1】:

    你可以做一个简单的 if 测试来看看 $key 包含什么...

    $field_val = get_post_meta($post->ID, $field['id'], true);
    
                $bgtypes= array('youtube', 'videos', 'images', 'solid', 'audio'); // adjust this to create the headings. As far as i can see this will be more or less consistant? 
    
        foreach($bgtypes as $bgkey):
    
            //remove plurals to make checking easier
    
            if (substr($bgkey, -1) == 's')
                $bgkey = substr($bgkey, 0, -1);
    
            foreach($field['options'] as $option => $key):  
                if(stripos($option, $bgkey) !==false ):
                    $options[$bgkey][$option]= $key;
                    unset($field['options'][$option]);
                endif;
            endforeach;  
    
        endforeach;
    
        $options['other']= $field['options'];
    
    
        echo '<select id="'.$field['id'].'" name="'.$field['id'].'">';
    
    
            foreach($options as $item=>$key):
                echo '<optgroup label="'.$item.'">';
                    foreach($key as $line=>$data):
                        echo '<option value="'.$data.'" >'.$line.'</option>';
                    endforeach;
                echo '</optgroup>';
            endforeach;
        echo '</select>';
    

    我不得不猜测一些数组的输出,但它应该足够接近。

    第三次编辑的答案:

            $bgs = get_posts(array(
            'post_type'   => 'wpbp-backgrounds',
            'numberposts' => -1,
            'orderby'     => 'title',
        ));
    
        foreach($bgs as $key => $value){
            // Post Id
            $cpid =  $value->ID;
            // Post Title
            $cptitle = $value->post_title;
            // BGType
            $custom_fields = get_post_custom($cpid);
            $cpbgtype = $custom_fields['bgtype'][0];
    
            // since the data is associated with the post its easier to implement.
            if (isset($custom_fields['bgtype'][0]) && $custom_fields['bgtype'][0]) {
                $output[$cpbgtype][]= '<option value="'.$cpid.'" >'.$cptitle.'</option>'  ;
            }
        }
    
        echo '<select id="'.$field['id'].'" name="'.$field['id'].'">'; // dont know if the $field values are still there
    
        foreach($output as $type=>$data):
            echo '<optgroup label="'.$type.'">';
                foreach($data as $item):
                    echo $item;
                endforeach; 
            echo '</optgroup>';
        endforeach;
    
        echo '</select>';
    

    【讨论】:

    • 谢谢@David,我试过你的代码,但它仍然没有对“bgtypes”进行分组。
    • 是的,根据您的需要修改它......如果这是分组元素&lt;optgroup label="images"&gt;,我已经调整了上面的内容,但您需要自己检查比较值.. .
    • 嗨@David,感谢您的帮助。无论我尝试什么,我仍然无法让您的代码对选项进行分组。可能是因为在第一个 foreach 循环中我循环了所有“选项”,而第二个(内部)foreach 循环循环了“bgtypes”。
    • 好的,如果您检查它,我认为它现在应该比较正确的密钥。基本上 strpos 函数在变量中查找值,因此如果您查找“图像”并且您的键是图像,它将返回 0(我们接受为真)如果键是 IMAGE,它将返回 false(它区分大小写)。您需要通过以下方式决定将元素组合在一起的内容:查看您在上面输入的代码,输出的内容是什么?你用什么值来检查等等。只需为你想要检查的 ea 值创建一个新的 else if 循环,并且显然是一个新变量。
    • 嗨@David,再次感谢。我正在尝试按元素的“bgtype”(图像、youtube、视频、模式)等对元素进行分组。我将添加到我的上述问题中,向您展示我试图让代码正常工作的两种方法。
    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2023-02-16
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2012-03-24
    相关资源
    最近更新 更多