$_Cookie voor geselecteerde taal
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
$lang = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
}
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
}
Met andere woorden als $_Cookie{"language"] bestaat (nl, en, de) dan dient de uitgangs- taal (bij een tweede bezoek) de waarde van het Cookie te zijn (www.website.com/de/ of een van de andere twee), bestaat het Cookie nog niet zet de taal dan op Nederlands (www.website.com/nl/).
In de navigatie wil ik graag een taal dropdown hebben waar de Cookie taal de link voor de dropdown is:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' ): ?>
<li class="nav-item dropdown">
<a id"languageDropdown" class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">
<img src="/images/flaggs/nl.png"> Nederlands
</a>
<div class="dropdown-menu" aria-labelledby="languageDropdown">
<a href="/en<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/uk.png"> English
</a>
<a href="/de<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/de.png"> Deutsch
</a>
</div>
</li>
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'en'): ?>
// Zelfde als boven met Engels als uitgangs taal
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'de'): ?>
// Zelfde als boven met Duits als uitgangs taal
<?php endif; ?>
<li class="nav-item dropdown">
<a id"languageDropdown" class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">
<img src="/images/flaggs/nl.png"> Nederlands
</a>
<div class="dropdown-menu" aria-labelledby="languageDropdown">
<a href="/en<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/uk.png"> English
</a>
<a href="/de<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/de.png"> Deutsch
</a>
</div>
</li>
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'en'): ?>
// Zelfde als boven met Engels als uitgangs taal
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'de'): ?>
// Zelfde als boven met Duits als uitgangs taal
<?php endif; ?>
Ik kom er alleen niet uit op welk moment en waar ik het best het Cookie kan zetten. Zit me nu al een uur of wat rot te tobben. Iedere hulp zou ik zeer op prijs stellen.
Toevoeging op 30/09/2018 18:11:46:
Ik heb dit op de volgende wijze opgelost:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
$lang = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
} else {
$lang = (string)$lang;
setcookie( 'language', $lang, time() + 60*60*24*365, '/' );
}
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
} else {
$lang = (string)$lang;
setcookie( 'language', $lang, time() + 60*60*24*365, '/' );
}
En dat werkt prima. Het enige probleem dat ik nu nog ondervind is de content voor de dropdown niet wijzigd, althans niet met gebruik van de header("Location") Als iemand bijvoorbeeld Engels kies veranderd de waarde van het Cookie naar en maar de nederlandse vlag met bijbehorende tekst blijven staan.
Als ik daarna de pagina handmatig ververs veranderd de content wel naar de engelse versie:
Hoe zou ik dit kunnen oplossen? Alvast bedankt
Gewijzigd op 30/09/2018 10:11:38 door Donald Boers
Achter zo'n header moet trouwens nog steeds een exit-statement, want het instellen van een Location header transporteert je niet direct naar de nieuwe locatie (interne link).
En dan moet je wellicht nog rekening houden met dat geneuzel dat de gebruiker expliciet moet instemmen met het gebruik van cookies om je site fatsoenlijk te laten werken.
Thomas van den Heuvel op 30/09/2018 21:11:02:
In je controller, voordat je een header verstuurt?
Wat bedoel je precies met het bovenstaande?
Thomas van den Heuvel op 30/09/2018 21:11:02:
Achter zo'n header moet trouwens nog steeds een exit-statement, want het instellen van een Location header transporteert je niet direct naar de nieuwe locatie (interne link).
Bedankt voor je opmerkzaamheid. Ik heb het meteen aangepast!
Thomas van den Heuvel op 30/09/2018 21:11:02:
En dan moet je wellicht nog rekening houden met dat geneuzel dat de gebruiker expliciet moet instemmen met het gebruik van cookies om je site fatsoenlijk te laten werken.
Wanneer dit op een andere/betere manier opgelost zou kunnen worden, sta ik open voor iedere suggestie. Hoe zou jij dit dan aanpaggen
Gewijzigd op 01/10/2018 10:53:45 door Donald Boers
je bent bekend met het MVC-pattern?
Gewijzigd op 01/10/2018 11:30:49 door Donald Boers
Stel dat de taal niet bekend is. Je moet dan een taal als standaard taal nemen en deze opslaan in
a) een variabele ergens in je applicatie en op zo een manier dat je er overal gemakkelijk bij kunt komen. (Je gebruikt elders in je applicatie niet meer rechtstreeks je $_COOKIE['language'] maar gebruikt een eigen variabele, bijvoorbeeld $language). en
b) moet je een COOKIE meesturen in de header van je response, dus de "pagina" die je terug gaat sturen naar de browser.
Als de taal wel bekend is (Je hebt een cookie meegestuurd gekregen in de REQUEST) dan stel je eveneens de taal in een variabele ergens in je applicatie. Het verschil is echter dat het nu de voorkeurstaal van de gebruiker is in plaats van de default-taal die jij zelf ingesteld hebt. Er hoeft nu geen nieuw cookie verstuurd te worden want de gebruiker heeft die al. (ga er van uit dat je hem een lange geldigheidsduur geeft).
Vervolgens kun je overal dus bijvoorbeeld in je controller, je menu-builder en in je view de $language variabele raadplegen. Dit betekend dus ook dat je bij voorkeur deze variabele al geïnitialiseerd hebt voordat je controller wordt geraadpleegd of misschien uiterlijk in de constructor van je baseController class.
Indien bovenstaande niet duidelijk is laat dan even weten hoe je controller class er uit ziet en of deze van een base class extended wordt.
Gewijzigd op 01/10/2018 13:15:23 door Frank Nietbelangrijk
Gebruik je een bestaand framework? Vaak hebben deze de beschikking over 'auto loaders', en daar zou dit prima in passen.
Frank Nietbelangrijk op 01/10/2018 13:12:33:
Het lijkt me dat je het wat "centraler" zou moeten regelen Donald. Je zou niet in elke functie van je controller jezelf moeten bezighouden met welke taal er nu gebruikt moet worden. Ik heb geen idee welk framework je gebruikt en al zou ik dat hebben dan ben ik er wellicht niet bekend mee dus ik probeer je de goede richting in te duwen.
@Frank Nietbelangrijk. Lang niet gehoord. Het is geen bestaand Framewerk, maar een samengesteld. Het taal gebeuren vind niet echt plaats in elke functie van een Controller. Ik heb een file (Bootstrap.php) wat ik include in index.php. In dit document worden zaken zoals autoloader, PATH en routes gedefinieerd Voor de goede orde. Dit is wat er dit document staat:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
error_reporting(E_ALL);
ini_set('display_errors', 1);
define('APP_PATH', realpath(__DIR__.'/../'));
session_start();
$lang = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
exit;
} else {
$lang = (string)$lang;
setcookie( 'language', $lang, time() + 60*60*24*365, '/' );
}
require_once 'autoloader.php';
require_once APP_PATH . '/lib/password.php';
require_once APP_PATH . '/lib/i18n.class.php';
require_once APP_PATH . '/lib/AltoRouter.php';
Config::setDirectory(APP_PATH.'/config');
View::setDirectory(APP_PATH.'/templates');
$router = new Router();
$router->dispatch('/'.$route);
ini_set('display_errors', 1);
define('APP_PATH', realpath(__DIR__.'/../'));
session_start();
$lang = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');
if ( !$lang ) {
if ( isset($_COOKIE["language"]) ) {
$lang = $_COOKIE["language"];
} else {
$lang = 'nl';
}
header("Location: /$lang/$route");
exit;
} else {
$lang = (string)$lang;
setcookie( 'language', $lang, time() + 60*60*24*365, '/' );
}
require_once 'autoloader.php';
require_once APP_PATH . '/lib/password.php';
require_once APP_PATH . '/lib/i18n.class.php';
require_once APP_PATH . '/lib/AltoRouter.php';
Config::setDirectory(APP_PATH.'/config');
View::setDirectory(APP_PATH.'/templates');
$router = new Router();
$router->dispatch('/'.$route);
Daarnaast heb ik een main Controller waarin zaken zoals de navigatie geregeld worden. Ik heb werkelijk geen idee wat in dit geval de beste aanpak zou kunnen zijn
Toevoeging op 01/10/2018 13:35:22:
@- Ariën - Dit staat niet in elke Controller. Dit staat alleen in het document wat ik in index.php include:
Gewijzigd op 01/10/2018 13:32:36 door Donald Boers
http://php.net/manual/en/language.oop5.autoload.php
Je Language-systeem kan je ook dan tot een Language-class verpakken.
Gewijzigd op 01/10/2018 13:43:02 door - Ariën -
- Ariën - op 01/10/2018 13:42:03:
Een auto-loader zou dan makkelijker zijn. Dan hoef je eigenlijk niet steeds meer alles zelf te includeren ;-)
http://php.net/manual/en/language.oop5.autoload.php
Je Language-systeem kan je ook dan tot een Language-class verpakken.
http://php.net/manual/en/language.oop5.autoload.php
Je Language-systeem kan je ook dan tot een Language-class verpakken.
@- Ariën - Ik gebruik een auto-loader zoals ik in mijn antwoord aan @Frank reeds aangaf. Dit is mijn auto-loader:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
class LanguageManager
{
private static $defaultLanguage = 'nl'; // of haal deze uit de configuratie
private static $language;
public static function init()
{
/* checken of we een cookie hebben ontvangen */
if ( isset($_COOKIE["language"]) ) {
self::$language = $_COOKIE["language"];
/* anders dan maken we een taal nederlands en schrijven we een cookie weg */
} else {
self::setLanguage(self::$defaultLanguage);
}
}
public static function getLanguage()
{
return self::$language;
}
public static function setLanguage($language)
{
self::$language = $language;
setcookie( 'language', self::$language, time() + 60*60*24*365, '/' );
}
}
/* ergens in je applicatie voordat je met je controllerfuncties aan de gang gaat: */
LanguageManager::init();
/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)
/* welke taal moeten we hebben? */
echo LanguageManager::getLanguage();
?>
class LanguageManager
{
private static $defaultLanguage = 'nl'; // of haal deze uit de configuratie
private static $language;
public static function init()
{
/* checken of we een cookie hebben ontvangen */
if ( isset($_COOKIE["language"]) ) {
self::$language = $_COOKIE["language"];
/* anders dan maken we een taal nederlands en schrijven we een cookie weg */
} else {
self::setLanguage(self::$defaultLanguage);
}
}
public static function getLanguage()
{
return self::$language;
}
public static function setLanguage($language)
{
self::$language = $language;
setcookie( 'language', self::$language, time() + 60*60*24*365, '/' );
}
}
/* ergens in je applicatie voordat je met je controllerfuncties aan de gang gaat: */
LanguageManager::init();
/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)
/* welke taal moeten we hebben? */
echo LanguageManager::getLanguage();
?>
Frank Nietbelangrijk op 01/10/2018 14:00:11:
/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)
@Frank Nietbelangrijk. Ik heb de klas gemaakt en geinitieerd. als ik die echo geeft deze de juiste taal aan maar hoe verwerk ik dit in een dropdown?
Gewijzigd op 01/10/2018 22:38:03 door Donald Boers
Donald Boers op 01/10/2018 13:49:09:
@- Ariën - Ik gebruik een auto-loader zoals ik in mijn antwoord aan @Frank reeds aangaf. Dit is mijn auto-loader:
Heb je die functie wel eens gebenchmarkerd? Dit lijkt mij een extreem "dure" autoloader variant. De default implementatie van spl_autoload_register() is nagenoeg altijd het snelste en regelt alles eigenlijk al automatisch. Als de directorystructuur van de class-bestanden de naamgeving volgt dan werkt het eigenlijk al out-of-the-box.
Het enige wat je zou moeten doen is ergens een include path instellen waarin de classes staan. Sterker nog, hier kun je zelfs een volgorde in aanbrengen waarbij je bijvoorbeeld eerst een directory include voor alternatieve implementaties van "core" classes, en vervolgens de directory van de standaard implementaties. Dit zodat je af kunt wijken van standaard implementaties zonder de "core" functionaliteit aan te passen.
Dit is ook handig als je met externe libraries werkt waarin je waarschijnlijk beter niet zelf kunt gaan lopen modderen (en dat wordt ook een ramp als je die dingen versioned).
Donald Boers op 01/10/2018 14:05:24:
Maar op welk moment/waar roep ik deze Class aan?
Wanneer heb je de taal nodig?
Code (php)
1
2
3
4
5
2
3
4
5
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#">
<img src="/images/flaggs/nl.png"> Nederlands
</a>
</li>
<a class="nav-link dropdown-toggle" href="#">
<img src="/images/flaggs/nl.png"> Nederlands
</a>
</li>
Met in de dropdown de andere talen
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<div class="dropdown-menu dropdown-menu-right mt-0">
<a href="/en<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/uk.png"> English
</a>
// andere talen
</div>
<a href="/en<?php echo $current_route?>" class="dropdown-item">
<img src="/images/flaggs/uk.png"> English
</a>
// andere talen
</div>
Dus op het moment dat iemand op b.v. de engelse link klikt moet de li nav-item van nederlands in engels veranderen. Op zich werkt dit alleen als ik de pagina handmatig ververs
In je index.php doe je nu een setcookie(), maar in je template kijk je naar $_COOKIE["lang"] (die dus nog niet is bijgewerkt, dat zie de volgende call pas terug). Als je nu van regel 21 in index.php het volgende maakt:
Code (php)
1
2
2
setcookie( 'language', $_COOKIE["lang"] = $lang, time() + 60*60*24*365, '/' );
// ^^^^^^^^^^^^^^^^^^^ - dit toevoegen
// ^^^^^^^^^^^^^^^^^^^ - dit toevoegen
Werkt het dan wel zoals bedoeld?
Bonus: ipv regel 12 t/m 16 kun je tegenwoordig (PHP 7) ook:
Gewijzigd op 01/10/2018 19:59:39 door Rob Doemaarwat
Rob Doemaarwat op 01/10/2018 19:55:39:
Werkt het dan wel zoals bedoeld?
Nee helaas niet. Ik moet de pagina nog steeds handmatig verversen alvorens de actieve nav-item veranderd naar de nieuwe taal:(
Rob Doemaarwat op 01/10/2018 19:55:39:
Leuke bonus. Scheelt toch weer 4 regels code. Hartelijk bedankt.
- Dit klopt volgens mij niet:Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)
- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.
Rob Doemaarwat op 01/10/2018 22:17:12:
- Dit klopt volgens mij niet:Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)
Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)
Heb je helemaal gelijk in. Dat was inderdaad niet juist. Het werkte wel maar was ietwat omslachtig
Rob Doemaarwat op 01/10/2018 22:17:12:
- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.
$current_route is gedefinieerd in de Main Controller:
dat is de huidige pagina/template waarop een bezoeker zich bevindt als deze een ander taal kiest. Als ik bijvoorbeeld op www.website.com/nl/over ben dan is $_COOKIE["lang"] /nl/ en $current_route /over. Waneer ik vervolgens voor engels kies dan wordt $_COOKIE["lang"] /en/ en $current_route /about
Gewijzigd op 01/10/2018 22:41:53 door Donald Boers
Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.
Rob Doemaarwat op 01/10/2018 23:21:29:
Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.
@Rob Doemaarwat. Klein foutje van mijn kant. Is een enkele slash
de tweedeslash hoort bij de Route