对于tx_news记录的详细页面以及我自己编写的日历扩展,我希望在URL中记录日期,直到具有realURL扩展名的TYPO3 8LTS:/path-to/my-page/yyyy/mm/dd/extension-record-path-segment/
。我设法创建了链接,但附加了cHash。
我在/typo3conf/sites/my-site/config.yaml
中的tx_news_pi1的routeEnhancers设置如下:
routeEnhancers:
NewsPlugin:
type: Extbase
limitToPages: [7]
extension: News
plugin: Pi1
routes:
- { routePath: '/{year}/{month}/{day}/{news}', _controller: 'News::detail' }
defaultController: 'News::detail'
requirements:
year: '^20[0-9]{2}$'
month: '^[01][0-9]$'
day: '^[0-3][0-9]$'
aspects:
news:
type: PersistedAliasMapper
tableName: 'tx_news_domain_model_news'
routeFieldName: 'path_segment'
我添加了requirements
部分有非常严格的正则表达式,因为description in the T3 changelog提到这是为了避免cHash。
我也尝试在StaticRangeMappers
部分使用aspects
一年,一个月和一天(as described in this answer),但这导致PersistedAliasMapper
被忽略并显示新闻记录的UID。或者有时甚至在TYPO3异常(1/1)#1537696772溢出异常:所有映射器的可能范围大于10000个项目(当我每月和每天删除它们并将年份范围设置为仅2016-2019时甚至这样做)。
year:
type: StaticRangeMapper
start: '2016'
end: '2100'
month:
type: StaticRangeMapper
start: '01'
end: '12'
day:
type: StaticRangeMapper
start: '01'
end: '31'
event:
type: PersistedAliasMapper
tableName: 'tx_thesimplecal_domain_model_events'
routeFieldName: 'path_segment'
编辑:我已经更新了这篇文章,因为神奇的一些原先提到的错误消失了。
新路由的整个概念现在有点不同:-)
基本上,现在的想法是,为某个记录创建一个slug并将其存储在数据库中,而不是在请求时创建/解析字符串。这也是使用v9中的路径和页面完成的,只需查看slug
表中的pages
字段即可。
因此,现在后端有一种新型的TCA字段,称为slug。您可以将其配置为从多个数据库字段创建。提示:请注意,编辑器需要对您希望生成slug的所有字段具有写权限。有a bug与readonly
领域,所以记住这一点!如果该字段然后正确存储在数据库中,您可以使用以下路由:
routeEnhancers:
News:
type: Extbase
limitToPages:
- <YOUR-DETAIL-PID-HERE>
extension: <YOUR-EXTENSION-NAME>
plugin: <YOUR-PLUGIN-NAME>
routes:
-
routePath: '/{news_title}'
_controller: 'News::show'
_arguments:
offer_title: news
defaultController: 'News::show'
aspects:
news_title:
type: PersistedAliasMapper
tableName: <YOUR-TABLE-NAME>
routeFieldName: slug
routeValuePrefix: ''
所有其他花哨的mappers都是非常特殊的情况。
这个问题的原因是月份是带有前导零的字符串,但是StaticRangeMapper构建范围而没有前导0并且没有像01那样映射月份。映射会在一个值无法映射时立即停止,现在是uid新闻记录未映射,因为这将在月份映射后发生。
一个简单的解决方案是编写一个StaticMonthMapper
class StaticMonthMapper implements StaticMappableAspectInterface, \Countable
{
/**
* @var array
*/
protected $settings;
/**
* @param array $settings
* @throws \InvalidArgumentException
*/
public function __construct(array $settings)
{
$this->settings = $settings;
}
/**
* {@inheritdoc}
*/
public function count(): int
{
return 12;
}
/**
* {@inheritdoc}
*/
public function generate(string $value): ?string
{
return $this->respondWhenInRange($value);
}
/**
* {@inheritdoc}
*/
public function resolve(string $value): ?string
{
return $this->respondWhenInRange($value);
}
/**
* @param string $value
* @return string|null
*/
protected function respondWhenInRange(string $value): ?string
{
switch ($value) {
case '01':
case '02':
case '03':
case '04':
case '05':
case '06':
case '07':
case '08':
case '09':
case '10':
case '11':
case '12':
return $value;
default:
return null;
}
}
}
并注册
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['StaticMonthMapper'] = \Package\Namespace\StaticMonthMapper::class;
这可以在站点配置中使用。对于days参数,可以创建类似的映射器。
year:
type: StaticRangeMapper
start: '2016'
end: '2100'
month:
type: StaticMonthMapper