Skip to content

Custom Post Types

Arun Prakash edited this page Nov 3, 2026 · 2 revisions

Custom Post Types and Plugin Routes

client.resource<T> gives any REST collection the same typed operations as the built-in interfaces, without writing a request class or interface. Use it for custom post types (rest_base of the type) and for plugin routes such as my-shop/v1/orders.

class Event {
  Event(this.id, this.title);
  factory Event.fromJson(Map<String, dynamic> j) => Event(j['id'] as int, j['title'] as String);
  final int id;
  final String title;
  Map<String, dynamic> toJson() => {'title': title};
}

final events = client.resource<Event>(
  'events',                      // rest_base of the post type
  decoder: Event.fromJson,
  encoder: (e) => e.toJson(),    // only needed to create/update from a model
);

final page = await events.list(perPage: 20, query: {'status': 'publish'});
final all = await events.listAll();                    // every page
await for (final p in events.listPages()) {}           // lazy
final one = await events.retrieve(7);
await events.create(Event(0, 'Launch'));               // or a Map
await events.update(7, {'title': 'Renamed'});
await events.delete(7, force: true);
Parameter Meaning
namespace Default wp/v2. Anything else (my-shop/v1) is resolved against the site root, on the client's own origin
requireAuthForReads Send credentials on GET too (default false)

Instead of writing Event by hand, generate it from the site's schema:

dart run wordpress_client:generate --site https://example.com --route wp/v2/events --out lib/models/event.dart

See Model Generator. Custom fields: Meta and ACF.

Asking for the same type and route twice returns the same interface. Every call goes through middlewares, retries and the cache.

Plugin namespaces

final orders = client.resource<Order>(
  'orders',
  namespace: 'my-shop/v1',          // https://example.com/wp-json/my-shop/v1/orders
  decoder: Order.fromJson,
  requireAuthForReads: true,        // private data: send credentials on GET too
);

The route is always resolved against the client's own origin (Bootstrap and Configuration).

Failures and raw access

Like every interface, calls return WordpressResponse<T> (Error Handling and Responses). listRaw returns the untyped response. For fully custom request and response classes, or non-CRUD routes, see Using Custom Requests and Raw Requests.

Clone this wiki locally