Claude Skill

je-listings-callback

Registers or audits a JetEngine Listings callback used by Dynamic Field rendering through jet-engine/callbacks/register or the legacy callback filters. Covers callable identifiers, positional control arguments, multi-callback chains, zero-value defaults, serialized/non-scalar inp

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download lonsdale201-wp-agent-skills-jet-engine_je-listings-callback-52f6020.zip · 4 KB
Part of lonsdale201/wp-agent-skills — 226 skills

Install

skills CLI npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/jet-engine/je-listings-callback
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
Git git clone https://github.com/Lonsdale201/wp-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

JetEngine Listings callback

Add a Dynamic Field transform through JetEngine's allowlist. Treat the callback as render code: make it deterministic, cheap, and explicit about whether it returns plain text or already-safe HTML.

When to use this skill

  • Add a formatter to Dynamic Field's Filter field output control.
  • Add callback-specific controls and positional PHP arguments.
  • Diagnose a selected callback that yields blank or malformed output.
  • Process serialized arrays, chained callbacks, HTML, or zero-valued settings.
  • Audit output escaping or N+1 work in Listing Grids.

Preferred registration

Register on jet-engine/callbacks/register. The identifier must pass is_callable() and JetEngine's allowed-callback gate. Use a global function or a fully qualified static callable string.

final class My_Plugin_JE_Callbacks {
    public static function format_distance($value, $decimals = 1, $unit = 'km') {
        if (! is_numeric($value)) {
            return '';
        }

        $decimals = max(0, min(6, (int) $decimals));
        $unit     = in_array($unit, array('km', 'mi'), true) ? $unit : 'km';

        return number_format_i18n((float) $value, $decimals) . ' ' . $unit;
    }
}

add_action(
    'jet-engine/callbacks/register',
    static function($manager): void {
        $manager->register_callback(
            'My_Plugin_JE_Callbacks::format_distance',
            __('Format distance', 'my-plugin'),
            array(
                'my_plugin_decimals' => array(
                    'label'   => __('Decimals', 'my-plugin'),
                    'type'    => 'number',
                    'default' => 1,
                ),
                'my_plugin_unit' => array(
                    'label'   => __('Unit', 'my-plugin'),
                    'type'    => 'select',
                    'default' => 'km',
                    'options' => array(
                        'km' => 'km',
                        'mi' => 'mi',
                    ),
                ),
            )
        );
    }
);

JetEngine calls the function as:

callback(field value, my_plugin_decimals, my_plugin_unit)

Control declaration order is argument order. Prefix every control key. The modern registration adds its own UI conditions; do not duplicate them.

Critical argument edge

In 3.8.14, modern argument extraction uses ! empty($settings[$key]). Saved 0, '0', false, and '' therefore fall back to the declared default. The default is read with ! empty() too, so a declared default of 0 becomes an empty string. If zero is valid:

  • choose a non-ambiguous UI representation and normalize it in the callback; or
  • use the legacy jet-engine/listing/dynamic-field/callback-args filter and array_key_exists() for that argument.

Do not promise that a numeric control can pass literal zero through the modern helper unchanged.

Input and output contract

  • The first argument is the current field result.
  • Multiple filter_callbacks run sequentially; each output becomes the next callback's input.
  • Return string, number, null, or WP_Error intentionally. Raw arrays and objects produce a visible JetEngine error with available child keys; they are not silently stringified.
  • Return an empty string for unsupported input only when hiding the value is the desired behavior. Otherwise return a WP_Error during development.
  • Bound database/remote work. A Listing Grid may invoke the callback once per field, per item, and per callback in the chain.

Serialized and array-backed values

JetEngine only safely unserializes input for callbacks listed by jet-engine/listings/non-scalar-callbacks. Add a custom callback only when its source field is documented to store arrays:

add_filter(
    'jet-engine/listings/non-scalar-callbacks',
    static function(array $callbacks): array {
        $callbacks['My_Plugin_JE_Callbacks::join_labels'] = true;
        return $callbacks;
    }
);

Do not call unrestricted unserialize() in a callback. Validate the resulting shape and convert it to a scalar before returning.

Output security

Custom callback output is not automatically escaped by default. The filter jet-engine/listings/dynamic-field/kses-output defaults to false at the final render point.

  • For plain text, return esc_html($text) if the callback owns final HTML rendering, or return a raw scalar only when the consuming format escapes it.
  • For URLs/attributes, escape at the final attribute context; do not use esc_html() as a universal sanitizer.
  • For intentional limited HTML, return wp_kses_post($html) or enable final KSES for the exact field settings.
  • Never pass user-controlled shortcode or arbitrary callable names through.
add_filter(
    'jet-engine/listings/dynamic-field/kses-output',
    static function($use_kses, $settings) {
        return 'My_Plugin_JE_Callbacks::safe_badge'
            === ($settings['filter_callback'] ?? '') ? true : $use_kses;
    },
    10,
    2
);

Legacy route

Use the three legacy filters only for compatibility or zero-sensitive argument handling:

  • jet-engine/listings/allowed-callbacks
  • jet-engine/listings/allowed-callbacks-args
  • jet-engine/listing/dynamic-field/callback-args

Keep the same fully callable identifier in all three. Read callback-contracts.md before implementing the legacy path or chained/non-scalar behavior.

Verification

Test direct is_callable(), allowlist presence, argument order, omitted values, literal zero, empty input, malicious HTML, array/object output, a multi-callback chain, and a multi-item Listing Grid. Confirm the actual rendered DOM and count queries, not only the callback's direct return value.

References

Files (wp-agent-skills)
  • agents
    • openai.yaml 255 B
      interface:
        display_name: "JetEngine Listings Callback"
        short_description: "Build safe Dynamic Field callbacks"
        default_prompt: "Use $je-listings-callback to implement or audit this JetEngine Dynamic Field callback, arguments, output, and escaping."
      
  • references
    • callback-contracts.md 3.1 KB
      # Listings callback contracts
      
      Load this reference for legacy registration, zero-sensitive controls, chained
      callbacks, or array-backed field data.
      
      ## Gate sequence
      
      JetEngine executes a callback only when both conditions hold:
      
      1. the identifier is present in `jet-engine/listings/allowed-callbacks`;
      2. PHP `is_callable($identifier)` returns true.
      
      Valid examples:
      
      ```php
      'my_plugin_global_formatter'
      'My_Plugin_JE_Callbacks::format_distance'
      'Vendor\\Package\\Formatter::format'
      ```
      
      A bare alias such as `format_distance` is invalid unless a global function with
      that exact name exists. Registering a label does not create a callable.
      
      ## Legacy registration
      
      ```php
      $id = 'My_Plugin_JE_Callbacks::format_distance';
      
      add_filter('jet-engine/listings/allowed-callbacks', static function($items) use ($id) {
          $items[$id] = __('Format distance', 'my-plugin');
          return $items;
      });
      
      add_filter('jet-engine/listings/allowed-callbacks-args', static function($args) use ($id) {
          $args['my_plugin_decimals'] = array(
              'label'     => __('Decimals', 'my-plugin'),
              'type'      => 'number',
              'default'   => 1,
              'condition' => array(
                  'dynamic_field_filter' => 'yes',
                  'filter_callback'      => array($id),
              ),
          );
          return $args;
      });
      
      add_filter(
          'jet-engine/listing/dynamic-field/callback-args',
          static function($runtime, $callback, $settings) use ($id) {
              if ($id !== $callback) {
                  return $runtime;
              }
      
              $runtime[] = array_key_exists('my_plugin_decimals', $settings)
                  ? $settings['my_plugin_decimals']
                  : 1;
              return $runtime;
          },
          10,
          3
      );
      ```
      
      The runtime array already contains the field value. Append arguments in the
      same order as the callable signature.
      
      ## Multiple callbacks
      
      When `filter_callbacks` is populated, JetEngine ignores the singular
      `filter_callback` path and applies each row in order. A formatter must accept
      the previous formatter's output, not only the original database shape.
      
      Test chains such as:
      
      ```text
      stored ID -> title lookup -> HTML badge
      stored array -> join -> uppercase
      missing value -> fallback-aware formatter
      ```
      
      ## Non-scalar input
      
      The non-scalar allowlist tells JetEngine that the callback expects safely
      decoded array-backed data. It does not validate element types for the callback.
      After decoding:
      
      ```php
      public static function join_labels($value, $separator = ', ') {
          if (! is_array($value)) {
              return '';
          }
      
          $labels = array_filter($value, 'is_scalar');
          $labels = array_map('sanitize_text_field', array_map('strval', $labels));
          return implode((string) $separator, $labels);
      }
      ```
      
      Do not mark a scalar callback as non-scalar merely to make malformed data work.
      
      ## Performance checklist
      
      - Preload related objects with one query where possible.
      - Use request-local memoization keyed by input and every control argument.
      - Do not cache personalized output under a global key.
      - Put timeouts and failure handling around remote services; preferably hydrate
        remote data before render time.
      - Benchmark a realistic Listing Grid with all configured callback chains.
      
  • SKILL.md 7 KB
    ---
    name: je-listings-callback
    description: >-
      Registers or audits a JetEngine Listings callback used by Dynamic Field
      rendering through jet-engine/callbacks/register or the legacy callback
      filters. Covers callable identifiers, positional control arguments,
      multi-callback chains, zero-value defaults, serialized/non-scalar input,
      scalar output, escaping, and render-time performance. Use when adding a field
      formatter, callback controls, array-aware transforms, or diagnosing blank,
      unsafe, incorrectly ordered, or unexpectedly defaulted Dynamic Field output.
    metadata:
      wp-skills-author: "Soczó Kristóf"
      wp-skills-contact: "mailto:lonsdale201@hotmail.com"
      wp-skills-plugin: "jet-engine"
      wp-skills-plugin-version-tested: "3.8.14"
      wp-skills-wp-version-tested: "7.0.4"
      wp-skills-php-min: "7.4"
      wp-skills-last-updated: "2026-08-17"
    ---
    
    # JetEngine Listings callback
    
    Add a Dynamic Field transform through JetEngine's allowlist. Treat the callback
    as render code: make it deterministic, cheap, and explicit about whether it
    returns plain text or already-safe HTML.
    
    ## When to use this skill
    
    - Add a formatter to Dynamic Field's Filter field output control.
    - Add callback-specific controls and positional PHP arguments.
    - Diagnose a selected callback that yields blank or malformed output.
    - Process serialized arrays, chained callbacks, HTML, or zero-valued settings.
    - Audit output escaping or N+1 work in Listing Grids.
    
    ## Preferred registration
    
    Register on `jet-engine/callbacks/register`. The identifier must pass
    `is_callable()` and JetEngine's allowed-callback gate. Use a global function or
    a fully qualified static callable string.
    
    ```php
    final class My_Plugin_JE_Callbacks {
        public static function format_distance($value, $decimals = 1, $unit = 'km') {
            if (! is_numeric($value)) {
                return '';
            }
    
            $decimals = max(0, min(6, (int) $decimals));
            $unit     = in_array($unit, array('km', 'mi'), true) ? $unit : 'km';
    
            return number_format_i18n((float) $value, $decimals) . ' ' . $unit;
        }
    }
    
    add_action(
        'jet-engine/callbacks/register',
        static function($manager): void {
            $manager->register_callback(
                'My_Plugin_JE_Callbacks::format_distance',
                __('Format distance', 'my-plugin'),
                array(
                    'my_plugin_decimals' => array(
                        'label'   => __('Decimals', 'my-plugin'),
                        'type'    => 'number',
                        'default' => 1,
                    ),
                    'my_plugin_unit' => array(
                        'label'   => __('Unit', 'my-plugin'),
                        'type'    => 'select',
                        'default' => 'km',
                        'options' => array(
                            'km' => 'km',
                            'mi' => 'mi',
                        ),
                    ),
                )
            );
        }
    );
    ```
    
    JetEngine calls the function as:
    
    ```text
    callback(field value, my_plugin_decimals, my_plugin_unit)
    ```
    
    Control declaration order is argument order. Prefix every control key. The
    modern registration adds its own UI conditions; do not duplicate them.
    
    ## Critical argument edge
    
    In 3.8.14, modern argument extraction uses `! empty($settings[$key])`. Saved
    `0`, `'0'`, `false`, and `''` therefore fall back to the declared default. The
    default is read with `! empty()` too, so a declared default of `0` becomes an
    empty string. If zero is valid:
    
    - choose a non-ambiguous UI representation and normalize it in the callback; or
    - use the legacy `jet-engine/listing/dynamic-field/callback-args` filter and
      `array_key_exists()` for that argument.
    
    Do not promise that a numeric control can pass literal zero through the modern
    helper unchanged.
    
    ## Input and output contract
    
    - The first argument is the current field result.
    - Multiple `filter_callbacks` run sequentially; each output becomes the next
      callback's input.
    - Return `string`, number, `null`, or `WP_Error` intentionally. Raw arrays and
      objects produce a visible JetEngine error with available child keys; they are
      not silently stringified.
    - Return an empty string for unsupported input only when hiding the value is the
      desired behavior. Otherwise return a `WP_Error` during development.
    - Bound database/remote work. A Listing Grid may invoke the callback once per
      field, per item, and per callback in the chain.
    
    ## Serialized and array-backed values
    
    JetEngine only safely unserializes input for callbacks listed by
    `jet-engine/listings/non-scalar-callbacks`. Add a custom callback only when its
    source field is documented to store arrays:
    
    ```php
    add_filter(
        'jet-engine/listings/non-scalar-callbacks',
        static function(array $callbacks): array {
            $callbacks['My_Plugin_JE_Callbacks::join_labels'] = true;
            return $callbacks;
        }
    );
    ```
    
    Do not call unrestricted `unserialize()` in a callback. Validate the resulting
    shape and convert it to a scalar before returning.
    
    ## Output security
    
    Custom callback output is not automatically escaped by default. The filter
    `jet-engine/listings/dynamic-field/kses-output` defaults to `false` at the final
    render point.
    
    - For plain text, return `esc_html($text)` if the callback owns final HTML
      rendering, or return a raw scalar only when the consuming format escapes it.
    - For URLs/attributes, escape at the final attribute context; do not use
      `esc_html()` as a universal sanitizer.
    - For intentional limited HTML, return `wp_kses_post($html)` or enable final
      KSES for the exact field settings.
    - Never pass user-controlled shortcode or arbitrary callable names through.
    
    ```php
    add_filter(
        'jet-engine/listings/dynamic-field/kses-output',
        static function($use_kses, $settings) {
            return 'My_Plugin_JE_Callbacks::safe_badge'
                === ($settings['filter_callback'] ?? '') ? true : $use_kses;
        },
        10,
        2
    );
    ```
    
    ## Legacy route
    
    Use the three legacy filters only for compatibility or zero-sensitive argument
    handling:
    
    - `jet-engine/listings/allowed-callbacks`
    - `jet-engine/listings/allowed-callbacks-args`
    - `jet-engine/listing/dynamic-field/callback-args`
    
    Keep the same fully callable identifier in all three. Read
    [callback-contracts.md](references/callback-contracts.md) before implementing
    the legacy path or chained/non-scalar behavior.
    
    ## Verification
    
    Test direct `is_callable()`, allowlist presence, argument order, omitted values,
    literal zero, empty input, malicious HTML, array/object output, a multi-callback
    chain, and a multi-item Listing Grid. Confirm the actual rendered DOM and count
    queries, not only the callback's direct return value.
    
    ## References
    
    - Official documentation: <https://crocoblock.com/knowledge-base/plugins/jetengine/>
    - Crocoblock developer documentation: <https://github.com/Crocoblock/developer-documentation/tree/main/01-jet-engine>
    - Verified source paths:
      - `wp-content/plugins/jet-engine/includes/components/listings/callbacks.php`
      - `wp-content/plugins/jet-engine/includes/components/listings/manager.php`
      - `wp-content/plugins/jet-engine/includes/components/listings/render/dynamic-field.php`
      - `wp-content/plugins/jet-engine/includes/core/functions.php`
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related