Actions & Filters

Grid Panda exposes 60+ WordPress actions and filters for extending or modifying its behaviour without touching plugin files. All hook names follow the gridpanda/ namespace prefix.

Convention: Actions use add_action() and do not return values. Filters use add_filter() and must return the (possibly modified) first argument. Arguments listed are in order — the first arg is always the filterable value for filters.

Grid & Rendering

HookTypeArgumentsDescription
gridpanda/grid/query_argsfilter$query_args (array), $grid (array)Modify WP_Query arguments before the grid query executes. Use to add custom tax_query, meta_query, or post__in constraints.
gridpanda/grid/before_renderaction$grid_id_or_slug (int|string), $args (array)Fires before the grid renders. Use for analytics, cache busting, or debug logging.
gridpanda/grid/after_renderaction$grid_id_or_slug, $html (string), $query (WP_Query)Fires after render with the final HTML and the WP_Query instance.
gridpanda/grid/htmlfilter$html (string), $grid (array), $posts (array)Modify the final rendered grid HTML before it is returned to the client.
gridpanda/grid/before_itemaction$post (WP_Post), $grid (array), $index (int)Fires before each post card is rendered.
gridpanda/grid/after_itemaction$post (WP_Post), $grid (array), $index (int)Fires after each post card is rendered.
gridpanda/grid/item_datafilter$item_data (array), $post (WP_Post), $grid (array)Customize the data array passed to the card template for each post. Use to inject extra fields.
gridpanda/grid/dynamic_tagsfilter'' (string), $tag (string), $post (WP_Post), $is_raw (bool)Handle custom dynamic tags. Return a non-empty string to resolve the tag; return empty to fall through to defaults.
gridpanda/grid/initaction(none)Fires in GridServiceProvider boot. Use to extend the grid system before it initializes.
gridpanda/grid/register_sourcesaction$source_manager (SourceManager)Register custom data source handlers that implement the source contract.
gridpanda/grid/dynamic_data_initaction$dynamic_data (DynamicData)Fires when DynamicData initializes. Use to extend the dynamic data system.

Facets

HookTypeArgumentsDescription
gridpanda/facets/query_argsfilter$query_args (array)Customize query args used for fetching facet choices.
gridpanda/facets/choicesfilter$choices (array), $facet_id (int), $active_post_ids (array)Modify the computed facet choices and counts before they are returned.
gridpanda/facets/before_renderaction$facets (array|int[]), $context (string)Fires before facet widgets are rendered.
gridpanda/facets/after_renderaction$output (string), $facets, $contextFires after facet rendering with the HTML output.

Indexer & Queue

HookTypeArgumentsDescription
gridpanda/indexer/reindex_allaction(none)Fires after a full site reindex is queued. Useful for notifications or cache invalidation.
gridpanda/indexer/reindex_facetaction$facet_id (int)Fires after a per-facet reindex is queued.
gridpanda/indexer/facet_progressaction$facet_id (int), $percentage (float)Fires during batch indexing with current progress percentage.
gridpanda/index/purgedaction(none)Fires after the index table is fully purged.
gridpanda/queue/before_processaction(none)Fires before a queue batch is processed.
gridpanda/queue/after_processaction$processed (int)Fires after a queue batch completes with the count of jobs processed.
gridpanda/queue/job_completedaction$job_id (int)Fires when a queue job completes successfully.
gridpanda/queue/job_failedaction$job_id (int), $error (string)Fires when a queue job fails after max attempts.
gridpanda/worker/startedaction(none)Fires when the async worker process starts.
gridpanda/worker/tickaction$processed (int)Fires on each worker iteration.
gridpanda/worker/stoppedaction(none)Fires when the worker process stops.

REST API

HookTypeArgumentsDescription
gridpanda/rest/batch_requestsfilter$requests (array)Modify the batch request array before execution.
gridpanda/rest/enable_corsfilter$enabled (bool)Override whether CORS headers are added to responses.
gridpanda/rest/cors_originfilter$origin (string)Override the CORS allowed origin.
gridpanda/rest/rate_limit_enabledfilter$enabled (bool)Override whether rate limiting is active.
gridpanda/rest/rate_limitfilter$limit (int), $is_authenticated (bool)Override the rate limit per minute. Return higher values for authenticated users.
gridpanda/rate_limiter/trusted_proxiesfilter$proxies (array)Array of trusted proxy IP addresses for rate limit IP detection.
gridpanda/rest/dashboard_statsfilter$stats (array)Modify the dashboard statistics object before response.
gridpanda/rest/settingsfilter$settings (array)Modify the settings object before it is returned via REST.
gridpanda/rest/settings_updatedaction$validated (array)Fires after settings are saved via the REST API.
gridpanda/rest/sample_post_datafilter$data (array), $post (WP_Post)Add extra fields to the sample post data returned for the card builder.
gridpanda/rest/before_renderaction$facets (array), $page (int)Fires before a grid render request is processed.
gridpanda/rest/render_responsefilter$response_data (array), $grid (array), $last_query (WP_Query)Modify the grid render response data before sending.
gridpanda/rest/card_createdaction$card_id (int), $card (array)Fires after a card is created.
gridpanda/rest/card_updatedaction$card_id (int), $card (array)Fires after a card is updated.
gridpanda/rest/card_deletedaction$card_id (int), $card (array)Fires after a card is deleted.
gridpanda/rest/facet_createdaction$facet_id (int), $facet (array)Fires after a facet is created.
gridpanda/rest/facet_updatedaction$facet_id (int), $facet (array)Fires after a facet is updated.
gridpanda/rest/facet_deletedaction$facet_id (int), $facet (array)Fires after a facet is deleted.
gridpanda/rest/grid_createdaction$grid_id (int), $grid (array)Fires after a grid is created.
gridpanda/rest/grid_updatedaction$grid_id (int), $grid (array)Fires after a grid is updated.
gridpanda/rest/grid_deletedaction$grid_id (int), $grid (array)Fires after a grid is deleted.

SEO

HookTypeArgumentsDescription
gridpanda/seo/clean_urls_enabledfilter$enabled (bool)Override whether clean filter URLs (/filter/slug-value/) are active. Useful for disabling on specific post types.
gridpanda/seo/canonicalfilter$canonical (string), $active_filters (array), $current_page (int)Modify the canonical URL for the current filtered page.
gridpanda/seo/max_indexable_depthfilter$depth (int)Override the maximum facet depth included in the sitemap.
gridpanda/seo/robots_strategyfilter$strategy (string)Override robots strategy: 'noindex' or 'canonical_only'.
gridpanda/seo/robotsfilter$directives (array), $active_filters, $current_pageModify the robots meta directives array before output.
gridpanda/seo/meta_titlefilter$title (string), $active_filters (array)Modify the <title> tag content for filtered pages.
gridpanda/seo/meta_descriptionfilter$desc (string), $active_filters (array)Modify the meta description for filtered pages.
gridpanda/seo/sitemap_urlsfilter$urls (array)Modify the array of indexable filter URLs added to the sitemap.
gridpanda/seo/sitemap_base_urlfilter$base_url (string), $slug (string), $value (string)Customize the base URL for sitemap filter URLs per facet slug.
gridpanda/seo/structured_datafilter$item_list (array), $posts, $grid, $active_filtersModify the Schema.org ItemList JSON-LD structured data before output.

Cache

HookTypeArgumentsDescription
gridpanda/cache/before_purgeaction(none)Fires before the cache is purged.
gridpanda/cache/after_purgeaction(none)Fires after the cache is purged.
gridpanda/cache/purgedaction(none)Fires when cache is purged via the settings REST endpoint.

Images

HookTypeArgumentsDescription
gridpanda/image/qualityfilter82 (int)Override JPEG compression quality for generated image variants. Default 82.
gridpanda/image/generate_webpfilterfalse (bool)Enable WebP generation for card images. Disabled by default.

Integrations

HookTypeArgumentsDescription
gridpanda/integration/bootedaction$integration (object), $id (string)Fires after each integration boots. $id is the integration slug: woocommerce, acf, elementor, wpml, polylang.
gridpanda/integrations_bootedaction$manager (IntegrationManager)Fires after all integrations boot.
gridpanda/integrations/readyaction$manager (IntegrationManager)Fires when integrations are fully ready.
gridpanda/register_integrationsaction$manager (IntegrationManager)Register custom integration modules with the integration manager.
gridpanda/acf/readyaction(none)Fires when the ACF integration finishes initializing.
gridpanda/wpml/indexing_setupaction(none)Fires during WPML indexing setup. Use to customize multilingual indexing behaviour.
gridpanda/polylang/indexing_setupaction$languages (array)Fires during Polylang setup with the list of active languages.

Core Lifecycle

HookTypeArgumentsDescription
gridpanda/activatedaction(none)Fires when the plugin is activated. Schema installation and default options run before this.
gridpanda/deactivatedaction(none)Fires when the plugin is deactivated. Data is preserved unless delete_data_on_uninstall is true.
gridpanda/get_servicefilternull, $service_name (string)Service locator for queue jobs. Return a service instance by name (e.g. 'IndexManager', 'FacetRepository').

Database & Migrations

HookTypeArgumentsDescription
gridpanda_migration_ranaction$version (string), $migration (object)Fires after a migration runs successfully.
gridpanda_migration_rolled_backaction$version (string), $migration (object)Fires after a migration is rolled back.

Admin

HookTypeArgumentsDescription
gridpanda/import/beforeaction$data (array)Fires before data import. $data contains the import payload.
gridpanda/import/afteraction$data (array), $result (array)Fires after data import completes.

Usage Examples

// Restrict grid to current user's posts
add_filter( 'gridpanda/grid/query_args', function( $args, $grid ) {
    if ( 'my_posts_grid' === ( $grid['slug'] ?? '' ) ) {
        $args['author'] = get_current_user_id();
    }
    return $args;
}, 10, 2 );

// Add custom dynamic tag
add_filter( 'gridpanda/grid/dynamic_tags', function( $value, $tag, $post, $is_raw ) {
    if ( 'days_ago' === $tag ) {
        $diff = (int) ( ( time() - strtotime( $post->post_date ) ) / DAY_IN_SECONDS );
        return $diff === 0 ? 'Today' : "{$diff} days ago";
    }
    return $value;
}, 10, 4 );

// Disable noindex on a specific facet combination
add_filter( 'gridpanda/seo/robots', function( $directives, $active_filters, $page ) {
    if ( isset( $active_filters['category'] ) && ! isset( $active_filters['color'] ) ) {
        // Single-category filter is indexable — remove noindex
        $directives = array_filter( $directives, fn( $d ) => $d !== 'noindex' );
    }
    return $directives;
}, 10, 3 );

// Add product badge field to card sample data
add_filter( 'gridpanda/rest/sample_post_data', function( $data, $post ) {
    $data['badge'] = get_post_meta( $post->ID, '_product_badge', true );
    return $data;
}, 10, 2 );