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

Joomla! 提供了許多類型的表單元件,不過官方網站文件幾乎找不到。在沒有使用 xml 表單元件的時候,我們可能會這樣寫

<input type="text">
<select>
    <option></option>
</select>
<textarea></textarea>

這樣寫也可以正確的提交表單,但如果我們想要連結 Joomla 的提供功能,例如選取註冊會員、挑選已上傳的圖片、挑選已發佈的文章,像這類屬於套件的功能,我們不打算從頭自己刻一個吧?那多累呀,於是我們可以在 Model 的地方動些手腳,讓這些表單元件顯示的方式,是透過 xml 定義。

我們看後台(administrator)範例,元件名稱叫做 com_todolist,打算挑選已經上傳的圖片--在這之前你必須要先對如何設計 Joomla! 的元件 (Component)有一定的瞭解。

Controller

<?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 舊系統而採用。
<?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 設置打開後的起始路徑。

<!-- 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

<?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[] 陣列包裝起來喔。

<!-- administrator/components/com_todolist/views/todolist/tmpl/media.php -->
<form method="post" action="">
    <?=$this->form->renderFieldset('details');?>
    <?=$this->form->renderField('imageurl');?>
</form>

 

這樣就完成畫面了,我們從瀏覽器應該可以看到挑選圖片的表單元件

點擊選擇後,可以出現視窗

Comments

  1. 好文,期待更多大大的文章~

發表迴響