升级到TYPO3 v9.5.14后路由异常

Routing exception after upgrading to TYPO3 v9.5.14

升级到 TYPO3 v9.5.14 后,我们的新闻详情页面出现异常崩溃

Symfony\Component\Routing\Exception\InvalidParameterException

Parameter "p88bd715a41119d0e8087a5d19cb049" for route "tx_news_pi1_1" must match "[^/]++" ("" given) to generate a corresponding URL.

怎么回事?

站点使用了这个配置:

  NewsTagPlugin:
    type: Extbase
    limitToPages: [14]
    extension: News
    plugin: Pi1
    routes:
      - routePath: '/{tag-name}'
        _controller: 'News::list'
        _arguments:
          tag-name: 'overwriteDemand/tags'
      - routePath: '/{tag-name}/page/{page}'
        _controller: 'News::list'
        _arguments:
          tag-name: 'overwriteDemand/tags'
          page: '@widget_0/currentPage'
          requirements:
            page: '\d+'
    defaultController: 'News::list'
    defaults:
      page: ''
    aspects:
      page:
        type: IntegerMapper
        start: 1
        end: 5000
      tag-name:
        type: PersistedAliasMapper
        tableName: tx_news_domain_model_tag
        routeFieldName: slug

首先,考虑 https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/9.5.x/Important-86895-RouteAspectsTakePrecedenceOverRequirements.html

罪魁祸首是 page 方面的 default 配置。 它曾经被引入以确保第一个标签页面的 URL 始终是“/tag-name”,只有后续页面才有“/tag-name/page/2”等等。

现在需要删除此默认值,以便根据需要应用要求。

1) 多余的映射

  NewsTagPlugin:
    ...
    routes:
      ...
      - routePath: '/{tag-name}/page/{page}'
        _controller: 'News::list'
        _arguments:
          tag-name: 'overwriteDemand/tags'
          page: '@widget_0/currentPage'
          requirements:
            page: '\d+'
  • _arguments 定义路由参数和内部变量的映射(例如作为查询参数`
  • requirements 在这里是错误的,因为它不能用作参数映射
  • 参数requirements需要在NewsTagPlugin
  • 的根级别定义

2) 无效的空默认值

  NewsTagPlugin:
    ...
    routes:
      ...
      - routePath: '/{tag-name}/page/{page}'
      ...
    defaults:
      page: ''
    aspects:
      ...
  • defaults 未在 TYPO3 v9.5.14 之前应用并在 https://review.typo3.org/c/Packages/TYPO3.CMS/+/60361
  • 中解决
  • 参数 page 的空默认值没有多大意义,会导致像 /some-tag/page/ 这样的 URL,这会导致答案 [=49] 中显示的错误消息=]
  • 默认值应该是page: 1
  • 如果在 URL 中应该省略参数(例如具有 /some-tag/page/),则需要在路由路径
  • 中使用 {!page} 明确定义

参考资料

调整后的增强器配置

  NewsTagPlugin:
    type: Extbase
    limitToPages: [14]
    extension: News
    plugin: Pi1
    routes:
      - routePath: '/{tag-name}'
        _controller: 'News::list'
        _arguments:
          tag-name: 'overwriteDemand/tags'
      - routePath: '/{tag-name}/page/{!page}'
        _controller: 'News::list'
        _arguments:
          tag-name: 'overwriteDemand/tags'
          page: '@widget_0/currentPage'
    defaultController: 'News::list'
    defaults:
      page: 1
    aspects:
      page:
        type: IntegerMapper
        start: 1
        end: 5000
      tag-name:
        type: PersistedAliasMapper
        tableName: tx_news_domain_model_tag
        routeFieldName: slug
  • (未经测试)因为 IntegerMapper 似乎是一个自定义方面实现 - 不适用于 public