-
Notifications
You must be signed in to change notification settings - Fork 122
Field groups not in schema when location is a page template #76
Comments
Had this issue myself and asked for a workaround on Slack and got this helpful advice:
Code snippet: Don't forget to add |
I've got a particular variation on this issue. I have a field group which has the following location rules: <?php
$location = [
0 => [
0 => [
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
],
],
1 => [
0 => [
'param' => 'post_type',
'operator' => '==',
'value' => 'page',
],
1 => [
'param' => 'page_type',
'operator' => '!=',
'value' => 'posts_page',
],
2 => [
'param' => 'page_type',
'operator' => '!=',
'value' => 'front_page',
],
3 => [
'param' => 'page_template',
'operator' => '!=',
'value' => 'page-locations.php',
],
],
]; In English, show if:
// $post_type is each of your registered post types, called one by one
$field_groups = acf_get_field_groups(
[
'post_type' => $post_type,
]
); This doesn't return the field group for the I took a deep dive into the ACF internals, and into how ACF resolves the visibility of a particular field group based on a set of location rules. Here are the main functions that runs in order to determine visibility of the field group given the context:
$result = apply_filters( "acf/location/match_rule/type={$rule['param']}", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/match_rule", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/rule_match/{$rule['param']}", $result, $rule, $screen, $field_group );
$result = apply_filters( "acf/location/rule_match", $result, $rule, $screen, $field_group ); I plan on experimenting with these filters, to see if I can get the rules to pass for all fields which are registered on the |
I ended up with a pretty crude solution to this, but one that works with the plugin out of the box: function whitelistedFieldGroups( $result, $rule, $screen, $field_group) {
$graphqlFieldNames = [ 'homepage', 'pageFields' ];
if (
in_array($field_group['graphql_field_name'], $graphqlFieldNames)
&& $screen['post_type'] === 'page'
) {
return true;
}
return $result;
}
add_filter('acf/location/rule_match', 'whitelistedFieldGroups', 10, 4); Hopefully this might help someone else! |
@JodiWarren can you post a sample of the code here please? |
@izzygld This is all I have (and need) in my current setup: function whitelistedFieldGroups( $result, $rule, $screen, $field_group) {
$graphqlFieldNames = [ 'homepage', 'pageFields' ];
if (
in_array($field_group['graphql_field_name'], $graphqlFieldNames)
&& $screen['post_type'] === 'page'
) {
return true;
}
return $result;
}
add_filter('acf/location/rule_match', 'whitelistedFieldGroups', 10, 4); This also requires a location rule that's tied to a particular post type. So if you only want a set of fields to appear on a certain page template, you'll need to set it to a combination location rule of post type and page template. Why this works: Let's take a field group with the location rules of:
The WPGraphQL ACF plugin loops through all post types and fetches their related field groups like so: function add_acf_fields_to_post_object_types() {
/**
* Get a list of post types that have been registered to show in graphql
*/
$graphql_post_types = get_post_types( [ 'show_in_graphql' => true ] );
// Do some checks
/**
* Loop over the post types exposed to GraphQL
*/
foreach ( $graphql_post_types as $post_type ) {
/**
* Get the field groups associated with the post type
*/
$field_groups = acf_get_field_groups(
[
'post_type' => $post_type,
]
);
// Do the magic of adding those field groups to GraphQL etc
}
} We basically hijack one of the checks that happens within the function The main takeaway should not necessarily be the exact code that I used, but that this filter allows you to adjust what gets included. |
We workaround this issue by conditionally skipping the rule definitions on the graphql context. Using acf-codifier: if (!is_graphql_http_request()) {
$rule_group->add_rule( 'page_template', '==', 'template.php' );
} We did discuss some solutions to this with @jasonbahl yesterday on Slack |
Could you detail this application better? I would like to use WPGraphql to return the fields of an ACF group "FrontPage". But I never used the acf-codifier. I'm not able to apply it properly. |
ACF Codifier discussion is offtopic for this thread but my guess is that you are missing add_filter(
'wpgraphql_acf_should_field_group_show_in_graphql',
function ( $show, $field_group ){
if ( "my_group" === $field_group['key'] ) {
return true;
}
return $show;
},
10,
2
); ...but now that I think of it this might work too $field_group->show_in_graphql = true; |
I tried @JodiWarren's setup (thank you!) but it only got me 99% of the way there because it has the unfortunate side effect of displaying all ACF fields on all pages in the admin edit screens. Then I caught a great tidbit from @esamattis's solution that brought it home, so I check for function expose_acf_to_graphql_only($result, $rule, $screen, $field_group) {
if(!is_graphql_http_request()) {
return $result;
}
$page_template_acf_groups = [
'acfPageTemplateHome',
'acfPageTemplateAbout',
'acfPageTemplateContact',
];
if(in_array($field_group['graphql_field_name'], $page_template_acf_groups) && $screen['post_type'] === 'page') {
return true;
}
return $result;
}
add_filter('acf/location/rule_match', __NAMESPACE__.'\\expose_acf_to_graphql_only', 10, 4); I was also able to extrapolate this and apply it to other field groups, such as a field group that applies to a post type in a certain taxonomy. Works great until there's a more solid solution within the plugin itself! |
I believe this is similar to an issue I've just resolved, take a look at my pull request #134 |
Hi, is this going to be fixed? seems like quite an important feature? this fix does the trick but it would be nice to be implemented into the main build. Thanks |
@sirichards Yes there is discussion about a major change in how you specify which fields are added to which GraphQL types, this would address this issue, see details #135 |
Typo? This finally worked for me after I changed "page_type" to "post_type" here: |
Is there some merge request? I do not understand why does not include yet. |
Is there a solution for this problem? The ACF-Fields aren't in the schema, when the condition is set to a specific page-template.. |
Sure, this comment: #76 (comment) |
So I have to edit the class-config.php? |
I would try using #207 if possible, that seems like the most relevant/new solution and probably the one that will be used going forward. @maweo-mathis any of the 'workaround' solutions such as the one suggested here (or my own one: #134) require you to edit |
This is addressed by v0.5.0 (#250). With this release, we can now assign field groups to templates and we can see that it's properly assigned to the GraphQL Type for the template: Then, we can see the Field Group available on the Template in the Schema: Then, we can query like so: {
posts {
nodes {
id
template {
__typename
... on Template_AboutUs {
acfDocs { # <-- This is the ACF Field Group assigned to the Template location
text
}
}
}
}
}
} |
It appears that this does not work as planned yet, see #251 |
Hey team, I still have the same issue. I am using the latest version of the plugin and also the latest version of the graphql plugin. When I assign the ACF fields to a page template they appear in the admin page but they does not appear in the graphql schema. |
@jasonbahl I can provide more details regarding #76 (comment) if needed or open a new ticket. |
When a field group is tied to a page template for its location, it seems as though it is not available to pages in the GraphQL schema. I also tried combining the rules so it's set as page AND page template === whatever but that still didn't work.
Any possibility of this landing in the future? I did see you can use page === page name as the location but usually we want to tie them to template so either us or a client can create a new page based off of a template without having to change field group settings.
The text was updated successfully, but these errors were encountered: