drupal可以让你使用任意URL路径来访问某个页面,从而提供良好的SEO支持和语义性,如此强大的功能是由路径处理子系统完成的,在讲解她之前需要明白一个概念:“内部路径”,也就是路由中指定的路径,任意进来的路径都会被路径处理系统转化为内部路径(非可路由内部url除外),从而让系统内部有一个统一的环境,面向内部路径即可,而不用考虑用户到底使用的什么路径,路径处理系统实现了访问路径和系统实现的解耦,路径处理分为两部分:入站处理和出站处理,她们相互协作提供了用户层面连贯的访问体验。
路径处理管理器:
路径处理是由处理器链完成的,链中每一个节点是一个独立的处理器,入站和出站各有一条处理器链,链中处理器按照优先级顺次执行,前一个处理器处理后的路径及相关参数继续传给后一个处理器,最终得到完全处理的路径,路径处理管理器被用来收集处理器,并按顺序执行她们,服务定义如下:
服务: path_processor_manager
类:Drupal\Core\PathProcessor\PathProcessorManager
该服务被设置了service_collector标签,在容器编译阶段会收集被标记为以下标签的服务:
path_processor_inbound:通过addInbound方法注入,入站路径处理器服务
path_processor_outbound:通过addOutbound方法注入,出站路径处理器服务
她们按优先级执行,数值越大越优先,默认优先级为0
默认提供的入站处理器及优先级如下(服务id:优先级):
path_processor_decode:1000
path_processor.image_styles:300
path_processor_language:300
path_processor_front:200
path_processor.files:200
path_processor_alias:100
默认提供的出站处理器及优先级如下(服务id:优先级):
path_processor_alias:300
path_processor_front:200
path_processor_language:100
入站处理:
入站的路径处理时机是在系统派发请求事件时在路由系统中执行,路由系统订阅了请求事件,路由是工作在内部路径上的,在执行路由工作之前调用路径处理器以将访问路径转变为内部路径,具体是在得到路由集前,详见服务:router.route_provider的以下方法:
\Drupal\Core\Routing\RouteProvider::getRouteCollectionForRequest
整个入站路径处理是从以下代码开始的:
$path =\Drupal::service("path_processor_manager")->processInbound($path, $request);
参数$path是由请求对象返回的路径信息($request->getPathInfo()),是网址中第一个“/”开始到“?”之间的部分,不含协议、主机名、端口、查询参数等,以“/” 开头,末尾不含“/”,如果没有路径则值为“/”
参数$request是请求对象
在该方法内部将按优先级依次调用入站处理器的以下方法:
$path = $processor->processInbound($path, $request);
前一个处理器返回的已处理路径被传给下一个处理器,模块自定义入站处理器方法如下:
定义一个实现入站路径处理器接口的类(\Drupal\Core\PathProcessor\InboundPathProcessorInterface)
将该类定义为服务,并给出服务标签:path_processor_inbound和优先级参数
自定义的入站路径处理器需要注意和核心提供的处理器(见下)的优先级顺序
核心默认入站路径处理器:
path_processor_decode:
类:Drupal\Core\PathProcessor\PathProcessorDecode
优先级:1000
作用:将url编码的路径解码
path_processor.image_styles:
类:Drupal\image\PathProcessor\PathProcessorImageStyles
优先级:300
图片模块定义,重写图像样式的URL
path_processor_language:
类:Drupal\language\HttpKernel\PathProcessorLanguage
优先级:300
多语言站点中,有些语言协商使用特定的路径格式,在路径中包含语言信息,该处理器同时涉及出入站处理,重要,单独讲解,见后
path_processor_front:
类:Drupal\Core\PathProcessor\PathProcessorFront
优先级:200
解析首页的内部路径,这是系统可以将任意页面设为首页的关键所在,首页的内部路径储存在配置项system.site的page.front键下,注意在设置首页内部路径时不要带语言前缀