1. 無法客制化 Table
Voyager 擁有一個完整的 CMS 平台功能,而整個平台都是圍繞著 BREAD 這個設計為核心的。
何為 BREAD ? 即 Browse、Read、Edit、Add、Delete。用戶可以透過新增 BREAD 來很簡單地開始制作他們的表單 。而這個 BREAD 也是整個套件的限制核心,因為 Voyager 希望你可以透過 BREAD 來處理所有表單問題,包括帳號管理、權限管理、各種需要顯示的表單等等。
即當你需要做客制化的表單時,就是惡夢的開始了。
先說明一下 Voyager 的表單生成方式,是透過匯入 DB Table 來產生的。這話的意思就是:一張表單的欄位只可以是 Table 裡面擁有的欄位以及跟其有 Relationship 的表單欄位。
那麼,假如如果今天我們要做一張由兩張 Table 組成,且其中一個不在兩張表單的已有欄位內,而是要透過計算才能獲得的話,那就只能說一聲恭喜了,因為 Voyager 是沒有辦法做到這種複雜度更高的表單的。
當我在工作要實作這種表單時,基本上都只能在既有的空白 Blade 上完全重寫。當完成了表單後,卻又發現更大的問題,就是 Voyager 原有的 Read 、Delete、Edit、Add 等等都不能用。因為現在的表單已經不在當初 Voyager 設計的 System 當中。當然,這些功能也可以人工做上去,但我認為這就失去了使用這種後台的意義了。
所以,唯一的解決辦法就是,在原有的框架底下做改動,即大量地 Override 其功能。如表單上,我們要做 Filter 功能,我們就把 index function 從原來的 Controller 中 Extend 到自己的 Controller,再透過改動其中一些 code 來為其加點功能,這種做法雖然能做到最後想做的功能,但是大大增加了 Code 的維護難度,甚至可以說是「臭」的 code。
而如果要做兩層式的表單呢?即進去第一個總覽式的表單,再進到詳細式的表單。是的,同樣恭喜你,那當然是不能做到的。這個時候,相信我,感覺會是有三千萬支馬在跑。
當然,一切皆 code ,只要找到他們,什麼都可以改的。這時候你就需要大量的 source code reading 了。
2. 難以操控的權限
有些後台需求會需要一個可以透過勾選來管理權限。而當時我們在選用 Voyager 時,也是考量到他有這樣子的工能。但是,在真正接觸之後,卻發現,他的權限管理也是完全依照 BREAD 來制定的。就是 BREAD 有什麼,你就可以控制什麼,即剛剛說到的什麼客制化表單,是完全不在權限管理的範圍內了。
那由 BREAD 組合的 Menu 呢?可惜地,這也是不被權限管理所控制的。即,就算你反選了 BREAD 的所有功能,在 Menu 上,那個 BREAD 還是能被看見,還是能被點擊的。當點擊之後他會 Redirect 到一個空白的 403 畫面,相信我,這對正常便用者來說絕對不會是一個好的體驗。
為了克服這個問題,我們不止要 Override 一堆 code,還要改變一下 Voyager 的 DB 結構。也就是說,除非我們把 Voyager folk下來再模組化已經修改的功能,否則當我們遇到類似的專案時,我們是無法重用的。
3. 內建 Multilanguage 基本無用化
Voyager supports multiple languages for your models.
Voyager 內建的多語基本上只能作用到你的 Model 上,也就是說,他既不能作用到你的 Bread 上,亦不是用他來負責你的 Blade。意思是, 當你按照文件上寫的 use Translatable; 你可以在後台的 Bread 右上角上看到如英、中文的選項。但是你不能因此來改動 Bread 的 Column Name,他能改的只有 Header 的部分,如 Display Name。
那我們真的需要 Multilanguage 時是用在哪一部分?是 Blade 的內容,是 Table 的客制化,是所有可以被 UI 顯示的東西,而不會只是一個 Model。我想這是我直接放棄用 Voyager Multilanguage 的原因,而改為直接用 Laravel 來處理。那這樣做的問題就是,當要處理包在 Voyager 中的東西時,如改動 Bread 的 Column Name 時,我們就需要先了解整個架構,才可以就改動最少的方法來處理多語這個事件。
以上都是我想到比較在意的事,當然其中還是踩了很多坑,如果有想到會再更新,或是歡迎以留言討論。