-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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: