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
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/grid/query_args | filter | $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_render | action | $grid_id_or_slug (int|string), $args (array) | Fires before the grid renders. Use for analytics, cache busting, or debug logging. |
| gridpanda/grid/after_render | action | $grid_id_or_slug, $html (string), $query (WP_Query) | Fires after render with the final HTML and the WP_Query instance. |
| gridpanda/grid/html | filter | $html (string), $grid (array), $posts (array) | Modify the final rendered grid HTML before it is returned to the client. |
| gridpanda/grid/before_item | action | $post (WP_Post), $grid (array), $index (int) | Fires before each post card is rendered. |
| gridpanda/grid/after_item | action | $post (WP_Post), $grid (array), $index (int) | Fires after each post card is rendered. |
| gridpanda/grid/item_data | filter | $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_tags | filter | '' (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/init | action | (none) | Fires in GridServiceProvider boot. Use to extend the grid system before it initializes. |
| gridpanda/grid/register_sources | action | $source_manager (SourceManager) | Register custom data source handlers that implement the source contract. |
| gridpanda/grid/dynamic_data_init | action | $dynamic_data (DynamicData) | Fires when DynamicData initializes. Use to extend the dynamic data system. |
Facets
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/facets/query_args | filter | $query_args (array) | Customize query args used for fetching facet choices. |
| gridpanda/facets/choices | filter | $choices (array), $facet_id (int), $active_post_ids (array) | Modify the computed facet choices and counts before they are returned. |
| gridpanda/facets/before_render | action | $facets (array|int[]), $context (string) | Fires before facet widgets are rendered. |
| gridpanda/facets/after_render | action | $output (string), $facets, $context | Fires after facet rendering with the HTML output. |
Indexer & Queue
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/indexer/reindex_all | action | (none) | Fires after a full site reindex is queued. Useful for notifications or cache invalidation. |
| gridpanda/indexer/reindex_facet | action | $facet_id (int) | Fires after a per-facet reindex is queued. |
| gridpanda/indexer/facet_progress | action | $facet_id (int), $percentage (float) | Fires during batch indexing with current progress percentage. |
| gridpanda/index/purged | action | (none) | Fires after the index table is fully purged. |
| gridpanda/queue/before_process | action | (none) | Fires before a queue batch is processed. |
| gridpanda/queue/after_process | action | $processed (int) | Fires after a queue batch completes with the count of jobs processed. |
| gridpanda/queue/job_completed | action | $job_id (int) | Fires when a queue job completes successfully. |
| gridpanda/queue/job_failed | action | $job_id (int), $error (string) | Fires when a queue job fails after max attempts. |
| gridpanda/worker/started | action | (none) | Fires when the async worker process starts. |
| gridpanda/worker/tick | action | $processed (int) | Fires on each worker iteration. |
| gridpanda/worker/stopped | action | (none) | Fires when the worker process stops. |
REST API
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/rest/batch_requests | filter | $requests (array) | Modify the batch request array before execution. |
| gridpanda/rest/enable_cors | filter | $enabled (bool) | Override whether CORS headers are added to responses. |
| gridpanda/rest/cors_origin | filter | $origin (string) | Override the CORS allowed origin. |
| gridpanda/rest/rate_limit_enabled | filter | $enabled (bool) | Override whether rate limiting is active. |
| gridpanda/rest/rate_limit | filter | $limit (int), $is_authenticated (bool) | Override the rate limit per minute. Return higher values for authenticated users. |
| gridpanda/rate_limiter/trusted_proxies | filter | $proxies (array) | Array of trusted proxy IP addresses for rate limit IP detection. |
| gridpanda/rest/dashboard_stats | filter | $stats (array) | Modify the dashboard statistics object before response. |
| gridpanda/rest/settings | filter | $settings (array) | Modify the settings object before it is returned via REST. |
| gridpanda/rest/settings_updated | action | $validated (array) | Fires after settings are saved via the REST API. |
| gridpanda/rest/sample_post_data | filter | $data (array), $post (WP_Post) | Add extra fields to the sample post data returned for the card builder. |
| gridpanda/rest/before_render | action | $facets (array), $page (int) | Fires before a grid render request is processed. |
| gridpanda/rest/render_response | filter | $response_data (array), $grid (array), $last_query (WP_Query) | Modify the grid render response data before sending. |
| gridpanda/rest/card_created | action | $card_id (int), $card (array) | Fires after a card is created. |
| gridpanda/rest/card_updated | action | $card_id (int), $card (array) | Fires after a card is updated. |
| gridpanda/rest/card_deleted | action | $card_id (int), $card (array) | Fires after a card is deleted. |
| gridpanda/rest/facet_created | action | $facet_id (int), $facet (array) | Fires after a facet is created. |
| gridpanda/rest/facet_updated | action | $facet_id (int), $facet (array) | Fires after a facet is updated. |
| gridpanda/rest/facet_deleted | action | $facet_id (int), $facet (array) | Fires after a facet is deleted. |
| gridpanda/rest/grid_created | action | $grid_id (int), $grid (array) | Fires after a grid is created. |
| gridpanda/rest/grid_updated | action | $grid_id (int), $grid (array) | Fires after a grid is updated. |
| gridpanda/rest/grid_deleted | action | $grid_id (int), $grid (array) | Fires after a grid is deleted. |
SEO
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/seo/clean_urls_enabled | filter | $enabled (bool) | Override whether clean filter URLs (/filter/slug-value/) are active. Useful for disabling on specific post types. |
| gridpanda/seo/canonical | filter | $canonical (string), $active_filters (array), $current_page (int) | Modify the canonical URL for the current filtered page. |
| gridpanda/seo/max_indexable_depth | filter | $depth (int) | Override the maximum facet depth included in the sitemap. |
| gridpanda/seo/robots_strategy | filter | $strategy (string) | Override robots strategy: 'noindex' or 'canonical_only'. |
| gridpanda/seo/robots | filter | $directives (array), $active_filters, $current_page | Modify the robots meta directives array before output. |
| gridpanda/seo/meta_title | filter | $title (string), $active_filters (array) | Modify the <title> tag content for filtered pages. |
| gridpanda/seo/meta_description | filter | $desc (string), $active_filters (array) | Modify the meta description for filtered pages. |
| gridpanda/seo/sitemap_urls | filter | $urls (array) | Modify the array of indexable filter URLs added to the sitemap. |
| gridpanda/seo/sitemap_base_url | filter | $base_url (string), $slug (string), $value (string) | Customize the base URL for sitemap filter URLs per facet slug. |
| gridpanda/seo/structured_data | filter | $item_list (array), $posts, $grid, $active_filters | Modify the Schema.org ItemList JSON-LD structured data before output. |
Cache
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/cache/before_purge | action | (none) | Fires before the cache is purged. |
| gridpanda/cache/after_purge | action | (none) | Fires after the cache is purged. |
| gridpanda/cache/purged | action | (none) | Fires when cache is purged via the settings REST endpoint. |
Images
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/image/quality | filter | 82 (int) | Override JPEG compression quality for generated image variants. Default 82. |
| gridpanda/image/generate_webp | filter | false (bool) | Enable WebP generation for card images. Disabled by default. |
Integrations
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/integration/booted | action | $integration (object), $id (string) | Fires after each integration boots. $id is the integration slug: woocommerce, acf, elementor, wpml, polylang. |
| gridpanda/integrations_booted | action | $manager (IntegrationManager) | Fires after all integrations boot. |
| gridpanda/integrations/ready | action | $manager (IntegrationManager) | Fires when integrations are fully ready. |
| gridpanda/register_integrations | action | $manager (IntegrationManager) | Register custom integration modules with the integration manager. |
| gridpanda/acf/ready | action | (none) | Fires when the ACF integration finishes initializing. |
| gridpanda/wpml/indexing_setup | action | (none) | Fires during WPML indexing setup. Use to customize multilingual indexing behaviour. |
| gridpanda/polylang/indexing_setup | action | $languages (array) | Fires during Polylang setup with the list of active languages. |
Core Lifecycle
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/activated | action | (none) | Fires when the plugin is activated. Schema installation and default options run before this. |
| gridpanda/deactivated | action | (none) | Fires when the plugin is deactivated. Data is preserved unless delete_data_on_uninstall is true. |
| gridpanda/get_service | filter | null, $service_name (string) | Service locator for queue jobs. Return a service instance by name (e.g. 'IndexManager', 'FacetRepository'). |
Database & Migrations
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda_migration_ran | action | $version (string), $migration (object) | Fires after a migration runs successfully. |
| gridpanda_migration_rolled_back | action | $version (string), $migration (object) | Fires after a migration is rolled back. |
Admin
| Hook | Type | Arguments | Description |
|---|---|---|---|
| gridpanda/import/before | action | $data (array) | Fires before data import. $data contains the import payload. |
| gridpanda/import/after | action | $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 );