Query Forge Documentation

Complete guide to using Query Forge — the visual node-based logic engine for Elementor.

Requirement: Query Forge requires Elementor (Free or Pro) to be installed and active on your site.

What is Query Forge?

Query Forge is a visual query builder for Elementor that replaces the standard dropdown-based query interface with a node-based canvas. You connect Source, Filter, Logic, Sort, and Target nodes with lines to describe what you want to fetch and how — without writing any code.

The Free version is a fully functional static query builder. Pro adds dynamic context tags, advanced operators, additional source types, and multi-source queries.

Core Concepts

Every query is a directed graph. Logic always flows left to right: Source → (optional nodes) → Target. The canvas is the query.

  1. Source Node — defines what you are fetching (Posts, a Custom Post Type, Users, etc.)
  2. Filter Nodes — narrow the results (category is "News", meta field "featured" equals "yes")
  3. Logic Nodes — combine multiple filters with AND or OR
  4. Sort Nodes — define the order of results
  5. Include/Exclude Node — pin specific IDs in or out
  6. Target Node — defines output settings (posts per page, fallback sort order)
Complete path required: Every Source node must have an unbroken connection to the Target node. If any node in the chain is disconnected, the query produces no results. Disconnected nodes are shown with a visual indicator on the canvas.

Free vs Pro

The Free version supports: Posts, Pages, and Custom Post Types as sources; Filter nodes with basic operators (=, !=, LIKE, NOT LIKE); Logic, Sort, Include/Exclude, and Target nodes; Save & Reuse; and standard pagination. AJAX, Load More, and Infinite Scroll pagination are Pro only. The Preview node and Source Preview are also Pro only.

Pro adds: Dynamic context tags; advanced operators (>, >=, <, <=, EXISTS, NOT EXISTS); multiple Source nodes per canvas with independent filter chains; Users, Comments, SQL Tables, and REST API sources; mixed queries; Visual SQL Joins; sort by meta value, random, and menu order; plugin integrations; and the Preview node for live canvas results.

Installation

Free Version

  1. Install Query Forge from the WordPress plugin directory
  2. Activate the plugin
  3. Ensure Elementor is installed and activated

Pro Version

  1. Download the Pro plugin zip from your purchase confirmation email
  2. Go to Plugins → Add New → Upload Plugin
  3. Upload the zip file and activate
  4. Go to Settings → Query Forge License
  5. Enter your license key and click ACTIVATE
Note: Free and Pro cannot run simultaneously. When Pro is activated, it automatically deactivates the Free version.

Adding a Query Forge Widget to a Page

  1. Open any page in the Elementor editor
  2. Search for "Query Forge" in the widget panel
  3. Drag the widget onto your page
  4. Click ⚡ Open Builder to open the visual canvas
  5. Build your query, then click Save Logic

Your First Query

Example: Latest 10 Posts

  1. Open the Query Builder from the widget settings
  2. A Source node and Target node are already on the canvas by default
  3. Click the Source node and confirm it is set to Posts
  4. Click the Target node and set Posts Per Page to 10, Order By to date, Order to DESC
  5. Connect the Source node's right handle to the Target node's left handle by dragging
  6. Click Save Logic

Result: Your 10 most recent published posts, newest first.

From here you can add Filter nodes between Source and Target to narrow results, Logic nodes to combine multiple filters, and Sort nodes for custom ordering.

Widget Settings

Once you have added the Query Forge widget to a page in Elementor, the widget panel on the left contains four sections of settings that control how results are displayed. These settings are separate from the query logic — the query defines what to fetch, the widget settings define how to show it.

Query Builder

Contains a single button: ⚡ Open Builder. Click it to open the visual query canvas. The compiled query logic is stored invisibly in this section after you save.

Layout

Controls the grid structure that wraps all result cards.

SettingOptionsDefault
Columns1 – 63 desktop / 2 tablet / 1 mobile
Column Gap0 – 100px20px
Row Gap0 – 100px20px

Columns is a responsive control — you can set different values for desktop, tablet, and mobile independently using the device switcher in the Elementor panel.

Card Style

Controls which card layout is used to render each result. Choose from five built-in styles:

StyleDescription
Vertical CardImage on top, content below. The default. Good for standard blog grids.
Horizontal CardImage on the left, content on the right. Good for list-style layouts.
Minimal ListTitle and meta only, no image. Good for dense content lists.
Grid CardImage-dominant card with overlay text. Good for visual galleries.
Magazine StyleMixed-size cards suitable for editorial layouts.

Custom Elementor Template Requires Elementor Pro

Uses an Elementor Loop Item template as the card layout, giving you full design control over each result item. This requires Elementor Pro — Loop Item templates are part of Elementor's Theme Builder which is not available in Elementor Free. This option is available in both Query Forge Free and Query Forge Pro, but will only function if Elementor Pro is installed and active.

  1. In Elementor Pro, go to Templates → Theme Builder → Loop Item and create a new template
  2. Design the template as you want each card to look, using Elementor's dynamic tags to pull in post data
  3. Publish the Loop Item template
  4. In the Query Forge widget, set Display Type to Custom Elementor Template
  5. Select your template from the dropdown
Template tip: The template renders once per result item in the loop, with each item's data available to Elementor's dynamic tags. This is the recommended approach for full design control, especially with custom post types.

Content Fields

Controls which fields appear on each card. Only visible when using a canned style.

SettingOptions
Show TitleOn / Off
Show ExcerptOn / Off
Excerpt Length10 – 500 characters (shown when Excerpt is on)
Show DateOn / Off
Show AuthorOn / Off
Show Featured ImageOn / Off
Image SizeThumbnail / Medium / Large / Full (shown when Image is on)
Link TargetSame Window / New Window
Show Read More ButtonOn / Off
Button PositionTop / Bottom (shown when Read More is on)

Card Design

Controls the visual appearance of canned card layouts. Available in both Free and Pro. All controls are in the Content tab and only appear when a canned style is selected. Typography and alignment controls are conditional — they only appear when the corresponding field is enabled in Content Fields.

Typography

ControlTargetsCondition
Title Typography.qf-card-titleShow Title is on
Excerpt Typography.qf-card-excerptShow Excerpt is on
Meta Typography.qf-card-metaAlways shown
Button Typography.qf-card-buttonShow Read More is on

Element Alignment

Per-element text alignment. All controls are responsive — you can set different values for desktop, tablet, and mobile.

ControlOptionsCondition
Title AlignLeft / Center / RightShow Title is on
Meta AlignLeft / Center / RightAlways shown
Excerpt AlignLeft / Center / RightShow Excerpt is on
Button AlignLeft / Center / RightShow Read More is on

Colors

ControlTargetsCondition
Card Background.qf-card backgroundAlways shown
Title.qf-card-title and linksShow Title is on
Meta.qf-card-meta and linksAlways shown
Excerpt.qf-card-excerptShow Excerpt is on
Button.qf-card-button background colorShow Read More is on

Layout & Style

ControlOptionsNotes
AlignmentLeft / Center / RightResponsive. Aligns the entire card content block.
Image Ratio16:9 / 4:3 / 1:1Controls aspect ratio of the featured image. Shown when Show Featured Image is on.
Border Radius0 – 40pxResponsive slider. Rounds the card corners.
Card ShadowNone / Soft / StrongControls the card drop shadow. Default: Soft.

Style Tab

The Style tab contains two additional sections for fine-tuning canned card appearance. Both are only visible when a canned style is selected.

Typography

A duplicate typography panel in the Style tab targeting the same elements as the Card Design typography controls. Use whichever location is more convenient — changes in either place apply to the same CSS selectors.

ControlCondition
TitleShow Title is on
ExcerptShow Excerpt is on
Date & AuthorAlways shown

Spacing

ControlOptionsNotes
Card Paddingpx / em / %Responsive. Controls padding on all four sides of each card individually.
Content Spacing0 – 50pxResponsive slider. Controls the vertical gap between each element inside the card content area.

Results Summary

Displays a line of text showing how many results are being shown out of the total — for example, Showing 1–10 of 47 results. Available in both Free and Pro for canned card layouts. Off by default.

ControlOptionsNotes
Show Results SummaryOn / OffOff by default. Only visible when a canned style is selected.
PositionAbove Grid / Above Pagination / Below PaginationControls where the summary line appears relative to the card grid and pagination controls.
TypographyFull Elementor typography groupFont family, size, weight, line height, etc.
Text ColorColor pickerOverrides the default color (#555).
AlignmentLeft / Center / RightResponsive.
How the count is calculated: The summary uses $query->found_posts for the total, posts_per_page from the Target node for page size, and the current page number to compute the start and end positions. It reflects the actual database result count, not just the number of cards visible on screen.

Pagination

Controls how users move through results when there are more than the Posts Per Page limit set in the Target node.

SettingOptionsEdition
Show PaginationOn / OffFree + Pro
Standard (Page Numbers)Full page reload with ?paged=N URLFree + Pro
AJAX (Page Numbers)In-place update, no page reload, URL does not changePro only
Load More ButtonAppends next page of results below existing resultsPro only
Infinite ScrollAutomatically loads next page as user scrolls toward the bottomPro only
Button TextCustom label for the Load More buttonPro only
Scroll OffsetDistance from bottom of viewport to trigger next load (px). Default: 200pxPro only
Free version: Only Standard (page numbers) pagination is available. AJAX, Load More, and Infinite Scroll require Pro.

Standard vs AJAX pagination

Standard pagination generates links that cause a full page reload with a ?paged=N URL parameter — good for SEO and shareable paginated URLs. AJAX pagination updates results in place without a reload, keeping scroll position — better for user experience on content-heavy pages.

Saving and Importing Queries

Query Forge lets you save any query canvas to a site-wide library and reload it into any widget at any time. This is how you build a query once and reuse it across multiple pages or widgets.

Permissions: Saving and importing queries requires administrator access (manage_options capability). Queries are stored per site and are not transferable between sites.

Save Logic

The Save Logic button in the top-right of the Query Builder commits the current canvas to the widget you opened it from. This is always the final step — it applies your query to the specific widget on the specific page you are editing. It does not save to the shared library.

Save As

The Save As button saves the current canvas to the shared query library so it can be reused elsewhere.

  1. Build your query on the canvas
  2. Click Save As in the toolbar
  3. Enter a name for the query when prompted
  4. Click OK — a confirmation appears when the save succeeds
Save As validates first. If your canvas has a broken or incomplete connection, Save As will refuse to save and show the validation errors. Fix the issues before saving.

Save As always creates a new entry — it does not overwrite an existing saved query with the same name. Each save is a snapshot of the canvas at that moment. Changes you make later on the canvas do not update the saved version unless you Save As again.

Import

The Import button opens a panel showing all queries in your saved library.

  1. Click Import in the toolbar
  2. The Import panel opens on the right side of the canvas, listing all saved queries with their name and save date
  3. Click Import next to the query you want to load
  4. The canvas is replaced with the saved query's nodes and edges
  5. Click Save Logic to apply the imported query to the current widget
Importing does not automatically apply the query to the widget. After importing, you must click Save Logic to commit the changes. This lets you inspect or modify the imported canvas before applying it.

Deleting a Saved Query

In the Import panel, each saved query has a Delete button. Deleting removes the query from the library permanently. It does not affect any widgets that are already using that query — those widgets store their own copy of the query logic.

How saved queries are stored

Saved queries are stored in WordPress options on the site where they were created. They are not transferable between sites. The library is shared across all users with administrator access on the site.

Typical workflow: Build once, deploy to many widgets

  1. Open the Query Builder on any page
  2. Build and test your query until it returns the right results
  3. Click Save As and give it a descriptive name (e.g. "Featured Products — Homepage")
  4. Click Save Logic to apply it to the current widget
  5. On a different page or widget, open the Query Builder
  6. Click Import, find your saved query, and click Import
  7. Click Save Logic to apply it to this widget

Preview Node PRO

The Preview node lets you see live query results directly on the canvas as you build — without saving or reloading the page. Drop one onto the canvas and it will automatically fetch and display matching post titles and IDs along with the total result count.

Adding a Preview Node

Click + Preview in the toolbar. The node appears on the canvas. Only one Preview node is allowed per canvas at a time — clicking + Preview again when one already exists highlights the existing node instead of creating another.

Node States

The Preview node has three visual states:

  • Inactive — dashed border. Shown when there is no complete query path on the canvas. Message: Build a valid query to preview.
  • Loading — solid border, fetching indicator. Appears briefly after a canvas change while the AJAX request is in flight.
  • Results — displays a list of post titles and IDs from the first page of results, plus the total result count (e.g. 47 total results). If the query returns no posts, shows No results for this query.

Post IDs — copy on click

Each result row shows the post ID to the left of the title in a small monospace style. Click any ID to copy it to the clipboard — the ID flashes teal briefly to confirm the copy. IDs are useful for pasting directly into the Include/Exclude node to pin or exclude specific posts.

Search

A Search toggle in the Preview node header enables an inline search input. Type a term and press Enter or click Search to filter the displayed results by title. Toggle search off to return to the full results list.

How it updates

The Preview node watches the canvas schema. Whenever the schema changes — a node is added, removed, connected, or its settings are updated — the preview waits 600ms and then fires a new fetch. It updates once per change and will not re-fetch if the schema hasn't actually changed.

The Preview node is canvas-only. It is not part of the query logic and never affects what gets saved to the widget. You can leave it on the canvas permanently or remove it with the × button — either way has no effect on query output.

Deleting the Preview Node

Click the red × button in the top-right corner of the node to remove it from the canvas.

Source Preview PRO

Source Preview lets you browse the raw content of any Source node directly on the canvas — without running the full query. Enable it on a Source node to get an inline, searchable, paginated list of posts from that source. Useful for finding post IDs to use in Include/Exclude, or for confirming that the right content is available before building your query.

Source Preview is available for post type sources only (Posts, Pages, Custom Post Types). It does not appear for Users, Comments, SQL Tables, or REST API sources.

Enabling Source Preview

Click a Source node to open its settings panel. At the bottom of the settings, below the post type dropdowns, you will find a Source preview toggle. Switch it on and click Apply. The node will show a small teal indicator dot when preview is armed but the node is collapsed.

Opening the Preview Panel

With Source Preview enabled, click the Source node on the canvas. It expands downward to reveal the preview panel — the existing node header and source type are unchanged, and the preview content appears below them. Only one Source node can be expanded at a time. Clicking a different Source node collapses the current one and expands the new one. Clicking the canvas background collapses the panel.

Browsing Results

The panel loads the first 10 posts from that source, ordered alphabetically by title. Each row shows the post ID on the left in monospace and the post title on the right. The list is scrollable. Prev and Next buttons at the bottom paginate through results, with a page counter showing your current position.

Searching

Type a search term into the input at the top of the panel and press Enter or click Search. Results are fetched from the server matching that term against post titles. Clear the search field and search again with no term to return to the full list.

Copying Post IDs

Click any post ID in the list to copy it to the clipboard. The ID flashes teal briefly to confirm. Paste the copied ID directly into the Include/Exclude node's Post In or Post Not In fields to pin or exclude that specific post from your query.

Typical workflow: find and exclude a post by ID

  1. Enable Source Preview on your Source node
  2. Click the Source node to expand the preview panel
  3. Search for the post title you want to exclude
  4. Click its ID to copy it
  5. Add an Include/Exclude node to the canvas
  6. Open its settings and paste the ID into the Post Not In field
  7. Click Apply and connect the Include/Exclude node to your query

Query Builder Interface

Query Builder Interface

Canvas

The main workspace. Right-click anywhere on the canvas to open the node menu, or use the toolbar buttons at the top. Drag from a node's right-side handle to another node's left-side handle to create a connection. Use scroll to zoom, drag the background to pan.

Toolbar

The top bar contains buttons to add each node type, Import (load a saved query), Save As (save current query with a name), Cancel, and Save Logic (commit the query to the widget).

Settings Panel

Click any node to open its settings in a panel on the right side of the canvas. Changes take effect immediately on the canvas but are not committed to the widget until you click Save Logic.

Node States

Nodes that are not on a complete path from Source to Target are visually dimmed. This indicates they will not contribute to the query. A query only executes the nodes that form an unbroken chain from Source to Target.

Minimap

The minimap in the bottom-right corner shows an overview of the full canvas. Useful when working with complex multi-node queries.

Source Node

The Source node defines where your query data comes from. Every query must have at least one Source node connected to the Target node.

Source Type Options

  • Posts — standard WordPress posts
  • Pages — WordPress pages
  • Custom Post Types — any registered CPT; a second dropdown appears to select the specific type
  • Users PRO — WordPress users, optionally filtered by role
  • Comments PRO — WordPress comments, optionally filtered by status and post type
  • SQL Table PRO — a custom database table
  • REST API PRO — an external REST endpoint

Multiple Sources PRO

Pro allows more than one Source node on the same canvas. Each source runs independently with its own filter chain. Results are merged and sorted before pagination is applied. See Multiple Sources for full details.

Filter Node

Filter nodes narrow query results based on field values. Each Filter node specifies one condition: a field, an operator, and a value. Chain multiple Filter nodes to apply multiple conditions.

Filter Node

Field Selection

The field dropdown is populated from two sources: standard WordPress post fields (always available) and meta keys detected from posts of the selected source type (loaded dynamically). You can also type a custom field name directly.

Standard Post Fields

FieldDescription
post_titlePost title — searches using a WHERE clause on the title column
post_contentPost content — searches using a WHERE clause on the content column
post_datePublication date — uses WordPress date_query
post_modifiedLast modified date — uses WordPress date_query
post_authorAuthor ID — maps to WP_Query author/author__in parameters
post_statusPost status (publish, draft, pending, private, etc.)
post_namePost slug
comment_countNumber of comments on the post

Any other field name is treated as a meta key and handled via meta_query.

Operators

Available operators depend on edition. See Operators for the full reference.

Value

Enter a static value, or use Dynamic Tags PRO to inject context at runtime. Click the ⚡ button next to the value field to open the dynamic tag picker.

Value Type

Sets how the value is cast when building a meta query: Text (CHAR), Number (NUMERIC), or Date (DATE). Only applies to meta field filters.

Example: Filter by Meta Field

Field:    featured
Operator: =
Value:    yes
Type:     Text

Returns posts where the featured meta key equals "yes".

Example: Filter by Post Status

Field:    post_status
Operator: =
Value:    publish

Returns only published posts. Note: by default Query Forge already restricts to published posts on the frontend, so this is only needed when you want to change that default (e.g. include drafts in a preview context).

Logic Node

Logic nodes combine multiple incoming filter branches using one of four relations. Connect two or more Filter nodes to the Logic node's left handle, then connect the Logic node's right handle toward the Target. Click the relation label on the node to cycle through the options.

Relation Options

RelationBehaviour
ANDA post must satisfy all incoming branches to be included
ORA post that satisfies any one incoming branch is included. Duplicates are removed.
UNIONCombines results from all branches into one set, removing duplicates. Equivalent to OR in most cases.
UNION ALLCombines results from all branches into one set, keeping duplicates. Useful when you intentionally want a post to appear more than once because it matched multiple branches.
A Logic node with only one incoming connection is valid but will be flagged with a warning indicator on the canvas. It still executes correctly.

AND: Must match all conditions

Filter (post_status = publish) ──┐
                                  ├──> Logic (AND) ──> Target
Filter (post_date >= 2024-01-01) ─┘

Result: posts that are published AND from 2024 onward

OR: Match any condition

Filter (featured = yes) ──┐
                           ├──> Logic (OR) ──> Target
Filter (on_sale = yes) ───┘

Result: posts that are featured OR on sale (or both), deduplicated

UNION ALL: Keep duplicates

Filter (category = News) ──┐
                            ├──> Logic (UNION ALL) ──> Target
Filter (featured = yes) ───┘

Result: all News posts plus all featured posts — a post that is
both News AND featured will appear twice in the results

Chaining Logic with Filters

You can connect a Filter node downstream of a Logic node's output to add further narrowing after the relation is applied. The Logic node produces a result set, and any node downstream of it filters within that set.

OR then AND narrowing

Filter (featured = yes) ──┐
                           ├──> Logic (OR) ──> Filter (post_status = publish) ──> Target
Filter (on_sale = yes) ───┘

Result: posts that are (featured OR on sale) AND published

Sort Node

Sort nodes define result ordering. Connect a Sort node between any node and the Target (or directly between Source and Target) to apply custom ordering. Multiple Sort nodes can be chained — the first in the chain is the primary sort, subsequent nodes are secondary sorts.

Sort Fields

FieldEditionDescription
dateFree + ProPublication date
titleFree + ProPost title (alphabetical)
IDFree + ProPost ID (numeric)
menu_orderPro onlyDrag-and-drop page order
meta_valuePro onlyText meta field value; requires Meta Key to be set
meta_value_numPro onlyNumeric meta field value; requires Meta Key to be set
randPro onlyRandom order (reshuffles on each page load)

Direction

  • ASC — ascending: A→Z, 1→10, oldest first
  • DESC — descending: Z→A, 10→1, newest first

Example: Sort by Price (Pro)

Sort Node:
  Field:     meta_value_num
  Meta Key:  price
  Direction: ASC

Result: products sorted cheapest to most expensive

Include / Exclude Node

The Include/Exclude node lets you explicitly pin specific posts in or out of the result set, and filter by author. Place it anywhere in the chain between Source and Target.

Settings

FieldFormatDescription
Post IDs — IncludeComma-separated IDsOnly include these post IDs (intersects with filter results)
Post IDs — ExcludeComma-separated IDsRemove these post IDs from results
Author IDs — IncludeComma-separated IDsOnly include posts by these authors
Author IDs — ExcludeComma-separated IDsRemove posts by these authors
Ignore Sticky PostsToggleWhen on (default), sticky posts are not forced to the top

All ID fields support Dynamic Tags PRO. You can mix static IDs and dynamic tags: 1,2,3,{{ current_post_id }}.

Example: Exclude Current Post (Pro)

Post IDs Exclude: {{ current_post_id }}

Result: all filtered posts except the one currently being viewed

Join Node PRO

Join nodes add a SQL LEFT JOIN to the underlying WP_Query, allowing you to filter posts based on data in custom or third-party database tables.

Settings

SettingDescription
Table NameTable name without the wp_ prefix. e.g. postmeta not wp_postmeta
AliasOptional SQL alias for the table in queries
Left ColumnColumn from wp_posts to join on. Default: ID
Right ColumnColumn from the joined table to match. Default: post_id
Security: Table names are validated — only alphanumeric characters and underscores are permitted. The table must exist in the WordPress database.

Generated SQL

LEFT JOIN wp_custom_orders AS orders ON wp_posts.ID = orders.post_id

Example: Filter Posts by Custom Orders Table

Join Node:
  Table:        custom_orders
  Alias:        orders
  Left Column:  ID
  Right Column: post_id

Filter Node:
  Field:    order_status
  Operator: =
  Value:    completed

Result: posts that have a completed order in the custom table

Target Node

The Target node is the output of every query. Every Source node must have a path that reaches the Target. There can only be one Target node per canvas.

Settings

SettingDefaultDescription
Posts Per Page10Number of results per page
Order BydateFallback sort field when no Sort node is present
OrderDESCASC or DESC
Sort nodes take priority. When Sort nodes are connected in the chain, they override the Target node's Order By and Order settings. The Target node's sort settings only apply when no Sort node is present.

Source: Posts

Queries standard WordPress posts (post_type = post). No additional configuration required. Use Filter nodes to narrow by category, tag, author, date, or any meta field.

Source: Pages

Queries WordPress pages (post_type = page). Useful for building page directories, sitemaps, or selecting specific pages by meta field.

Source: Custom Post Types

Queries any registered custom post type. After selecting Custom Post Types, a second dropdown appears listing all CPTs registered on the site. Select the one you want to query.

Common examples: Products (WooCommerce), Events (The Events Calendar), Courses, Testimonials, Team Members.

Pro users can enable plugin-grouped CPT lists under Settings → Query Forge License → Integrations — see Plugin Integrations.

Source: Users PRO

Queries WordPress users via WP_User_Query. Results are wrapped in post-like objects for compatibility with Elementor Loop Grid.

Settings

  • Role — optionally filter by user role (Administrator, Editor, Author, Contributor, Subscriber, or any custom role). Leave blank for all roles.

Common use cases: Team member directories, author lists, member-only dashboards.

Source: Comments PRO

Queries WordPress comments via WP_Comment_Query.

Settings

  • Status — Approved, Pending, Spam, Trash, or All
  • Post Type — optionally restrict to comments on posts of a specific post type

Common use cases: Recent reviews, comment activity feeds, testimonial displays.

Source: SQL Tables PRO

Queries a custom database table directly. Results are wrapped in post-like objects for Loop Grid compatibility.

Settings

  • Table Name — table name without the wp_ prefix

The table must exist in the WordPress database. Table names are validated for security — only alphanumeric characters and underscores are accepted.

Common use cases: Bookings tables, order history, any data stored in a non-standard WP table by a third-party plugin.

Source: REST API PRO

Fetches data from an external REST API endpoint and makes it available in the query pipeline.

Settings

  • API URL — full URL to the endpoint including any required query parameters
  • Method — GET or POST (default: GET)

Filter nodes applied after a REST API source operate on the fetched JSON data rather than the database. Pagination is calculated from the response.

Common use cases: External product catalogs, news feeds from external APIs, integrating third-party services into a Loop Grid.

Standard Fields

These fields map directly to WordPress post columns rather than meta keys. When used in a Filter node they are handled differently from meta filters — they modify WP_Query parameters directly or add SQL WHERE clauses.

FieldHow it filtersNotes
post_titleSQL WHERE on post_title columnLIKE operator searches by title only, not excerpt or content
post_contentSQL WHERE on post_content columnUse LIKE for full-text search within content
post_dateWP_Query date_queryUse = for exact day, >= for after a date, <= for before
post_modifiedWP_Query date_queryLast modification date
post_authorWP_Query author / author__inAccepts author user ID
post_statusWP_Query post_statusDefault is publish + private on frontend
post_nameWP_Query nameThe post slug
comment_countCustom SQL WHERE clauseSupports =, >=, <=

Any field name not in this list is treated as a meta key and runs through meta_query.

Meta Fields

Any field name that is not a standard post field is treated as a meta key. Meta filters are executed via WordPress's meta_query parameter.

The field dropdown auto-loads meta keys that exist on posts of the selected source type. You can also type a custom meta key directly or use the "Custom Field" entry option.

Value Type

When filtering by meta, set the Value Type to match your data:

  • Text (CHAR) — default; string comparison
  • Number (NUMERIC) — numeric comparison; use for price, count, rating fields
  • Date (DATE) — date comparison for meta fields storing dates

Example: Filter by Numeric Price

Field:      _price
Operator:   >=
Value:      100
Value Type: Number

Result: products with a price of 100 or more

Filter Operators

Free Edition Operators

OperatorMeaningWorks with
=Exact matchText, numbers, dates, post fields
!=Not equalText, numbers, post fields
LIKEContains (case-insensitive substring)Text fields, post_title, post_content
NOT LIKEDoes not contain (case-insensitive substring)Text fields, post_title, post_content

Pro Edition Operators

Pro adds the following operators to the filter node settings panel:

OperatorMeaningUse with
>Greater thanNumeric meta, dates
>=Greater than or equalNumeric meta, dates
<Less thanNumeric meta, dates
<=Less than or equalNumeric meta, dates
EXISTSMeta key exists (no value required)Meta fields only
NOT EXISTSMeta key does not existMeta fields only

Example: Posts Published After a Date (Pro)

Field:    post_date
Operator: >=
Value:    2024-01-01

Result: posts published on or after 1 January 2024

Example: Posts Where Featured Image Exists (Pro)

Field:    _thumbnail_id
Operator: EXISTS

Result: posts that have a featured image set

Logic Relations

When you chain Filter nodes directly (Source → Filter → Filter → Target) without a Logic node, each filter narrows the result of the previous one — they are implicitly ANDed in sequence. See Pipeline Execution for how this works internally.

A Logic node makes the AND/OR relationship explicit and allows branching: multiple Filter nodes feed into a single Logic node from different paths.

RelationBehaviour
ANDA post must satisfy every incoming branch
ORA post that satisfies any one incoming branch is included

AND vs OR — practical difference

AND example:
Filter (category = News) AND Filter (featured = yes)
→ Only featured posts that are also in the News category

OR example:
Filter (category = News) OR Filter (category = Events)
→ Posts in News OR Events (or both)

Pipeline Execution

Understanding how Query Forge executes your canvas is important when building complex queries, especially with multiple chained filters or multiple sources.

Single Filter

The simplest case: Source → Filter → Target. The filter's conditions are passed directly to WP_Query and the database does the work in one query.

Chained Filters (the pipeline)

When you chain multiple Filter nodes in sequence — Source → Filter A → Filter B → Target — Query Forge executes them as a sequential pipeline:

  1. Step 1: Filter A runs as a full WP_Query, returning a set of matching post IDs
  2. Step 2: Filter B runs as a new WP_Query, but constrained to only the IDs returned by Step 1 (via post__in)
  3. Each subsequent filter step narrows the result of the previous step
  4. If any step returns zero results, the pipeline short-circuits and the query returns nothing

Pipeline narrowing in action

Source (Products) 
  → Filter A (post_status = publish)     [Step 1: returns 200 IDs]
  → Filter B (featured = yes)            [Step 2: filters within those 200, returns 12]
  → Target

Final result: 12 published, featured products

This is different from putting both conditions into a Logic (AND) node, which would combine them into a single database query. The pipeline approach is useful when each condition needs to be evaluated independently — for example, when one condition filters on a standard field and the next filters on a meta field.

OR steps in a pipeline

When a Logic (OR) node is part of a chain, the OR step unions its result with the previous step's result rather than narrowing it:

  • AND step (default): take only the IDs that appear in both the previous result and the current step
  • OR step: take all IDs from the previous result plus all IDs from the current step (deduplicated)

Multi-Source Pipelines PRO

When the canvas has multiple Source nodes, each source runs its own independent pipeline. After all sources have been processed, their results are merged into a single pool, sorted, and paginated. See Multiple Sources for details.

Performance note: Each step in the pipeline is a separate database query. A chain of five filters runs five queries. For simple conditions, using a Logic (AND) node instead of chaining is more efficient — it produces a single combined query.

Multiple Sources PRO

Pro allows you to add more than one Source node to the same canvas. Each source can have its own independent chain of Filter nodes before they all converge at the Target node.

How it works

  1. Each source runs its complete filter pipeline independently
  2. Results from all sources are merged into a single pool
  3. The merged pool is sorted using the Target node's sort settings (or Sort nodes)
  4. Pagination is applied to the merged, sorted pool

Example: Two Post Types, Same Filters

Source (membercontent) ──┐
                          ├──> Filter (post_content LIKE "tutorial") ──> Logic (OR) ──> Target
Source (reminders) ──────┘    Filter (post_content LIKE "guide")

Result: posts from either CPT whose content contains "tutorial" or "guide",
merged and sorted together by the Target node's sort setting

Per-source filter chains

Each source can have a completely different filter chain. The canvas routes each source's outgoing edge through its own set of filter nodes before converging at Target. Filters connected downstream of a specific source only apply to that source's results.

Example: Different Filters per Source

Source (Products) ──> Filter (featured = yes) ──────────────────┐
                                                                    ├──> Target
Source (Events) ──> Filter (post_date >= 2024-01-01) ─────────────┘

Result: featured Products merged with Events from 2024 onward, sorted together

Include/Exclude with multiple sources

An Include/Exclude node placed on a specific source's path applies only to that source. This lets you, for example, exclude the current post from one source but not another.

Sorting merged results

After merging, all results are sorted using the Target node's sort field and direction. The sort operates on the properties of each result object — for post-type sources this is the standard post fields (post_date, post_title, etc.); for user or comment sources, equivalent fields are mapped.

Mixed Queries PRO

A mixed query combines sources of different types — for example, Posts and Users, or Events and Comments — in a single query. The execution model is the same as multiple sources: each source runs independently, results are merged, sorted, and paginated.

Example: Activity Feed

Source (Posts) ──────────────────────────────┐
                                               ├──> Target (20 items, date DESC)
Source (Comments) ──> Filter (status = approve)┘

Result: recent posts and approved comments sorted by date, newest first
Template consideration: Mixed source results are displayed using the same Elementor Loop template. Your template should handle cases where some fields (like post_author) may not be present on every item type. Using conditional dynamic tags within your Loop template is the recommended approach.

Dynamic Tags PRO

Dynamic tags inject context-aware values into filter fields and include/exclude lists at query execution time — not at save time. This means the same saved query produces different results depending on who is viewing the page, which post they are on, or what is in the URL.

Tags are entered in the value field of a Filter or Include/Exclude node. Click the ⚡ button to open the tag picker, or type the tag directly using the {{ tag_name }} syntax.

Tag Reference

TagReturnsReturns when not available
{{ current_user_id }}ID of the currently logged-in user0 (not logged in)
{{ current_post_id }}ID of the current post or page being viewed0 (not on a singular post)
{{ current_author_id }}ID of the author of the current post0
{{ current_date }}Today's date in Y-m-d format (server time)Never empty
{{ url_param:key }}Value of the URL query parameter named keyEmpty string
{{ user_meta:key }}Meta value stored on the current user under keyEmpty string (not logged in or key not set)
{{ current_post_terms:taxonomy }}Comma-separated term IDs from the current post for taxonomyEmpty (not on a post, or no terms)

Tag Examples

My Content Dashboard

Show only posts authored by the currently logged-in user.

Filter Node:
  Field:    post_author
  Operator: =
  Value:    {{ current_user_id }}

Related Posts by Category

Show posts in the same categories as the current post, excluding the current post itself.

Filter Node:
  Field:    post_category
  Operator: =
  Value:    {{ current_post_terms:category }}

Include/Exclude Node:
  Post IDs Exclude: {{ current_post_id }}

URL-Driven Filter

Filter posts by a category slug passed in the URL — e.g. ?filter_cat=news.

Filter Node:
  Field:    post_category
  Operator: =
  Value:    {{ url_param:filter_cat }}

When the URL parameter is absent the tag resolves to an empty string, which typically means no filtering is applied for that condition.

Posts Published Before Today

Filter Node:
  Field:    post_date
  Operator: <=
  Value:    {{ current_date }}

Filter by User Meta

Show posts matching a value stored in the current user's profile — e.g. their region or membership tier.

Filter Node:
  Field:    region
  Operator: =
  Value:    {{ user_meta:user_region }}

Mixing Static and Dynamic Values

In Include/Exclude fields you can mix static IDs with dynamic tags:

Post IDs Exclude: 5,10,{{ current_post_id }}

This excludes posts 5 and 10 always, plus the current post when on a singular page.

When Tags Resolve to Zero or Empty

If a tag resolves to 0 or an empty string and that value is passed to a filter, it may return unexpected results or no results. For example, {{ current_user_id }} returns 0 for non-logged-in visitors — a filter on post_author = 0 will return nothing. Design your queries with these fallback values in mind.

Joins PRO

The Join node adds a SQL LEFT JOIN to the underlying WP_Query, allowing filters to operate on columns from a related custom table. See the Join Node reference for configuration details.

When to use Joins

Use a Join when the data you need to filter on lives in a separate database table — not in wp_postmeta. Common scenarios: a third-party plugin stores order data or booking records in its own table and you want to surface related posts based on that data.

Connection pattern

Source → Join → Filter → Target

The Join node must come before Filter nodes that reference the joined table's columns. The connection left-to-right on the canvas determines the SQL join order.

Plugin Integrations PRO

Pro can group post types from popular plugins into a dedicated section in the Custom Post Types dropdown, making it easier to find them in the Query Builder.

Enabling integrations

Go to Settings → Query Forge License → Integrations. Only plugins that are installed and active on your site appear in the list. Enable the ones you want — their post types will appear under a divider in the source dropdown.

Supported plugins

PluginPost Types surfaced
WooCommerceProducts, Orders, Coupons
Easy Digital DownloadsDownloads
The Events CalendarEvents, Venues, Organizers
bbPressForums, Topics, Replies
WP Job ManagerJob Listings

More integrations may be added in future updates.

Basic Examples

Query Flow Diagram

Latest Blog Posts

Display the 6 most recent published blog posts.

Source (Posts) ──> Target (6, date DESC)

No filter needed — Query Forge restricts to published posts by default on the frontend.

Posts from a Specific Category

Source (Posts) ──> Filter (post_category = 5) ──> Target (10, date DESC)

Replace 5 with the term ID of your category.

Featured Products

Source (Products CPT) ──> Filter (featured = yes) ──> Target (12, date DESC)

Posts Containing a Keyword

Source (Posts) ──> Filter (post_content LIKE wordpress) ──> Target (10, date DESC)

LIKE is a substring match — this returns any post whose content contains the word "wordpress".

Advanced Examples

Posts Matching Either of Two Keywords (OR Logic)

Source (Posts)
  ──> Filter (post_content LIKE tutorial) ──┐
                                             ├──> Logic (OR) ──> Target (10, date DESC)
  ──> Filter (post_content LIKE guide) ─────┘

Returns posts whose content contains "tutorial" or "guide" (or both).

Posts That Must Match Two Conditions (AND Logic)

Source (Posts)
  ──> Filter (featured = yes) ──────────────┐
                                             ├──> Logic (AND) ──> Target (6, date DESC)
  ──> Filter (post_status = publish) ───────┘

Returns only posts that are both featured and published.

Chained Filters (Pipeline Narrowing)

Source (Posts)
  ──> Filter (post_content LIKE tutorial)
  ──> Filter (post_content LIKE advanced)
  ──> Target (10, date DESC)

Step 1 fetches posts containing "tutorial". Step 2 narrows that set to only posts that also contain "advanced". Equivalent to an AND but executed as two separate queries.

Sorted by Custom Field

Source (Products CPT)
  ──> Filter (featured = yes)
  ──> Sort (meta_value_num, meta_key: price, ASC)
  ──> Target (12)

Featured products sorted cheapest to most expensive. Requires Pro for meta sort.

Pro Examples PRO

Related Posts — Same Category, Exclude Current

Source (Posts)
  ──> Filter (post_category = {{ current_post_terms:category }})
  ──> Include/Exclude (Exclude: {{ current_post_id }})
  ──> Target (6, date DESC)

Shows posts from the same categories as the post being viewed, excluding that post itself.

My Saved Items Dashboard

Source (Posts)
  ──> Filter (post_author = {{ current_user_id }})
  ──> Target (20, date DESC)

Shows only posts authored by the currently logged-in user. Returns nothing for non-logged-in visitors.

User Directory — Editors Only

Source (Users, Role: Editor) ──> Target (20, title ASC)

Lists all users with the Editor role, sorted alphabetically.

Two CPTs, Independent Filters, Merged Result

Source (membercontent) ──> Filter (post_content LIKE disassociation) ──┐
                         ──> Logic (OR)                                    ├──> Target (10, title DESC)
Source (reminders) ──> Filter (post_content LIKE disassociation) ──┐    │
                       ──> Logic (OR)                               └────┘

(each source has its own filter chain; results are merged before sorting)

Both CPTs run the same filter logic independently. Their matching posts are merged into one pool and sorted by title before pagination.

URL-Filtered Product Listing

Source (Products CPT)
  ──> Filter (post_category = {{ url_param:cat }})
  ──> Target (12, date DESC)

Category is driven by the URL: /shop/?cat=5 shows category 5 products. When cat is absent from the URL, the filter resolves to empty and may return all products depending on how WP_Query handles the empty condition.

Common Patterns

Simple List

Source → Target

All posts of the selected type, paginated. No filtering applied.

Single Filter

Source → Filter → Target

One condition, one database query.

AND Conditions via Logic Node

Source → Filter A ──┐
        Filter B ───┼──> Logic (AND) → Target

All conditions must be true. More efficient than chaining — executes as a single query.

OR Conditions via Logic Node

Source → Filter A ──┐
        Filter B ───┼──> Logic (OR) → Target

Any condition may be true. Useful for "this category or that category" scenarios.

Sequential Narrowing (Pipeline)

Source → Filter A → Filter B → Filter C → Target

Each filter narrows the previous result. Three separate queries. Use when each condition needs independent evaluation.

OR then AND

Source → Filter A ──┐
        Filter B ───┼──> Logic (OR) → Filter C → Target

(A OR B) AND C. The Logic node produces a union, then Filter C narrows it further.

Multiple Sources, Merged Results (Pro)

Source A → Filter ... ──┐
Source B → Filter ... ──┼──> Target
Source C → Filter ... ──┘

Each source runs independently. Results are merged, sorted, and paginated together.

License Management

Activating

  1. Go to Settings → Query Forge License
  2. Enter your license key
  3. Click ACTIVATE
  4. Status updates automatically — Pro features become available immediately

Deactivating

  1. Go to Settings → Query Forge License
  2. Click DEACTIVATE
  3. The activation slot is freed and can be used on another site

Transferring to a New Site or Domain

Deactivate on the old site first, then activate on the new site using the same key. Each activation uses one slot from your license tier.

License Status

  • Active — all Pro features enabled
  • Inactive — Free features only
  • Grace Period — if our license API is temporarily unreachable, Pro features remain active for 14 days. After 14 days without successful validation, Pro features are disabled until the API is reachable again.

Plugin Integrations (Pro)

On the same license settings page, the Integrations section lets you choose which plugin post types appear in the Query Builder. Only active plugins on your site are listed. See Plugin Integrations for details.

Troubleshooting

Query returns no results

  1. Check that all nodes have a complete connected path from Source to Target. Any broken link produces no output — look for dimmed nodes on the canvas.
  2. Check your filter conditions — they may be too restrictive for the available data
  3. Verify the source type matches your data (e.g. the CPT slug is correct)
  4. Check post status — by default only published and private posts are returned on the frontend
  5. Review any include/exclude settings
  6. If using dynamic tags, check what the tag resolves to for the current visitor (e.g. {{ current_user_id }} returns 0 for non-logged-in users)

Results are missing some posts

  1. Check whether chained Filter nodes are too restrictive — each step in the pipeline narrows the previous result
  2. Verify that the posts exist with the field values you are filtering on
  3. Check the Value Type setting on meta filters — a numeric field filtered with type Text may not match correctly

Pro features not available

  1. Confirm the license is activated: Settings → Query Forge License
  2. Check that status shows "active"
  3. Clear any caching plugin caches
  4. Ensure you have the Pro plugin installed, not just the Free version

Dynamic tags not resolving

  1. Confirm you are using Pro — dynamic tags are a Pro feature
  2. Check that the tag syntax is exactly {{ tag_name }} with double curly braces
  3. For {{ current_post_id }} — this only resolves on singular post/page templates, not archive pages
  4. For {{ current_user_id }} — returns 0 for non-logged-in visitors
  5. For {{ current_post_terms:taxonomy }} — ensure the taxonomy slug is correct and the current post has terms assigned

Join not working

  1. Verify the table name is correct and does not include the wp_ prefix
  2. Check that column names match the actual table structure
  3. Confirm the table exists in the database
  4. Verify your Pro license is active

REST API source returning no data

  1. Confirm the API URL is correct and accessible from your server
  2. Check that the API does not require authentication headers that are not being sent
  3. Check the browser console for network errors
  4. Verify the response format matches what Query Forge expects (JSON array or object)

Saved queries not loading

  1. Confirm the query was saved successfully (you saw the confirmation)
  2. Check the browser console for JavaScript errors
  3. Ensure your user has edit permissions on the page
  4. Try refreshing the Query Builder

Multi-source results in wrong order

Multi-source queries are sorted after merging using the Target node's sort field. Ensure the sort field exists on all result types. If sorting by a meta field, all sources must have that meta key for consistent ordering.