原文地址:http://www.sitepoint.com/build-drupal-8-module-routing-controllers-menu-links/
翻译:Drupal猎人
转载说明:你想转载?不用给我面子,尽情转,不用留出处,我很大方的!
Drupal8为了适应新时代PHP主流框架发展的需要,做了很多改变,这就意味着以往面向过程的PHP 4 编程风格将被面向对象的方式取代,为了实现这一目标,在Proudly Found Elsewhere(可能是一个组织团体)的倡仪下,Drupal 8 其实包含了很多看起来不是为deupal开发的代码 其中最大的变化是引入了Symfony框架,这对开发人员来说,会产生两个重大影响首先,这可能将会大大增加Drupal开发者的数量,比如那些曾经自认为是大师,不屑于面向过程开发的传统"高端程序猿",现在Drupal8,也是面向对像了,也用了新框架,他们已经没有理由拒绝加入drupal开发者的行列
第二,新的框架内核变化,会给现在那些没有多少PHP现代框架开发经验的人许多恐惧,他们会担心自己不能适应这种开发方式的巨大转变,但是没关系,我们都需要重新学习,学习Symfony框架,还有充满希望的Drupal8, 像其他PHP框架一样,它们都是很容易扩展的,我们要给自己信心。
在目前,Drupal 8 还在其发布周期中,目前最新的版本是alpha12,我们会基于这个版本,来展示一些Drupal 7开发者会先遇到的一些基本变化,我们应该先熟悉这些基本变化,我建了一个git仓库,你可以在那里找到我在这个文章系列中所涉及到的一些代码,所以如果你想要获取这些代码,可以查看这里
我怎样创建一个模块?
我们第一件事是要确定必须的文件和文件夹结构来告诉Drupal8识别我们的新模块。在Drupal 7 里,我们必须创建至少2个文件(.info 和 .module文件),但是在Drupal 8里,.info文件替换成了.info.yml,文件里的内容数据信息相同,但格式略有差异。
另一个主要变化是,自定义模块和第三方贡献模块文件夹的存放位置现在被放到了根目录下的modules/,这是因为所有核心的代码已经被移动到了它单独的文件夹core/,当然,在根目录下的modules文件夹内,我们依然鼓励你像以往的Drupal 7 一样,可以创建 custom 和contrib 子文件夹来分别存放你的自定义模块和官网下载的第三方模块。
让我们继续,我们现在先来学习创建一个叫demo(非常简单)的模块,并把它放到modules/custom/文件夹下,正如我之前所提到的,我们需要在这个新创建的demo/文件夹里,创建一个 demo.info.yml 文件,并在文件里输入以下代码:
name: Drupal 8 Demo module description: 'Demo module for Drupal 8 alpha12' type: module core: 8.x
这些大部分你应该看着很熟悉吧(name, description and core), type 字段也是现在必须有的一项,它的值可以是module,theme,theme_engine分别定义此文件类型是模块,还是主题或者模板引擎,另外要注意的一件重要的细节是,注意yml文件里的空格,正确缩进可以像数组一样组织数据。
你可以查看此文档说里其他可用的key|value , 然后打开一个模块文件夹下的.info.yml文件,尝试改变key|value,这里是官方的变更说明
现在,只要有这一个文件就足够了,你可以进入导航菜单下的Extend(扩展)页,找到Demo模块,并启用它。
正如我之前提到的,现在我不需要再创建一个.module的文件,drupal 8就已经可以识别此模块了,因为在drupal 8里,.module文件已经不再是必须存在的文件。因为现在大部分的业务逻辑代码都转移到了service类,控制器和插件里,我们稍后会看到这一点。
什么是路由?调用hook_menu()会发生什么?它的回调怎么工作?
在drupal 7里,hook_menu()可能是最能实现这些功能需求的钩子,因为它就是被用于设定路径并且把这些路径和回调函数连接起来,它也用来创建菜单链接和其他一些东西
在Drupal 8里,我们不再需要hook_menu()了,因为我们会大量使用Symfony2的组件来处理路由,这涉及定义一个路由配置和在控制器里处理一个回调(Controller类的方法), 让我们来实际看下它是如何工作的,我们来创建一个简单的页面来输出那句程序界的永恒经典:Hello world!
首先,我们需要为我们的模块创建一个路由文件:demo.routing.yml ,这个文件也是放在demo模块根目录下,在这个文件里,我们可以有如下(简单)路由设定:
demo.demo: path: '/demo' defaults: _content: '\Drupal\demo\Controller\DemoController::demo' _title: 'Demo' requirements: _permission: 'access content'
第一行代码是一个新路由的开始,这个路由的名字叫做demo(原作者真蛋疼,你就不能取一个不一样的路由名嘛,非要和模块名一样,你让我的小伙伴误会了怎么办?),第一个是demo是模块名,第二个demo是路由名.
第二行path, 我们指定了这个路由的注册路径。
第三行defaults默认设置,我们设定了两件事:默认的页面标题(_title)和引用一个DemoController类的一个方法(_content)
第四行requirements要求,我们指定了用户需要有什么权限才能查看该页面。
你可以查此文档知道你还可以在这个路由文件里设定哪些选项。
现在,让我们来创建第一个叫做DemoController的控制器,并且它包含了一个方法叫做:demo(),用于当用户访问该页面时调用此方法。
在模块目录里,创建一个src的文件夹和一个Controller的文件夹,这就是我们存放controller类的地方,好了,进入Controller文件夹,创建文件:DemoController.php。
该控制器的位置,正如我们将看到的一样,把其他类放入src文件夹里是采用PSR-4标准的一部分,在之前,我们有一个更深层更大的文件夹结构(PSR-0标准),但现在有一个过渡阶段,这两种标准的文件夹结构路径都会起作用,所以你如果看到代码类仍然被放在lib/文件夹下,不用觉得奇怪,那是PSR-0标准。
在DemoController.php文件里,我们可以声明我们的类了:
<?php /** * @file * Contains \Drupal\demo\Controller\DemoController. */ namespace Drupal\demo\Controller; /** * DemoController. */ class DemoController { /** * Generates an example page. */ public function demo() { return array( '#markup' => t('Hello World!'), ); } }
这是我们为了在一个页面上显示"Hello World!"的一个结构最简单的实例,在顶部,我们指定了类的命名空间,在下面,我们声明了我们的类
在DemoController类里,我们只需要demo()方法,用来返回一个像以往的drupal 7里一样的渲染数组,没有大量的东西,现在我们要做的就是清空缓存,并在浏览器里输入地址:http://example.com/demo ,然后我们就应该可以看到一个输出有Hello World!的页面!
怎么创建菜单链接?
在Drupal 7里,为了让菜单链接显示在网站上,我们可以在实施hook_menu()时,添加已经注册过的路径,但在Drupal8里,这个不再需要用hook来处理,我们可以像配置一样使用一个yml文件来声明菜单链接
让我们来看看,该怎样创建一个菜单链接来显示在Structure(结构)管理菜单下,首先,我们在我们的模块根目录下创建一个demo.menu_links.yml 文件,在这个文件中,我们将设定菜单链接和在现有网站菜单上的位置,为了实现我们所要做的,我们需要在文件里输入以下代码:
demo.demo: title: Demo Link description: 'This is a demo link' parent: system.admin_structure route_name: demo.demo
这又是一个基于缩进的yml结构文件,
第一行我们定义了模块的菜单链接的机器名(就像之前定义路由一样),接下来,我们设定了链接的标题,描述,父菜单路径(作为子菜单放在该父菜单下),以及该菜单关联的路由名。
父菜单选项的值是父菜单路径(通它的所属模块附加),你想找个这个父菜单链接,你需要查找一些类似的*.menu_links.yml文件,因为这里的值是system.admin_structure,所以我就可以知道,它肯定是由核心的System模块设定的,所以你就可以判断这个父菜单链接存在于system.menu_links.yml文件里。
route_name是我们想要为这个菜单关联的路由名(这们之前创建的),当你清空缓存后,然后输入浏览器地址:http://example.com/admin/structure你应该可以看到一个新的菜单标题和描述,并且此链接是链接到demo/path的,怎么样,很不错吧?
结论
在这篇文章中,我们开始讨论Drupal 8 的模块开发,在这个阶段(alpha12发布),正是开始学习怎样使用新的API接口来开发贡献模块,为此,我会大家一起退出传统框架的思维,用全新的思维一起探索学习Drupal 8的变化。
首先,我们了解了一些基础知识,如何启动一个Drupal8模块(文件和文件夹结构等),所有这些与Drupal 7的不同之处,我们还看到了如何设定路由和一个控制器类的方法来调用一个路由地址,最后,我们已经看到了如何创建一个使用我们所定义路由的菜单链接。
在接下来的教程中,我们将继续构建完善这个模块,并期待发现在Drupal8中其他一些很酷的东西,我们将看到我们如何创建区块和如何配合使用表单和配置管理系统,下期见。