===============
LIBRARY RULES
===============
From library maintainers:
- Describe model properties with PHPDoc @property annotations — the annotated type determines the form widget
- Mark models with the #[Aura] attribute or define policies; otherwise the Gate denies access and the form renders empty
- Render an editable form with and a read-only table with
- Handle form submissions with ActionHandler::update($request, $object)->save()
- Requires PHP 8.2+ and Laravel 12.17+
### Example Property Translation File
Source: https://github.com/ttbooking/formster/blob/master/README.md
A sample configuration file structure for defining model property translations.
```php
// lang/{locale}/formster.php
return [
'model' => [
'user' => [
'first_name' => 'First name',
'_summary' => 'User profile', // table heading
'_description' => 'Basic data', // table description
],
],
];
```
--------------------------------
### Install Formster via Composer
Source: https://github.com/ttbooking/formster/blob/master/README.md
Run this command in your terminal to add the package to your Laravel project.
```bash
composer require ttbooking/formster
```
--------------------------------
### Render Formster widget components
Source: https://github.com/ttbooking/formster/blob/master/README.md
Example of calling a specific widget component directly.
```blade
```
--------------------------------
### Render Formster structural components
Source: https://github.com/ttbooking/formster/blob/master/README.md
Examples of using the form and table components, including custom button slots.
```blade
{{-- A ready-made form with a "Save" button --}}
{{-- Table only, without the defaults column --}}
{{-- A custom button instead of the default one (via a slot) --}}
```
--------------------------------
### Configure File pseudotype via annotations
Source: https://github.com/ttbooking/formster/blob/master/README.md
Define MIME-type filters, disposition, and storage disks using generic annotations.
```php
/**
* PDF documents, "attachment" disposition (download), "documents" disk:
* @property File<"application/pdf", "attachment", "documents"> $contract
*
* Multiple files (the field gets the multiple attribute):
* @property list $attachments
*/
```
--------------------------------
### Run Composer Scripts
Source: https://github.com/ttbooking/formster/blob/master/README.md
Execute package testing, static analysis, linting, and development server commands.
```bash
composer test # run the tests (Pest)
composer analyse # static analysis (PHPStan)
composer lint # code-style check (Pint --test)
composer serve # run the demo app (workbench)
```
--------------------------------
### Visualize the Formster lifecycle
Source: https://github.com/ttbooking/formster/blob/master/README.md
A diagram illustrating the flow from object parsing to component rendering and submission handling.
```text
┌─────────────────────┐
object ───► │ PropertyParser │ ──► Aura { properties: AuraProperty[] }
│ (aura,phpstan,refl.)│
└─────────────────────┘
│
▼ for each property
┌─────────────────────┐
│ HandlerFactory │ ──► PropertyHandler (by property type)
└─────────────────────┘
│
┌──────────────┴───────────────┐
▼ ▼
component() → Blade widget handle($obj, $request) → write value
(rendering the form) (processing the submission)
```
--------------------------------
### Publish Formster assets
Source: https://github.com/ttbooking/formster/blob/master/README.md
Publish configuration, view templates, or handler stubs to customize the package behavior.
```bash
# configuration
php artisan vendor:publish --tag=formster-config
# Blade widget templates (to customize markup)
php artisan vendor:publish --tag=formster-views
# the handler generator stub (to customize make:formster-handler)
php artisan vendor:publish --tag=formster-stub
```
--------------------------------
### Scaffold a new handler
Source: https://github.com/ttbooking/formster/blob/master/README.md
Use the artisan command to generate a new handler class for a specific type.
```bash
php artisan make:formster-handler MoneyHandler --type=Money
```
--------------------------------
### Instantiate a Color pseudotype
Source: https://github.com/ttbooking/formster/blob/master/README.md
The Color constructor validates the HEX format and throws an exception if invalid.
```php
$product->brand_color = new Color('#3366ff');
```
--------------------------------
### Translation Key Structure for Enum Cases
Source: https://github.com/ttbooking/formster/blob/master/README.md
The standard key format for looking up descriptions for specific enum cases.
```text
formster.enum.{alias}.{enum_case_in_snake_case}
```
--------------------------------
### Declare properties using PHPDoc annotations
Source: https://github.com/ttbooking/formster/blob/master/README.md
Use standard PHPDoc tags to define property types, access levels, and descriptions.
```php
/**
* @property string $name User name
* @property int $age
* @property string|null $bio May be null
* @property \App\Enums\Status $status
* @property-read int $id Read-only
* @property-write string $password Write-only
*/
class User extends Model {}
```
--------------------------------
### Translation Key Structure for Properties
Source: https://github.com/ttbooking/formster/blob/master/README.md
The standard key format for looking up field descriptions based on model or object aliases.
```text
formster.{model|object}.{alias}.{property_name_in_snake_case}
```
--------------------------------
### Configure Formster settings
Source: https://github.com/ttbooking/formster/blob/master/README.md
The configuration file controls property parsing, caching, active handlers, policy enforcement, and file upload settings.
```php
return [
// The property parser(s). Several — comma-separated (enables aggregation).
'property_parser' => env('FORMSTER_PROPERTY_PARSER', 'aura,phpstan,reflection'),
// Parsing-result cache.
'property_cache' => [
'store' => env('FORMSTER_PROPERTY_CACHE_STORE'), // cache store (default — the standard one)
'ttl' => (int) env('FORMSTER_PROPERTY_CACHE_TTL') ?: null, // TTL (null — forever)
],
// Active property handlers (order = satisfies() check priority).
'property_handlers' => [
TTBooking\Formster\Handlers\BooleanHandler::class,
TTBooking\Formster\Handlers\IntegerHandler::class,
TTBooking\Formster\Handlers\FloatHandler::class,
TTBooking\Formster\Handlers\StringHandler::class,
TTBooking\Formster\Handlers\EnumHandler::class,
TTBooking\Formster\Handlers\DateTimeHandler::class,
TTBooking\Formster\Handlers\DateTimeZoneHandler::class,
TTBooking\Formster\Handlers\ColorHandler::class,
TTBooking\Formster\Handlers\ImageHandler::class,
TTBooking\Formster\Handlers\FileHandler::class,
],
// Policy enforcement:
// false — lenient mode (grant access when policy/method is missing),
// true — the regular Laravel Gate behavior.
'enforce_policies' => (bool) env('FORMSTER_ENFORCE_POLICIES', false),
// File pseudotype settings.
'file' => [
'disk' => env('FORMSTER_DISK'), // disk for uploads
'static_disk' => env('FORMSTER_STATIC_DISK', env('FORMSTER_DISK')), // disk for static files
'content_disposition' => env('FORMSTER_CONTENT_DISPOSITION', 'attachment'),
'show_uploaded_name' => (bool) env('FORMSTER_SHOW_FILENAME', true), // show the file name in the link
],
// Preview settings for the Image pseudotype.
'preview' => [
'width' => (int) env('FORMSTER_PREVIEW_WIDTH', 100),
'height' => (int) env('FORMSTER_PREVIEW_HEIGHT', 100),
'scale_down_threshold' => (int) env('FORMSTER_PREVIEW_SCALE_DOWN_THRESHOLD', 10_240), // bytes
],
];
```
--------------------------------
### Define a PropertyHandler interface
Source: https://github.com/ttbooking/formster/blob/master/README.md
Implement this interface to define how a specific property type is rendered, validated, and persisted.
```php
interface PropertyHandler
{
public static function satisfies(FinalAuraProperty $property): bool; // does the type match?
public function component(): string; // Blade widget
public function validationRules(): string|array; // validation rules for the field
public function handle(object $object, Request $request): void; // write the value
}
```
--------------------------------
### PropertyHandler::for
Source: https://github.com/ttbooking/formster/blob/master/README.md
Selects an appropriate handler for a specific property.
```APIDOC
## PropertyHandler::for
### Description
Retrieves the appropriate handler for a given property.
### Signature
`for(FinalAuraProperty $property): PropertyHandler`
### Parameters
- **$property** (FinalAuraProperty) - Required - The property instance to handle.
```
--------------------------------
### Widget Components
Source: https://github.com/ttbooking/formster/blob/master/README.md
Individual input widgets for specific data types.
```APIDOC
## Widget Components
### Description
Individual input widgets available under the formster:: namespace. Supported types include: text, number, decimal, checkbox, radio, select, datetime, color, timezone, file, image, and disclaimer.
### Usage
### Behavior
Widgets inherit context from parent components (object, editable) and automatically render error messages when validation fails.
```
--------------------------------
### Implement a custom handler class
Source: https://github.com/ttbooking/formster/blob/master/README.md
The generated handler must implement the PropertyHandler contract and define the logic for validation and data handling.
```php
namespace App\Formster\Handlers;
use App\Formster\Types\Money;
use Illuminate\Http\Request;
use TTBooking\Formster\Contracts\PropertyHandler;
use TTBooking\Formster\Entities\FinalAuraProperty;
class MoneyHandler implements PropertyHandler
{
public function __construct(public FinalAuraProperty $property) {}
public static function satisfies(FinalAuraProperty $property): bool
{
return $property->type->contains(Money::class);
}
public function component(): string
{
return 'formster::form.money';
}
public function validationRules(): string|array
{
return $this->property->mergeValidationRules();
}
public function handle(object $object, Request $request): void
{
$object->{$this->property->variableName} = new Money($request->{$this->property->variableName});
}
}
```
--------------------------------
### Declare properties using PHP attributes
Source: https://github.com/ttbooking/formster/blob/master/README.md
Use Aura and AuraProperty attributes for granular control over metadata and validation rules.
```php
use TTBooking\Formster\Entities\Aura;
use TTBooking\Formster\Entities\AuraProperty;
use TTBooking\Formster\Entities\AuraNamedType;
#[Aura(summary: 'Profile', description: 'User data')]
class Profile
{
#[AuraProperty(
type: new AuraNamedType('string'),
description: 'Nickname',
validationRules: ['...', 'min:3'],
)]
public string $nickname;
}
```
```php
#[Aura(properties: [
'text' => new AuraProperty(validationRules: ['...', 'min:3']),
])]
class Frankenstein extends Model {}
```
```php
#[Aura(exclude: ['password', 'remember_token'])]
class User extends Model {}
```
--------------------------------
### Describe a model for Formster
Source: https://github.com/ttbooking/formster/blob/master/README.md
Annotate your Eloquent model with PHPDoc properties and the #[Aura] attribute to enable automatic form generation.
```php
namespace App\\Models;
use Illuminate\\Database\\Eloquent\\Model;
use TTBooking\\Formster\\Entities\\Aura;
/**
* @property string $text Some text
* @property int $number Some number
* @property bool $flag Some flag
*/
#[Aura]
class Frankenstein extends Model
{
protected $table = 'frankenstein';
}
```
--------------------------------
### Handle form submission
Source: https://github.com/ttbooking/formster/blob/master/README.md
Process form data and save the object using the ActionHandler utility.
```php
// Handling the form submission is a one-liner too
Route::put('/orders/{order}', function (Request $request, Order $order) {
ActionHandler::update($request, $order)->save();
return back();
});
```
--------------------------------
### Handle form submissions
Source: https://github.com/ttbooking/formster/blob/master/README.md
Use ActionHandler to validate and save model updates from a request.
```php
use App\\Models\\Frankenstein;
use Illuminate\\Http\\Request;
use TTBooking\\Formster\\Facades\\ActionHandler;
Route::get('/formster/{model}', fn (Frankenstein $model) => view('table', compact('model')))->name('view');
Route::get('/formster/{model}/edit', fn (Frankenstein $model) => view('form', compact('model')))->name('edit');
Route::put('/formster/{model}', function (Request $request, Frankenstein $model) {
ActionHandler::update($request, $model)->save();
return back();
})->name('update');
```
--------------------------------
### PropertyParser::parse
Source: https://github.com/ttbooking/formster/blob/master/README.md
Parses an object or class into metadata.
```APIDOC
## PropertyParser::parse
### Description
Parses a given object or class name into an Aura metadata object.
### Signature
`parse(mixed $objectOrClass): Aura`
### Parameters
- **$objectOrClass** (mixed) - Required - The object instance or class string to parse.
```
--------------------------------
### x-formster::form
Source: https://github.com/ttbooking/formster/blob/master/README.md
Renders a full HTML form with a save button, supporting automatic multipart/form-data for file uploads.
```APIDOC
##
### Description
A full