Skip to content

Instantly share code, notes, and snippets.

@bwaidelich
Last active August 31, 2018 13:04
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bwaidelich/03efc03f5bc1c87a3ae6 to your computer and use it in GitHub Desktop.
Save bwaidelich/03efc03f5bc1c87a3ae6 to your computer and use it in GitHub Desktop.
A TYPO3 Flow HTTP component that detects the user agent language and redirects to the corresponding URL if no language has been requested explicitly.
<?php
namespace Wwwision\Test\Http;
/* *
* This script belongs to the TYPO3 Flow package "Wwwision.Test". *
* *
* */
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Http\Component\ComponentChain;
use TYPO3\Flow\Http\Component\ComponentContext;
use TYPO3\Flow\Http\Component\ComponentInterface;
use TYPO3\Flow\I18n\Detector;
use TYPO3\Flow\I18n\Locale;
use TYPO3\Neos\Domain\Service\ContentDimensionPresetSourceInterface;
/**
* A HTTP component that detects the user agent language and redirects to a corresponding section
*/
class DetectLanguageComponent implements ComponentInterface {
/**
* @Flow\Inject
* @var Detector
*/
protected $localeDetector;
/**
* @Flow\Inject
* @var ContentDimensionPresetSourceInterface
*/
protected $contentDimensionPresetSource;
/**
* @var array
*/
protected $options;
/**
* @param array $options The component options
*/
public function __construct(array $options = array()) {
$this->options = $options;
}
/**
* @param ComponentContext $componentContext
* @return void
*/
public function handle(ComponentContext $componentContext) {
$httpRequest = $componentContext->getHttpRequest();
$requestPath = $httpRequest->getUri()->getPath();
$firstRequestPathSegment = explode('/', ltrim($requestPath, '/'))[0];
if (in_array($firstRequestPathSegment, $this->options['ignoreSegments'])) {
return;
}
$preset = $this->contentDimensionPresetSource->findPresetByUriSegment('language', $firstRequestPathSegment);
// first request path segment corresponds to a valid language preset -> no need to redirect
if ($preset !== NULL) {
return;
}
$detectedLocale = $this->localeDetector->detectLocaleFromHttpHeader($httpRequest->getHeader('Accept-Language'));
if (!$detectedLocale instanceof Locale) {
return;
}
$uri = $httpRequest->getUri();
$uri->setPath('/' . $detectedLocale->getLanguage() . $requestPath);
$httpResponse = $componentContext->getHttpResponse();
$httpResponse->setContent(sprintf('<html><head><meta http-equiv="refresh" content="0;url=%s"/></head></html>', htmlentities((string)$uri, ENT_QUOTES, 'utf-8')));
$httpResponse->setStatus(303);
$httpResponse->setHeader('Location', (string)$uri);
$componentContext->setParameter(ComponentChain::class, 'cancel', TRUE);
}
}
TYPO3:
Flow:
http:
chain:
'preprocess':
chain:
'detectLanguage':
component: 'Wwwision\Test\Http\DetectLanguageComponent'
componentOptions:
ignoreSegments: ['', 'neos']
@hlubek
Copy link

hlubek commented Jul 8, 2015

I would suggest to match the languages from Accept-Language against the configured dimension presets (which have to follow some convention or need an additional localeIdentifier), that's safer because not every locale will be available as a language preset in most systems.

@pankajlele
Copy link

How much this affects the site SEO?

@pankajlele
Copy link

Please have a look at my fork:
Added ignorePattern instead of ignoreSegments. Also handled to not redirect if no preset exists for detected language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment