110. 菜单本地动作MenuLocalActions

菜单本地动作Menu local actions用来为目标路由提供操作动作,在路由对应页面中以操作按钮呈现,比如在呈现某内容列表的路由页面提供一个添加新内容的按钮,可参考内容管理页(/admin/content)的“添加内容”按钮

 

image

 

本地动作块:

路由页面是以本地动作块来呈现本地动作按钮的,因此需显示本地动作的页面须添加该块,块定义如下:

块管理标签admin_labelPrimary admin actions

块插件IDlocal_actions_block

块插件类:Drupal\Core\Menu\Plugin\Block\LocalActionsBlock

该块是一个很简单的块(见本系列块相关主题),主要渲染工作由菜单本地动作插件管理器完成(见下)。

 

本地动作概述:

系统将动作按钮视为插件,一个按钮对应一个插件定义,一对一关系,如果需要为某页面添加动作按钮,定义插件即可,具体是在模块根目录下建立文件:“模块名.links.action.yml”,其中以根键做插件id,其值做插件定义,插件定义有如下键名:

route_name:动作按钮所指页面的路由名,换句话说即点击后跳转到该路由,字符串值,必填项

route_parameters:对应以上路由名的路由参数,数组值,默认为空数组[],可选

title:动作按钮文本,字符串值,被系统理解为可翻译的,在系统内部被转化为翻译对象TranslatableMarkup,用于按钮上显示的文本,并非title属性值

title_context:可选,标题翻译上下文,见翻译系统

appears_on:路由名构成的数组,指示该本地动作将出现在哪些路由页面中

weight:排序权重,默认为null

options:按钮链接选项,见本系列URL篇,可在其中指定链接属性,如是否在新窗口打开、属性值等

id:插件id,系统以yml文件中的定义根键自动赋值,最佳实践推荐根键采用路由名,如果多个定义有相同路由名,那么可以采用后缀加以区分

provider:提供插件定义的模块名,由系统赋值

deriver:插件派生器的全限定类名,见插件系统

cache_tags:数组值,缓存标签,默认为空数组(见默认插件类)

cache_contexts:数组值,缓存上下文,默认为空数组(见默认插件类)

cache_max_age:缓存最大时间,整数秒,默认为永久(-1见默认插件类)

class:实例化插件对象的默认实现类,默认为“Drupal\Core\Menu\LocalActionDefault”,当有特殊需要时可以自定义,在默认安装中仅两个定义没有采用该默认类(但都继承了该类),插件id和类如下:

block_content_add_action
     Drupal\block_content\Plugin\Menu\LocalAction\BlockContentAddLocalAction

entity.menu.add_link_form
     Drupal\menu_ui\Plugin\Menu\LocalAction\MenuLinkAdd

 

菜单本地动作(Menu local actions)插件管理器:

该插件管理器除了收集管理本地动作插件外,还负责为其构造渲染数组,定义如下:

服务idplugin.manager.menu.local_action

类:Drupal\Core\Menu\LocalActionManager

插件修改钩子:menu_local_actions

获取方法:

$localActionManager =\Drupal::service('plugin.manager.menu.local_action');

使用入口:

$local_actions =$localActionManager->getActionsForRoute($route_name);

这里$local_actions是可以直接返回呈现的渲染数组,包含该路由拥有的所有本地动作,其格式如下:

$local_actions [$plugin_id] = [
        '#theme' => 'menu_local_action',
        '#link' => [
          'title' => $this->getTitle($plugin),
          'url' => Url::fromRoute($route_name, $route_parameters),
          'localized_options' => $plugin->getOptions($this->routeMatch),
        ],
        '#access' => $access,
        '#weight' => $plugin->getWeight(),
      ];

一个动作按钮一个子元素,此外还会被附加缓存元数据,在以下预处理函数中会进一步处理:

   template_preprocess_menu_local_action(&$variables)

该函数使链接被渲染成按钮,对应的默认模板为:

   core/themes/classy/templates/navigation/menu-local-action.html.twig

 

补充:

1、菜单本地动作被渲染成一个按钮,但页面中的按钮不一定就是本地动作,后者是针对整个路由页面的全局操作

2、如何查询目标页面的路由名呢?你可以下载本系列配套的“yunke_help”模块,输入地址即可查询路由参数,或者依据路径到可能的模块下查找路由定义yml文件

3、本地动作是基于路由设置的,是否可以基于url地址呢?答案是不可以,因此本地动作不会指向站外,且系统没有派发关于页面本地动作相关的钩子(插件修改钩除外),模块无法干预页面本地动作块的生成,但如有需求一定要这些“不可以”变成“可以”怎么办呢?在不修改核心的情况下,云客给出一种解决方案:覆写菜单本地动作插件管理器服务,自定义一个继承原插件管理器的类,在自定义类中通过模块处理器派发修改钩子,这又一次体现了drupal的强大灵活和oop开发的优越性。

 

 

本书共128小节:

评论 (写第一个评论)