Skip to main content

Drupal 8 教學 - 新增Controller

Submitted by admin on Thu, 01/30/2020 - 06:36

0. route與controller在Drupal中扮演的角色

當我們在Drupal中建立一個自定義頁面的時候,我們會需要讓Drupal知道要透過何種網址存取這個頁面,以及這個頁面要呈現甚麼樣的內容。

等等會介紹的Route檔案會負責定義頁面的URL連結,而Controller則負責控制頁面回傳的內容,或是該頁面被存取時要執行的其他動作。

在這個範例中,我們會定義一個最簡單的Controller,讓使用者在存取/demo/simple_controller時輸出一個Hello World頁面。

我們可以在這裡看到範例的輸出結果。

 

1. 宣告一個custom module模組

這部分已經在Drupal 簡單的自製表單中提到過了,我們要先在[SiteDocumentRoot]/modules底下建立一個custom資料夾,並在裡面放置我們的自製模組檔案。

在這個範例中,我們將這個會輸出hello world的模組命名為SimpleController,因此我們要在custom資料夾下建立一個跟模組名稱一樣的資料夾。

接下來,我們要建立模組info檔案,讓Drupal認識到有這個模組存在。

檔案的完整名稱與所在路徑應該是[SiteDocumentRoot]/modules/SimpleController/SimpleController.info.yml,內容如下。

name: SimpleController
description: A simple drupal controller demo.
package: Simple Examples
type: module
core: 8.x

name代表模組名稱,必須與我們剛剛建立的資料夾名稱以及info檔案名稱完全相同。

description會出現在使用者在/admin/modules要啟用模組時看到的模組說明。

package是使用者在/admin/modules看到的模組分類。

core代表這個模組適用Drupal 8。

 

2.建立routing規則

Drupal的Routing定義了一段程式碼與URL之間的對應關係。換言之,Routing描述了『當網站上的某個URL被訪問時,執行某一段程式』這樣的規則。

在這個範例中routing檔案應該被放在[SiteDocumentRoot]/modules/SimpleController/SimpleController.routing.yml,內容如下。

SimpleController.example:
  path: '/demo/simple_controller' 
  defaults: 
    _controller: '\Drupal\SimpleController\Controller\SimpleExampleController::print_example' 
    _title: 'A demo of how drupal controller works'
  requirements: 
    _permission: 'access content'

這個檔案描述了當path所記載的頁面被訪問時,賦予該頁面_title所定義的標題以及_controller函式所回傳的內容,而且使用者必須有_permission以上的權限才能夠訪問該頁面。

SimpleController.example是這個route規則的名稱,會這樣寫是因為我們其實可以在一個routin檔案底下定義多個route。如果有需要的話可以再定義SimpleController.content或是SimpleController.execute等等內容。

比較值得一提的是_controller項目中所記載的長字串,它的格式其實是{namespace}\{class}::{method},我們會在下面更深入提及這部分。

 

3. 建立一個Controller class

接下來我們要建立一個controller檔案,這個檔案內記載了controller的class與對應的method。

透過觀察上一步所建立的routing檔案,我們可以猜到等等要建立的class名稱是SimpleExampleController,並且在這個class中至少存在一個叫做print_example的方法可以被外部呼叫。

不同於info與routing檔案用模組名稱作為檔案名稱,這次我們要用class的名稱來做為檔案名稱,檔案應該要被放在[SiteDocumentRoot]/modules/SimpleController/src/Controller/SimpleExampleController.php,並且有以下內容:

<?php

namespace Drupal\SimpleController\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * An example controller.
 */
class SimpleExampleController extends ControllerBase {

  /**
   * Returns a render-able array for a test page.
   */
  public function print_example() {
    $build = [
      '#markup' => $this->t('Hello World!'),
    ];
    return $build;
  }

}

可以注意到我們的namespace宣告為Drupal\SimpleController\Controller,與routing檔案中的描述相符合。最後回傳的陣列會被Drupal進行後續處理並輸出到頁面上。

最後,請不要忘記文件開頭的<?php,但並不需要多一個?>結尾,這是Drupal的規則。