ProcessWire - Multilanguage Website: Unterschied zwischen den Versionen
| Zeile 157: | Zeile 157: | ||
==== 4. Language Switcher ==== | ==== 4. Language Switcher ==== | ||
| − | + | Für Text Navigation z.B. so: | |
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
<?php namespace ProcessWire; | <?php namespace ProcessWire; | ||
| Zeile 173: | Zeile 173: | ||
$url = $page->localUrl($language); | $url = $page->localUrl($language); | ||
$hreflang = $pages->get('/')->getLanguageValue($language, 'name'); | $hreflang = $pages->get('/')->getLanguageValue($language, 'name'); | ||
| − | echo "<a hreflang='$hreflang' href='$url'>$language->title</a></li>"; | + | echo "<a hreflang='$hreflang' href='$url' style="text-transform:uppercase;">$language->title</a></li>"; |
echo "</li>"; | echo "</li>"; | ||
} | } | ||
Version vom 26. Februar 2020, 18:00 Uhr
Mehrsprachige Websites mit ProcessWire / Andere Default Sprache
Links
- https://processwire.com/talk/topic/5518-multi-language-site/
- http://processwire.com/api/multi-language-support/multi-language-urls/
- https://processwire.com/talk/topic/9322-change-default-language-for-homepage/ (Modul Solution, mehr zur Anschauung)
Einleitung
Es gibt mehrere Bereiche an die man denken muss. Einmal geht es um die Eingabe im Backend, die Ausgabe im Frontend, die Sprachnavigation auf der Website und die Templates:
- Wie übersetze ich Text in meinen Templates ? Siehe unten i18n
- Wie übersetze ich Inhalte im Backend ? Dafür ist das Modul Language Support Fields zuständig
- Wie sollen meine URLs aussehen ? Prinzipiell kann man jedem User unterschiedliche Sprachen auch ohne andere Domain liefern (über seine Session) aber i.d.R wollen wir die URL anzupassen.
- domain.de/en/meineSeite oder domain.de/myPage
- Um Seitennamen zu übersetzen oder ein Domainkürzel in der URL voranzustellen benötige ich das Modul Language Support Page Names
Welche Module benötige ich
Da es einige Module in diesem Zusammenhang gibt hier eine Übersicht. Man findet Sie am besten unter
Modules > Core > Language
- Languages Support - ProcessWire multi-language support. Basis Modul bracht man für alle Beispiele unten. Reicht aus, wenn man nur die Standard-Sprache ändern will.
- Languages Support - Fields Required to use multi-language fields. Basis für mehrsprachige Felder im Backend.
- Languages Support - Page Names (LanguageSupportPageNames) Required to use multi-language page names. Braucht man nur wenn alle Seiten in allen Sprachen unterschiedliche Namen bekommen sollen.
- Languages Support - Tabs Organizes multi-language fields into tabs for a cleaner easier to use interface.
Für mehrsprachige Seiten benötigen wir im Frontend i.d.R. folgende Module:
- Language Support Fields - Sind Felder, die im Backend für jede Sprache eine eigene Eingabe bieten.
- Language Support Page Names benötigt man, damit man für die Sprachen eigene URLs angeben kann. Z.B. bei Home in Englisch /en/ usw.
- FieldtypePageTitleLanguage benötigt man wenn man alle Seitenamen anpassen will (seite1_de seite1_fr ...) Für einen reinen Sprachpfad (/de/Seite) braucht man das nicht.
Einsprachige Seite aber Deutsch als Default Sprache
Wenn nur die Standardsprache verändern möchte, aber keine Mehrsprachige Seite benötigt brauchen wir nur das Modul Language Support
- Enable languages support -> Core Module "Language Support" aktivieren. -> Sprachen stehen num im Backend Setup zur Verfügung
- Titel der Default Sprache anpassen (z.B. Deutsch (default) )
- Language Pack in der default Sprache installieren -> Dies ist ab jetzt die Default Sprache. Nicht vergessen auch den lang Tag im Header zu setzen, damit der Browser die Sprache richtig erkennt.
Mehrere Sprachen
Für mehrsprachige Seiten benötigen wir i.d.R. folgende Module:
- Language Support Fields für die Backend Übersetzungen und Language Support Page Names für die URLs.
- FieldtypePageTitleLanguage benötigt man wenn man alle Seitenamen anpassen will (seite1_de seite1_fr ...) Für einen reinen Sprachpfad (/de/Seite) braucht man das nicht.
- Für weitere Sprachen entsprechend hinzufügen.
Vorgehen:
- Language Packs installieren: drop in the none english language pack (for admin backend) into the default language, (e.g. german langpack)
- As a nice sideeffect every new user in your system gets the native language per default without have it to select from the list.
Templates für Multilanguage vorbereiten (i18n)
https://processwire.com/docs/multi-language-support/code-i18n/ https://processwire.com/blog/posts/functional-fields/
Functional fields
In PW3 kamen die functional Fields hinzu. Mit diesen kann man statischen Text dynamisch im Page Editor ansprechen. D.h. das Functional Field findet Texte im Template und macht sie automatisch editierbar im Page Editor. Das Ganze funktioniert auch Mehrsprachig.
ProcessWire - Functional Fields https://processwire.com/blog/posts/functional-fields/
Beispiele für die Ausgabe von
__text('your text');
__textarea('your text');
__richtext('<p>your text</p>');
__text('Subscribe Now', 'subscribe') // define a identifier for this text snippet...
__text('subscribe') // ..reuse it this way
$pages->get('/')->mytext->subscribe // reuse from another template
__text('Subscribe Now', 'subscribe', 'Submit button'); // Label for page editor
__text('Subscribe Now', 'subscribe', 'label=Submit button, notes=Test'); // or use a pw selector
__text('Subscribe Now', 'name=subscribe, label=Submit button, notes=Test'); // equivalent to upper
=== Standard Multilanguage nach i18n ===
$out = $this->_("Live long and prosper"); // syntax within a class
$out = __("Live long and prosper!"); // syntax outside of a class
Dann im Backend unter der Sprache "Find files to translate" und die Template Datei auswählen.
=== Variablen in i18n ===
$out = sprintf(__("Created %d pages."), $count);
$out = sprintf(__('Your city is %1$s, and your zip code is %2$s.'), $city, $zipcode);
=== Plural in Multilanguage Files===
Hierzu gibt es die _n() Funktion
$out = sprintf(_n("Created %d page.", "Created %d pages.", $count), $count);
=== Unterschiedliche Übersetzungen bei gleichem Wortlaut ===
Manchmal muss der Begriff in anderen Sprachen unterschiedlich übersetzt werden, obwohl er in der Default Sprache gleich lautet:
<pre>
$label = _x('Comment', 'noun'); // or $this->_x('Comment', 'noun') in a class
...
// some other place in the code
echo _x('Comment', 'column name');
Kommentare für den Übersetzer und User
$date = __('g:i:s a'); // Date string in PHP date() format
echo __("Welcome Guest"); // Headline for guest user // Keep it short (2-3 words)
Regeln
- Eine Zeile ein Paar Anführungszeichen
- Nur eine Übersetzungsfunktion pro Zeile
Language Switcher
// remember what language is set to
$savedLanguage = $user->language;
foreach($languages as $language) {
// if user is already viewing the page in this language, skip it
if($language->id == $savedLanguage->id) continue;
// if this page isn't viewable (active) for the language, skip it
if(!$page->viewable($language)) continue;
// set the user's language, so that the $page->url and any other
// fields we access from it will be reflective of the $language
$user->language = $language;
// output a link to this page in the other language
echo "<li><a href='$page->url'>$language->title: $page->title</a></li>";
}
// restore the original language setting
$user->language = $savedLanguage;
Seiten nur in einer Sprache verfügbar
What If I want to create/publish a page only in DE language, and that page should not be available in the default language? Default language is required. But you could always add your own checkbox field to the page as a toggle to disable it. Your head.inc or _init.php or whatever your common initialization file is could check:
if($page->disable_default_language && $user->language->isDefault()) throw new Wire404Exception();
You'd also have to consider it with navigation generation, perhaps skipping over pages that have the toggle set while in the default language, or adding it to your selectors when querying pages.
Edit: you could also just choose to not use the default language at all.
if($user->language->isDefault()) $user->language = $languages->get("en-us"); // or whatever you want your default to be
Beispiele
Multilanguage Page allgemeines Vorgehen
1. Module
- s.o. alle benötigten installieren
2. Backend
- Default Sprache festlegen
- Wenn nicht Englisch Sprachpaket installieren
- Wenn der Titel der Sprache auch der Identifier für den html Tag sein soll muss er de, en, fi... lauten
- Weitere Sprachen hinzufügen. Für Englisch benötigt man kein Sprachpaket
- Die Homepage entscheidet über den Pfad. Wenn Englisch z.B. unter www.meineSeite.com/en/seitenname/ erreichbar sein soll, dann muss für Englisch unter Einstellung > Namen en eingetragen werden.
- Alle Felder die Übersetzt werden sollen auf Multilanguage Felder umstellen
3. Templates
Das lang Attribut sollte zur Sprache passen. Mit der _x Funktion kann PW beliebige Strings in Templates übersetzten. PW findet diese automatisch. _main.php (oder header..)
<html lang="<?php echo _x('en', 'HTML language code'); ?>">
Im Backend kann man nun in den Spracheinstellungen Verwaltung > Sprachen > meineSprache das Label HTML language code suchen und mit dem passenden lang tag ersetzen. Das Funktioniert auch mit beliebigen anderen Werten die man im Template hartkodiert hat.
Man kann auch den Language Title verwenden wenn dieser entsprechend vergeben wurde.
<html lang="<?= $user->language->title ?>">
Dies hat bei mir nicht funktioniert:
<? $lang = $pages->get(1)->getLanguageValue($user->language, 'name'); ?> <html lang="<?php echo $lang ?>">
Hier wird einfach der Name der Sprache die der Benutzer im Moment hat (Session) ausgegeben. Der Name der Sprache sollte im Backend entsprechend der Norm gewählt sein. (de, it, fi...). Problem war das man den Namen der default Sprache nicht vergeben kann.
4. Language Switcher
Für Text Navigation z.B. so:
<?php namespace ProcessWire;
?>
<ul id="nav-lang" class="">
<?php
foreach($languages as $language){
if(!$page->viewable($language)) continue; // is page viewable in this language?
if($language->id == $user->language->id) {
echo "<li class='current'>";
} else {
echo "<li>";
}
$url = $page->localUrl($language);
$hreflang = $pages->get('/')->getLanguageValue($language, 'name');
echo "<a hreflang='$hreflang' href='$url' style="text-transform:uppercase;">$language->title</a></li>";
echo "</li>";
}
?>
</ul>
Prantner
language-switcher.inc
<?php namespace ProcessWire;
$imgMarkup = "";
$out = "";
foreach($languages as $language) {
if(!$page->viewable($language)) continue; // is page viewable in this language?
$url = $page->localUrl($language);
$hreflang = $homepage->getLanguageValue($language, 'name');
$imgUrl = $config->urls->templates.'assets/flags/'.$language->name.'_sq.png';
$imgMarkup = "<img src=\"$imgUrl\" title=\"$language->title\" alt=\"$language->title\" class=\"circle z-depth-1\">";
if($language->id == $user->language->id) {
$out .= "<span class=\"lang-button current\">";
} else {
$out .= "<span class=\"lang-button\">";
}
$out .= "<a hreflang=\"$hreflang\" href=\"$url\">$imgMarkup</a></span>";
}
$out = '<div id="nav-lang">'.$out.'</div>';
echo $out;
?>
language-switcher-mobile.inc
<?php namespace ProcessWire;
?>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<?php
foreach($languages as $language) {
if(!$page->viewable($language)) continue; // is page viewable in this language?
if($language->id == $user->language->id) {
echo "<li class='current'>";
} else {
echo "<li>";
}
$url = $page->localUrl($language);
$hreflang = $homepage->getLanguageValue($language, 'name');
echo "<a hreflang='$hreflang' href='$url'>$language->title</a></li>";
}
?>
</ul>