Skip to main content

Drupal 簡單的自製表單

Submitted by admin on Wed, 12/11/2019 - 04:20

這個教學會告訴大家如何定義一個自己的Drupal 8模組。

還記得我們在Drupal 如何安裝模組這篇文章中曾經進入管理員列表中的Extend介面,透過打勾的方式來Enable列表中某個模組嗎。如同我們在那時候所看到的,每個模組都有自己的名稱,以及自己的所屬的package,更細節一點還有自己的模組敘述(description)、與其他模組的相依性關係。

上面這些事情全部定義在Drupal的結構中,一個叫做.info.yml的檔案裡面,每一個模組都有屬於自己的.info.yml。

 

在實際動手之前,我們要決定我們的模組名稱。

由於這個範例展示的是一個簡單的,將兩個數字相加輸出的表單,因此就先命名為[SimpleForm]吧。

各位可以先到這裡來看看這個範例最後的輸出結果。

 

好了,下面開始進入主題。

 

1. 建立一個SimpleForm.info.yml文件

這份文件的位置應該要落在[SiteDocumentRoot]/modules/custom/SimpleForm/SimpleForm.info.yml。

其中的SiteDocumentRoot是網站所在的資料夾目錄,裡面應該已經有一個modules資料夾了。如果這是一個新部屬的Drupal網站,要自己在裡面建立一個新的custom資料夾。

建立custom的資料夾是為了把自己撰寫的模組與網路上安裝的模組區分開來,在更新時才不會發生不預期的覆蓋。順便一提,如果我們日後打算更動一個安裝好的第三方模組,應該先Disable該模組後,把模組搬移到custom資料夾底下,再重新Enable這個模組。

在custom資料夾底下的SimpleForm資料夾是這麼模組的資料夾目錄,所有屬於SimpleForm模組的檔案都會放在這裡面。

至於SimpleForm.info.yml本身,請按照下面的內容輸入並儲存。

name: SimpleForm

description: adds a simple form which adds up two numbers.

package: Simple Examples

type: module

core: 8.x

這份檔案的內容是寫給Drupal核心看的,傳達的內容依序是: 模組名稱、呈現在Extend頁面的模組敘述、呈現在Extend頁面的這個模組所屬的package、這是一個模組、這個模組運行在Drupal 8上面。

把這份SimpleForm.info.yml存檔之後clear cache,如果步驟沒出錯的話,我們就能夠在Extend頁面中找到這個模組了。

這時候我們甚至可以Enable這個模組,儘管目前這個模組並沒有任何的功能。

simple_form_01.png

 

2.建立一個SimpleForm.routing.yml文件

這份文件的功用在於告訴Drupal在SimpleForm模組中存在一個MySimpleForm的物件(或者更精確地說,route name)

來談一下這份routing文件包含甚麼樣的資訊。

MySimpleForm可以透過'/simple_form'的路徑存取,內容物是張表單(_form),表單物件定義在name space \Drupal\SimpleForm\Form\SimpleExampleForm裡面,這個表單頁面的標題(title)是'a simple form adding two inputs',而這個表單頁面只要有存取內容(access content)權限的使用者才可以讀取。

看不懂也沒關係!會複製下面的程式碼就好。

放置的位置應該要在 [SiteDocumentRoot]/modules/custom/SimpleForm/SimpleForm.routing.yml 。

內容如下:

SimpleForm.MySimpleForm:

  path: '/simple_form'

  defaults:

    _form: '\Drupal\SimpleForm\Form\SimpleExampleForm'

    _title: 'a simple form adding two inputs'

  requirements:

    _permission: 'access content'

 

3.建立SimpleExampleForm.php

SimpleExampleForm.php文件中定義了表單的實際內容以及按下送出後的行為。

這份文件應該被放置在[SiteDocumentRoot]/modules/custom/SimpleForm/src/Form/SimpleExampleForm.php,其中src與Form的資料夾是需要自己建立的。

文件內容如下:

<?php

namespace Drupal\SimpleForm\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class SimpleExampleForm extends FormBase {

  public function getFormId() {
    return 'SimpleForm_SimpleExample_Form';
  }

 public function buildForm(array $form, FormStateInterface $form_state){

    $form['number_1'] = [
      '#type' => 'textfield',
      '#title' => $this->t('frist number'),
    ];

    $form['number_2'] = [
      '#type' => 'textfield',
      '#title' => $this->t('second number'),
    ];

    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Apply'),
    ];

    return $form;

  }

public function submitForm(array &$form, FormStateInterface $form_state){
    $result = (int)($form['number_1']['#value']) + (int)($form['number_2']['#value']);
    \Drupal::messenger()->addMessage(t('the result is '.$result));
  }

}

 

接著我們來講講文件內容所代表的意義,裡面會用到一點php class的概念。

首先,我們可以注意到namespace的內容與第二步的.routing.yml文件中“_form”欄位的前半部是相同的,而欄位的後半部SimpleExampleForm則與我們所定義的classname一致。這點很重要,要是其中有錯字的話會導致Drupal找不到表單的定義,從而找到一個空白頁面。

getFormId這個函式會回傳這個表單的名稱,這個名稱最好不要跟其他表單重複。之後會提到,Drupal透過一種hook_function來讓兩個不同的模組間進行互動。換言之,如果有另一個模組想要自動化的編輯這份範例表單,例如在欄位填入預設值,甚至增加減少這個範例表單的欄位選項,那個模組必須能夠識別出這份SimpleExampleForm與其他表單不同的地方,這時候就要靠getFormId的回傳值了。

buildForm函式內定義了表單所包含的物件內容,可以看到這份表單裡面包含了三個元件,分別是兩個名為number_1number_2的textfield,以及一個名為submit的按鈕。

最後,submitForm函式定義了使用者按下按鈕後的行為。第一步先把number_1number_2轉成整數之後相加,第二部則是印出兩個數字相加的結果呈現給使用者。

 

按下儲存後,就可以到[SiteDocumentRoot]/simple_form看看我們做出來的表單長什麼樣子了,或者可以到這裡先睹為快。下一篇會介紹如何建立一個會隨使用者操作即時反應的ajax表單。

 

enjoy~