これが私が達成しようとしていることです:
私は2言語(en、fr)の多言語サイトを持っていますが、4つのiso_codes(us、gb、fr、be)も持っています。
Drupalは、たとえば/ usや/ gbが/ enのエイリアスであることを理解するために必要です(これらはまったく同じコンテンツを共有します)。
プログラムまたはモジュールでそれを達成する方法があるかどうか知っていますか?
私は現在、 setPath on the go: RouteCollection とKernelEvents :: Requestの2つのイベントサブスクライバーを調べていますが、今のところ結果はありません。
どんな助けでも大歓迎です。
PathProcessorサービスを使用して、やりたいことを実現できました。
Here is my services.yml
mymodule.path_processor:
class: Drupal\mymodule\PathProcessor\PathProcessor
arguments: ['@language_manager', '@config.factory', '@path.alias_manager']
tags:
- { name: path_processor_inbound, priority: 200 }
そして、私のPathProcessor.phpクラスの私のコード:
/**
* Processes the inbound path using path alias lookups.
*/
class PathProcessorCustom implements InboundPathProcessorInterface, OutboundPathProcessorInterface {
protected $language_manager;
protected $configFactory;
protected $aliasManager;
public function __construct(LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory, AliasManagerInterface $alias_manager) {
$this->languageManager = $language_manager;
$this->configFactory = $config_factory;
$this->aliasManager = $alias_manager;
}
public function processInbound($path, Request $request) {
if (!strpos($path, '/admin/')) {
$path = $this->removeISOCode($path);
}
return $path;
}
public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
if (!strpos($path, '/admin/')) {
$path = $this->insertISOCode($path);
}
return $path;
}
protected function removeISOCode($path) {
$langcode = $this->languageManager->getDefaultLanguage()->getId();
$isocodes = $this->getISOCodeMapping();
$path_items = explode('/', $path);
if (isset($path_items[1]) && strlen($path_items[1]) == 2 && in_array($path_items[1], $isocodes[$langcode])) {
$config_negotiation_url = $this->configFactory->get('language.negotiation')->get('url');
if (!in_array($path_items[1], $config_negotiation_url['prefixes'])) {
array_splice($path_items, 1, 1);
if (count($path_items) == 1) {
$config_system_site = $this->configFactory->get('system.site')->get('page');
$path = $config_system_site['front'];
}
else {
$path = implode('/', $path_items);
$path = $this->aliasManager->getPathByAlias($path, 'en');
}
}
}
return $path;
}
protected function insertISOCode($path) {
$path_items = explode('/', $path);
if (isset($path_items[1]) && strlen($path_items[1]) == 2 && $path_items[1] == 'gb') {
$config_negotiation_url = $this->configFactory->get('language.negotiation')->get('url');
if(!in_array($path_items[1], $config_negotiation_url['prefixes'])) {
$path_items[1] = $language;
}
}
$path = implode('/', $path_items);
return $path;
}
protected function getISOCodeMapping() {
return [
'en' => ['gb', 'us'],
'fr' => ['fr', 'be']
];
}
}
私が行うことは、URLを分解し、不要だとわかっているものを削除し、URLを実際のコンテンツURLにマップすることです。それ以外の場合は、デフォルトの404にリダイレクトします。