Skip to content
Gravity Tables
All documentation

Developer

PHP hooks

Action and filter hooks for extending Gravity Tables behaviour from a child theme or custom plugin.

Gravity Tables exposes a stable hook API for extending behaviour without forking the plugin. All hook names are prefixed with gt_ (filters) or gt_action_ (actions).

Render filters#

gt_render_cell#

Modify a cell’s rendered HTML. Fires for every cell on every render.

add_filter('gt_render_cell', function ($html, $value, $field, $entry, $table) {
    if ($field['adminLabel'] === 'phone') {
        return '<a href="tel:' . esc_attr($value) . '">' . esc_html($value) . '</a>';
    }
    return $html;
}, 10, 5);

Parameters:

  • $html (string), current rendered HTML for the cell
  • $value (string), raw entry value
  • $field (array), Gravity Forms field config
  • $entry (array), full entry array
  • $table (object), table config

gt_render_row#

Modify the <tr> element. Useful for adding data- attributes or row-level CSS classes.

add_filter('gt_render_row', function ($attrs, $entry, $table) {
    if ($entry['payment_status'] === 'failed') {
        $attrs['class'] = ($attrs['class'] ?? '') . ' is-payment-failed';
    }
    return $attrs;
}, 10, 3);

gt_render_table_classes#

Modify the <table> element’s CSS classes.

add_filter('gt_render_table_classes', function ($classes, $table) {
    if ($table->id === 42) {
        $classes[] = 'is-customer-portal';
    }
    return $classes;
}, 10, 2);

Query filters#

gt_entries_query_args#

Modify the GFAPI::get_entries() arguments before the query runs. Most common extension point.

add_filter('gt_entries_query_args', function ($args, $table) {
    $args['paging']['offset'] = 0;
    $args['search_criteria']['field_filters'][] = [
        'key' => 'status',
        'operator' => '!=',
        'value' => 'archived',
    ];
    return $args;
}, 10, 2);

gt_entries_after_fetch#

Run after entries are fetched. Useful for enrichment or hiding rows post-query.

add_filter('gt_entries_after_fetch', function ($entries, $table) {
    return array_map(function ($e) {
        $e['_user_meta'] = get_user_meta($e['created_by'], 'company', true);
        return $e;
    }, $entries);
}, 10, 2);

Permission filters#

gt_can_view_table#

Customise the view-permission check.

add_filter('gt_can_view_table', function ($allowed, $table, $user) {
    if ($table->id === 99 && in_array('beta_tester', $user->roles)) {
        return true;
    }
    return $allowed;
}, 10, 3);

gt_can_edit_cell#

Per-cell edit permission, runs after edit_permissions evaluation.

add_filter('gt_can_edit_cell', function ($allowed, $field, $entry, $user) {
    // Customer can only edit their own row's address
    if ($field['adminLabel'] === 'address' && $entry['created_by'] !== $user->ID) {
        return false;
    }
    return $allowed;
}, 10, 4);

Action hooks#

gt_action_after_inline_edit#

Fires after a successful inline edit commits. Useful for webhooks, analytics, or syncing to external systems.

add_action('gt_action_after_inline_edit', function ($entry_id, $field_id, $new_value, $old_value, $user_id) {
    wp_remote_post('https://hooks.slack.com/...', [
        'body' => json_encode([
            'text' => "User {$user_id} edited entry {$entry_id} field {$field_id}: {$old_value} → {$new_value}",
        ]),
    ]);
}, 10, 5);

gt_action_before_export#

Fires just before an export is generated. Useful for adding a watermark to PDFs or rejecting an export based on custom logic.

add_action('gt_action_before_export', function ($table, $format, $rows, $user) {
    if ($format === 'pdf' && count($rows) > 10000) {
        wp_die('PDF exports limited to 10,000 rows. Use CSV instead.');
    }
}, 10, 4);

gt_action_bulk_complete#

Fires after a bulk action finishes processing all rows.

add_action('gt_action_bulk_complete', function ($action, $entry_ids, $table) {
    if ($action === 'approve') {
        update_post_meta(POST_PIPELINE_ID, 'last_approved', count($entry_ids));
    }
}, 10, 3);

Bulk action registration#

Register custom bulk actions for the bulk shortcode parameter.

add_filter('gt_register_bulk_actions', function ($actions) {
    $actions['archive'] = [
        'label' => 'Archive selected',
        'capability' => 'manage_options',
        'callback' => function ($entry_ids) {
            foreach ($entry_ids as $id) {
                gform_update_meta($id, 'archived', 1);
            }
            return ['success' => count($entry_ids)];
        },
    ];
    return $actions;
});

Then enable in shortcode:

[gravity_table id="42" bulk="approve,archive,delete"]

Logging#

If you’ve enabled debug mode (?gt_debug=1), gt_log() writes to wp-content/uploads/gt-logs/.

add_action('gt_action_after_inline_edit', function ($entry_id, $field_id) {
    gt_log("Edit committed: entry={$entry_id} field={$field_id}", 'info');
}, 10, 2);