eddev

View Data

Pipe WordPress data into your templates

A view can have a GraphQL file with the same name as the .tsx file. eddev executes that query whenever the view is resolved, and passes the query result to the view as props.

views/
  page.tsx
  page.graphql
  single-case-study.tsx
  single-case-study.graphql

You do not call a hook or write a loading state for normal view data. If the query file exists, the data is part of the route payload before the view renders. If no query file exists, the view gets an empty props object.

Current Post Data

For views attached to a WordPress object, use $postId.

query Page($postId: ID!) {
  page(id: $postId, idType: DATABASE_ID) {
    title
    contentBlocks
  }
}
import { ContentBlocks } from "eddev/blocks"
import { defineView } from "eddev/views"

export default defineView("page", (props) => {
  return <ContentBlocks blocks={props.page?.contentBlocks} />
})

$postId is usually available for page, front-page, single, single-{post-type}, and custom page templates. A $preview boolean is also sent when WordPress is rendering a preview.

Listing Data

View queries can fetch more than the current page. Archive and index pages often combine editable page content with a list of related posts or taxonomy terms.

query ArchiveCaseStudies($postId: ID!) {
  page(id: $postId, idType: DATABASE_ID) {
    contentBlocks
  }
  caseStudies(first: 100, where: { orderby: { field: MENU_ORDER, order: ASC } }) {
    nodes {
      title
      uri
      subtitle
    }
  }
  workCategories {
    nodes {
      name
      slug
    }
  }
}

Use this pattern when authors need page-builder content at the top of an archive, but the view also needs structured data for filters, tiles, or navigation.

Custom Route Variables

Custom routes can provide their own query variables through ED()->addCustomRoute(). The PHP route maps URL segments to GraphQL variables, and the paired view query declares those variables.

ED()->addCustomRoute('planner/([A-Za-z0-9-]+)/?$', [
  'template' => 'views/shared-planner.tsx',
  'title' => 'Shared Planner',
  'queryVars' => [
    'plannerId' => "$1"
  ],
]);
query SharedPlannerPage($plannerId: String!) {
  sharedPlanner(id: $plannerId) {
    id
    name
    sessions {
      id
    }
  }
}

Keep the route definition in Custom Routes, and keep this page focused on the view query that consumes the variables.

Generated Prop Types

eddev generates types.views.ts from views/**/*.tsx and views/**/*.graphql.

For a view with a query, the generated prop type comes from the GraphQL operation result. For a view without a query, the generated prop type is {}.

declare global {
  interface ViewProps {
    page: PageQuery
    "shared-planner": SharedPlannerPageQuery
    "search-results": {}
  }
}

Because defineView is typed against ViewProps, props should normally be inferred without manually importing the generated query type.

Query Scope

Use a view query for data needed before the route renders. Use a query hook in queries/*.graphql when the user needs to search, paginate, mutate, refetch, or otherwise load data dynamically after the view is already on screen.

On this page