module structure
demo-module/
├─ Livewire/
│ ├─ Home.php
│ ├─ ArticlesTable.php
│ ├─ ArticlesView.php
│ └─ ArticlesEdit.php
├─ Views/
│ ├─ home.blade.php
│ ├─ articles_table.blade.php
│ ├─ articles_view.blade.php
│ ├─ articles_edit.blade.php
│ ├─ menu.blade.php
│ └─ frontend_menu.blade.php
├─ Models/ Article.php, Author.php
├─ Database/ Migrations/, Seeders/
├─ config.php layout, menu entry
├─ routes.php
└─ DemoModuleServiceProvider.php
route
routes.php
Route::get('demo/articles/edit/{article:id?}', ArticlesEdit::class)
->middleware(['web'])
->name('demo.articles.edit')
->crumbs(function ($crumbs, $article = null) {
$article
? $crumbs->parent('demo.articles.view', $article)->push('Edit Article', route('demo.articles.edit', $article))
: $crumbs->parent('demo.articles')->push('Add Article', route('demo.articles.edit'));
});
component
Livewire/ArticlesEdit.php
<?php
namespace App\Modules\Demo\Livewire;
use App\Modules\Demo\Models\Article;
use App\Modules\Demo\Models\Author;
use Livewire\Component;
class ArticlesEdit extends Component
{
public Article $article;
// Fields bound with x-rpd:: components: also what survives between requests
// on a model that is not saved yet.
protected $rules = [
'article.title' => 'required',
'article.author_id' => 'required|exists:demo_authors,id',
'article.body' => 'nullable',
'article.public' => 'nullable|boolean',
'article.publication_date' => 'required|date',
];
public function mount(?Article $article = null): void
{
$this->article = $article ?? new Article();
}
public function save()
{
$this->validate();
$this->article->save();
return redirect()->to(route('demo.articles.view', $this->article->getKey()));
}
public function render()
{
return view('demo::articles_edit', [
'authors' => Author::query()->orderBy('firstname')->pluck('firstname', 'id')->toArray(),
])->layout('layout::admin');
}
}
view
Views/articles_edit.blade.php
<x-rpd::card>
<x-rpd::edit title="Article">
<div class="row">
<x-rpd::input col="col-md-6" model="article.title" label="Title" />
<x-rpd::select col="col-md-6" model="article.author_id" :options="$authors" label="Author" addempty />
</div>
<div class="row">
<x-rpd::date col="col-md-4" model="article.publication_date" format="dd/MM/yyyy" value-format="yyyy-MM-dd" label="Publication date" />
<x-rpd::checkbox col="col-md-4 pt-4" model="article.public" label="Public" checkLabel="visible to everyone" />
</div>
<div class="row mb-4">
<x-rpd::rich-text col="col-12" model="article.body" label="Body" />
</div>
<x-slot name="actions">
<x-rpd::button type="submit" label="Save" />
</x-slot>
</x-rpd::edit>
</x-rpd::card>