Wordpress:获取 ACF(高级帖子字段)插件中的选择字段选项选项?

Alf*_*ang 4 php wordpress advanced-custom-fields

我现在在 wordpress 中使用高级自定义字段插件。

现在我定义了一些选择,它们的选择设置如下:

字段名称:time_availability

字段类型:选择

low : Once or twice
high : Several times
Run Code Online (Sandbox Code Playgroud)

所以,我想在页面代码中枚举这些设置,比如渲染:

<ul>
  <li><input type="radio" name="low" /> Once or twice</li>
  <li><input type="radio" name="high" /> Several times</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到选择?


更新:

似乎如果调用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)
}
Run Code Online (Sandbox Code Playgroud)

不是预期的结果。

如果我使用原始字段名称调用该函数:

get_field_object('field_55df081515e81');
Run Code Online (Sandbox Code Playgroud)

没错!

怎么了?有什么区别,我怎样才能正确使用 field_name?

xph*_*han 7

在 ACF 网站上,他们声明:

“API 将返回选定的值。如果您为此字段选择多个选项,API 将返回一个值数组。”

所以请尝试以下操作:

// 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>
Run Code Online (Sandbox Code Playgroud)

如果您启用了多个值的选择,则应使用复选框而不是单选框。


要访问可用的选项,您必须获取字段对象

// 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>';
}
Run Code Online (Sandbox Code Playgroud)

要从user获取字段对象,请使用以下表示法:

$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)
Run Code Online (Sandbox Code Playgroud)

  • 因此,请更新您的问题,不要投反对票。请参阅我更新的问题。 (2认同)
  • **get_field_object** 适用于 field_name 或 field_key (这是唯一的)。如果您使用“field_name”执行“get_field_object”且没有相应的页面 ID,它会尝试从当前页面获取元值。因此,如果您尝试在 **不同** 站点上获取字段值,则需要将字段键或字段名称与保存字段的帖子 ID 结合使用。 (2认同)

Alf*_*ang 6

最后,毕竟我找到了一个可靠的解决方案来解决这个问题:

可以先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;
}
Run Code Online (Sandbox Code Playgroud)

我们可以遍历所有已注册的字段以选择正确的字段。

但是$GLOBALS['acf_register_field_group']只有当我们register_field_group明确调用时才存在(下面的案例 2)。或者在正常情况下(下面的案例 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;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,字段组存储为帖子类型为acf,字段信息存储post_meta为该字段组。

因此,我们获取所有注册的字段(从数据库中),并选择正确的字段。


情况 2:当register_field_group显式时,例如在以下内容中使用导出 php 脚本functions.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;
}
Run Code Online (Sandbox Code Playgroud)

然后我们终于得到了一个永远工作的函数:

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;
}
Run Code Online (Sandbox Code Playgroud)


ahg*_*ood 5

不知道为什么get_field_object总是返回 false,并且我在不再工作之前投票的答案,所以我必须制定一个新的解决方案,我想也许 ACF 更新了数据存储的方式,自定义字段现在存储在wp_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;
}
Run Code Online (Sandbox Code Playgroud)