⌘K

Panels

Command Line

The artisan commands that write a resource, its pages, a page of your own and a relationship's table — and the one that reads back what is registered.

On this page

Everything a panel is made of can be written by hand, and every command here writes exactly what the pages expect — so the first file is right and the rest is yours. None of them edits a file you already have unless you pass --force.

Generating A Resource

php artisan make:wire-resource Order

writes the resource and the three pages an ordinary resource has:

app/Resources/OrderResource.php
app/Livewire/Resources/Orders/ListOrders.php
app/Livewire/Resources/Orders/CreateOrder.php
app/Livewire/Resources/Orders/EditOrder.php

The resource declares its pages(), so once it is registered and Route::wireResources() runs in your panel's route group, its URLs exist. The edit page is written with $this->deleteHeaderAction() in its header — the one default the pages leave to you, because who may delete what is your rule (Pages).

Option What it changes
--model=App\Domain\Order The model, when it is not App\Models\{Name}
--generate Fields, columns and infolist entries read off the model's table
--view A read-only ViewPage and an infolist() on the resource
--simple One ManagePage instead of three pages
--soft-deletes ManagesTrashedRecords, and Restore / Force delete in the record pages' headers
--register Adds the class to a published config/wire-core.php
--force Overwrites files that already exist

--generate reads the table, not the model. Each column becomes a field, a column and an entry by its type — a boolean a Toggle and a BooleanColumn, a date a DateTimePicker::make()->asDate() and a ->date() column, a text column a Textarea, a number ->numeric(), anything else a TextInput — and a column that is neither nullable nor defaulted is required(). The key, the timestamps, deleted_at and credentials are left out. It is a starting point written once: a table that does not exist yet writes the resource without generated lines and says so, rather than failing.

It ends by saying where the pages are, or what is missing. It reads the application as it is: whether the resource is registered — listed in config('wire-core.resources'), just added with --register, or inside a folder config('wire-core.discover.resources') names — and whether anything routes registered classes — a route file calling Route::wireResources(), or a panel entry of wire-core.routes.groups. With both in place it prints Ready: registered and routed at /admin/order-lines; otherwise it names only the step that is missing, written out for this resource. make:wire-page does the same for a page of your own.

--register only writes where it can do so safely — into a published config/wire-core.php that has a resources list, and only once. Anywhere else it prints the line to add.

Generating A Page Of Your Own

php artisan make:wire-page TaskBoard
php artisan make:wire-page History --resource=Order

The first writes a Page and the view it draws — app/Livewire/Pages/TaskBoard.php and resources/views/livewire/pages/task-board.blade.php. The second writes a page about one record of OrderResource: it composes BelongsToResource, ResolvesOneRecord and LinksToRecordPages, so it takes the record's key and draws the record's tabs. The command prints what is left to do: a page of its own is registered like a resource — config('wire-panels.pages') or a discovered folder — and is then routed and listed by itself; a record page is routed from its resource's pages():

'history' => RoutePage::make(\App\Livewire\Resources\Orders\History::class)->uri('{record}/history'),

— which is also what makes it one of the record's tabs. Routing is the owner's declaration, so the command prints it rather than editing the resource.

Generating A Cluster

php artisan make:wire-cluster Settings
php artisan make:wire-page Taxes --cluster=Settings

The first writes app/Clusters/Settings.php, a cluster — one section with one menu entry and one URL prefix — and says how to register it, which is the way a page is registered. The second writes a page that is a member of it: the page names the cluster with protected static ?string $cluster. A resource joins by implementing BelongsToCluster, one method, written by hand.

Generating A Relationship's Table

php artisan make:wire-relation-manager Order items

writes app/Livewire/Resources/Orders/ItemsRelationManager.php, a RelationManager over the items relationship with a table to fill in, and prints how to embed it: have the resource implement ProvidesRelationManagers and return the class from relationManagers().

Reading Back What Is Registered

php artisan wire:resources
php artisan wire:resources orders

The first lists every registered resource — its key, class, model, the surfaces it declares, its pages and how many routes they have. The second shows one resource page by page: the component, every route that reaches it (a page routed in two zones is two rows), its URI and the permission it requires, or not routed. Both read the catalogue and the router — the same answers the menu, the palette and Route::wireResources() work from — so what it prints is what the application actually has.

Changing What They Write

php artisan vendor:publish --tag=wire-panels::stubs

copies the templates to stubs/wire-panels/, and every command here reads a published template before its own: resource.stub, resource-page.stub, page.stub, page-view.stub, relation-manager.stub and dashboard-page.stub.

Generating A Component

The parts a table, a form or an infolist is built from have generators of their own, in the package that owns each one — so they exist without a panel too:

Command Writes Package
make:wire-column Price app/Tables/Columns/PriceColumn.php + its cell view wire-table — custom column
make:wire-filter Region app/Tables/Filters/RegionFilter.php + its control view wire-table — custom filter
make:wire-field MoneyInput app/Forms/Components/MoneyInput.php + its input view wire-forms — custom field
make:wire-entry Money app/Infolists/Components/MoneyEntry.php + its view wire-core — custom entry
make:wire-action Archive [--bulk] app/Wire/Actions/ArchiveAction.php wire-core — preset action
make:wire-widget Revenue app/Widgets/RevenueWidget.php + its view wire-core — widgets

Each adds its suffix unless the name already ends with it (a field takes none), never overwrites a view that exists, and replaces the class only with --force. Each package publishes its own templates — --tag=wire-table::stubs, wire-forms::stubs, wire-core::stubs — into stubs/<package>/.

  • Resources — what a generated resource declares
  • Pages — what the generated pages are
  • Routing — giving the pages URLs