Resources
A Resource class maps an Eloquent model to terminal UI screens. Each resource defines two methods: form() for the card screen and table() for the list screen.
Basic structure
use TwoWee\Laravel\Resource;
class CustomerResource extends Resource
{
protected static string $model = \App\Models\Customer::class;
protected static string $label = 'Customer'; // Shown in menu and title bar
protected static ?string $slug = 'customers'; // URL slug, auto-generated if omitted
public static function form(): array { /* ... */ }
public static function table(): array { /* ... */ }
}Resources in app/TwoWee/Resources/ are auto-discovered. You can also register them manually in config/twowee.php:
'resources' => [
\App\TwoWee\Resources\CustomerResource::class,
],Title
Override title() to customize what appears in the title bar when viewing a record:
public static function title(Model $model): string
{
return 'Customer - ' . $model->no . ' ' . $model->name;
}Record key
By default, records are identified in URLs by the model's primary key. Override $recordKey when your first table column is a natural key like a customer number:
protected static ?string $recordKey = 'no';The URL becomes /screen/customers/card/C-73065 instead of /card/1. Save, delete, and action endpoints use the same key.
Layout types
The default layout is a Card — a single-record form. Override layout() for document or journal screens:
public static function layout(): string
{
return 'Card'; // Default: single-record form
// return 'HeaderLines'; // Document with editable line items
// return 'Grid'; // Full-screen editable grid
}See Header Lines and Grids for details.
Search
List screens filter by ?query=. By default the plugin searches all text columns with LIKE. Override searchColumns() to control which columns are searched:
public static function searchColumns(): ?array
{
return ['no', 'name', 'city'];
}If your model uses Laravel Scout's Searchable trait, the plugin uses Scout automatically — no configuration needed.
Row limiting
For large tables, cap the number of rows returned:
public static function maxRows(): ?int
{
return 5000;
}Authorization
The plugin uses Laravel Policies. If no policy exists for the model, all operations are allowed. Add a policy when you need to restrict access:
class CustomerPolicy
{
public function delete(User $user, Customer $customer): bool
{
return $user->is_admin;
}
// Undefined methods → allowed
}The plugin checks viewAny, view, create, update, and delete. The authenticated TwoWee guard user is passed to the policy.
Screen ID
Every screen response includes a screen_id derived from the resource class name. Override it only if you need a stable ID that survives a class rename:
protected static ?string $screenId = 'customer_card';Next steps
- Sections — lay out fields in columns
- Fields — all available field types
- Navigation — menu placement, tabs, popup groups
- Lookups — relational field selection
- Screen Actions — custom operations
- Header Lines — documents with line items
- Grids — full-screen editable grids