本文へ移動
cccskills
無料GitHub で公開

wp-plugin-presenter

Design and review native presenter classes in WordPress plugins without requiring better-data - converting DTOs or domain objects into REST arrays, admin table rows, JS config payloads, email variables, and public view models with allowlisted fields, context methods, redaction by default, locale/date/number formatting, no DTO mutation, and correct WordPress escaping boundaries. Use when adding FooPresenter, response mappers, admin-row arrays, wp_send_json payloads, rest_ensure_response data, wp_add_inline_script config, or when code returns raw DTOs, WP_Post, WC_Order, get_object_vars, json_encode, or unescaped HTML from controllers.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md8.6 KB
  • references/before-after-controller-output.md3.4 KB
  • references/presenter-context-patterns.md5.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

WordPress plugin: native presenters

For plugin code that turns DTOs / domain objects into output shapes. A presenter chooses fields, computes labels, formats dates/numbers, redacts sensitive values, and returns arrays that controllers can send to REST, AJAX, admin tables, JS config, email templates, exports, or views.

This skill is intentionally better-data-free. If the project already uses better-data, run bd-presenter; otherwise use this native pattern.

When to load references

Misconception this skill corrects

"The DTO already has to_array(), so the controller can return that everywhere."

Wrong. to_array() is usually the DTO's canonical data snapshot. REST output, admin table rows, export rows, JS config, and email variables have different audiences and redaction rules. A presenter makes those contexts explicit instead of letting every controller hand-edit arrays.

When to use this skill

Trigger when ANY of the following is true:

  • Adding or reviewing FooPresenter, FooViewModel, ResponseMapper, AdminRow, JsonPresenter, or similar classes.
  • REST/AJAX code returns arrays derived from DTOs, WP_Post, WP_User, WooCommerce objects, options, or custom table rows.
  • Code calls wp_send_json_success(), rest_ensure_response(), wp_add_inline_script(), or builds admin table rows.
  • A DTO has sensitive fields and the output needs redaction.
  • A controller currently contains formatting, labels, computed fields, or output-specific conditionals.

Layer boundaries

LayerResponsibility
DTONormalized data. No audience-specific output.
PresenterContext-specific arrays and computed fields. No DB writes.
ControllerPermission check, nonce/REST validation, calls presenter, sends response.
View/templateEscapes and echoes HTML.

Presenter output for REST/JSON should be raw JSON-safe primitives, not pre-escaped HTML. Presenter output for an HTML-only view may include already escaped markup, but the method name must make that clear, e.g. render_badge_html().

Minimal class shape

namespace MyPlugin\Presenter;

use MyPlugin\Dto\ProductDto;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

final class ProductPresenter {
    private ProductDto $product;

    public function __construct( ProductDto $product ) {
        $this->product = $product;
    }

    /** @return array<string,mixed> */
    public function for_rest(): array {
        return array(
            'id'      => $this->product->id(),
            'title'   => $this->product->title(),
            'enabled' => $this->product->enabled(),
        );
    }

    /** @return array<string,string|int> */
    public function for_admin_table(): array {
        return array(
            'id'     => $this->product->id(),
            'title'  => $this->product->title(),
            'status' => $this->product->enabled() ? __( 'Enabled', 'my-plugin' ) : __( 'Disabled', 'my-plugin' ),
        );
    }
}

Use explicit context methods instead of a generic to_array( $context ) until the contexts genuinely share most of the same shape. Method names make reviews easier: for_rest(), for_admin_table(), for_export(), for_email(), for_js_config().

Output rules by context

  • REST/AJAX: return unescaped scalars, arrays, and nulls. Let WP JSON-encode them.
  • Admin table / template: presenter chooses values; view escapes with esc_html(), esc_attr(), esc_url(), or wp_kses_post().
  • Inline JS config: pass presenter output through wp_json_encode() inside wp_add_inline_script().
  • Email: present subject/body variables separately from HTML template rendering.
  • Export: use stable machine-readable keys and raw scalar values unless the export is explicitly human-facing.

See references/presenter-context-patterns.md for complete examples.

Redaction by default

Presenter methods should be public-safe by default. Sensitive values require explicit opt-in:

public function for_admin_table(): array {
    return array(
        'name'    => $this->credential->name(),
        'api_key' => '***',
    );
}

public function for_private_admin( bool $can_reveal_secret ): array {
    if ( ! $can_reveal_secret ) {
        return $this->for_admin_table();
    }

    $api_key = $this->credential->api_key();

    return array(
        'name'    => $this->credential->name(),
        'api_key' => $api_key ? $api_key->reveal() : '',
    );
}

The controller passes $can_reveal_secret = current_user_can( 'manage_options' ); the presenter applies that already-made authorization decision. Do not create convenience methods like reveal_all() or include secrets in a generic for_rest() response.

Critical rules

  • Presenter never mutates the DTO. Compute output values into arrays.
  • Allowlist fields. Never get_object_vars( $dto ), json_encode( $dto ), or return raw WP/WC objects.
  • One context, one method. for_rest() and for_admin_table() should not share a leaky "everything" array.
  • Redact sensitive fields by default. Explicit reveal only in narrowly named methods, and pass the authorization decision in from the controller.
  • Escape at the final HTML boundary. REST/AJAX/JS config arrays are not HTML.
  • Do not put HTML in REST payloads. If a method returns HTML, name it render_*_html() and escape inside it.
  • Keep DB and WP writes out. Presenter may call formatting/i18n helpers, but not repositories, update_option(), $wpdb, or remote APIs.
  • Collections replay per-item presenters. No duplicated mapping logic.

Common mistakes

// WRONG - exposes every public property and misses redaction.
return get_object_vars( $dto );

// WRONG - REST payload contains HTML from an admin use case.
return array( 'status' => '<span class="badge">Enabled</span>' );

// WRONG - escaping too early for JSON.
return array( 'title' => esc_html( $dto->title() ) );

// WRONG - side effect in presenter.
update_option( 'myplugin_last_presented', time() );

Cross-references

  • Run wp-plugin-dto when the presenter input is still a raw array or unclear object.
  • Run wp-plugin-architecture when deciding folder placement, namespaces, or by-feature vs by-type organization.
  • Run wp-plugin-assets-loading when passing presenter output into wp_add_inline_script().
  • Run bd-presenter only if the project intentionally uses the better-data library. better-data automates builder-style presentation; this skill is the native no-library version.

What this skill does NOT cover

  • DTO hydration and validation. Use wp-plugin-dto.
  • Template partial organization or block rendering architecture.
  • better-data Presenter internals.
  • REST route registration and permission callbacks.

References

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

Control a headless browser to navigate URLs, click elements, fill forms, extract content from JavaScript-rendered pages, take screenshots, and automate end-to-end web workflows.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

Review code for quality, simplicity, and maintainability. Identifies unnecessary abstractions, duplicated logic, oversized functions, missing error handling, and naming issues — then fixes them automatically before presenting the result.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

WooCommerce store operations through NV oOS Pro — product research, catalog cross-referencing, inventory lookups, and Shopify or Flowhub comparisons where integrations are configured.

日本語の概要は準備中です。原文の説明を表示しています。

nvdigitalsolutions/mcp-ai-wpoos72026年10月12日 更新

nvdigitalsolutions のスキルをすべて見る

このスキルの問題を報告する