# Builderius GraphQL Schema Documentation - V1 (beta-public) # About This Document This is a comprehensive reference guide for [Builderius](https://builderius.io) GraphQL - a custom query language for WordPress data. **This document is primarily designed to train AI systems** (like Claude, ChatGPT, etc.) to write correct GraphQL queries for you. We have tried to check this entire document for errors. However, errors happen, so if you find any please leave a comment in this document (you need a free notion account) or write to [support@builderius.io](mailto:support@builderius.io) ## How to Use This Guide **For AI Training:** Upload this entire document to your AI assistant, then ask it to write specific GraphQL queries. The AI will use this reference to generate accurate, working code that follows Builderius's unique syntax rules. ## What You'll Find Here - Complete syntax rules and examples - Field references for posts, users, terms, and custom fields - Common query patterns and advanced techniques - What works and what doesn't (important - this isn't standard GraphQL) ## Example Prompts for Better Results After uploading this document to your AI assistant, use these prompt patterns to get the best GraphQL queries: ### Basic Data Requests > Write a GraphQL query to get the 10 most recent blog posts with title, excerpt, featured image, and publication date. > > I need a query that shows all users with the 'author' role, including their name, email, and profile photo. > > Get all product categories with their names, descriptions, and post counts. > --- ### Specific Requirements > Create a query for an events page that shows upcoming events (after today's date) with event title, date, location (ACF field), and featured image. Limit to 12 events. > > I need related posts for the current post - same category, exclude current post, limit to 6 posts with title and excerpt. > > Query all products under $100 that are in stock, showing title, price, SKU (MetaBox field), and thumbnail image. > --- ### Troubleshooting & Optimization > This query isn't working: [paste your query]. Can you fix it and explain what was wrong? > > My query is too slow. Can you optimize this and add @private fields where appropriate? > > I'm getting an error about data variables. Can you check the scope in this query? > --- ### Best Practices for Prompting - **Be specific** about what data you need and where it comes from (ACF, MetaBox, standard WordPress fields) - **Mention context** (single post page, archive, homepage, etc.) - **Include pagination requirements** if you need it - **Specify limits** (how many posts, users, etc.) - **Ask for explanations** when you want to understand the query structure - **Provide error messages** when troubleshooting broken queries --- # Getting Started ## Syntax Fundamentals Builderius GraphQL uses a **custom implementation** with WordPress-specific syntax. This is NOT standard GraphQL - it’s a specialized query language designed for WordPress data. **Key Syntax Rules:** 1. **Data variables:** Use `"{{field_name}}"` for local context, `"[[globalVar]]"` for global 2. **Multiple same-field calls:** Always use aliases 3. **Query field before referencing:** Mark private with `@private` if not displaying 4. **MetaBox fields:** Include `option_name` only for root-level settings pages 5. **URL helpers:** Only work at root level, use `php_function_output` in loops 6. **Custom taxonomies:** Use `terms_query` approach, not direct fields **Arguments Structure:** All query functions use an `arguments` object to pass parameters: ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 } ) { posts { ID post_title } } ``` ### GraphQL Aliases Aliases allow you to call the same field multiple times with different parameters or rename fields for clarity. **When Aliases Are Required:** Multiple calls to the same field will cause errors without aliases: ```graphql # ❌ Wrong - same field called multiple times featured_image { file_url(size: THUMBNAIL) file_url(size: MEDIUM) file_url(size: LARGE) } # ✅ Correct - use aliases featured_image { thumb: file_url(size: THUMBNAIL) medium: file_url(size: MEDIUM) large: file_url(size: LARGE) } ``` ```graphql # ❌ Wrong - multiple ACF calls without aliases posts_query { posts { acf_value(name: "price") acf_value(name: "sale_price") acf_value(name: "member_price") } } # ✅ Correct - use aliases posts_query { posts { regular_price: acf_value(name: "price") sale_price: acf_value(name: "sale_price") member_price: acf_value(name: "member_price") } } ``` ```graphql posts_query { posts { # Optional aliases for cleaner naming title: post_title content: post_content published: post_date author_name: post_author { display_name } } } ``` ### Common GraphQL Errors and Prevention GraphQL errors are based on schema validation. Here are the most common error patterns: **Missing Required Arguments:** ```graphql # ❌ Error - missing required 'name' argument acf_value() # ✅ Correct - provide required argument acf_value(name: "field_name") ``` **Non-Existent Sub-Fields:** ```graphql # ❌ Error - 'fake_field' doesn't exist on Post posts_query { posts { ID fake_field } } # ✅ Correct - use valid fields from schema posts_query { posts { ID post_title } } ``` **String Arguments Must Be Single Line:** ```graphql # ❌ Error - multiline strings not allowed expression_result( expression: "function1() && function2()" ) # ✅ Correct - keep on single line expression_result( expression: "function1() && function2()" ) ``` **No Spaces in Aliases:** ```graphql # ❌ Error - spaces in alias names posts_query { posts { blog title: post_title # Space in alias main content: post_content } } # ✅ Correct - use underscores or camelCase posts_query { posts { blog_title: post_title mainContent: post_content } } ``` ## Data Variables and Context ### Local Data Variables Use `"{{localDataVar}}"` syntax to reference data from the current context: - `"{{ID}}"` - Current post/user/term ID - `"{{post_author.ID}}"` - Current post’s author ID - `"{{term_id}}"` - Current term ID Example: ```graphql post { ID @private related_posts: posts_query( arguments: { post_type: "post" posts_per_page: 6 post__not_in: ["{{ID}}"] } ) { posts { ID post_title } } } ``` ### Global Data Variables Use `"[[globalDataVar]]"` syntax to reference global context data. ### Expression Language Functions ### String Functions - `upper(string)` - Uppercase string - `lower(string)` - Lowercase string - `count(string)` - Count characters in string - `limit_words(string, count)` - Limit string to specified word count - `limit_characters(string, count)` - Limit string to specified character count - `includes(string, substring)` - Check if string contains substring - `escape(string)` - Escape HTML characters - `match(string, pattern)` - Match string against regex pattern - `strtotime(string)` - Convert date string to timestamp - `floatval(string)` - Convert to float - `intval(string)` - Convert to integer ### Array Functions - `join(array, separator)` - Join array elements - `pluck(array, key)` - Extract values from array of objects - `count(array)` - Count elements - `filter(array, callback)` - Filter array elements - `foreach(array, callback)` - Transform array elements - `merge(object1, object2)` - Merge objects - `split(string, delimiter)` - Split string into array - `serialize(array)` / `unserialize(string)` - Serialize/unserialize data - `findIndex(array, callback)` - Find index of element - `includes(array, value)` - Check if array contains value - `isset(array, key)` - Check if array key exists - `joinKeys(array)` / `joinValues(array)` - Join array keys or values - `push(array, value)` - Add element to array end - `unshift(array, value)` - Add element to array beginning - `rsort(array)` / `sort(array)` / `usort(array, callback)` - Sort arrays - `set(array, key, value)` / `unset(array, key)` - Set/unset array values - `sum(array)` - Sum numeric array values ### Arithmetic Functions - `ceil(number)` - Round up to nearest integer - `floor(number)` - Round down to nearest integer - `min(array)` / `max(array)` - Find minimum/maximum values - `round(number, precision)` - Round to specified precision ### Boolean Functions - `is_email(string)` / `isEmail(string)` - Validate email format - `is_empty(value)` - Check if value is empty - `is_url(string)` - Validate URL format - `is_numeric(value)` - Check if value is numeric - `is_json(string)` - Check if string is valid JSON - `is_int(value)` / `is_float(value)` - Check number types ### Multilingual Functions - `translate(key, textdomain)` - Get translation for key ## Special Directives (@private, @recursive, @transform) ### `@private` Marks field as private (not rendered in output): ```graphql post { ID @private post_title } ``` ### `@recursive` Enables recursive field querying: ```graphql nav_menu(identifier: "slug", value: "main-menu") { items { ID title children @recursive(depth: 5) { ID title url } } } ``` ### @recursive Limitations **Default Behavior:** - Default depth: 10 nested levels - Configurable limit (can be adjusted) - **Important:** GraphQL itself has no native recursion - this is a Builderius-specific directive ### `@transform` Transform field value using Expression Language: ```graphql posts_query { posts { post_title post_date @transform(expression: "date('F j, Y', strtotime(post_date))") } } ``` ## Critical Limitations and Anti-Patterns ### ❌ Don’t Use WPGraphQL style Syntax **This is NOT standard GraphQL** - it’s Builderius’s custom implementation with WordPress-specific syntax: **WPGraphQL patterns DON’T work:** ```graphql query { posts(where: {status: "publish"}) { edges { node { title content } } } } ``` **WPGraphQL variables DON’T work:** ```graphql query GetPosts($postType: String!) { posts(postType: $postType) { ... } } ``` **GraphQL fragments DON’T work:** ```graphql fragment PostFields on Post { title content } ``` ### ❌ Don’t Use These Patterns **Non-existent fields:** ```graphql # These don't exist queried_post # Use post without arguments instead queried_term # Use archive.term instead queried_user # Use current_user instead ``` **Wrong MetaBox syntax:** ```graphql # Wrong - using old metabox_option_value syntax metabox_option_value(field_id: "contact_email") # Wrong - missing option_name for root level metabox_value(field_id: "contact_email") # Wrong - including option_name for post level post { price: metabox_value(field_id: "price", option_name: "settings") } ``` **URL helpers in loops:** ```graphql # Won't work - URL helpers don't work in loops terms_query { terms { category_url: category_archive_url(slug: "{{slug}}") # ❌ } } ``` ### ✅ Correct Patterns **Use context-aware queries:** ```graphql # For current post context post { ... } # For archive context archive { ... } # For current user current_user { ... } ``` **Correct MetaBox syntax:** ```graphql # Root level - include option_name with metabox_value metabox_value(field_id: "contact_email", option_name: "site_settings") # Post level - exclude option_name post { price: metabox_value(field_id: "price") } ``` **Use PHP functions for URLs in loops:** ```graphql terms_query { terms { category_url: php_function_output( function: "get_category_link" arguments: ["{{term_id}}"] ) } } ``` # Core Query Types ## Post Queries ### posts_query - Basic Examples Query posts with flexible filtering and pagination. **Arguments:** - `post_type` (MixedOrDataVar) - Post type slug - `post_status` (MixedOrDataVar) - Post status - `posts_per_page` (IntOrDataVar) - Number of posts - `meta_query` (WP_Meta_Query) - Custom field filtering - `tax_query` (WP_Tax_Query) - Taxonomy query filtering - `orderby` (StringOrDataVar) - Order by field - `order` (StringOrDataVar) - ASC or DESC - `author` (IntOrDataVar) - Author ID - `post__in` (ArrayOrDataVar) - Include specific post IDs - `post__not_in` (ArrayOrDataVar) - Exclude specific post IDs - `meta_key` (StringOrDataVar) - Meta key for filtering - `meta_value` (StringOrDataVar) - Meta value for filtering **Returns:** `PostsQuery` object **Example - Basic Posts Loop:** This code fetches posts using `posts_query` with basic arguments. It limits results to 10 posts per page, orders by publication date newest first, and shows only published posts. Returns each post's ID, title, excerpt, content, publication date, and featured image with URL and alt text. Includes pagination controls and total post count. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 orderby: "date" order: "DESC" } ) { posts { ID post_title post_excerpt post_content post_date featured_image { file_url alt_text } } has_pagination pagination( arguments: { pagination_url_param_name: "posts_page" } ) { links } posts_count } ``` ### posts_query - Advanced Filtering **Example - Posts with Meta Query (Custom Fields):** This code fetches "product" post type and uses `meta_query` filtering with "AND" relation. Filters posts where "featured" custom field equals true (boolean type) and "price" is between 100-500 (numeric type). Orders by price value ascending using `meta_value_num` with `meta_key`. Returns ACF fields for price, featured, and sku. ```graphql posts_query( arguments: { post_type: "product" post_status: "publish" posts_per_page: 10 meta_query: { relation: "AND" array: [ { key: "featured" value: true compare: "=" type: "BOOLEAN" } { key: "price" value: [100, 500] compare: "BETWEEN" type: "NUMERIC" } ] } orderby: "meta_value_num" meta_key: "price" order: "ASC" } ) { posts { ID post_title post_excerpt price: acf_value(name: "price") featured: acf_value(name: "featured") sku: acf_value(name: "sku") } posts_count } ``` **Example - Posts with Tax Query (Taxonomy Filtering):** This code fetches "event" post type and uses `tax_query` filtering with "AND" relation. Filters posts that are in "conference" or "workshop" categories ("IN" operator) but excludes "online" location ("NOT IN" operator). Includes nested `terms_query` to get event categories for each post. The `{{ID}}` data variable passes the current post's ID to `object_ids`, which filters terms to only those assigned to that specific post. ```graphql posts_query( arguments: { post_type: "event" post_status: "publish" posts_per_page: 12 tax_query: { relation: "AND" array: [ { taxonomy: "event_category" field: "slug" terms: ["conference", "workshop"] operator: "IN" } { taxonomy: "event_location" field: "slug" terms: ["online"] operator: "NOT IN" } ] } orderby: "date" order: "DESC" } ) { posts { ID post_title post_excerpt post_date event_date: acf_value(name: "event_date") # Get event categories for this post event_categories: terms_query( arguments: { taxonomy: "event_category" object_ids: ["{{ID}}"] } ) { terms { name slug } } } posts_count } ``` ### post - Single Post Access **Example - Current Post Context:** This code fetches current post without arguments and creates related posts using nested `posts_query`. Uses `@private` directive on ID field to hide it from output while making it available for data variable. Excludes current post from related results using `post__not_in: ["{{ID}}"]` argument. ```graphql post { ID @private post_title related_posts: posts_query( arguments: { post_type: "post" posts_per_page: 6 post__not_in: ["{{ID}}"] } ) { posts { ID post_title post_excerpt } } } ``` Get single post by identifier. **Arguments:** - `identifier` (StringOrDataVar) - “ID” or “slug” (default: “ID”) - `value` (MixedOrDataVar) - The actual ID or slug value **Returns:** `Post` object **Example - Single Post:** This code fetches a specific post by slug ("about-us" page) using `post` function with `identifier: "slug"` and `value: "about-us"`. Use this to get any specific post from anywhere on the site. Returns the post's basic fields plus ACF field for contact form shortcode. ```graphql post(identifier: "slug", value: "about-us") { ID post_title post_content post_date featured_image { file_url alt_text } contact_form: acf_value(name: "contact_form_shortcode") } ``` ## User Queries ### users_query Query users with filtering options. **Arguments:** - `role` (StringOrDataVar) - User role - `include` (ArrayOrDataVar) - Include specific user IDs - `exclude` (ArrayOrDataVar) - Exclude specific user IDs - `search` (StringOrDataVar) - Search term - `number` (IntOrDataVar) - Number of users - `offset` (IntOrDataVar) - Offset for pagination - `order` (StringOrDataVar) - ASC or DESC - `orderby` (StringOrDataVar) - Order by field **Returns:** `UsersQuery` object ### user and current_user **`user`** - Get single user by identifier. **Arguments:** - `identifier` (StringOrDataVar) - “ID”, “slug”, “email”, or “login” (default: “ID”) - `value` (MixedOrDataVar!) - The actual identifier value **Returns:** `User` object **Example - Specific User:** This code fetches a specific user by ID (user 1) using `user` function with `identifier: "ID"` and `value: 1`. Returns user fields including nickname, email, login, description, roles array, plus ACF field for custom_field. ```graphql user(identifier: "ID", value: 1) { ID nickname user_email user_login description roles custom_field: acf_value(name: "custom_field") } ``` **`current_user`** - Get currently logged-in user. **Returns:** `User` object ## Taxonomy and Term Queries ### terms_query Query taxonomy terms. **Arguments:** - `taxonomy` (StringOrDataVar) - Taxonomy name - `hide_empty` (BooleanOrDataVar) - Hide empty terms - `include` (ArrayOrDataVar) - Include specific term IDs - `exclude` (ArrayOrDataVar) - Exclude specific term IDs - `object_ids` (ArrayOrDataVar) - Filter terms by object IDs - `name` (ArrayOrDataVar) - Term names - `slug` (ArrayOrDataVar) - Term slugs - `number` (IntOrDataVar) - Number of terms - `offset` (IntOrDataVar) - Offset for pagination - `orderby` (StringOrDataVar) - Order by field - `order` (StringOrDataVar) - ASC or DESC **Returns:** `TermsQuery` object ### term - Single Term Access Get single term by identifier. **Arguments:** - `identifier` (StringOrDataVar) - “term_id”, “term_taxonomy_id”, “slug”, or “name” - `value` (MixedOrDataVar!) - The actual identifier value - `taxonomy` (StringOrDataVar!) - Taxonomy name **Returns:** `Term` object ## Navigation and Menu Queries ### nav_menu and primary_nav_menu **`nav_menu`** - Get navigation menu by identifier. **Arguments:** - `identifier` (StringOrDataVar) - “ID”, “slug”, or “name” (default: “ID”) - `value` (MixedOrDataVar!) - The actual identifier value **Returns:** `NavMenu` object **Example - Recursive Menu:** This code fetches navigation menu by its name ("Main Navigation") using `nav_menu` function. Returns menu items with ID, title, description, classes, URL, and ACF field. Uses `@recursive` directive on `children` field to get nested submenu items with unlimited depth. ```graphql nav_menu( identifier: "name" value: "Main Navigation" ) { items { ID title description classes url acf_value(name: "field_name") children @recursive { ID title url classes description } } } ``` **`primary_nav_menu`** - Get the primary navigation menu. **Returns:** `NavMenu` object ### NavMenuItem Fields Navigation menu items have extensive field coverage for building complex menu structures with custom functionality. ### H4 Standard NavMenuItem Fields - `ID` (int) - Menu item ID - `title` (string) - Menu item display text (most commonly used) - `url` (string) - Link URL for the menu item - `description` (string) - Menu item description (if set) - `classes` (string) - CSS classes assigned to menu item - `target` (string) - Link target (`_blank`, `_self`, etc.) - `attr_title` (string) - Title attribute for the link - `db_id` (int) - Database ID of menu item - `menu_item_parent` (int) - Parent menu item ID - `post_parent` (int) - WordPress post parent ID - `post_title` (string) - Original post/page title - `object` (string) - Object type (post, page, category, custom, etc.) - `object_id` (int) - ID of the linked object - `type` (string) - Menu item type - `type_label` (string) - Human-readable type label - `xfn` (string) - XFN relationship attributes ### H4 NavMenuItem Relationships - `parent` - Parent NavMenuItem object - `children` - Array of child NavMenuItem objects - `nav_menu` - Parent NavMenu object - `meta` - Array of Meta objects for menu item meta fields - `meta_value(key: StringOrDataVar!)` - Get specific menu item meta value ### Complete NavMenuItem Examples **Detailed Menu Structure** This code fetches navigation menu by its name and returns detailed menu item fields including target, attr_title, object, object_id, type, and type_label. Shows explicit parent-child relationships with `parent` object containing ID, title, URL, and `menu_item_parent` field for hierarchy reference. ```graphql nav_menu(identifier: "name", value: "Main Navigation") { items { ID title url description classes target attr_title object object_id type type_label # Relationship info menu_item_parent parent { ID title url } # Child menu items children @recursive { ID title url classes target description object type } } } ``` Menu with Custom Fields and Meta This code fetches navigation menu by its slug ("header-menu") and adds custom meta fields using `meta_value` with key parameter. Introduces `expression_result` for computed values using conditional logic - `has_children` checks if children count is greater than 0, and `is_external` detects external URLs by checking for "http" but excluding site URL. ```graphql nav_menu(identifier: "slug", value: "header-menu") { items { ID title url classes description # ACF fields on menu items menu_icon: acf_value(name: "menu_icon") highlight_item: acf_value(name: "highlight_item") mega_menu_content: acf_value(name: "mega_menu_content") # Custom meta fields custom_color: meta_value(key: "menu_color") badge_text: meta_value(key: "badge_text") # Enhanced display data has_children: expression_result( expression: "count(children) > 0 ? true : false" ) is_external: expression_result( expression: "includes(url, 'http') && !includes(url, site_url()) ? true : false" ) children @recursive { ID title url classes menu_icon: acf_value(name: "menu_icon") } } } ``` ## Archive Queries ### archive - Archive Context Get archive context (for archive pages). **Returns:** `Archive` object **Example - Archive Page:** This code fetches archive context using `archive` function and returns title, description, and type fields. Shows nested object access with `post_author { display_name }` to get specific user field. Demonstrates multiple taxonomy arrays with `categories` and `tags` returning name and slug for each. ```graphql archive { title description type posts_query { posts { ID post_title post_excerpt post_content post_date post_author { display_name } categories { name slug } tags { name slug } } } } ``` ### Complete Archive Context Fields The Archive object provides comprehensive context information for all types of archive pages in WordPress. ### Standard Archive Fields - `title` (string) - Archive page title - `description` (string) - Archive description text - `type` (string) - Archive type (category, tag, author, date, search, etc.) - `search_keyword` (string) - Search term for search result archives - `term` (Term) - Term object for taxonomy archives - `author` (User) - Author object for author archives - `posts_query` (ArchivePostsQuery) - Posts in this archive **Author Archive Context** This code fetches archive context for author archives with detailed author object including user metadata. Uses comparison operator `==` in expressions to verify post authorship. ```graphql archive { title description type author { ID display_name user_login description avatar_url user_url roles # Author metadata first_name last_name user_email } # Author's posts posts_query { posts { ID post_title post_excerpt post_date post_type # Verify authorship is_by_author: expression_result( expression: "post_author.ID == author.ID ? 'Yes' : 'No'" ) } posts_count has_pagination pagination { current_page total_pages links } } } ``` **Search Results Context** This code fetches archive context for search results and introduces `lower()` function for case-insensitive string comparison and `count()` function to get string length. Shows complex string concatenation with quoted text using escaped quotes `\"` in expressions. Uses conditional logic to detect search term presence in content vs title/meta and builds dynamic result summaries with post counts. ```graphql archive { title description type search_keyword # Search context information search_info: expression_result( expression: "search_keyword ? 'Searching for: ' . search_keyword : 'No search term'" ) search_term_length: expression_result( expression: "count(search_keyword)" ) # Search results posts_query { posts { ID post_title post_excerpt post_content post_type post_date # Highlight search term in title highlighted_title: expression_result( expression: "includes(lower(post_title), lower(search_keyword)) ? post_title : post_title" ) # Check if search term is in content has_search_term: expression_result( expression: "includes(lower(post_content), lower(search_keyword)) ? 'Found in content' : 'Found in title/meta'" ) } posts_count has_pagination pagination { current_page total_pages links } } # Search statistics search_results_summary: expression_result( expression: "posts_query.posts_count > 0 ? 'Found ' . posts_query.posts_count . ' results for \"' . search_keyword . '\"' : 'No results found for \"' . search_keyword . '\"'" ) } ``` **Date Archive Context** This code fetches archive context for date archives and introduces `date()` function for formatting dates with format strings like 'F j, Y' (full month, day, year) and 'F Y' (month, year only). Uses `strtotime()` function to parse date strings before formatting. Shows simple expression that just references existing field value in `archive_period`. ```graphql archive { title description type # Date archive posts posts_query { posts { ID post_title post_excerpt post_date post_author { display_name } # Date formatting formatted_date: expression_result( expression: "date('F j, Y', strtotime(post_date))" ) month_year: expression_result( expression: "date('F Y', strtotime(post_date))" ) } posts_count has_pagination pagination { current_page total_pages links } } # Date archive summary archive_period: expression_result( expression: "title" ) } ``` # Field Reference ## Post Fields ### Standard Post Fields - `ID` (int) - Post ID - `post_author` (User) - Author User object - `post_date` (string) - Publication date (formatted by default) - `post_datetime` (string) - Publication datetime - `post_content(raw: BooleanOrDataVar)` (string) - Post content - `post_title` (string) - Post title - `post_excerpt` (string) - Post excerpt - `post_status` (string) - Post status - `post_name` (string) - Post slug - `post_modified_date` (string) - Last modified date - `post_parent` (int) - Parent post ID - `post_type` (string) - Post type - `permalink` (string) - Full post URL - `guid` (string) - Global unique identifier ### Media Fields - `has_featured_image` (boolean) - Whether post has featured image - `featured_image(size: ThumbnailSize)` - Featured image object ### Complete FeaturedImage Field Coverage The FeaturedImage object provides comprehensive metadata beyond the commonly used `file_url` and `alt_text` fields. **All FeaturedImage Fields** - `title` (string) - Image title/filename - `alt_text` (string) - Alt text for accessibility - `caption` (string) - Image caption text - `description` (string) - Image description - `file_url(size: ThumbnailSize)` (string) - Image URL at specified size - `sizes` (Json) - Complete size information object **Basic FeaturedImage Usage** This code demonstrates featured image object structure with complete field coverage including title, alt_text, caption, description, file_url, and sizes. Introduces `has_featured_image` boolean field and field aliasing to get same `file_url` with different size parameters (THUMBNAIL, MEDIUM, LARGE, ORIGINAL). ```graphql posts_query { posts { ID post_title has_featured_image featured_image { # Complete field coverage title alt_text caption description file_url sizes # Multiple sizes thumbnail: file_url(size: THUMBNAIL) medium: file_url(size: MEDIUM) large: file_url(size: LARGE) original: file_url(size: ORIGINAL) } } } ``` **Image Metadata Analysis** This code demonstrates metadata validation using empty string checking with `!= ''` operator combined with existence checks. Uses multiple logical operators in single expressions - `&&` for required conditions and `||` for alternative options in `content_richness` field that checks if both caption AND description exist, or either one exists, or neither. ```graphql posts_query { posts { ID post_title featured_image { title alt_text caption description sizes # Metadata completeness check has_alt_text: expression_result( expression: "alt_text && alt_text != '' ? 'Yes' : 'No'" ) has_caption: expression_result( expression: "caption && caption != '' ? 'Yes' : 'No'" ) has_description: expression_result( expression: "description && description != '' ? 'Yes' : 'No'" ) # SEO readiness seo_ready: expression_result( expression: "alt_text && alt_text != '' ? 'SEO Ready' : 'Missing Alt Text'" ) # Content richness content_richness: expression_result( expression: "caption && description ? 'Rich' : (caption || description ? 'Partial' : 'Basic')" ) } } } ``` **Image Sizes and Responsive Images** This code shows additional image size constants including MEDIUM_LARGE, SIZE_1536X1536, and SIZE_2048X2048. Uses field aliases within expressions - `responsive_setup` references the aliased fields (thumb, medium, large, xl) to create breakpoint object with `merge()`. Shows simple existence check with `sizes ?` for conditional messaging. ```graphql posts_query { posts { ID post_title featured_image { title alt_text sizes # All available sizes thumb: file_url(size: THUMBNAIL) medium: file_url(size: MEDIUM) medium_large: file_url(size: MEDIUM_LARGE) large: file_url(size: LARGE) xl: file_url(size: SIZE_1536X1536) xxl: file_url(size: SIZE_2048X2048) original: file_url(size: ORIGINAL) # Responsive image setup responsive_setup: expression_result( expression: "merge({'mobile': thumb, 'tablet': medium, 'desktop': large, 'retina': xl})" ) # Size information from JSON size_info: expression_result( expression: "sizes ? 'Multiple sizes available' : 'Size data unavailable'" ) } } } ``` **Accessibility and SEO Optimization** This code demonstrates range checking using `count()` function with multiple conditions `> 10 && < 125` for accessibility scoring. Introduces `filter()` function with arrow function syntax `(field) -> { field && field != '' }` to count non-empty fields. Uses negation operator `!` in expressions like `!alt_text` for negative conditions and complex nested conditionals with multiple logical operators for optimization suggestions. ```graphql posts_query { posts { ID post_title featured_image { title alt_text caption description file_url(size: MEDIUM) # Accessibility compliance accessibility_score: expression_result( expression: "alt_text && alt_text != '' ? (count(alt_text) > 10 && count(alt_text) < 125 ? 'Excellent' : 'Good') : 'Poor'" ) # SEO optimization seo_optimization: expression_result( expression: "merge({'has_alt': alt_text ? true : false, 'has_title': title ? true : false, 'has_caption': caption ? true : false, 'descriptive': description ? true : false})" ) # Content completeness metadata_completeness: expression_result( expression: "count(filter([title, alt_text, caption, description], (field) -> { field && field != '' })) . '/4 fields completed'" ) # Image optimization suggestions optimization_tips: expression_result( expression: "!alt_text ? 'Add alt text for accessibility' : (!caption && !description ? 'Consider adding caption or description' : 'Well optimized')" ) } } } ``` **Image Performance Optimization** This code demonstrates building responsive image attributes using `merge()` to create HTML-like properties (src, data-src, data-srcset) with pixel width descriptors like '300w', '768w', '1024w'. Shows file format detection by using `includes()` on original file URL to check for '.webp' extension. ```graphql posts_query { posts { ID post_title featured_image { title sizes # Performance-optimized image delivery mobile_image: file_url(size: THUMBNAIL) tablet_image: file_url(size: MEDIUM) desktop_image: file_url(size: LARGE) retina_image: file_url(size: SIZE_1536X1536) # Lazy loading setup lazy_loading_data: expression_result( expression: "merge({'src': mobile_image, 'data-src': desktop_image, 'data-srcset': mobile_image . ' 300w, ' . tablet_image . ' 768w, ' . desktop_image . ' 1024w'})" ) # Image optimization status optimization_status: expression_result( expression: "sizes ? 'Multiple sizes available' : 'Limited size options'" ) # WebP alternative check webp_ready: expression_result( expression: "includes(file_url(size: ORIGINAL), '.webp') ? 'WebP format' : 'Traditional format'" ) } } } ``` ### Taxonomy Fields - `categories` - Array of Term objects - `tags` - Array of Term objects - `terms_query(arguments: WP_Term_Query!)` - Query specific taxonomy - `category_names` (string) - Comma-separated category names - `category_links` (string) - HTML links for categories - `tag_names` (string) - Comma-separated tag names - `tag_links` (string) - HTML links for tags ### Relationships - `post_author` - User object of post author - `children` - Array of child Post objects - `comments` - Array of Comment objects - `comments_open` (boolean) - Whether comments are open ### Extended Post Date and Content Fields Beyond the standard post fields, several advanced options provide more granular control over date formatting and content output. **** ## **GMT Date and Time Fields** All post date fields have GMT equivalents that return dates in GMT timezone instead of the site's local timezone. **GMT Date Fields:** - `post_date_gmt(formatted: BooleanOrDataVar = true)` (string) - Publication date in GMT - `post_datetime_gmt(formatted: BooleanOrDataVar = true)` (string) - Publication datetime in GMT - `post_modified_date_gmt(formatted: BooleanOrDataVar = true)` (string) - Last modified date in GMT - `post_modified_datetime_gmt(formatted: BooleanOrDataVar = true)` (string) - Last modified datetime in GMT **GMT vs Local Time Comparison** This code demonstrates GMT date field variants (post_date_gmt, post_datetime_gmt, post_modified_date_gmt) and introduces `formatted: false` parameter to get raw timestamps instead of formatted dates. Shows mathematical operations in expressions using subtraction and division operators to calculate timezone offset by converting seconds to hours with `/ 3600`. ```graphql posts_query { posts { ID post_title # Local timezone dates (formatted by default) local_date: post_date local_datetime: post_datetime local_modified: post_modified_date # GMT timezone dates (formatted by default) gmt_date: post_date_gmt gmt_datetime: post_datetime_gmt gmt_modified: post_modified_date_gmt # Raw GMT timestamps for calculations gmt_timestamp: post_date_gmt(formatted: false) gmt_modified_timestamp: post_modified_date_gmt(formatted: false) # Time difference calculation timezone_offset: expression_result( expression: "(strtotime(post_date) - strtotime(post_date_gmt)) / 3600 . ' hours'" ) } } ``` **Date Formatting Control** All date fields accept a `formatted` parameter to control output format. ### **Raw Content Parameter** The `post_content` field accepts a `raw` parameter to control content processing. **Raw vs Processed Content** This code demonstrates `post_content(raw: true)` parameter to get unprocessed content without WordPress filters or shortcodes. Shows content analysis techniques using `count()` for character length comparison between processed and raw versions. Detects shortcodes by checking for `[` and `]` characters with `includes()` and uses mathematical operations to calculate processing differences. ```graphql posts_query { posts { ID post_title # Processed content (default) - WordPress filters applied processed_content: post_content # Raw content - no WordPress filters, shortcodes, or processing raw_content: post_content(raw: true) # Content analysis content_length: expression_result( expression: "count(processed_content)" ) raw_length: expression_result( expression: "count(raw_content)" ) has_shortcodes: expression_result( expression: "includes(raw_content, '[') && includes(raw_content, ']') ? 'Yes' : 'No'" ) processing_difference: expression_result( expression: "(count(processed_content) - count(raw_content)) . ' characters difference'" ) } } ``` ### Complete Date Field Coverage **All Available Date Fields** This code demonstrates complete date field coverage including `modified_datetime` field and shows additional date format codes: 'l' for full day names, 'M' for short month names, and 'g:i A' for time-only format. Provides comprehensive reference for all available date field variants (standard, GMT, and raw timestamp versions). ```graphql post { ID post_title # Standard formatted dates publish_date: post_date publish_datetime: post_datetime modified_date: post_modified_date modified_datetime: post_modified_datetime # GMT formatted dates publish_date_gmt: post_date_gmt publish_datetime_gmt: post_datetime_gmt modified_date_gmt: post_modified_date_gmt modified_datetime_gmt: post_modified_datetime_gmt # Raw timestamps for calculations publish_timestamp: post_date(formatted: false) publish_timestamp_gmt: post_date_gmt(formatted: false) modified_timestamp: post_modified_date(formatted: false) modified_timestamp_gmt: post_modified_date_gmt(formatted: false) # Custom formatting examples human_publish_date: expression_result( expression: "date('l, F j, Y', strtotime(publish_timestamp))" ) iso_publish_date: expression_result( expression: "date('c', strtotime(publish_timestamp))" ) short_date: expression_result( expression: "date('M j', strtotime(publish_timestamp))" ) time_only: expression_result( expression: "date('g:i A', strtotime(publish_timestamp))" ) } ``` **Timezone and Localization** **Working with Timezones** This code demonstrates timezone offset calculations using comparison operators `> 0` for conditional UTC display formatting. Shows escaped literal text `\\U\\T\\C` to output "UTC" in date strings and introduces 'T' format code for timezone abbreviations. Uses mathematical comparison to build user-friendly timezone labels with positive/negative UTC offsets. ```graphql posts_query { posts { ID post_title # Compare local vs GMT local_time: post_datetime(formatted: false) @private gmt_time: post_datetime_gmt(formatted: false) @private # Timezone calculations site_timezone_offset: expression_result( expression: "(strtotime(local_time) - strtotime(gmt_time)) / 3600" ) # User-friendly timezone display timezone_display: expression_result( expression: "site_timezone_offset > 0 ? 'UTC+' . site_timezone_offset : 'UTC' . site_timezone_offset" ) # Different timezone representations utc_time: expression_result( expression: "date('Y-m-d H:i:s \\U\\T\\C', strtotime(gmt_time))" ) local_with_tz: expression_result( expression: "date('Y-m-d H:i:s', strtotime(local_time)) . ' (Local)'" ) # Event scheduling friendly format event_time: expression_result( expression: "date('F j, Y \\a\\t g:i A T', strtotime(local_time))" ) } } ``` ## Comment Fields ### Standard Comment Fields Access comments through the `comments` field on Post objects. Each comment has the following fields: - `ID` (int) - Comment ID - `comment_ID` (int) - Same as ID, alternative access - `comment_post_ID` (int) - ID of the post this comment belongs to - `comment_author` (string) - Comment author name - `comment_author_email` (string) - Comment author email - `comment_author_url` (string) - Comment author website URL - `comment_author_IP` (string) - Comment author IP address - `comment_date` (string) - Comment publication date - `comment_date_gmt` (string) - Comment date in GMT - `comment_content` (string) - Comment text content - `comment_karma` (mixed) - Comment karma/rating - `comment_approved` (string) - Comment approval status - `comment_agent` (string) - User agent string - `comment_type` (string) - Comment type (comment, pingback, trackback) - `comment_parent` (int) - Parent comment ID for threaded comments - `user_id` (int) - WordPress user ID if comment author is registered ### Comment Relationships - `children` - Array of child Comment objects (for threaded comments) - `meta` - Array of Meta objects for comment meta fields - `meta_value(key: StringOrDataVar!)` - Get specific comment meta value ### Comment Query Examples Basic Post Comments This code introduces `comments_open` boolean field and `comments` array containing comment objects. Shows comment-specific fields including comment_author, comment_author_email, comment_date, comment_content, comment_approved status, and comment_type for different comment types. ```graphql post { ID post_title comments_open comments { ID comment_author comment_author_email comment_date comment_content comment_approved comment_type } } ``` **Threaded Comments with Nested Replies:** This code demonstrates threaded comment structure using `comment_parent` field for hierarchy and `children` nested objects for comment replies. Shows multiple levels of nesting without `@recursive` directive, manually defining each level depth. ```graphql post { ID post_title comments { ID comment_author comment_date comment_content comment_parent # Get nested comment replies children { ID comment_author comment_date comment_content comment_parent # Can nest deeper if needed children { ID comment_author comment_content } } } } ``` ### Performance Considerations **Note:** Loading all comments for posts with many comments can impact performance. Consider limiting comment display or implementing pagination at the application level when dealing with high-traffic comment sections. ## Meta Type with Operators WordPress meta fields support operators for conditional value checking and filtering. The Meta type provides `key` and `value` fields that accept operator parameters. ### Available Operators ```graphql enum Operator { equal # Check if value equals specified value notEqual # Check if value does not equal specified value } ``` ### Meta Field Structure - `key(operator: Operator)` (string) - Meta key with optional operator - `value(operator: Operator)` (mixed) - Meta value with optional operator ### Basic Meta Queries with Operators **Post Meta with Operators** This code introduces `operator` parameter on `key` and `value` fields with `equal` and `notEqual` operators for conditional meta field checking. Shows multiple aliases on same `meta` field and uses `null` return value in expressions for conditional field display. ```graphql posts_query( arguments: { post_type: "product" posts_per_page: 10 } ) { posts { ID post_title # Access all meta fields meta { key value # Check for specific key equality is_featured_key: key(operator: equal) is_not_price_key: key(operator: notEqual) # Check for specific value equality is_true_value: value(operator: equal) is_not_false_value: value(operator: notEqual) } # Find specific meta values featured_meta: meta { key value # Only show if key equals "featured" matching_key: expression_result( expression: "key == 'featured' ? key : null" ) } } } ``` ## User Fields ### Standard User Fields - `ID` (int) - User ID - `user_login` (string) - Username - `user_email` (string) - Email address - `user_url` (string) - Website URL - `display_name` (string) - Display name - `nickname` (string) - Nickname - `first_name` (string) - First name - `last_name` (string) - Last name - `description` (string) - Bio/description - `avatar_url` (string) - Avatar image URL - `roles` (array) - Array of user roles - `capabilities` (array) - List of user capabilities ## Term Fields ### Standard Term Fields - `term_id` (int) - Term ID - `name` (string) - Term name - `slug` (string) - Term slug - `term_group` (string) - Term group - `term_taxonomy_id` (int) - Term taxonomy ID - `taxonomy` (string) - Taxonomy name - `description` (string) - Term description - `count` (int) - Post count - `parent` (int) - Parent term ID - `children` - Array of child Term objects ## Available Thumbnail Sizes ```graphql enum ThumbnailSize { ORIGINAL # original size THUMBNAIL # 150x150 MEDIUM # 300x300 MEDIUM_LARGE # 768x0 LARGE # 1024x1024 SIZE_1536X1536 # 1536x1536 SIZE_2048X2048 # 2048x2048 } ``` # Advanced Query Patterns ## Meta Query Examples ### EXISTS/NOT EXISTS Queries **Posts that HAVE specific custom fields:** This code introduces `compare: "EXISTS"` operator in `meta_query` to check for meta field presence without validating values. Filters products that have all three required meta keys (product_price, product_sku, featured_product) regardless of their actual values. ```graphql posts_query( arguments: { post_type: "product" post_status: "publish" posts_per_page: 15 meta_query: { relation: "AND" array: [ { key: "product_price" compare: "EXISTS" } { key: "product_sku" compare: "EXISTS" } { key: "featured_product" compare: "EXISTS" } ] } orderby: "title" order: "ASC" } ) { posts { ID post_title price: acf_value(name: "product_price") sku: acf_value(name: "product_sku") featured: acf_value(name: "featured_product") } posts_count } ``` **Posts that DON’T HAVE specific custom fields:** This code introduces `compare: "NOT EXISTS"` operator to filter posts that lack specific meta fields. Uses "OR" relation to include posts missing either featured_image_override OR hide_from_homepage meta keys, opposite logic from EXISTS filtering. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 meta_query: { relation: "OR" array: [ { key: "featured_image_override" compare: "NOT EXISTS" } { key: "hide_from_homepage" compare: "NOT EXISTS" } ] } orderby: "date" order: "DESC" } ) { posts { ID post_title post_date featured_image { file_url alt_text } } posts_count } ``` ### LIKE/NOT LIKE Pattern Matching **Partial text matching:** This code introduces `compare: "LIKE"` and `compare: "NOT LIKE"` operators for partial text matching in meta queries. Shows using same meta key multiple times with different operators - filtering courses containing "JavaScript" and "beginner" while excluding "advanced" content. ```graphql posts_query( arguments: { post_type: "course" post_status: "publish" posts_per_page: 12 meta_query: { relation: "AND" array: [ { key: "course_title" value: "JavaScript" compare: "LIKE" } { key: "course_description" value: "beginner" compare: "LIKE" } { key: "course_title" value: "advanced" compare: "NOT LIKE" } ] } orderby: "title" order: "ASC" } ) { posts { ID post_title course_title: acf_value(name: "course_title") course_description: acf_value(name: "course_description") course_level: acf_value(name: "course_level") } posts_count }contacts from multiple approved domains while filtering out spam domains. ``` ### REGEXP Pattern Matching **Phone number format validation:** This code introduces `compare: "REGEXP"` operator for regex pattern matching in meta queries. Uses pattern `"^[0-9]{3}-[0-9]{3}-[0-9]{4}$"` to validate phone numbers in 123-456-7890 format - matching exactly 3 digits, hyphen, 3 digits, hyphen, 4 digits with start `^` and end `$` anchors. ```graphql posts_query( arguments: { post_type: "business" post_status: "publish" posts_per_page: 15 meta_query: { array: [ { key: "phone_number" value: "^[0-9]{3}-[0-9]{3}-[0-9]{4}$" compare: "REGEXP" } ] } orderby: "title" order: "ASC" } ) { posts { ID post_title phone: acf_value(name: "phone_number") business_type: acf_value(name: "business_type") } posts_count } ``` ### Numeric BETWEEN/NOT BETWEEN Comparisons **Price range filtering:** This code demonstrates SKU pattern validation using `"^[A-Z]{2}[0-9]{4}$"` regex pattern requiring exactly 2 uppercase letters followed by 4 digits. Introduces `compare: "NOT REGEXP"` to exclude invalid patterns like all-numeric SKUs `"^[0-9]+$"`. Orders results by meta field value using `orderby: "meta_value"` with `meta_key: "product_sku"`. ```graphql posts_query( arguments: { post_type: "product" post_status: "publish" posts_per_page: 15 meta_query: { relation: "AND" array: [ { key: "product_price" value: [100, 500] type: "NUMERIC" compare: "BETWEEN" } { key: "discount_price" value: [10, 20] type: "NUMERIC" compare: "NOT BETWEEN" } { key: "inventory_count" value: 0 type: "NUMERIC" compare: ">" } ] } orderby: "meta_value_num" meta_key: "product_price" order: "ASC" } ) { posts { ID post_title price: acf_value(name: "product_price") discount: acf_value(name: "discount_price") inventory: acf_value(name: "inventory_count") final_price: expression_result( expression: "price - (price * discount / 100)" ) } posts_count } ``` ## Date Query Examples ### Posts from Specific Date Range **Posts from Specific Date Range:** This code introduces `date_query` for filtering posts by publication date range using `after: "2024-01-01"` and `before: "2024-12-31"` parameters. Uses `inclusive: true` to include posts from the exact start and end dates in results. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 date_query: { array: [ { after: "2024-01-01" before: "2024-12-31" inclusive: true } ] } orderby: "date" order: "DESC" } ) { posts { ID post_title post_date post_excerpt } posts_count } ``` **Posts from Specific Year and Month:** This code demonstrates date filtering by specific time periods using `year: 2024` and `month: 12` parameters instead of date ranges, filtering posts from December 2024 only. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 date_query: { array: [ { year: 2024 month: 12 } ] } orderby: "date" order: "ASC" } ) { posts { ID post_title post_date post_excerpt } posts_count } ``` ### Posts from Last 30 Days This code uses relative date string "30 days ago" in `date_query` instead of absolute dates, filtering posts from the last 30 days. Shows single date boundary using only `after` parameter without `before` for open-ended date ranges. ```graphql posts_query( arguments: { post_type: "event" post_status: "publish" posts_per_page: 15 date_query: { array: [ { after: "30 days ago" inclusive: true } ] } orderby: "date" order: "DESC" } ) { posts { ID post_title post_date event_date: acf_value(name: "event_date") } posts_count } ``` ### Posts Modified in Last 24 Hours This code introduces `column: "post_modified"` parameter to filter by modification dates instead of publication dates. Uses `orderby: "modified"` to sort by last modified date and shows relative date string "24 hours ago" for filtering recently updated content. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 date_query: { column: "post_modified" array: [ { after: "24 hours ago" inclusive: true } ] } orderby: "modified" order: "DESC" } ) { posts { ID post_title post_date post_modified_date last_modified: expression_result( expression: "human_time_diff(strtotime(post_modified_date), time()) . ' ago'" ) } posts_count } ``` ## Author Query Examples ### Posts by Multiple Specific Authors This code introduces `author__in: [1, 5, 12, 23]` parameter to filter posts by multiple specific author IDs rather than single author filtering. Shows nested `post_author` object with ID, display_name, user_login, and avatar_url fields. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 15 author__in: [1, 5, 12, 23] orderby: "date" order: "DESC" } ) { posts { ID post_title post_date post_excerpt post_author { ID display_name user_login avatar_url } } posts_count } ``` **Posts Excluding Specific Authors:** This code introduces `author__not_in: [3, 7, 15]` parameter to exclude posts by specific author IDs, opposite of inclusion filtering. Shows `roles` array field within `post_author` object for user role information. ```graphql posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 author__not_in: [3, 7, 15] orderby: "date" order: "DESC" } ) { posts { ID post_title post_date post_author { ID display_name roles } } posts_count } ``` # Custom Fields Integration ## ACF (Advanced Custom Fields) ### Basic ACF Access Access any ACF field with raw value: ```graphql acf_value(name: "field_name") ``` ### Advanced ACF Field Types **Post Object/Relationship Fields:** - `acf_post_object_value(name: "field_name")` - Returns Post object - `acf_post_objects_value(name: "field_name")` - Returns array of Post objects - `acf_relationship_value(name: "field_name")` - Returns array of related posts **User Fields:** - `acf_user_value(name: "field_name")` - Returns User object - `acf_users_value(name: "field_name")` - Returns array of User objects **Taxonomy Fields:** - `acf_taxonomy_value(name: "field_name")` - Returns Term object - `acf_taxonomies_value(name: "field_name")` - Returns array of Term objects **Structured Fields:** - `acf_group_value(name: "field_name")` - Returns AcfGroupField object - `acf_repeater_value(name: "field_name")` - Returns array of AcfRepeaterRow objects ### ACF Options Page Access Access ACF Options Page fields from root query: This code demonstrates root-level ACF access for global site options without post context. Shows `acf_repeater_value` at root level with nested `acf_value` calls for social media platform and URL data. ```graphql # Global site options acf_value(name: "site_logo") acf_value(name: "contact_email") acf_repeater_value(name: "social_links") { platform: acf_value(name: "platform") url: acf_value(name: "url") } ``` ### ACF Repeater with Post Objects This code demonstrates nested `acf_post_object_value` within `acf_repeater_value` structure, creating post references inside repeater fields. Shows accessing both `meta_value` and `acf_value` fields on referenced post objects within the nested structure. ```graphql post { ID testimonials: acf_repeater_value(name: "manage_testimonials") { headline: acf_value(name: "headline") post: acf_post_object_value(name: "post_object") { ID post_title post_content some_meta_key: meta_value(key: "some_meta_key") custom_acf_value: acf_value(name: "custom_acf_field_name") } } } ``` ### ACF Image Fields with Size Parameters ACF image fields can return different image sizes similar to featured images, though the exact parameter syntax may vary by ACF field configuration. **Basic ACF Image Field** This code demonstrates different ACF image field types (hero_image, product_gallery, company_logo) all accessed using same `acf_value(name: "...")` syntax regardless of field configuration. ```graphql posts_query { posts { ID post_title # Standard ACF image field hero_image: acf_value(name: "hero_image") # Gallery field product_gallery: acf_value(name: "product_gallery") # Logo field company_logo: acf_value(name: "company_logo") } } ``` **ACF Image Fields in Different Contexts** This code demonstrates ACF fields attached to different object types - root level for global options, terms for taxonomy metadata, users for profile data, and comments for review information. Shows same `acf_value(name: "...")` syntax works across all WordPress object contexts. ```graphql # Root level (Options Page) { site_logo: acf_value(name: "site_logo") hero_background: acf_value(name: "hero_background") default_avatar: acf_value(name: "default_avatar") } # On Terms terms_query(arguments: {taxonomy: "product_category"}) { terms { term_id name category_icon: acf_value(name: "category_icon") featured_image: acf_value(name: "featured_image") } } # On Users users_query { users { ID display_name profile_photo: acf_value(name: "profile_photo") background_image: acf_value(name: "background_image") } } # On Comments post { comments { comment_content reviewer_photo: acf_value(name: "reviewer_photo") product_photo: acf_value(name: "product_photo") } } ``` **ACF Image Responsive Transformation** This code demonstrates complex ACF image object processing using logical OR operator `||` for fallback values like `hero_image_data.sizes.medium || hero_image_data.url`. Shows nested object property access with dot notation `hero_image_data.sizes.medium` and builds responsive image attributes (src, srcset, sizes, alt, width, height, loading) using complex single-line expressions with `filter()` and `join()` functions. ```graphql posts_query { posts { ID post_title # Get ACF image field data hero_image_data: acf_value(name: "hero_image") @private # Transform to responsive image attributes (for now one line, we will look into wats to enable multiline) hero_image: expression_result( expression: "hero_image_data && hero_image_data.sizes ? merge({'src': hero_image_data.sizes.medium || hero_image_data.url, 'srcset': join(filter([hero_image_data.sizes.thumbnail ? hero_image_data.sizes.thumbnail . ' 150w' : null, hero_image_data.sizes.medium ? hero_image_data.sizes.medium . ' 300w' : null, hero_image_data.sizes.medium_large ? hero_image_data.sizes.medium_large . ' 768w' : null, hero_image_data.sizes.large ? hero_image_data.sizes.large . ' 1024w' : null, hero_image_data.sizes.full ? hero_image_data.sizes.full . ' ' . hero_image_data.width . 'w' : null ]), ', '),'sizes': '(max-width: 768px) 100vw, (max-width: 1024px) 768px, 1024px', 'alt': hero_image_data.alt || '', 'width': hero_image_data.width || '', 'height': hero_image_data.height || '', 'loading': 'lazy'}) : null" ) } } ``` **Note:** ACF image field size parameters depend on ACF field configuration and may not follow the same pattern as MetaBox `args` parameters. The field may return image URLs, image objects, or arrays depending on ACF settings. ## MetaBox Support ### ⚠️ CRITICAL SYNTAX DIFFERENCES **Root Level (Settings Pages):** Requires `option_name` parameter ```graphql metabox_value(field_id: "contact_email", option_name: "site_settings") ``` **Post/Page/Term/User Level:** NO `option_name` parameter ```graphql metabox_value(field_id: "price") ``` ### MetaBox Settings Page Fields (Root Level) This code demonstrates MetaBox fields at root level requiring `option_name: "site_settings"` parameter. Introduces `metabox_post_value` for post object references and `metabox_group_value` for grouped field structures with nested `metabox_value` calls inside groups. Uses `field_id` parameter instead of `name` for MetaBox field identification. ```graphql # Settings page fields - REQUIRES option_name parameter metabox_value(field_id: "contact_email", option_name: "site_settings") metabox_value(field_id: "company_address", option_name: "site_settings") # Advanced MetaBox option fields metabox_post_value(field_id: "featured_page", option_name: "site_settings") { ID post_title permalink } metabox_group_value(field_id: "contact_info", option_name: "site_settings") { phone: metabox_value(field_id: "phone") email: metabox_value(field_id: "email") address: metabox_value(field_id: "address") } ``` ### MetaBox Post/Page/Term/User Fields This code demonstrates MetaBox fields on post objects without `option_name` parameter (unlike root level). Introduces `args: "size=medium"` parameter for image sizing and `metabox_posts_value` for multiple post object relationships. Shows nested MetaBox calls within related post structures, accessing same field types on referenced posts. ```graphql posts_query( arguments: { post_type: "product" posts_per_page: 12 } ) { posts { ID post_title # MetaBox fields on Post objects - NO option_name price: metabox_value(field_id: "price") sku: metabox_value(field_id: "sku") product_gallery: metabox_value(field_id: "product_gallery", args: "size=medium") # Post object field related_category: metabox_post_value(field_id: "related_category") { ID post_title permalink } # Multiple post objects related_products: metabox_posts_value(field_id: "related_products") { ID post_title price: metabox_value(field_id: "price") } } } ``` ### MetaBox Group Fields **Handle MetaBox group structures:** This code demonstrates `metabox_group_value` on post objects (not just root level) and shows nested `metabox_post_value` within group structures. The referenced manufacturer post contains its own `metabox_value` fields, creating multi-level MetaBox object relationships. ```graphql post(identifier: "ID", value: 123) { specifications: metabox_group_value(field_id: "specifications") { dimensions: metabox_value(field_id: "dimensions") weight: metabox_value(field_id: "weight") material: metabox_value(field_id: "material") # Nested objects within group manufacturer: metabox_post_value(field_id: "manufacturer") { ID post_title website: metabox_value(field_id: "website") } } } ``` ### Advanced MetaBox Field Types **MetaBox Post Object Fields** This code demonstrates MetaBox post object references at both root level (requiring `option_name: "site_settings"`) and post level (no `option_name`). Shows accessing standard WordPress fields (ID, post_title, post_excerpt, permalink) and featured_image with size parameters within MetaBox-referenced post objects. ```graphql # Root level (settings page) featured_post: metabox_post_value( field_id: "featured_post" option_name: "site_settings" ) { ID post_title post_excerpt permalink featured_image { file_url(size: MEDIUM) alt_text } } # Post level posts_query { posts { ID post_title # Related post object field related_article: metabox_post_value(field_id: "related_article") { ID post_title post_excerpt permalink } } } ``` **MetaBox Taxonomy Fields** Single Taxonomy Term This code introduces `metabox_taxonomy_value` for single taxonomy term references following same root/post level pattern - root level requires `option_name: "site_settings"` while post level omits it. Returns term objects with standard taxonomy fields (term_id, name, slug, taxonomy, description, count). ```graphql # Root level (settings page) default_category: metabox_taxonomy_value( field_id: "default_category" option_name: "site_settings" ) { term_id name slug taxonomy description } # Post level posts_query { posts { ID post_title primary_category: metabox_taxonomy_value(field_id: "primary_category") { term_id name slug count } } } ``` **MetaBox User Fields** Single user: This code introduces `metabox_user_value` for single user object references following same root/post level pattern - root level requires `option_name: "site_settings"` while post level omits it. Returns user objects with standard user fields (ID, display_name, user_email, roles, avatar_url, description). ```graphql # Root level (settings page) site_manager: metabox_user_value( field_id: "site_manager" option_name: "site_settings" ) { ID display_name user_email roles avatar_url } # Post level posts_query { posts { ID post_title reviewer: metabox_user_value(field_id: "reviewer") { ID display_name description avatar_url } } } ``` ### MetaBox Args Parameter All MetaBox functions support an optional `args` parameter for additional formatting or filtering options. **Image Field Sizing** This code demonstrates `args: "size=..."` parameter for MetaBox image field sizing, using different size values (medium, thumbnail, large) to control image output dimensions. ```graphql posts_query { posts { ID post_title # Specify image size with args gallery: metabox_value(field_id: "gallery", args: "size=medium") thumbnail: metabox_value(field_id: "featured_img", args: "size=thumbnail") hero_image: metabox_value(field_id: "hero", args: "size=large") } } ``` Multiple Values with Limits This code demonstrates `args: "limit=3"` parameter with `metabox_posts_value` to limit the number of returned post objects instead of image sizing, restricting related features to only 3 items. ```graphql posts_query { posts { ID post_title # Limit number of returned items top_features: metabox_posts_value( field_id: "related_features" args: "limit=3" ) { ID post_title } } } ``` ### Complex MetaBox Relationships **Nested Post Objects with MetaBox Fields** This code demonstrates complex nested MetaBox relationships with multiple field types - `metabox_post_value` for instructor posts containing `metabox_groups_value` qualifications and `metabox_taxonomies_value` specialties. Shows deep nesting with `metabox_posts_value` for resources within course module groups, creating multi-level MetaBox object hierarchies. ```graphql posts_query(arguments: {post_type: "course"}) { posts { ID post_title course_instructor: metabox_post_value(field_id: "instructor") { ID post_title instructor_bio: metabox_value(field_id: "bio") qualifications: metabox_groups_value(field_id: "qualifications") { qualification_name: metabox_value(field_id: "name") institution: metabox_value(field_id: "institution") year: metabox_value(field_id: "year") } specialties: metabox_taxonomies_value(field_id: "specialties") { name slug description } } course_modules: metabox_groups_value(field_id: "course_modules") { module_title: metabox_value(field_id: "title") module_content: metabox_value(field_id: "content") related_resources: metabox_posts_value(field_id: "resources") { ID post_title permalink } } } } ``` # Utility Features ## Helper URLs (Root Level Only) - `front_page_url` - Homepage URL - `current_url` - Current page URL - `posts_index_page_url` - Blog index URL - `page_url(name: StringOrDataVar!)` - Page URL by slug - `post_url(name: StringOrDataVar!)` - Post URL by slug - `author_archive_url(username: StringOrDataVar!)` - Author archive URL - `category_archive_url(slug: StringOrDataVar!)` - Category archive URL - `tag_archive_url(slug: StringOrDataVar!)` - Tag archive URL **⚠️ CRITICAL LIMITATION:** These URL helper functions work ONLY at root level, NOT inside loops or nested objects. ## URL Helper Functions Limitations & Alternatives ### ❌ URL Helpers DON’T Work In Loops These functions are **root level only** and will not work inside: - `posts_query.posts` - `terms_query.terms` - `users_query.users` - Any nested query results ### ✅ Working Alternatives for URLs in Loops **Terms (Categories, Tags, Custom Taxonomies):** This code introduces `php_function_output` for calling WordPress functions with `get_term_link` using `{{term_id}}` and `{{taxonomy}}` data variables as function arguments. Shows `get_category_link` as category-specific alternative requiring only `{{term_id}}` parameter instead of taxonomy specification. ```graphql terms_query(arguments: {taxonomy: "category"}) { terms { term_id slug name taxonomy # Generic - works for any taxonomy term_url: php_function_output( function: "get_term_link" arguments: ["{{term_id}}", "{{taxonomy}}"] ) # Category-specific alternative category_url: php_function_output( function: "get_category_link" arguments: ["{{term_id}}"] ) } } ``` **Users/Authors:** ```graphql users_query { users { ID user_login author_url: php_function_output( function: "get_author_posts_url" arguments: ["{{ID}}"] ) } } ``` ## Expression Language Integration ### Basic Data Processing This code demonstrates `php_function_output` with `get_author_posts_url` function for generating author archive URLs using `{{ID}}` data variable from user context. ```graphql posts_query( arguments: { post_type: "event" posts_per_page: 10 } ) { posts { ID @private post_title event_date: acf_value(name: "event_date") @private ticket_price: acf_value(name: "ticket_price") @private # String formatting formatted_date: expression_result( expression: "date('F j, Y', strtotime(event_date))" ) formatted_price: expression_result( expression: "sprintf('$%.2f', ticket_price)" ) # Boolean logic is_soon: expression_result( expression: "strtotime(event_date) - strtotime('now') < 604800 ? true : false" ) # String manipulation short_title: expression_result( expression: "limit_words(post_title, 5)" ) } } ``` ### Advanced String Processing This code demonstrates advanced string processing functions including `upper()` for case conversion, `limit_words()` with word count limits, and string concatenation using `~` operator. Introduces `foreach()` with arrow function syntax `(name) -> { name[0] }` for array transformation and `join()` to convert arrays back to strings. Shows array indexing within arrow functions and `is_email()` for email validation. ```graphql posts_query( arguments: { post_type: "article" posts_per_page: 5 } ) { posts { ID post_title @private post_content @private author_name: acf_value(name: "author_name") @private # String manipulation title_uppercase: expression_result( expression: "upper(post_title)" ) short_excerpt: expression_result( expression: "limit_words(post_content, 25)" ) read_time: expression_result( expression: "ceil(count(split(post_content, ' ')) / 200) ~ ' min read'" ) author_initials: expression_result( expression: "upper(join(foreach(split(author_name, ' '), (name) -> { name[0] }), ''))" ) word_count: expression_result( expression: "count(split(post_content, ' '))" ) # Validation has_valid_email: expression_result( expression: "is_email(author_email) ? 'Valid' : 'Invalid'" ) } } ``` ### **Array Manipulation Examples** This code demonstrates comma-separated string processing using `split(tags_raw, ',')` to convert ACF fields into arrays and `join(...)` to convert back to formatted strings. Introduces `sort()` function for array alphabetization and case-insensitive matching with `lower()` function before checking array membership with `includes()`. ```graphql posts_query( arguments: { post_type: "portfolio" posts_per_page: 10 } ) { posts { ID post_title tags_raw: acf_value(name: "project_tags") @private skills_raw: acf_value(name: "skills_used") @private # Array processing tag_list: expression_result( expression: "join(split(tags_raw, ','), ', ')" ) skills_count: expression_result( expression: "count(split(skills_raw, ','))" ) # Sorting and filtering sorted_skills: expression_result( expression: "join(sort(split(skills_raw, ',')), ', ')" ) # Check for specific skills has_php: expression_result( expression: "includes(split(lower(skills_raw), ','), 'php') ? 'Yes' : 'No'" ) } } ``` ## Available Utility Functions ### Root Level Functions - `option_value(name: StringOrDataVar!)` - Get WordPress option - `url_parameter(name: MixedOrDataVar!, fallback: MixedOrDataVar)` - Get URL parameter - `cookie_parameter(name: MixedOrDataVar!, fallback: MixedOrDataVar)` - Get cookie value - `server_parameter(name: MixedOrDataVar!, fallback: MixedOrDataVar)` - Get server variable - `expression_result(expression: StringOrDataVar!)` - Evaluate Expression Language - `php_function_output(function: StringOrDataVar!, arguments: [MixedOrDataVar], fallback: MixedOrDataVar)` - Call PHP function ## Additional Root Level Functions These specialized functions provide access to WordPress hooks, forms, and advanced metadata at the root query level ### Hook Arguments Access arguments passed to WordPress action/filter hooks when GraphQL is executed within hook context **Function:** `hook_argument(position: Int!)` This code introduces `hook_argument(position: ...)` function for accessing WordPress hook arguments by zero-based index (0, 1, 2). Shows using hook arguments as data variables - `"{{post_id_from_hook}}"` references first hook argument to fetch specific post data in subsequent `post()` query. ```graphql # Access hook arguments by position (0-based index) { first_arg: hook_argument(position: 0) second_arg: hook_argument(position: 1) third_arg: hook_argument(position: 2) # Use in conditional logic post_id_from_hook: hook_argument(position: 0) @private # Get post data from hook argument current_post: post(identifier: "ID", value: "{{post_id_from_hook}}") { ID post_title post_content } } ``` Common Use Cases - Accessing post ID in `wp_insert_post` hook - Getting user ID in user registration hooks - Retrieving term data in taxonomy hooks ### Form Functions Handle form submissions and security nonces for custom forms. **Form Submission URL:** `form_submission_url(form: String!)` This code introduces `form_submission_url(form: "...")` function for generating form action URLs with specific form identifiers like "contact_form", "newsletter_signup", and "user_registration". Shows same function called multiple times with different form names. ```graphql { # Get submission URL for specific form contact_form_url: form_submission_url(form: "contact_form") newsletter_url: form_submission_url(form: "newsletter_signup") registration_url: form_submission_url(form: "user_registration") # Use in form HTML contact_form_action: form_submission_url(form: "contact_form") } ``` **Form Nonce:** `form_nonce(form: String!)` This code introduces `form_nonce(form: "...")` function for generating security nonces with form identifiers. Shows creating nested objects with `contact_form_data: { ... }` syntax combining both `form_submission_url` and `form_nonce` functions plus hardcoded values for complete form configuration. ```graphql { # Get security nonce for form validation contact_nonce: form_nonce(form: "contact_form") newsletter_nonce: form_nonce(form: "newsletter_signup") admin_nonce: form_nonce(form: "admin_action") # Complete form setup contact_form_data: { action_url: form_submission_url(form: "contact_form") nonce_field: form_nonce(form: "contact_form") form_id: "contact_form" } } ``` ### Pagination Type Differences Builderius GraphQL implements two distinct pagination types with different capabilities depending on the query context. **** **WP_Query_Pagination (Full Pagination**) Used by: `PostsQuery`, `UsersQuery`, `TermsQuery` **Available Fields:** - `current_page` (int) - Current page number - `total_pages` (int) - Total number of pages - `posts_per_page` (int) - Items per page - `links` (string) - HTML pagination links - All utility functions (option_value, url_parameter, etc.) **Arguments Required:** - `pagination_url_param_name` (string) - URL parameter name for pagination **Example - Posts with Full Pagination** This code shows pagination object fields including `current_page`, `total_pages`, and `posts_per_page` for building enhanced pagination information. Introduces `min()` function for value limiting and complex mathematical expressions with parentheses for operation order like `((current_page - 1) * posts_per_page + 1)` to calculate item ranges and display counts. ```graphql posts_query( arguments: { post_type: "product" posts_per_page: 12 } ) { posts { ID post_title price: acf_value(name: "price") } has_pagination pagination( arguments: { pagination_url_param_name: "product_page" } ) { current_page total_pages posts_per_page links # Enhanced pagination info page_info: expression_result( expression: "current_page . ' of ' . total_pages . ' pages'" ) showing_range: expression_result( expression: "'Showing ' . ((current_page - 1) * posts_per_page + 1) . '-' . min(current_page * posts_per_page, total_pages * posts_per_page) . ' of ' . (total_pages * posts_per_page)" ) } posts_count } ``` **WP_Query_Pagination_Limited (Limited Pagination)** Used by: `ArchivePostsQuery` **Available Fields:** - `current_page` (int) - Current page number - `total_pages` (int) - Total number of pages - `posts_per_page` (int) - Items per page - `links` (string) - HTML pagination links - All utility functions (option_value, url_parameter, etc.) **No Arguments Required** - Uses WordPress's built-in archive pagination **Example - Archive Limited Pagination** This code demonstrates archive pagination without requiring `arguments` parameter, unlike custom queries. Archive context uses automatic pagination settings from WordPress without needing `pagination_url_param_name` specification. ```graphql archive { title description type posts_query { posts { ID post_title post_excerpt post_date } has_pagination pagination { current_page total_pages posts_per_page links # Archive pagination info archive_page_info: expression_result( expression: "'Archive page ' . current_page . ' of ' . total_pages" ) } posts_count } } ``` **Key Differences Summary** | **Feature** | **WP_Query_Pagination** | **WP_Query_Pagination_Limited** | | --- | --- | --- | | Arguments Required | Yes (`pagination_url_param_name`) | No (automatic) | | **Used By** | PostsQuery, UsersQuery, TermsQuery | ArchivePostsQuery only | | **URL Parameter Control** | Custom parameter name | WordPress default | | Context | Custom queries | Archive pages | | **Flexibility** | High (custom pagination) | Limited (WordPress defaults) | ### Pagination Best Practices **URL Parameter Naming** - Use descriptive names: `products_page`, `team_page`, `portfolio_page` - Avoid conflicts: Don't use `page` (WordPress default) for custom pagination - Be consistent: Use same naming pattern across site **Performance Considerations:** - Set reasonable `posts_per_page` limits (typically 10-20) - Use `has_pagination` check before rendering pagination UI - Consider total post count for large datasets # Context-Aware Patterns ## Single Post Context Queries Use `post` without arguments (gets current post): This code fetches current post without arguments and creates related posts using nested `posts_query`. Uses `@private` directive on ID field to hide it from output while making it available for data variable. Excludes current post from related results using `post__not_in: ["{{ID}}"]` argument. ```graphql post { ID @private post_title related_posts: posts_query( arguments: { post_type: "post" posts_per_page: 6 post__not_in: ["{{ID}}"] } ) { posts { ID post_title post_excerpt } } } ``` ## Archive Context Queries Use `archive` to get context data: This code fetches archive context and gets term data with `@private` directive. Uses `tax_query` filtering with dot notation data variables `{{term.taxonomy}}` and `{{term.term_id}}` to filter posts by current archive's taxonomy terms using "IN" operator. ```graphql archive { term @private { term_id taxonomy } posts_query( arguments: { post_type: "post" posts_per_page: 12 tax_query: { array: [ { taxonomy: "{{term.taxonomy}}" field: "term_id" terms: ["{{term.term_id}}"] operator: "IN" } ] } } ) { posts { ID post_title post_excerpt } } } ``` ## User Context Queries Posts by Current User: This code fetches currently logged-in user with `current_user` function and creates nested `posts_query` using `author: "{{ID}}"` to get posts authored by current user. Shows `post_status` field for checking post publication status. ```graphql current_user { ID @private display_name my_posts: posts_query( arguments: { author: "{{ID}}" post_type: "post" posts_per_page: 10 } ) { posts { ID post_title post_status } } } ``` ## Related Content Patterns Related Posts by Taxonomy: This code fetches current post and gets category terms using `terms_query` with `@private` directive on entire query block. Uses `pluck(terms_query.terms, 'term_id')` function to extract term IDs from previous query results and references them in subsequent `tax_query` filtering to find posts sharing same categories. ```graphql post { ID @private terms_query( arguments: { taxonomy: "category" } ) @private { terms { term_id name } } # Query posts with shared taxonomy terms related_posts: posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 10 post__not_in: ["{{ID}}"] tax_query: { array: [ { taxonomy: "category" field: "term_id" terms: ["{{pluck(terms_query.terms, 'term_id')}}"] operator: "IN" } ] } } ) { posts { ID post_title post_excerpt } } } } ``` # Common Query Patterns ## Related Posts by Category This code fetches current post and uses direct `categories` field with `@private` directive instead of `terms_query`. Uses `pluck(categories, 'term_id')` to extract term IDs from post's category array and filters related posts by shared categories with `tax_query`. ```graphql post { ID @private categories @private { term_id } related_posts: posts_query( arguments: { post_type: "post" posts_per_page: 6 post__not_in: ["{{ID}}"] tax_query: { array: [ { taxonomy: "category" field: "term_id" terms: ["{{pluck(categories, 'term_id')}}"] operator: "IN" } ] } } ) { posts { ID post_title post_excerpt } } } ``` ## Category Archive with Posts This code fetches archive context and gets term data privately while showing archive title and description. Uses `posts_query` without arguments to get default archive posts and includes featured image with `size: MEDIUM` parameter. Shows basic pagination with `has_pagination` check and pagination links. ```graphql archive { term @private { term_id taxonomy } title description posts_query { posts { ID post_title post_excerpt featured_image { file_url(size: MEDIUM) alt_text } } has_pagination pagination { links } } } ``` ## Nested Terms and Posts This code queries categories with `hide_empty: true` to show only categories containing posts, ordered alphabetically. Uses nested `posts_query` with `{{term_id}}` data variable to get 5 recent posts per category filtered by `tax_query`. Demonstrates nested loop pattern returning posts within each category term. ```graphql terms_query( arguments: { taxonomy: "category" hide_empty: true orderby: "name" order: "ASC" } ) { terms { term_id name slug description count posts_in_category: posts_query( arguments: { post_type: "post" post_status: "publish" posts_per_page: 5 tax_query: { array: [ { taxonomy: "category" field: "term_id" terms: ["{{term_id}}"] operator: "IN" } ] } orderby: "date" order: "DESC" } ) { posts { ID post_title post_excerpt post_date featured_image { file_url alt_text } } posts_count } } } ``` ## Custom Posts with Taxonomy Terms This code fetches "movie" post type and uses nested `terms_query` with `object_ids: "{{ID}}"` parameter to get genre taxonomy terms assigned to each specific movie post. Shows reverse relationship pattern - getting terms that belong to each post rather than posts belonging to terms. ```graphql posts_query( arguments: { post_type: "movie" } ) { posts { ID post_title terms: terms_query( arguments: { object_ids: "{{ID}}" taxonomy: "genre" } ) { terms { name slug } } } } ``` --- ## Using GraphQL Data in Builderius Builder After creating GraphQL queries, the returned data is used in the Builderius visual builder through dynamic data tags. This section provides essential context for how query results integrate with builder elements. ### GraphQL Variable Setup 1. **Create Variable**: In the GraphQL editor, create a new "variable" 2. **Write Query**: Add your GraphQL query following the patterns in this documentation 3. **Test Query**: Click "Get Data" to preview the JSON response structure 4. **Use Data**: Reference the data in builder elements using dynamic tags ### Dynamic Data Tag Syntax **Built-in WordPress Data** (`wp` prefix - automatically available): Built-in queries are pre-created for each WordPress template context, matching the WordPress template hierarchy. You don't need to create these queries manually: - **Single Post/Page**: `[[wp.post_title]]`, `[[wp.post_content]]`, `[[wp.featured_image.file_url]]` - **Archive Pages**: `[[wp.archive.title]]`, `[[wp.archive.posts_query.posts]]` (main query loop) - **Front Page**: `[[wp.front_page_field]]` (front page specific data) - **Category/Tag Archives**: `[[wp.archive.term.name]]`, `[[wp.archive.posts_query.posts]]` **Custom Variables** (queries you create): ``` [[custom.posts_query.posts]] [[my_data.archive.title]] [[homepage.acf_value]] ``` **With GraphQL Aliases** (using your custom field names): ``` [[custom.custom_archive.custom_title]] [[products.featured_items.product_name]] ``` **Loop Data** (inside Collection elements): ``` {{field_name}} {{post_title}} {{custom_alias_name}} ``` ### Built-in vs Custom Variables **Built-in (`wp`) Variables:** - Automatically available based on current WordPress template context - Match WordPress's main query and template hierarchy - No GraphQL query creation needed - Examples: current post data on single templates, archive posts on archive templates **Custom Variables:** - Created by you in the GraphQL editor - For additional data beyond the main WordPress context - Custom queries, related posts, specific filtering, etc. - Use your chosen variable name as prefix ### Collection Elements for Loops **Structure for displaying post loops:** 1. **Collection Element**: Set data source to loop data - Built-in archive: `[[wp.archive.posts_query.posts]]` - Custom query: `[[my_variable.posts_query.posts]]` 2. **Template Element**: Automatically added inside Collection - Individual fields: `{{post_title}}`, `{{ID}}`, `{{post_excerpt}}` - Custom aliases: `{{my_custom_title}}`, `{{product_price}}` This system provides both automatic WordPress context data (`wp`) and the flexibility to create custom GraphQL queries for additional functionality. --- **Note:** This section provides only the essential context needed to understand how GraphQL data integrates with the Builderius builder. For comprehensive tutorials on working with dynamic data, elements, collections, and the visual builder interface, please refer to the **Builderius YouTube channel** and the official documentation (currently being updated to reflect the latest builder features).