'How do you create an ACF custom location rule to compare post meta keys to meta values?
Let's say you create a WordPress post and assign it a meta key foo with value bar. You only want to display an ACF field if foo is equal to bar. However, there's no built-in location rule in ACF to do this. How would you solve this problem by creating an ACF custom location rule?
Solution 1:[1]
In order to display ACF fields if a post meta key is equal or not equal to some value, use the following snippet. It's based off of the ACF Custom Location Rules guide.
if( ! defined( 'ABSPATH' ) ) exit;
class My_ACF_Location_Post_Meta extends ACF_Location {
public function initialize() {
$this->name = 'post_meta';
$this->label = __( "Post Meta", 'acf' );
$this->category = 'post';
$this->object_type = 'post';
}
public function rule_values($choices, $rule){
if(!acf_is_screen('acf-field-group') && !acf_is_ajax('acf/field_group/render_location_rule')){
return array(
$rule['meta_key'] => $rule['meta_key'],
$rule['meta_value'] => $rule['meta_value']
);
}
ob_start();
acf_render_field(array(
'type' => 'text',
'name' => 'meta_key',
'prefix' => 'acf_field_group[location]['.$rule['group'].']['.$rule['id'].']',
'value' => (isset($rule['meta_key']) ? $rule['meta_key'] : ''),
'placeholder' => 'Meta Key'
));
acf_render_field(array(
'type' => 'text',
'name' => 'meta_value',
'prefix' => 'acf_field_group[location]['.$rule['group'].']['.$rule['id'].']',
'value' => (isset($rule['meta_value']) ? $rule['meta_value'] : ''),
'placeholder' => 'Meta Value'
));
return ob_get_clean();
}
public function rule_operators($choices, $rule){
$choices = [];
$choices['key_is_equal_to_value'] = __('key is equal to value', 'acf');
$choices['key_is_not_equal_to_value'] = __('key is not equal to value', 'acf');
return $choices;
}
public function match( $rule, $screen, $field_group ) {
// Check screen args for "post_id" which will exist when editing a post.
// Return false for all other edit screens.
if( isset($screen['post_id']) ) {
$post_id = $screen['post_id'];
} elseif (isset($screen['attachment_id'])) {
$post_id = $screen['attachment_id'];
} else {
return false;
}
// Load the post meta object for this edit screen.
$post_meta_value = get_post_meta( $post_id, $rule['meta_key'], true );
if( !$post_meta_value ) {
return false;
}
// Compare the Post's meta value to rule meta value.
$result = ( strval($post_meta_value) == $rule['meta_value'] );
// Return result taking into account the operator type.
if( $rule['operator'] == 'key_is_not_equal_to_value' ) {
return !$result;
}
return $result;
}
}
add_action('acf/init', 'my_acf_init_location_types');
function my_acf_init_location_types() {
// Check function exists, then include and register the custom location type class.
if( function_exists('acf_register_location_type') ) {
acf_register_location_type( 'My_ACF_Location_Post_Meta' );
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tyler |
