Building a site
Creating blocks
A PHP class and a Blade view: what a block is and how to make one.
A block is one PHP class and one Blade view. The same view renders on the website, on the editor's canvas and in previews.
$ php artisan aurora:make-block "Pricing table" --category=marketing --icon=phosphor-currency-circle-dollar
$ php artisan aurora:make-block "Two columns" --container # a block that holds other blocks
This creates app/Blocks/PricingTableBlock.php and resources/views/components/blocks/pricing-table.blade.php. Blocks in app/Blocks are registered automatically. The class says what the block is:
namespace App\Blocks;
use Aurora\Blocks\Block;
use Aurora\Blocks\Editable;
use Aurora\Blocks\Fields;
use Aurora\Filament\Forms\Components\AssetPicker;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
class CardBlock extends Block
{
public static function type(): string { return 'card'; } // stored in the page JSON
public static function label(): string { return __('Card'); }
public static function description(): string { return __('Image, title, text and a link in a box.'); }
public static function icon(): ?string { return 'phosphor-identification-card'; }
public static function category(): string { return 'content'; } // palette group
// The inspector's fields: any Filament form components.
public static function schema(): array
{
return [
AssetPicker::make('image')->label(__('Image')), // a media library image
TextInput::make('title')->label(__('Title')),
Textarea::make('body')->label(__('Text'))->rows(3),
...Fields::link(), // page, file or URL
];
}
// What a new block starts with.
public static function defaults(): array
{
return ['title' => 'Card title', 'body' => 'Why this matters.'];
}
// Fields editors type into right on the canvas.
public static function editables(): array
{
return [
'title' => Editable::text()->placeholder(__('Title')),
'body' => Editable::text()->multiline(),
];
}
// Told to AI assistants: when to use it, and how.
public static function aiHints(): ?string
{
return 'Normally placed inside a "grid". The card becomes clickable when it has a link.';
}
}
More a block can say
| Method | What it does |
|---|---|
itemEditables() | Inline editing inside repeater items, such as FAQ questions |
sameInEveryLanguage() | Fields that aren't translated (links, numbers, settings) |
preview() | A picture of the block for the palette (or upload one in Settings › Blocks) |
isVisible() | Hide a block from some people, like code blocks |
Container blocks
Blocks that hold other blocks implement Aurora\Blocks\Contracts\Container, declare their slots, and draw each one with block_slot():
use Aurora\Blocks\Contracts\Container;
class BandBlock extends Block implements Container
{
public static function slots(array $data): array { return ['content']; }
// …
}
<section class="band">{{ block_slot('content') }}</section>
Ordering and registering by hand
Blocks from other folders, or in a set palette order, are registered from a service provider: Blocks::register([HeroBlock::class, CardBlock::class]). A type registered again replaces the earlier one, so a site can override a library block.
What you get for free
- validated when AI tools write it;
- described to AI assistants by
list_block_types, built from the schema; - translated block by block, and indexed for search;
- served structured by the REST and GraphQL APIs: images, page links and forms come out as what they point at.
This website's blocks
This website is built from 24 blocks of its own, in its app/Blocks. They're good examples to read or start from.
| Category | Blocks |
|---|---|
| Layout | Section band, Responsive grid, Button group |
| Content | Heading, Paragraph, Rich text, Button, Card, Callout, Accordion / FAQ, Tabs, Steps / timeline |
| Marketing | Hero, Feature, Statistic, Pricing plan, Testimonial, Team member, Logo cloud, Call to action |
| Media | Image, Gallery |
| Dynamic | Form, Page list |
| Developer | Code sample |
The page builder adds Section (columns), List, Quote, Spacer, Divider, Video, Embed, Shortcode and Code.