初探 Filament compoent 設計

這篇文章是針對 Dan Harrin 在 laracasts 的影片進行的設計範例和理解筆記,其設計哲學貫穿整個 filament package,理解其原理可以為後續開發思路打下基礎。 Filament/livewire 設計概念是以 component 為基礎,透過對應設計達到 component based design,意思就是透過 component 完成功能。 設計 TextInput Component namespace App\Components; class TextInput { public function __construct( protected string $name ) { } // 透過靜態類別方法來創建實體,避免要寫 new TextInput() public static function make(string $name): self { // 由靜態類 new instance return new self($name); } // render view component public function render(): View { return view('components.text-input'); } 接下來創建其對應的 html component,components/text-input.blade.php: <input type="text" /> 在主要 layout 當中使用其組件,這邊我的主 layout 為 demo....

December 18, 2023 · Yish

Filamentphp Customize Theme

官網寫得有點模糊,這邊記錄一對應的流程: 根據不同的 panel 建立 theme: $ php artisan make:filament-theme $ php artisan make:filament-theme person 會生成兩個給指定 panel 用的 tailwind.config.js 和 theme.css: resources/css/filament/person/tailwind.config.js resources/css/filament/person/theme.css 以我這邊的例子來說要需要引入 tiptap 所需要用的 css 和需要注入 tailwind 的監聽檔案: tailwind.config.js import preset from '../../../../vendor/filament/filament/tailwind.config.preset' export default { presets: [preset], content: [ ... './vendor/awcodes/filament-tiptap-editor/resources/**/*.blade.php', ], } theme.css @import '/vendor/awcodes/filament-tiptap-editor/resources/css/plugin.css'; 接著 build file: $ npm run build 接下來要告訴 panel provider 呼叫對應的 vitetheme,也就是剛剛的 theme.css style: class PersonPanelProvider extends PanelProvider { public function panel(Panel $panel): Panel { return $panel ->brandName('Person') ->default() //....

December 2, 2023 · Yish

在 SUI Chain 上發行代幣(Token)

由於 SUI 的合約機制跟 EVM 所使用的技術概念和機制都不同,這篇文章將會介紹如何在 SUI Chain 上發行代幣。 關於 SUI 本身的技術與介紹可以參考 Messari深度報告:Sui 技術優勢在哪?撐出 L1 公鏈新天地 或是 SUI 的官網都有細節的技術介紹,比較特別的是在 SUI 上面都是以 object 作為一個單位與中心進行交互,文中有一段很簡單的介紹: 以物件為中心的資料模型 與其他分散式帳本相區別的關鍵特性是 Sui 的以物件為中心的資料模型。大多數智能合約平臺,如以太坊、Solana 和 Aptos,使用帳戶來追蹤區塊鏈的狀態,其中帳戶是儲存使用者餘額的資料結構。其他平臺如比特幣和 Cardano 使用未消費交易輸出(UTXO)來記錄區塊鏈的狀態,也就是說,UTXO 代表了在交易執行後剩餘的資產數量。 Sui 將這兩種方法結合成一種混合模型,其中其歷史儲存在具有全域性唯一 ID 的物件中。物件還包含元資料,用於確定不同物件的特性,如所有權和交易歷史(部分來源於物件隨機數值,也稱為版本號)。Sui 的以物件為中心資料模型意味著全域性狀態只是所有 Sui 物件的集合。從結構上講,這採用了有向無環圖(DAG)的形式,其中物件對應於頂點,交易對應於邊,稱為 「活動物件」 的物件對應於沒有出邊的頂點。 在 Sui 中,所有交易都將物件作為輸入,並生成新的或修改後的物件作為輸出。每個物件都包含產生它的最後一筆交易的hash值。可用作輸入的物件稱為 「活動」 物件。因此,通過觀察所有活動物件,可以確定全域性狀態。 官網 SUI explorer 技術實作 接下來將會介紹如何在 SUI Chain 上發行代幣(Token),Sui wallet 與如何透過 faucet 領取 SUI 這邊就不多作介紹。 https://docs.sui.io/build/install#prerequisites https://docs.sui.io/build/install#install-sui-binaries 這邊用 devnet 作為測試: $ cargo install --locked --git https://github.com/MystenLabs/sui.git --branch devnet sui VSCode 整合 https://docs....

November 3, 2023 · Yish

Filament Global Search

Global search 搜尋條件 以什麼欄位搜尋 // 單獨 protected static ?string $recordTitleAttribute = 'title'; // 多個 public static function getGloballySearchableAttributes(): array { return ['title', 'slug', 'author.name', 'category.name']; } 客製化搜尋結果欄位顯示,舉例來說 title = Yish 前面想要添加 author.name: public static function getGlobalSearchResultTitle(Model $record): string { return $record->author->name .':'. $record->name; } 添加更多內容在搜尋結果欄位內: public static function getGlobalSearchResultDetails(Model $record): array { return [ 'Author' => $record->author->name, 'Category' => $record->category->name, ]; } 使用何種 query 來作搜尋,這邊可以看到我們必須先 eager load author 和 category:...

October 11, 2023 · Yish

貧血模型跟充血模型

軟體的「貧血模型」(Anemic Domain Model)和「充血模型」(Rich Domain Model)是兩種在軟體設計中常見的模型設計風格,特別是在使用面向對象編程(Object-Oriented Programming,簡稱OOP)時,這兩種模型風格對於如何處理領域邏輯(Domain Logic)有著不同的理念。 DDD 本身就是著名的充血模型實作,而分散式拆分則是為貧血模型,以下將會細節說明。 貧血模型(Anemic Domain Model): 在貧血模型中,對象(Object)通常只是包含資料的純資料結構,並且缺乏有效的行為(方法)。這種模型將領域邏輯(Domain Logic)主要放在服務(Service)或管理類別中,而不是在對象本身。這意味著對象只是資料的容器,而所有處理邏輯都放在外部。 貧血模型的優點是簡單且易於理解,因為領域邏輯都放在一個中央位置,容易進行修改和維護。然而,它也有一些缺點。例如,當領域邏輯變得複雜時,服務類別可能會變得過度龐大,造成程式碼不易維護和測試。此外,貧血模型也未完全利用面向對象編程的優點,如封裝和多型性。 充血模型(Rich Domain Model): 相比之下,充血模型是一種較為嚴格的面向對象設計風格,將領域邏輯嵌入到對象中。這意味著對象不僅包含資料,還包含了處理資料的相關行為和邏輯。這使得對象能夠自主管理自己的狀態和行為,更符合真實世界中物件的行為。 充血模型的優點是更好地利用了面向對象編程的特性,更容易理解,也更符合物件導向的設計原則,如封裝和單一職責原則。此外,由於領域邏輯分散在不同的對象中,這使得程式碼更容易擴展和維護。 然而,充血模型可能在某些情況下增加了複雜性。當領域邏輯變得非常複雜時,對象之間的交互可能變得複雜,需要更深入的設計和理解。 在選擇使用貧血模型還是充血模型時,開發者需要考慮項目的需求、複雜性和可擴展性等因素,以及團隊成員對於這兩種設計風格的熟悉程度。 當談到「貧血模型」和「充血模型」,這兩種模型風格涉及領域邏輯的處理方式。 貧血模型(Anemic Domain Model)範例: 在貧血模型中,對象只是包含資料的純資料結構,而大部分的領域邏輯則放在服務(Service)類別中。 // User.php (Entity) class User { private $id; private $name; private $email; // Getter and setter methods... } // UserService.php (Service) class UserService { public function sendWelcomeEmail(User $user) { // Send a welcome email to the user... } public function generateUsername(User $user) { // Generate a unique username based on user's name and ID....

August 22, 2023 · Yish

Laravel Precognition

如果要提供給前端作即時表單驗證時,傳統作法是要在提供一組 API 作為驗證返回使用,Laravel Precognition 這個新的 Laravel 套件提供了較為方便的即時驗證,並且不會讓驗證規則同時存在兩份,也與前端框架作了整合,以下將以註冊功能添即時驗證為範例。 前置 配置 Breeze $ laravel new laravel10 $ cd laravel10 $ composer require laravel/breeze --dev $ php artisan breeze:install $ php artisan migrate $ npm install $ npm run dev 原本規則 預設配置好之後,原本的規則寫法是送表單型態,也就是說在送出表單當下才會去驗證欄位機制,這邊如果要調整成即時作表單驗證會有兩種作法: 前端取得後端驗證規則後以 JS 再寫入一次規則 後端提供驗證 API 操作 這邊可以看到前端寫規則的話當需要作欄位驗證調整時就得再調整,規則分散在兩邊; 而後端自行提供驗證 API 操作需要經過一定設計才會讓代碼不會有重複的狀況。 Laravel Precognition 在先前版本中提供了一種新的工具 Precognition 就是用來解決這個煩惱的。 routes/auth.php 添加中間件作為驗證機制 Route::post('register', [RegisteredUserController::class, 'store'])->middleware([HandlePrecognitiveRequests::class]); Http/Controllers/Auth/RegisteredUserController.php 將 Validation rule 複製 創建 RegisterRequest $ php artisan make:request RegisterRequest 刪除 authorize 或是改為 true 添加規則,用於判斷送入與即時驗證 precognitive 要驗證什麼,我這邊僅先用 unique 作範例 return [ 'name' => ['required', 'string', 'max:255'], 'email' => [ // 判斷成立 -> 展開陣列到上層陣列 ....

May 25, 2023 · Yish