php – Joomla! 如何在 View 中使用 xml 的欄位

Joomla! 提供了許多類型的表單元件,不過官方網站文件幾乎找不到。在沒有使用 xml 表單元件的時候,我們可能會這樣寫
1 2 3 4 5 6 7 |
<input type="text"> <select> <option></option> </select> <textarea></textarea> |
這樣寫也可以正確的提交表單,但如果我們想要連結 Joomla 的提供功能,例如選取註冊會員、挑選已上傳的圖片、挑選已發佈的文章,像這類屬於套件的功能,我們不打算從頭自己刻一個吧?那多累呀,於是我們可以在 Model 的地方動些手腳,讓這些表單元件顯示的方式,是透過 xml 定義。
我們看後台(administrator)範例,元件名稱叫做 com_todolist,打算挑選已經上傳的圖片--在這之前你必須要先對如何設計 Joomla! 的元件 (Component)有一定的瞭解。
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php defined('_JEXEC') or die; // administrator/components/com_todolist/controller.php class TodoListController extends JControllerLegacy { public function display($cachable = false, $urlparams = array()) { // 取得模型 TodoListModelMedia: models/media.php $model = $this->getModel('Media'); // 取得視圖 TodoListViewTodoList: views/todolist/view.html.php $view = $this->getView('TodoList', 'html'); // 將模型傳入視圖 view.html.php $view->setModel($model, true); // 設定 html 模板 views/todolist/tmpl/media.php $view->setLayout('media'); // 顯示出來 $view->display(); } } |
Model
- 繼承 JModelAdmin 以後,我們要務必要實作 getForm() ,透過 loadForm 幫我們讀取 xml 檔案。
- 如果要在前台使用 xml 欄位設定,那麼要繼承 JModelForm 而不是 JModelAdmin。
- JModelAdmin 繼承 JModelForm ,而定義 getForm() 實作則是在 JModelForm 。
- JModelForm 是 libraries/src/MVC/Model/FormModel.php 的 Joomla\CMS\MVC\Model\FormModel 別名,在 libraries/classmap.php 中有定義。這是為了日後 (我想是 Joomla! 4) 將改用 namespace 的形式鋪路。目前前綴用法已經不符合 PHP 趨勢,只是相容 PHP 5 舊系統而採用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php defined('_JEXEC') or die; // administrator/components/com_todolist/models/media.php // 繼承的類別是 JModelAdmin,這樣我們才可以用 xml 呈現表單元件 class TodoListModelMedia extends JModelAdmin { // 務必要實作,因為抽象定義在 libraries/src/MVC/Model/FormModel.php public function getForm($data = Array(), $loadData = true) { // 呼叫 libraries/src/MVC/Model/FormModel.php $form = $this->loadForm ( 'com_todolist.todolist', // Form 的名稱 'media', // 要讀取的 xml: administrator/components/com_todolist/models/forms/media.xml array('control' => 'jform', 'load_data' => $loadData) ); return $form; } } |
Xml
fieldset 的 name 是我們自訂的,用於我們想要一次取得多筆欄位的時候可以呼叫對應。field 的用法可以參考官方列表,我們 name 自訂為 imageurl、 type 指定為媒體、directory 設置打開後的起始路徑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!-- administrator/components/com_todolist/models/forms/media.xml --> <?xml version="1.0" encoding="utf-8"?> <form> <fieldset name="details"> <field name="imageurl" type="media" label="圖片" description="選取你要的圖片" directory="banners" hide_none="1" size="40" /> </fieldset> </form> |
View
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php defined('_JEXEC') or die; // administrator/components/com_todolist/views/todolist/view.html.php class TodoListViewTodoList extends JViewLegacy { public function display($tpl = null) { // 呼叫 model 的 getForm(),並準備傳入 tmpl/media.php $this->form = $this->get('Form'); parent::display(); } } |
Tmpl
若要取得 xml 整個 <fieldset> 可使用 renderFieldset(),若只想單純取出 <field> 則使用 renderField()。另外經由 Joomla! 產生的 <input> 等等元件,名稱會用 jform[] 陣列包裝起來喔。
- renderField(名稱, null, 預設值)
若我們要編輯已經儲存的欄位,第三個參數可以設定。
- 若要自訂欄位請閱讀這篇教學
1 2 3 4 5 6 7 |
<!-- administrator/components/com_todolist/views/todolist/tmpl/media.php --> <form method="post" action=""> <?=$this->form->renderFieldset('details');?> <?=$this->form->renderField('imageurl');?> </form> |
Ryan Ye
2019-05-26 - 08:15
好文,期待更多大大的文章~