Wp-graphql: How to handle frontPage & pageTemplates?

Created on 10 Apr 2018  路  13Comments  路  Source: wp-graphql/wp-graphql

It's common for pages to be treated very different based on whether they are the Front Page or of a particular Page Template.

Right now, you can query a page and it's fields like so:

{
  page {
     title
     content
     someMetaField
  }
}

But _all_ pages are treated the same here. They all have the same Schema.

As brought up here (and the surrounding conversation) it might be nice to be able to query for things conditionally.

My initial thought is to introduce some sort of Union for handling pages.

So, possibly it could become:

{
  page {
     ...on FrontPage {
        someFrontPageField
    }
    ...on CustomPageTemplate {
       someFieldThatExistsOnJustThisTemplate
    }
    ...on DefaultTemplate {
        title
        content
     }
  }
}

This would allow for folks to register meta to show up only in the appropriate pieces of their Schema.

Need to think about use cases more but wanted to get some thoughts out there for discussion while it's fresh in my head.

Interfaces Needs Discussion Post Work In Progress

Most helpful comment

If you add this to your functions.php you can fetch the page template slug in your queries:

add_action('graphql_register_types', function () {
    register_graphql_field('Page', 'pageTemplate', [
        'type' => 'String',
        'description' => 'WordPress Page Template',
        'resolve' => function ($page) {
            return get_page_template_slug($page->pageId);
        },
    ]);
});

All 13 comments

After thinking about this a bit more, I think Post Types that support templates should get a template field which returns a PageTemplateUnion and each registered page template get's it's own Type.

Then we can query something like:

{
  page {
    id
    title
    template {
        __typename
        name
        ...on HomePageTemplate {
           someHomePageField
        }
        ...on ContactPageTemplate {
           someContactPageField
        }
    }
  }
}

See conversation here: https://wp-graphql.slack.com/archives/C3NM1M291/p1550506403167100?thread_ts=1550481491.162000&cid=C3NM1M291

How would we register_graphql_field just for that specific page-template and not show up on other pages.

something like:

register_graphql_field( 'HomePageTemplate', 'customField1', [
  'description' => __( 'The description of the field that's only intended for use on the HomePageTemplate', 'your-textdomain' ),
  'resolve' => function ( $post ) {
     return get_post_meta( $post->ID, 'customField1', true );
  }
])

perhaps even graphql_pageTemplate_fields

Any update on this one @jasonbahl ?

I'm currently setting up a Nuxt/GraphQL stack and hitting a snag with page templates and custom fields. Currently as a workaround I'm just adding additional fields for stubbing out the template slug and all ACF fields so I can map it to a specific template and bind all this ACF data.

Would be great if we could do something as you mentioned above

If you add this to your functions.php you can fetch the page template slug in your queries:

add_action('graphql_register_types', function () {
    register_graphql_field('Page', 'pageTemplate', [
        'type' => 'String',
        'description' => 'WordPress Page Template',
        'resolve' => function ($page) {
            return get_page_template_slug($page->pageId);
        },
    ]);
});

I've got something similar to get the page template, but the issue I'm experiencing is trying to query certain fields for certain page templates.

Currently can only query ACF fields that belong to all Page templates, but not ones that only exists on one without building additional functionality

I'm having the same issue as @lmounsey. Almost all of my custom field groups are configured for specific page templates, but I'm unable to see them.

To check front page, I add a pageOnFront field to my schema

function graphql_register_page_on_front() {
    register_graphql_field(
        'Page',
        'pageOnFront',
        array(
            'type'        => 'Boolean',
            'description' => 'WordPress page on front option',
            'resolve'     => function( object $page ) {
                $page_on_front_id = (int) get_option( 'page_on_front' );

                return $page->pageId === $page_on_front_id;
            },
        )
    );
}

add_action( 'graphql_register_types', 'graphql_register_page_on_front' );

Hi @19h47 do you mind elaborate on how to add that and how to query it? Thank you

Hello @bsides, you can add this snippet in your functions.php, then you can retrieve in your schema the pageOnFront field.

But, since the 0.4.1 version, thanks to @jasonbahl and @zgordon, this is obsolete: the boolean isFrontPage field has been added directly to the page schema.

But, since the 0.4.1 version, thanks to @jasonbahl and @zgordon, this is obsolete: the boolean isFrontPage field has been added directly to the page schema.

I noticed it, thanks!

I just would like to retrieve it as a filter, like { pages { where: { isFrontPage: true } } } but I don't think I can change what can go in as RootQueryToPageConnectionWhereArgs, could I?

I just would like to retrieve it as a filter, like { pages { where: { isFrontPage: true } } } but I don't think I can change what can go in as RootQueryToPageConnectionWhereArgs, could I?

Don't think you can... That's a shame because now you can't query just the front page without adding a custom RootQuery field yourself.

If you have found another way, I would love to hear it!

If you add this to your functions.php you can fetch the page template slug in your queries:

add_action('graphql_register_types', function () {
    register_graphql_field('Page', 'pageTemplate', [
        'type' => 'String',
        'description' => 'WordPress Page Template',
        'resolve' => function ($page) {
            return get_page_template_slug($page->pageId);
        },
    ]);
});

Nice!

On top of that, is anyone aware how we can add option to RootQueryToPageConnectionWhereArgs so that we can filter pages by pageTemplate, like:

query MyQuery {
  pages(where: {pageTemplate: "page-templates/visit-a-campus.php"}) {
    nodes {
      title
      pageTemplate
}
}
}

I have many custom templates which I would like to root via gatsby-node.js to create the pages for any items using these templates. If anyone is aware of an alternate method I'm also all ears

Would be lovely to be able to ask for post type, then template in the same query conditionally.

Something like:

nodeByUri(uri: "/") {
    __typename
    id
    uri
    ... on Post {
      title
    }
    ... on Page {
     title
     template {
          __typename
           ... on HomeTemplate {
               # homepage specific fields
           }
           ... on BlogTemplate {
               # blog specific fields
           }
       }
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

TylerBarnes picture TylerBarnes  路  4Comments

BE-Webdesign picture BE-Webdesign  路  3Comments

CalebBarnes picture CalebBarnes  路  4Comments

jasonbahl picture jasonbahl  路  4Comments

cr101 picture cr101  路  3Comments