Drupal – 模块开发
     发布在:PHP      浏览:34      评论:0 条评论

摘自: 《Now i code》

模块目录

创建目录 /modules/custom/hello_world

创建 info.yml 文件

  1. /modules/custom/hello_world 目录下创建 hello_world.info.yml 文件
  2. 添加如下代码
name: hello_world
description: Creates a page showing "Hello World"
package: Custom
type: module
core: 8.x
# dependencies:
#   - datetime: datetime
#   - link: link
#   - drupal: views
# test_dependencies:
#   - drupal: image

# configure: hello_world.settings
# hidden: true

# Note: do not add the 'version' property yourself!
# It will be added automatically by the packager on drupal.org

version: 1.0
  1. dependencies: 列出你的自定义模块所依赖的模块。其格式为 {project}:{module}{project} 是出现在 Drupal.org 项目 url 中的项目名称,例如 drupal.org/project/views{module} 是模块的机器名
  2. test_dependencies: 测试的依赖模块。testbot 会对整个模块的依赖关系进行测试。如果通过测试,依赖关系是正确、完整的,应该将其移动到 dependencies 中。在上面的例子中,测试期间 testbot 会包含 image 模块。但站点安装 Hello World Module 模块时不会要求安装 image 模块。测试依赖的命名规则与依赖的命名规则相同。
  3. configure: 如果你的模块提供了一个配置表单,在这里可以指定配置的路由。当用户展开模块细节时,它将会在 Extend 页(/admin/modules)显示一个链接。
  4. hidden: 若为 true 则在站点的 Extend 页面的模块列表中隐藏你的模块。如果模块仅仅包含一个测试或作为一个开发例子,你发现使用这个健是非常有用的。也可以在 settings.php 文件中添加 $settings['extension_discovery_scan_tests'] = TRUE 以显示模块。

创建 routing.yml 文件

routing 文档见 https://www.drupal.org/node/2092643

Drupal8 中的菜单主要由这几个文件构成:

  1. hello_world.routing.yml: 包含 URL 路径和回调函数的映射关系
  2. hello_world.links.menu.yml: 包含菜单项的结构
  3. hello_world.links.action.yml: 等效 Drupal7 的常量 MENU_LOCAL_ACTION
  4. hello_world.links.task.yml: 等效 Drupal7 的常量 MENU_DEFAULT_LOCAL_TASK

hello_world.routing.yml 中添加如下代码:

hello_world.content:
  path: '/hello'
  defaults:
    _controller: '\Drupal\hello_world\Controller\HelloController::content'
  requirements:
    _access: 'TRUE'
  1. path: 路由注册的路径,需要以斜线开头
  2. _controller: 定义路由的路径 HelloControllercontent 方法
  3. requirements: 用户能够访问这个页面所需要的权限

创建 HelloController.php 文件

在模块目录中,创建一个符合 PSR-4 标准的目录结构 /src/Controller,并在该目录下创建控制器文件 HelloController.php

我们这个模块只是想输出 hello world 这样的字符串,需要在 /src/Controller/HelloController.php 文件中输入一下代码:

<?php
/**
 * @file
 * Contains \Drupal\hello_world\Controller\HelloController.
 */

namespace Drupal\hello_world\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloController extends ControllerBase {
    public function content() {
        return [
            '#type' => 'markup',
            '#markup' => $this -> t('Hello, World!');
        ];
    }
}

在 url 地址栏输入 /hello,你将会看到 Hello, World! 这样的信息

Drupal - 模块开发

菜单说明

links.menu.yml

要用到 hello_world.links.menu.yml

在模块的根目录下,创建一个名为 hello_world.links.menu.yml 的文件,并输入一下内容:

hello_world.admin:
  title: 'Hello module settings'
  description: 'example of how to make an admin settings page link'
  parent: system.admin_config_development
  route_name: hello_world.content
  weight: 100
  1. route_name: 在 routing.yml 中定义的路由名称
  2. parent: 描述的是菜单的父链接菜单。这个菜单链接将会 /admin/config 下的 development 中创建。

清空缓存,看一下效果。

Drupal - 模块开发

links.action.yml

在模块的根目录下,创建一个名为 hello_world.links.action.yml 的文件,并输入以下的内容:

hello_world.link_add:
  route_name: hello_world.content.add
  title: 'Add hello world'
  appears_on:
    - hello_world.hello_world
  1. appears_on: 在哪个路由显示

当然也可以定义动态的菜单,如下:

hello_world.content.action:
  route_name: hello_world.content
  title: 'Example dynamic title action'
  weight: -20
  class: '\Drupal\hello_world\Plugin\Menu\LocalAction\CustomLocalAction'
  appears_on:
    - hello_world.content

CustomLocalAction.php 的代码如下:

<?php
/**
 * @file
 * Contains \Drupal\hello_world\Plugin\Menu\LocalAction\CustomLocalAction
 */

namespace Drupal\hello_world\Plugin\Menu\LocalAction;

use Drupal\Core\Menu\LocalActionDefault;

/**
 * Defines a local action plugin with a dynamic title.
 */
class CustomLocalAction extends LocalActionDefault {

    /**
     * {@inheritdoc}
     */
    public function getTitle() {
        return $this -> t('My @arg action', [
            '@arg' => 'dynamic-title'
        ]);
    }
}

links.task.yml

主要是定义 tab 切换的菜单,如:

example.admin: # The first plugin ID
  title: 'Settings'
  route_name: example.admin
  base_route: example.admin

example.admin_3rd_party: # The second plugin ID
  title: 'Third party services'
  route_name: example.admin_3rd_party
  base_route: example.admin

这里定义了两个菜单,adminadmin_3rd_party,并且默认显示 admin

当然也可以动态定义:

example.local_tasks:
  deriver: 'Drupal\example\Plugin\Derivative\DynamicLocalTasks'
  weight: 100

其中 DynamicLocalTasks.php 如下

<?php
/**
 * @file
 * Contains \Drupal\example\Plugin\Derivative\DynamicLocalTasks
 */

namespace Drupal\example\Plugin\Derivative;

use Drupal\Component\Plugin\Derivative\DeriverBase;

/**
 * Defines dynamic local tasks.
 */
class DynamicLocalTasks extends DeriverBase {
    /**
     * {@inheritdoc}
     */
    public function getDefivativeDefinitions($base_plugin_definition) {
        // Implement dynamic logic to provide values for the same keys as in example.links.task.yml
        $this -> derivatives['example.task_id'] = $base_plugin_definition;
        $this -> derivatives['example.task_id']['title'] = "I'm a tab";
        $this -> derivatives['example.task_id']['route_name'] = 'example.route';
        return $this -> derivatives;
    }
}

实践

  1. 创建一个名为 example 的模块
  2. admin/config 添加一个菜单
  3. 添加一个 task 菜单
  4. 添加一个 action 菜单
  5. 写一个 Controller,并把第一天发表的几篇文章显示出来

如果无法理解菜单路由配置,可以看 《Drupal – 配置开发》 中 [创建实体] 示例

下一篇: 《Drupal – 区块开发》

Responses