Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Wordpress Args Laravel Package

pollora/wordpress-args

A fluent PHP API for building WordPress arguments without messy arrays. Compose WP_Query, register_post_type, taxonomy, and similar configuration through chainable methods, keeping WordPress setup cleaner, more readable, and easier to maintain in Laravel or standalone PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require pollora/wordpress-args

There is no service provider and no config to publish — it is a plain value-object library that turns the associative arrays WordPress expects into fluent, typed builders. That is the whole mental model: build an object, call toArray(), hand the array to WordPress.

Where to look first

  1. src/ — the class names map 1:1 to WordPress APIs (PostType, Taxonomy, WPQuery, meta box / block args, etc.). Read the base/abstract argument class first; every concrete class inherits the same toArray() / setter conventions, so learning one teaches you all of them.
  2. tests/ — this is where the real API documentation lives for a 2-star package. The tests show the exact method names and the exact array shape produced.
  3. The README — usually a single "before/after" snippet. Confirm the PHP version constraint and whether it depends on illuminate/support (Arrayable, Collection), because that dictates whether you can use it outside a Laravel app.

First use case

Take the most painful array literal in your codebase — the register_post_type() call — and convert it:

// Before
register_post_type('book', [
    'labels'       => ['name' => 'Books', 'singular_name' => 'Book'],
    'public'       => true,
    'has_archive'  => true,
    'supports'     => ['title', 'editor', 'thumbnail', 'excerpt'],
    'rewrite'      => ['slug' => 'books', 'with_front' => false],
    'show_in_rest' => true,
]);

// After
$book = PostType::make('book')
    ->label('Books', 'Book')
    ->public()
    ->hasArchive()
    ->supports('title', 'editor', 'thumbnail', 'excerpt')
    ->rewrite(slug: 'books', withFront: false)
    ->showInRest();

register_post_type($book->name(), $book->toArray());

If that reads better to your team, adopt it everywhere. If it does not, stop here — this package has no other value proposition, and you should not adopt it anyway.


Implementation Patterns

1. One "definitions" file, not inline registration

The single biggest win is moving post types, taxonomies, and meta registrations out of functions.php/Plugin.php into dedicated classes or a definitions directory, then registering them in a loop:

// app/WordPress/PostTypes/Book.php
final class Book
{
    public static function args(): PostType
    {
        return PostType::make('book')
            ->label('Books', 'Book')
            ->public()
            ->hasArchive()
            ->supports('title', 'editor', 'thumbnail')
            ->showInRest()
            ->rewrite(slug: 'books');
    }
}

// registration
foreach ([Book::class, Author::class] as $type) {
    $args = $type::args();
    register_post_type($args->name(), $args->toArray());
}

This gives you a single place to diff when WordPress adds an argument, and makes the definitions greppable.

2. Conditional configuration with a fluent chain

Because setters return $this, you can branch mid-chain without building temporary arrays. This is where the object model beats arrays most clearly:

$args = PostType::make('event')
    ->label('Events', 'Event')
    ->public()
    ->supports('title', 'editor');

if (is_multisite()) {
    $args->showInRest();
}

if (wp_get_environment_type() !== 'production') {
    $args->rewrite(slug: 'events-dev');
}

register_post_type($args->name(), $args->toArray());

With raw arrays you would end up with array_merge soup and lose ordering guarantees for supports.

3. WP_Query wrapping for repeated query shapes

Use the query builder for named, reusable queries only. Ad-hoc queries inside a template should stay as arrays — otherwise you are paying ceremony for nothing.

$featured = WPQuery::make()
    ->postType('post')
    ->postsPerPage(3)
    ->metaKey('featured')
    ->metaValue('1')
    ->orderBy('date', 'DESC');

$loop = new WP_Query($featured->toArray());

A useful convention: expose these as static factory methods on a Queries class (Queries::featuredPosts(), Queries::upcomingEvents()) so query intent has a name.

4. Bridge into Laravel/container land

If you are on Pollora or a Laravel-flavoured WordPress stack, resolve definitions from the container rather than calling statics, so a site-specific plugin can override a definition:

$this->app->bind(Book::class, fn () => Book::args());

Then loop over an injected iterable of argument objects. This is the pattern that makes the package worthwhile on multi-site or white-label installs where the same codebase ships with different post types.

5. Composing with toArray() at the boundary

Keep the discipline: objects inside your code, arrays at the WordPress boundary. Never pass the object itself to a WordPress function and never let the object leak into templates. Every register_* / new WP_Query call should be a ->toArray() call, which makes it trivially searchable when you need to audit all WordPress registrations.

6. Testing

The main testability benefit is that you can assert on the produced array without booting WordPress:

$args = Book::args()->toArray();

$this->assertTrue($args['show_in_rest']);
$this->assertSame('books', $args['rewrite']['slug']);
$this->assertContains('thumbnail', $args['supports']);

Write one such test per definition. It is cheap and catches the "someone removed show_in_rest and the block editor broke" class of regression.


Gotchas and Tips

It is a thin wrapper, not a validator. Nothing stops you from setting an argument WordPress does not understand for your installed version, or omitting a required one. register_post_type() will still silently register something half-broken. Keep a test that asserts the key set, and check the WordPress version requirement of the package against your minimum supported WP.

Nested arguments are the sharp edge. labels, capabilities, rewrite, and supports are where array literals actually hurt, and they are also the most likely place for a fluent API to be incomplete or opinionated. Before adopting, verify the nested shapes you need (rewrite => ['with_front' => false, 'pages' => true], custom capabilities with map_meta_cap) are reachable. If they are not, fall back to a raw array merge for that key rather than fighting the builder.

(array) is not toArray(). Casting the object will expose internal properties, not WordPress arguments. Always call toArray(). Add a PHPStan rule or code review checklist item if you can.

Ordering matters for supports and labels. Fluent accumulation preserves insertion order, which is good — but be aware that calling supports() twice appends rather than replaces. Decide whether you want append or replace semantics and document it in your own wrapper; do not assume the package chose the one you wanted.

Booleans vs. strings. WordPress historically accepts 'true'/'false' strings for some args and real booleans for others, and a wrapper that type-hints bool can produce output that behaves differently from the array you used to write. Diff the produced array against your old literal during migration — literally var_export both and compare — before shipping.

2 stars and 0 dependents means you are the QA. Pin the version in composer.json ("pollora/wordpress-args": "^1.0" or an exact tag), read the changelog before every update, and be prepared to vendor-fork it. It is MIT and small, so forking is cheap; treat your usage as "we own this code now."

Extension points. The base argument class is where to hook in if you need site-wide defaults — e.g. a LocalizedPostType subclass that automatically applies show_in_rest and a capabilities map. Prefer one such subclass over sprinkling ->showInRest() across twenty definitions. Do not monkey-patch; extend.

Debugging. When a registration misbehaves, dump the array and compare against the WordPress developer reference for that function, not against the package docs. The package docs will always lag the WordPress handbook, and the handbook is the source of truth for what the array should contain.

Do not over-apply it. Block attributes, register_block_type args, and simple option arrays are often clearer as literal arrays. Reserve the object model for the handful of large, conditional, reused argument sets — post types, taxonomies, and repeatable queries.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console