Font awesome v6x – wp-graphql returns object when class is specified in settings
-
When using the plugin with v6x icons wp-graphql incorrectly returns an object when the field settings are set to return a class. This is not the case with v5x icons.
Is there something that can be done about this issue?
Please see attached images that hopefully demonstrate.We are using this on quite a number of client sites and it’s breaking front ends when people want to upgrade to v6 icons so hoping there is a possible fix for this. I’m assuming the issue is with the plugin and not wp-graphql. Please correct me if I’m wrong and I’ll open an issue there instead.
thanks :o)
-
Hello, I do recognize what is going on here but I am unsure *where* the fix is.
When you change the “Return Value” settings in an ACF field you are telling ACF how you want the value back. And so long as you use ACF functions to retrieve that value like
get_field()
orget_sub_field()
, you will get the specified return value format.But if you get the value another way, you are bypassing that ACF functionality and you will instead get the raw value from the database. I’ve seen this happen with other users of my plugin who are using
get_post_meta()
to retrieve their values.The fact that it used to work in your implementation with FontAwesome 5.x icons is actually a coincidence. You are looking for just the plain icon class, and that is how 5.x icons are stored in the database. So the raw DB value that was being returned happened to match what you needed/wanted. FontAwesome 6.x icons are a lot more complex and I’ve had to store more data in the database which is why that is no longer the case.
I am not a WP GraphQL user so I’m not familiar with how that plugin handles value formatting. Many of the ACF ‘core’ field types also have different return value options that I am guessing WP GraphQL already handles properly. It is likely that because my field is a third party field type it just has not been considered. Maybe they do not consider 3rd party fields as a matter of policy. Which would leave either a filter function that would go in your functions.php, or perhaps for future inclusion in my plugin.
Skimming the docs here: https://acf.wpgraphql.com/ I see this in their FAQ
- I have an ACF Extension that adds a new field type, will it work with WPGraphQL for ACF?WPGraphQL for ACF supports the field types that come with ACF (Free and PRO) as well as the field typs in ACF Extended (Free and PRO). Support for additional field types can be added by using the “register_graphql_acf_field_type” API.
If this is something you experiment with, please share your results here. If WPGraphQL doesn’t want to support this field type natively perhaps this plugin could register itself.
Thanks for the response. I’ll look into the “register_graphql_acf_field_type” API and post any success going down that route.
/**
* Add custom field types to the list of supported field types in WPGraphQL for ACF.
*/
add_filter('wpgraphql_acf_supported_fields', function ($supported_fields) {
return array_merge($supported_fields, ['font_awesome', 'unique_id']);
});
/**
* Register custom ACF field types in the GraphQL schema.
*/
add_filter('wpgraphql_acf_register_graphql_field', function ($field_config, $type_name, $field_name, $config) {
$acf_field = $config['acf_field'] ?? null;
if (!$acf_field || !in_array($acf_field['type'] ?? '', ['font-awesome', 'unique_id'], true)) {
return $field_config;
}
// Define GraphQL field type and resolver function
$field_config['type'] = 'String';
$field_config['resolve'] = function ($root) use ($acf_field) {
if (isset($root->ID)) {
return get_field($acf_field['key'], $root->ID, false) ?: null;
}
return $root[$acf_field['key']] ?? null;
};
return $field_config;
}, 10, 4);So I’ve been back to check what code we already have and the above is how we have been registering a couple of custom acf field types into the graphql schema. As you can see we are using get_field() in the resolver so I’m still at a loss as to why this isn’t returning the type as specified in the field settings.
Do you have any ideas.. ??Yes I see the issue.
You are passing the third optional argument to get_field():
get_field($acf_field['key'], $root->ID, false)
That third argument is called
format_value
. By passingfalse
to that argument you are telling it to give you the raw result from the DB without any formatting.Removing that argument or changing it to
true
should resolve things for you.Thanks again for the reply. Unfortunately passing the third argument to get_field as true throws an error with wp-graphql.
In the end I’ve settled for a bit of a messy brute force approach but it’s working for now..
Would be nice to see more acf addons working with wp-graphql in the future though.Thanks for the plugin none the less!!
/**
* Add custom field types to the list of supported field types in WPGraphQL for ACF.
*/
add_filter('wpgraphql_acf_supported_fields', function ($supported_fields) {
return array_merge($supported_fields, ['font_awesome', 'unique_id']);
});
add_filter('wpgraphql_acf_register_graphql_field', function ($field_config, $type_name, $field_name, $config) {
$acf_field = $config['acf_field'] ?? null;
if (!$acf_field || !in_array($acf_field['type'] ?? '', ['font-awesome', 'unique_id'], true)) {
return $field_config;
}
// Define GraphQL field type and resolver function
$field_config['type'] = 'String';
// Custom resolver function
$field_config['resolve'] = function ($root) use ($acf_field) {
// Get the raw field value
$value = isset($root->ID) ? get_field($acf_field['key'], $root->ID, false) : ($root[$acf_field['key']] ?? null);
// Handle FontAwesome field type
if ($acf_field['type'] === 'font-awesome' && is_string($value)) {
return handle_fontawesome_value($value);
}
// Return the value as-is for other fields (e.g., 'unique_id')
return $value ?: null;
};
return $field_config;
}, 10, 4);
/**
* Handle FontAwesome value, whether it's a JSON string or plain string.
* Because acf font awesome v5 and v6 return different values (either stringyfied object or simple string).
*
* @param string $value The raw value from the ACF field.
* @return string|null The processed FontAwesome class string or null if invalid.
*/
function handle_fontawesome_value($value)
{
// Check if the value looks like a JSON string (starts with "{" or "[")
if ($value[0] === '{' || $value[0] === '[') {
// Attempt to decode the JSON string
$decoded_value = json_decode($value, true);
// If decoding succeeds and it's an array, construct the FontAwesome class
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded_value)) {
$style = $decoded_value['style'] ?? 'regular';
$id = $decoded_value['id'] ?? '';
return "fa-$style fa-$id"; // Return the formatted FontAwesome class string
}
}
// If not JSON, assume it's already a valid Font Awesome class string
return $value;
}
- You must be logged in to reply to this topic.