basz / slmlocale Goto Github PK
View Code? Open in Web Editor NEWAuto detection of locale through different strategies for Zend Framework 2
License: Other
Auto detection of locale through different strategies for Zend Framework 2
License: Other
I've got an error trying to install the module with composer even I've followed the instruction step by step.
"The requested package slm/locale dev-master could not be found"
Is it possible to not alter the URI path if a host is matched?
f.e. If you have the following domains:
domain.com
domain.de
I need two things:
I think that there needs to be some way of indicating the "primary" domain when using the URI path strategy. The path segment will then only be added if you're on that primary domain (.com in this case).
Hi Jurian,
I have two domains: ferienhaussizilien.de and ferienhaussizilien.com and want to use the HostStrategy.
My SlmLocale config look's like this:
'default' => 'de-DE',
'supported' => ['de', 'en', 'de-DE', 'en-GB', 'en-US'],
'aliases' => ['de' => 'de-DE', 'en' => 'en-GB'],
'strategies' => [
[
'name' => 'SlmLocale\Strategy\HostStrategy',
'options' => [
'domain' => 'ferienhaussizilien.:locale',
'aliases' => ['de' => 'de-DE', 'com' => 'en-GB', 'trunk' => 'de-DE', 'trunk-en' => 'en-GB'],
],
'priority' => 1
],
[
'name' => 'SlmLocale\Strategy\HttpAcceptLanguageStrategy',
'priority' => 0.6
],
],
trunk and trunk-en is for local testing.
But everytime I open ferienhaussizilien.trunk it forwards me to ferienhaussizilien.de-de
I tried this last night in production environment, because I thougt only real TLD's are working, but that's not the problem.
If I delete the HostStrategy and switch only the default language, it works perfectly.
Could you explain this behaviour to me and show me a way how it works?
When using SlmLocale with the strategy "uripath", the module ZfTable (https://github.com/dudapiotr/ZfTable) is not working anymore. (Issue: dudapiotr/ZfTable#57)
I believe that the issue is due to the fact that the strategy add the locale in the URL and the Ajax requests of the module ZfTable do not know how to handle it.
Is there a way to deactivate dynamically the strategy in a controller to avoid the addition of the locale in the URL?
Has anyone tried to work with both these modules at the same time?
Hi!
After a while, I'm back on making this lib compatible with ZF3, and I was wondering if there would be anyone against dropping support for any unsupported php version (so > 5.6 only would be supported).
It make sense in a way as they are unsupported, and would allow using some of the new features (I personnaly love the ::class
syntax...)
@basz I see you everything merging to master not always this is good thing
I have created new release yesterday and packagist did not added it even master tag did not updated. @basz can you check whats wrong? I don't have access to packagist maybe this is because URL changed?
Have an option to set the Content-Language
in the response:
$response->getHeaders()->addHeaderLine('Content-Language', 'da');
I known the delimiter is not defined as _ or - explicite! BTW always I get only "_" fe:
php -r 'var_dump(\Locale::getDefault());'
returns a string "en_US"
hm!? pls explain to get right way for me. thx
I'm currently using a route 'locale' with everything else as a child route and I created a ViewHelper which returns 'locale' from the RouteMatch so I can do stuff in my view like:
<html class="<?php echo $this->locale() ?>">
For making CSS overrides for particular languages. like:
.en menu {
font-size: 12px;
}
.de menu {
font-size: 13px;
}
I see that some initial ViewHelpers were created to assemble a route with the locale but can't see anything for printing the locale into the View. Thought I'd ask what you think to this as I was expecting this to be one of the first things added.
Looking through your code I see the locale is stored within LocaleEvent so I guess I would have to listen for that and then populate it there.
Please advise and I'll create a pull-request for it as would like to replace my current child-route solution with your module.
Hi,
I have i little problem about using translator object.
At the layout, I have set the lang
parameter like that:
<html lang="<?php echo Locale::getPrimaryLanguage(Locale::getDefault())?>">
And it work, when i looking at source i see:
<html lang="fr">
That is my slmlocale.global.php
$settings = array(
'default' => 'fr',
'supported' => array('fr', 'en'),
'aliases' => array(
'fr-FR' => 'fr',
'en-US' => 'en',
),
'strategies' => array('uripath', 'acceptlanguage'),
);
return array(
'slm_locale' => $settings
);
And that is an extract of my module.config.php
'translator' => array(
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
However when i use $this->translate("A 404 error occurred");
, the string is not translated.
I'm attempting to create unit tests for my application which makes use of SlmLocale UriPathStrategy and am having issues with testing controller dispatches like so:
public function testLoginActionCanBeAccessed()
{
$this->dispatch('/en/account/login');
$this->assertResponseStatusCode(200);
}
This returns 302 and when I dump the RequestURI within UriPathStrategy, I'm getting the following twice:
class Zend\Uri\Http#819 (10) {
protected $validHostTypes => int(19)
protected $user => NULL
protected $password => NULL
protected $scheme => string(4) "http"
protected $userInfo => NULL
protected $host => NULL
protected $port => NULL
protected $path => string(1) "/"
protected $query => NULL
protected $fragment => NULL
}
Whereas when I dump the RequestURI from a typical request via my browser:
object(Zend\Uri\Http)[210]
protected 'validHostTypes' => int 19
protected 'user' => null
protected 'password' => null
protected 'scheme' => string 'http' (length=4)
protected 'userInfo' => null
protected 'host' => string 'konoro.dev' (length=16)
protected 'port' => null
protected 'path' => string '/en/' (length=4)
protected 'query' => string '' (length=0)
protected 'fragment' => null
From what I've been reading in the code, it looks like the only time detection is done (and redirection) is onBootstrap of the Module. So the unit test defaults to / without a locale and every other dispatch uses the same requestUri and it needs to redirect to /en/ with them all.
Are you doing anything in particular when testing your stuff or does there need to be some change so the detection is done onDispatch() instead?
Thanks, Dom
Is it possible to not redirect if the matched locale is the default?
For example, if the default locale is "en", stay at "/" instead of redirecting to "/en/".
Unless this is not recommended for some reason?
I want it to not matter what strategies you have registered. The helper should figure out if it can generate a localized link... Either by domain/path/query whichever comes first. That would be ideal for helper widgets that generate links.
@juriansluiman suggested the following
$this->localeUri($locale, $router, $options, $params);
To which i theorized a little...
where $locale is the locale you want to get the uri for and the other arguments are used to get a uri from the router
=== problem for 1
How do I find the strategy that is responsible for detection on the current request? It seems a task for the Detector Service. But it seems it is capable of knowing which listener returned is_string($r).
=== possible solution
add a property 'localeDetectedByStrategy' to the Event object
just before a strategy returning a locale string set that property to fqcn
this can then be read later from the Event
making that change in AbstractStrategy seems doable.
$this->listeners[] = $events->attach(LocaleEvent::EVENT_DETECT, array($this, '_detect'), $priority);
public function _detect(LocaleEvent $event)
{
$locale = $this->detect($event);
if (is_string($locale)) {
$event->setLocaleDetectedByStrategy(get_class($this));
return $locale;
}
}
Or Investigate
Event Handling more in-depth... Perhaps there is an other way to move this out of the Strategies.
So at this point the detector service could store the event? or just the property so the view helper can query that when needed.
=== problem for 2
How would a Strategy Advertise it knows how to modify the uri?
=== suggested solution
Capable Strategies implement an interface. Perhaps ...
interface AssemblyCapableInterface {
public function assemble($locale, $uri);
}
Got fatal error if using console commands:
PHP Fatal error: Uncaught TypeError: Argument 1 passed to SlmLocale\Strategy\UriPathStrategy::__construct() must be an instance of Zend\Mvc\Router\Http\TreeRouteStack or null, instance of Zend\Mvc\Router\Console\SimpleRouteStack given, called in ..../vendor/slm/locale/src/SlmLocale/Strategy/Factory/UriPathStrategyFactory.php on line 68 and defined in ..../vendor/slm/locale/src/SlmLocale/Strategy/UriPathStrategy.php:62
Can we disable strategies depending on ConsoleRequest vs. normal HttpRequest? How to deal with it?
There is a misprint in Module.php on line 84
"SlmLocale\Strategy\UriPathStrategy" is written as "SlmLocale\Strategy\UtiPathStrategy" twice
Warning: Invalid argument supplied for foreach() in SlmLocale\Strategy\HostStrategy.php on line 166
Use:
protected $aliases = array();
Then, tries to redirect to "http://domain./de/" because there is no alias (which shouldn't be required).
This code:
if (!$this->redirectToCanonical()) {
$locale = $this->getAliasForLocale($locale);
}
Should be something like this (untested):
if (!$this->redirectToCanonical() && ($alias = array_search($locale, $this->aliases, true)) !== false) {
$locale = $alias;
}
getAliasForLocale() is not required unless I'm missing something.
I'm not sure what this does. :-)
First off, thanks a lot basz for the work you've put into this code, the UriPathStrategy is exactly what I need for some SEO optimization.
Unfortunately, when I added in the 'uripath'
option to my strategies, I get the following error:
Uncaught Error: Call to a member function getServiceLocator() on null in /var/www/xxxxxxxx/vendor/slm/locale/src/SlmLocale/Strategy/UriPathStrategy.php:99
I am using slm/locale 0.2.0, zend-mvc 2.7.12, zend-servicemanager 2.7.8. Taking out the 'uripath'
strategy from my config, the app runs fine.
Here is my full slm_locale config:
'slm_locale' => [
'default' => 'en-US',
'supported' => ['en_US', 'es_ES', 'de_DE', 'pt_BR'],
'strategies' => ['query', 'uripath', 'cookie', 'acceptlanguage'],
'mappings' => [
'en' => 'en_US',
'es' => 'es_ES',
'pt' => 'pt_BR',
'de' => 'de_DE',
]
],
Along with SlmLocale I am using zf-commons/zfc-user, bjyoungblood/bjy-authorize and goalio/goalio-rememberme.
In Slm/Locale you set it to require a zf2 version below 2.3.x-dev, but i want to use that version, since i'm using apigility and its required by apigility and doctrine-module. Can you update your dependencies?
Thanks in advance,
I did a composer update and have right now again the version 0.0.1.
"slm/locale": "dev-master",
Where are the tags gone with the versions above 1.* ? I can find in the master branch only old versions. -_-
Is there a specific reason why SlmLocale requires zf2 >=2.1,<2.3?
Asking cause zf2 2.3 is about to be released...
The ZF3 Service manager and Event manager are finally out.
The ServiceLocatorAwareInterface has been removed and it is currenlty used in SlmLocale/Strategy/UriPathStrategy.php
First of all thanks for your module jurians!
I have implemented it by this simple configuration:
'slm_locale' => array(
'default' => 'en-US',
'supported' => array('en-US','it-IT','es-419'),
'strategies' => array(
array(
'name' => 'uripath',
'options' => array(
'redirect_when_found' => true,
'redirect_to_canonical' => false,
'aliases' => array('en' => 'en-US','es' => 'es-ES','es' => 'es-419','it' => 'it-IT'),
),
),
'acceptlanguage',
),
),
Then when I try to call the homepage http://www.mysite.com/ I get a 404 for the assets:
"NetworkError: 404 Not Found - http://www.site.com/it/css/homepage.css"
"NetworkError: 404 Not Found - http://www.site.com/it/js/application.js"
"NetworkError: 404 Not Found - http://www.site.com/it/css/application.css"
"NetworkError: 404 Not Found - http://www.site.com/it/js/application.js"
With this new configuration I get another strange behaviour: http://www.site.com/ returns a 404 error but the path of the assets is correct.
'slm_locale' => array(
'default' => 'en-US',
'supported' => array('en-US','it-IT','es-419'),
'strategies' => array(
array(
'name' => 'uripath',
'options' => array(
'redirect_when_found' => false,
'redirect_to_canonical' => false,
'aliases' => array('en' => 'en-US','es' => 'es-ES','es' => 'es-419','it' => 'it-IT'),
),
),
'acceptlanguage',
),
),
In both cases if I call an ajax request to http://www.site.com/events/index/savecoords I get a 404 error.
Any hint? Is this a bug?
Regards
Currently, it just replaces the existing locale. This is by far the best method and should be using similar methods as in detect and found.
In my case, I needed two host
strategies. The domain
could vary according to locale
.
So I tried to set up, two host
strategies with different parameters.
But when the strategies was added, the second one overlapped the first one. That's because strategy is pull from strategy plugin manager which gives you a reference to the object, not a new one.
ZF SetCookie now adds quotes around set locale. So "nl_NL" is not in the list of allowedLocales and the fallback is always chosen.
Not sure if ZF will fix this or if we should.
Fatal error: Cannot declare class SlmLocale\Strategy\Exception\InvalidArgumentException because the name is already in use in ...\vendor\slm\locale\src\SlmLocale\Strategy\Exception\InvalidArgumentException.php on line 48
At the moment, the module can't be installed while running PHP v8.0.0 or greater.
[InvalidArgumentException]
Package slm/locale at version 0.5.0 has requirements incompatible with your PHP version, PHP extensions and Composer version:
- slm/locale v0.5.0 requires php ^7.2 which does not match your installed version 8.0.20.
Is there any plan to support newer PHP versions?
Host names must change their part in the domain name, now it's not implemented.
if (strpos($domain, self::LOCALE_KEY)) {
Should be:
if (strpos($domain, self::LOCALE_KEY) === false) {
How can i render locales in a combobox. i use "$this->LocaleMenu()" this view helper but i want to show a combobox not ul list.
Config:
// SLM locale.
'slm_locale' => array(
'default' => 'en',
'supported' => array('en', 'de', 'ko'),
'strategies' => array(
'uripath',
'acceptlanguage'
)
)
Works:
de,de-DE;q=0.94,en-ZA;q=0.89,en;q=0.83,zh-CN;q=0.78,zh;q=0.72,en-GB;q=0.67,en-US;q=0.61,fr-FR;q=0.56,fr;q=0.5,es-ES;q=0.44,es;q=0.39,it-IT;q=0.33,it;q=0.28,nl-NL;q=0.22,nl;q=0.17,en-za;q=0.11,en-us;q=0.06
Doesn't:
de-DE,de;q=0.94,en-ZA;q=0.89,en;q=0.83,zh-CN;q=0.78,zh;q=0.72,en-GB;q=0.67,en-US;q=0.61,fr-FR;q=0.56,fr;q=0.5,es-ES;q=0.44,es;q=0.39,it-IT;q=0.33,it;q=0.28,nl-NL;q=0.22,nl;q=0.17,en-za;q=0.11,en-us;q=0.06
How do I make it so that "de-DE" maps to "de"? (and "en-XX" maps to "en", etc.)
$base = $this->getBasePath();
$found = $this->getFirstSegmentInPath($request->getUri(), $base);
esto no funciona devuelve un valor incorrecto parece que se ejecuta antes de que zf2 define el basepath
If you use the locale format from zend default install (ex: fr_FR, en_US,...), the HttpAcceptLanguage Strategy does not find the locale in the supported array.
With the following conf :
return array(
'slm_locale' => array(
'default' => 'es_ES',
'supported' => array('es_ES', 'en_US'),
'strategies' => array('acceptlanguage')
);
If the received Accept-Language header is for example :
"fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3"
the locale will be set to the default es_ES.
I think it should be set to en_US.
Hi there i'm using a localeResolver class with acceptLanguage strategy:
'localeResolver' => function ($sm) {
$service = new Service\LocaleResolver();
$service->resolveLocale($sm->get('request'));
return $service;
},
1 - How to use slmlocale instead ?
Moreover i'd like to detect locale from router (routeMatch) because first segment (lang) of uri is not mandatory and sometimes empty.
In that case i have to get lang by default that is set into route.
2 - Do you think is it correct or do i have to use UriPathStrategy ?
3 - What's the correct way to pass into url ? locale or language ?
I read somewhere that now the correct locale format is en_US_utf8 .
I that mean that i have to pass into url this stuff ?
http://myhost/en_US_utf8/...
It's not very clear for me.
The UriPath strategy redirects to a new alias without detecting a prior one. So if /en/my/path
is requested and the locale is changed to nl-NL (alias nl), the strategy redirects to /nl/en/my/path
instead of replacing "en" with "nl".
Hello, I enjoyed working on the UriPathStrategy yesterday and the discussion is stirred.
I was thinking about the routing problems that I encountered yesterday when combining this module with AssetManager.
Even though personally I would prefer pre-routing asset checking, SlmLocale's should not rely on such behavior - and the fact is the current implementation updated the baseurl of the router to have existing routes localized for every request. This may not be desired behavior.
An application developer would like to have to define what exactly which routes are localized and which are not - the dynamic assets example is just one manifestation. Having paths of my project that aren't localized at all would be another...
So perhaps we should take this as a queue that there is some deeper problem with messing with the router the way SlmLocale/UriPathStrategy does.
Intuitively it feels to me that the UriPathStrategy can still be used as a detection meganism - but that - since SlmLocale is planned for ZF2 integration anyway - anything to do with localized routes should be handled by the router itself. That would then include the HostStrategy and perhaps other.
Unfortunately I am too unfamiliar with the Router process to be authoritative here -but intuitively it feels to me that anything to do with routing should in fact be handled by the router. If that means that changes should be made to the the router a special route or plugin or whatever so be it.
How to do this I leave up to smarter people :-)
thanks
As a reminder, a few things must be addressed first during refactoring
Then:
I am using composer.phar to install the module as described in your documentation but I get this error:
"slm/locale": ">=0.1.0,<1.2.0-dev",
Problem 1
- The requested package slm/locale could not be found in any version, there may be a typo in the package name.
I followed your instructions, but I get ServiceNotFoundException, when I insert
'strategies' => array('uripath', 'acceptlanguage'),
Tested with ZF 2.2.6 and ZF 2.3.
Fatal error: Uncaught exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for uripath' in /mnt/hgfs/www/sicily-holidays.eu/trunk/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:526 Stack trace: #0 /mnt/hgfs/www/sicily-holidays.eu/trunk/vendor/slm/locale/src/SlmLocale/Service/DetectorFactory.php(90): Zend\ServiceManager\ServiceManager->get('uripath') #1 /mnt/hgfs/www/sicily-holidays.eu/trunk/vendor/slm/locale/src/SlmLocale/Service/DetectorFactory.php(65): SlmLocale\Service\DetectorFactory->addStrategies(Object(SlmLocale\Locale\Detector), Array, Object(Zend\ServiceManager\ServiceManager)) #2 [internal function]: SlmLocale\Service\DetectorFactory->createService(Object(Zend\ServiceManager\ServiceManager), 'slmlocalelocale...', 'SlmLocale\Local...') #3 /mnt/hgfs/www/sicily-holidays.eu/trunk/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(905): call_us in /mnt/hgfs/www/sicily-holidays.eu/trunk/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php on line 526
I'm still able to reproduce the issue you described in issue #32.
I will follow up with a pull request.
because.. also would be nice to see what's not tested
How could i switch local, example via url or POST Action?
via route?
array(
'label' => 'German',
'route' => 'home',
'locale'=>'de'
),
array(
'label' => 'English',
'route' => 'home',
'locale'=>'en'
),
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.