F
Filament16mo ago
Finn

One record resource

I am currently creating a website for a customer which should be able to edit content on the website. Now I had the idea to make everything managable through Filament (it will act as a CMS like Wordpress basically) because it's such easy to use and great looking. My original thought was: I will create a Database table called "home" which just has 1 record in it with columns such as: title, description, contact_button_text, header_image etc. which will be managable through Filament. Once the home page loads it will get the first record out of the database and send that to the page to load the text and images etc from those variables out of the database. Now to make it directly available without a "table view" within Filament when clicking on the resource in the menu, my thought was to make a custom navigation item which directly points to: project.test/home-page/1/edit this will edit record 1 because it only will have one record of course. But sounds kinda hacky to me, which doesn't matter, but maybe someone else achieved making something like this and has better idea's on making site content managable through Filament? I would love to hear that! I also know Filament's purpose isn't to be a CMS, but I think it would be perfect for this project.
Solution:
use a custom page with the form builder on it
Jump to solution
12 Replies
Dan Harrin
Dan Harrin16mo ago
dont use a resource
Solution
Dan Harrin
Dan Harrin16mo ago
use a custom page with the form builder on it
Finn
FinnOP16mo ago
I was reading about that, but wouldn't I have to write save, edit etc. actions myself to the database <:PES_Think:639363477458255874> Ah I see, I can even attach a model. I am going to play around with it for a bit and will see how it goes. As always, thanks Dan!
Dan Harrin
Dan Harrin16mo ago
if you're using v3 it should be relatively easy
Finn
FinnOP16mo ago
I am! Will try it out :)
<?php

namespace App\Filament\Pages;

use Filament\Forms\Form;
use Filament\Pages\Page;
use App\Models\SiteSetting;
use Filament\Forms\Components\Section;

class SiteSettings extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.site-settings';

public array $data = [];

public ?SiteSetting $setting = null;

public function mount(): void
{
$this->setting = SiteSetting::first();

$this->data = $this->setting->toArray();
}

public function form(Form $form): Form
{
return $form
->schema([
// All fields here
])
->statePath('data')
->model($this->setting);
}

public function update()
{
$this->setting->update($this->form->getState());
}
}
<?php

namespace App\Filament\Pages;

use Filament\Forms\Form;
use Filament\Pages\Page;
use App\Models\SiteSetting;
use Filament\Forms\Components\Section;

class SiteSettings extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.site-settings';

public array $data = [];

public ?SiteSetting $setting = null;

public function mount(): void
{
$this->setting = SiteSetting::first();

$this->data = $this->setting->toArray();
}

public function form(Form $form): Form
{
return $form
->schema([
// All fields here
])
->statePath('data')
->model($this->setting);
}

public function update()
{
$this->setting->update($this->form->getState());
}
}
Is this how it should be done? I directly assigned the model through ->model($this->setting). But is it true that I need to assign it as well to the $this->data? And do the save manually through the update function I made? At least this works fine, but I am unsure if this is actually the correct approach.
awcodes
awcodes16mo ago
I have the exact thing going on. I simplified by adding a field to my pages so that I can just tell a page to be the “front page”. That ways it’s just like any other page and there’s no need for a one row database table. Then I just added model observers to enforce that only one page at any given point in time can have the front page set to true. Then in the page controller it’s a simple check on the ‘/‘ route to get the page marked as front page.
Finn
FinnOP16mo ago
But you save everything (Filament form values) in 1 database table called “pages” for example, and it has a JSON column where u store all data instead of seperate columns in your database table? Because the homepage of course has different data then a contact page for example
Dan Harrin
Dan Harrin16mo ago
you could use the spatie settings package maybe
Finn
FinnOP16mo ago
I will take a look at that 👍
Dan Harrin
Dan Harrin16mo ago
there are plenty of ways you can do it, working out how to store it is the most important thing and filament will fit whatever you choose
Finn
FinnOP16mo ago
But making a pages table with the following columns: id, name, => ‘home’ for example data => JSON content of all Filament form data updated_at, created_at will that work fine as well? Because Filament seems to work fine with storing form data in an array As filament basically stores raw json data 🤔 Then I can save all pages in the ‘page’ table
awcodes
awcodes16mo ago
No the data doesn’t have to be json. You can have any fields you want on the db table. I use a pages table. Each record in the table is a different page with fields for title slug excerpt content published_at staus, etc. and even relationships to other tables for Seo items.
Want results from more Discord servers?
Add your server