Wordpress:获取 ACF(高级 Post 字段)插件中的 select 字段选项选项?
Wordpress: Get the select field option choices in ACF (Advanced Post Field) plugin?
我现在在 wordpress 中使用高级自定义字段插件。
现在我定义了一些Choices,它们的Choices设置如下:
Field Name: time_availability
Field Type: Select
low : Once or twice
high : Several times
所以,我想在页面代码中枚举这些设置,比如渲染:
<ul>
<li><input type="radio" name="low" /> Once or twice</li>
<li><input type="radio" name="high" /> Several times</li>
</ul>
如何获得选择?
更新:
似乎如果调用 get_field_object($field_name)
可能会得到整个字段设置,包括选项。
但是当我用字段名调用函数时,返回如下:
array(18) {
["key"]=>
string(33) "field_time_availability"
["label"]=>
string(0) ""
["name"]=>
string(27) "time_availability"
["_name"]=>
string(27) "time_availability"
["type"]=>
string(4) "text"
["order_no"]=>
int(1)
["instructions"]=>
string(0) ""
["required"]=>
int(0)
["id"]=>
string(37) "acf-field-time_availability"
["class"]=>
string(4) "text"
["conditional_logic"]=>
array(3) {
["status"]=>
int(0)
["allorany"]=>
string(3) "all"
["rules"]=>
int(0)
}
["default_value"]=>
string(0) ""
["formatting"]=>
string(4) "html"
["maxlength"]=>
string(0) ""
["placeholder"]=>
string(0) ""
["prepend"]=>
string(0) ""
["append"]=>
string(0) ""
["value"]=>
bool(false)
}
不是预期的结果。
而如果我使用原始字段名称调用该函数:
get_field_object('field_55df081515e81');
一切顺利!
怎么了?有什么区别,如何使用 field_name?
他们在 ACF 网站上声明:
"The API will return the selected value. If you select the multiple option for this field, the API will return an array of values."
所以请尝试以下操作:
// get the selected value
$value = get_field('time_availability');
?>
<ul>
<li><input type="radio" name="low" <?php echo ($value == 'low'?'checked="checked"':''); ?>/> Once or twice</li>
<li><input type="radio" name="high" <?php echo ($value == 'high'?'checked="checked"':''); ?>/> Several times</li>
</ul>
如果您启用了多个值的选择,您应该使用复选框而不是单选框。
要访问可用选项,您必须获取字段对象。
// choose the field
$field_name = 'time_availability';
$field = get_field_object($field_name);
if( $field )
{
// build the form
echo '<select name="' . $field['key'] . '">';
foreach( $field['choices'] as $k => $v )
{
echo '<option value="' . $k . '">' . $v . '</option>';
}
echo '</select>';
}
要从用户获取字段对象,请使用此表示法:
$user_id = 2; // the id of the user
$field_name = 'your_field'; // the name of the field
get_field_object($field_name, 'user_.'.$user_id)
终于找到了绕过这个问题的靠谱方案:
可以先在源码中看到api_acf_load_field
函数:
add_filter('acf/load_field', 'api_acf_load_field', 1, 2);
function api_acf_load_field( $field, $field_key )
{
// validate
if( !empty($GLOBALS['acf_register_field_group']) )
{
foreach( $GLOBALS['acf_register_field_group'] as $acf )
{
if( !empty($acf['fields']) )
{
foreach( $acf['fields'] as $f )
{
var_dump($f['key']);
if( $f['key'] == $field_key )
{
$field = $f;
break;
}
}
}
}
}
return $field;
}
我们可以遍历所有已注册的字段来选择正确的字段。
但是 $GLOBALS['acf_register_field_group']
仅在我们显式调用 register_field_group
时才存在(下面的案例 2)。或者在正常情况下(下面的Case 1),我们这样是获取不到的。
所以看不同的情况:
案例 1:在管理面板中(在数据库中)定义字段组时:
function get_field_choices($field_name, $multi=false) {
$results = array();
foreach (get_posts(array('post_type' => 'acf', 'posts_per_page' => -1)) as $acf) {
$meta = get_post_meta($acf->ID);
foreach($meta as $key => $field) {
if(substr($key, 0, 6) == 'field_') {
$field = unserialize($field[0]);
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
此时字段组存储为post,post类型为acf
,字段信息存储为该字段组的post_meta
.
因此,我们获取所有已注册的字段(从数据库中),然后选择正确的字段。
情况 2:当 register_field_group
显式时,例如在 functions.php
:
中使用导出 php 脚本
function get_field_choices($field_name, $multi=false) {
$results = array(); $results = array();
foreach($GLOBALS['acf_register_field_group'] as $acf) {
foreach($acf['fields'] as $field) {
if(substr($field['key'], 0, 6) == 'field_') {
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
然后我们终于得到了一个always work函数:
function get_field_choices($field_name, $multi=false) {
$results = array();
foreach($GLOBALS['acf_register_field_group'] as $acf) {
foreach($acf['fields'] as $field) {
if(substr($field['key'], 0, 6) == 'field_') {
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
foreach (get_posts(array('post_type' => 'acf', 'posts_per_page' => -1)) as $acf) {
$meta = get_post_meta($acf->ID);
foreach($meta as $key => $field) {
if(substr($key, 0, 6) == 'field_') {
$field = unserialize($field[0]);
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
不知道为什么 get_field_object
总是 return false,而且我之前投票的答案不再有效,所以我必须想出一个新的解决方案,我想也许 ACF 更新了数据存储的方式, 自定义字段现在存储在 wp_post
table, post 类型是 acf-field
.
function get_field_choices($field_name, $multi = false) {
$results = array();
foreach (get_posts(array('post_type' => 'acf-field', 'posts_per_page' => -1)) as $acf) {
if ($acf->post_excerpt === $field_name) {
$field = unserialize($acf->post_content);
if(isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
return $results;
}
我现在在 wordpress 中使用高级自定义字段插件。
现在我定义了一些Choices,它们的Choices设置如下:
Field Name: time_availability
Field Type: Select
low : Once or twice
high : Several times
所以,我想在页面代码中枚举这些设置,比如渲染:
<ul>
<li><input type="radio" name="low" /> Once or twice</li>
<li><input type="radio" name="high" /> Several times</li>
</ul>
如何获得选择?
更新:
似乎如果调用 get_field_object($field_name)
可能会得到整个字段设置,包括选项。
但是当我用字段名调用函数时,返回如下:
array(18) {
["key"]=>
string(33) "field_time_availability"
["label"]=>
string(0) ""
["name"]=>
string(27) "time_availability"
["_name"]=>
string(27) "time_availability"
["type"]=>
string(4) "text"
["order_no"]=>
int(1)
["instructions"]=>
string(0) ""
["required"]=>
int(0)
["id"]=>
string(37) "acf-field-time_availability"
["class"]=>
string(4) "text"
["conditional_logic"]=>
array(3) {
["status"]=>
int(0)
["allorany"]=>
string(3) "all"
["rules"]=>
int(0)
}
["default_value"]=>
string(0) ""
["formatting"]=>
string(4) "html"
["maxlength"]=>
string(0) ""
["placeholder"]=>
string(0) ""
["prepend"]=>
string(0) ""
["append"]=>
string(0) ""
["value"]=>
bool(false)
}
不是预期的结果。
而如果我使用原始字段名称调用该函数:
get_field_object('field_55df081515e81');
一切顺利!
怎么了?有什么区别,如何使用 field_name?
他们在 ACF 网站上声明:
"The API will return the selected value. If you select the multiple option for this field, the API will return an array of values."
所以请尝试以下操作:
// get the selected value
$value = get_field('time_availability');
?>
<ul>
<li><input type="radio" name="low" <?php echo ($value == 'low'?'checked="checked"':''); ?>/> Once or twice</li>
<li><input type="radio" name="high" <?php echo ($value == 'high'?'checked="checked"':''); ?>/> Several times</li>
</ul>
如果您启用了多个值的选择,您应该使用复选框而不是单选框。
要访问可用选项,您必须获取字段对象。
// choose the field
$field_name = 'time_availability';
$field = get_field_object($field_name);
if( $field )
{
// build the form
echo '<select name="' . $field['key'] . '">';
foreach( $field['choices'] as $k => $v )
{
echo '<option value="' . $k . '">' . $v . '</option>';
}
echo '</select>';
}
要从用户获取字段对象,请使用此表示法:
$user_id = 2; // the id of the user
$field_name = 'your_field'; // the name of the field
get_field_object($field_name, 'user_.'.$user_id)
终于找到了绕过这个问题的靠谱方案:
可以先在源码中看到api_acf_load_field
函数:
add_filter('acf/load_field', 'api_acf_load_field', 1, 2);
function api_acf_load_field( $field, $field_key )
{
// validate
if( !empty($GLOBALS['acf_register_field_group']) )
{
foreach( $GLOBALS['acf_register_field_group'] as $acf )
{
if( !empty($acf['fields']) )
{
foreach( $acf['fields'] as $f )
{
var_dump($f['key']);
if( $f['key'] == $field_key )
{
$field = $f;
break;
}
}
}
}
}
return $field;
}
我们可以遍历所有已注册的字段来选择正确的字段。
但是 $GLOBALS['acf_register_field_group']
仅在我们显式调用 register_field_group
时才存在(下面的案例 2)。或者在正常情况下(下面的Case 1),我们这样是获取不到的。
所以看不同的情况:
案例 1:在管理面板中(在数据库中)定义字段组时:
function get_field_choices($field_name, $multi=false) {
$results = array();
foreach (get_posts(array('post_type' => 'acf', 'posts_per_page' => -1)) as $acf) {
$meta = get_post_meta($acf->ID);
foreach($meta as $key => $field) {
if(substr($key, 0, 6) == 'field_') {
$field = unserialize($field[0]);
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
此时字段组存储为post,post类型为acf
,字段信息存储为该字段组的post_meta
.
因此,我们获取所有已注册的字段(从数据库中),然后选择正确的字段。
情况 2:当 register_field_group
显式时,例如在 functions.php
:
中使用导出 php 脚本
function get_field_choices($field_name, $multi=false) {
$results = array(); $results = array();
foreach($GLOBALS['acf_register_field_group'] as $acf) {
foreach($acf['fields'] as $field) {
if(substr($field['key'], 0, 6) == 'field_') {
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
然后我们终于得到了一个always work函数:
function get_field_choices($field_name, $multi=false) {
$results = array();
foreach($GLOBALS['acf_register_field_group'] as $acf) {
foreach($acf['fields'] as $field) {
if(substr($field['key'], 0, 6) == 'field_') {
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
foreach (get_posts(array('post_type' => 'acf', 'posts_per_page' => -1)) as $acf) {
$meta = get_post_meta($acf->ID);
foreach($meta as $key => $field) {
if(substr($key, 0, 6) == 'field_') {
$field = unserialize($field[0]);
if($field['name'] == $field_name && isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
}
return $results;
}
不知道为什么 get_field_object
总是 return false,而且我之前投票的答案不再有效,所以我必须想出一个新的解决方案,我想也许 ACF 更新了数据存储的方式, 自定义字段现在存储在 wp_post
table, post 类型是 acf-field
.
function get_field_choices($field_name, $multi = false) {
$results = array();
foreach (get_posts(array('post_type' => 'acf-field', 'posts_per_page' => -1)) as $acf) {
if ($acf->post_excerpt === $field_name) {
$field = unserialize($acf->post_content);
if(isset($field['choices'])) {
if(!$multi) return $field['choices'];
else $results []= $field;
}
}
}
return $results;
}