Vanilla 1.1.2 Forum von Lussumo. Weitere Informationen: Dokumentation, Community.

    • CommentAuthoraceman
    • CommentTime18.11.2008 bearbeitet
     permalink
    Konzept, Programmierung: aceman
    Anregungen, Kritik, Hilfen: stefan, Marc, Jako, ganeshXL, Bruno
    Übersetzung ins Deutsche: Smartsoul

    Features:
    • keine händische Verküpfung der Seiten notwendig (man muss nicht immer eintragen, welche ID die Seite in den anderen Sprachen hat), da man die Zuordnung über eine Template-Vvariable erstellt, welche in jeder Sprache gleich lautet.
    • Wenn man die Sprache wechselt, bleibt man auf der ausgewählten Seite, sofern diese in der gewählten Sprache vorhanden ist.
    • Die 404 Error Page und Kontaktseite sind auch mehrsprachig. Die 404 Seite zeigt die komplette Sitemap in der gewählten Sprache an.

    Die Kommentare der anderen User bis zum 21.11.2008 sind mit eingeflossen und brauchen nicht mehr beachtet zu werden.

    Einführung
    Nach dem Durchlesen verschiedener Lösungsansätze für multilinguale Websites mit MODx, war ich nicht überzeugt, dass dabei schon die Anforderungen an benutzerfreundliche mehrsprachige Websites erfüllt worden wären.

    Mein Anliegen war einerseits, den Benutzer bei einem Sprachwechsel auf der selben Seite zu belassen und nicht einfach nur auf die Startseite der Website umzuleiten. Andererseits wollte ich nicht, dass der Bezug zwischen den gleichen Seiten der unterschiedlichen Sprachen (jeweils mit der Zuweisung der Seiten-IDs) per Hand erfolgen muss. Es sollte eine Lösung sein, bei der diese Zuweisung automatisch erfolgt.

    So fand ich einen Lösungsansatz, der gut funktionierte, aber auch noch verbesserungswürdig war. Kommentare, Verbesserungsvorschläge und Programmierhilfen kamen nach Veröffentlichung der ersten Version speziell aus dem deutschen MODx-Forum von den Membern stefan, Marc, Jako, ganeshXL und Bruno.

    Der aktuelle Ansatz verknüpft die Seiten der unterschiedlichen Sprachen nun mit Hilfe einer Template-Variablen namens "languageIdentifier". In dieses Feld wird ein eindeutiger Name geschrieben, der bei der Duplizierung des Sprachordners (welcher alle Seiten eines Sprachzweigs enthält) gleich mit dupliziert wird.

    Und so geht's:

    1. Modifiziere die Konfiguration
    unter Werkzeuge -> Konfiguration -> Benutzerfreundliche URL

    Benutzerfreundliche URLs nutzen: ja
    Aliasnamen: ja
    Benutze benutzerfreundliche Aliaspfad-Angaben: ja

    2. Erstellen einer neuen Template-Variable

    Unter Ressourcen -> Ressourcenverwaltung -> Template-Variablen wird eine neue Template-Variable mit dem Namen "languageIdentifier" erstellt.

    3. Aufbau des Dokumentenbaums

    Jede Sprache der multilingualen Website muss in ihrem eigenen Ordner liegen. Im Root-Verzeichnis wird dazu zunächst ein Ordner für die Hauptsprache der Website angelegt, der als Namen z.B. "deutsch", "english" oder "français" erhält. Dieser Name ist gleichzeitig das, was der Benutzer als Sprachauswahl zu sehen bekommt. Also in das Feld nicht "Sprache 1", "Sprache 2" usw. reinschreiben.
    Der Alias für diesen Ordner sollte ein 2-Buchstaben ISO-Ländercode sein, eine komplette Auflistung ist unter http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm zu finden.

    Jetzt werden alle Seiten der Hauptsprache wie gewöhnlich erstellt. Im Feld für die Template-Variable "languageIdentifier" muss für jede Seite der Hauptsprache ein eindeutiger Name gesetzt werden. Anschließend wird der gesamte Ordner der Hauptsprache dupliziert und in der Zweit-, Dritt-, usw.-sprache der Titel des Sprachordners und der 2-Buchstaben ISO-Country-Code für die neue Sprache eingestellt.

    Dokumentname: english / alias: gb / Typ: Ordner / ID: (1)
    |-> Dokumentname: Welcome / ID: (2)
    Dokumentname: deutsch / alias: de / Typ: Ordner / ID: (3)
    |-> Dokumentname: Willkommen / ID: (4)

    Die ID´s sind natürlich nur Beispiele, sie werden bei euch wahrscheinlich unterschiedlich sein.
    Wichtig ist, dass die Ordner veröffentlicht sind und der Haken bei "Im Menü anzeigen" gesetzt ist.

    Unter Werkzeuge -> Konfiguration wird die Startseite des Internetauftritts eingestellt.

    4. Snippets anlegen

    Snippet Name: language
    Beschreibung: erstellt Platzhalter und speichert die aktuelle Sprache

    <?php
    $debugMsg = '$language is: '.$language.'<br />';
    $debugMsg = 'LanguageID from cookie: '.$_COOKIE['LanguageID'].'<br />';
    $params['topLevel'] =1;

    // Regular Page
    // find Ultimate Parent of this page. The alias of this page sets the language variable
    if ($modx->config['error_page'] != $modx->documentIdentifier){
    $up = $modx->runSnippet("UltimateParent", $params);
    $tv = $modx->getTemplateVar('alias', "", $up);
    $language = $tv['value'];
    setcookie("Language",$language,time()+604800, "/", "", 0);
    // LanguageID is needed for the 404 error page, to show the sitemap in the actual language
    setcookie("LanguageID",$up,time()+604800, "/", "", 0);
    $modx->setPlaceholder('LanguageID',$up);
    $modx->setPlaceholder('language',$language);
    }
    else{
    // If Error Page
    $debugMsg .= '<p>Error Page Start<br />';

    if ( !empty ($_COOKIE['LanguageID'])){
    $debugMsg .='$language is empty, try to read from cookie';
    $language = $_COOKIE['Language'];
    $LanguageID = $_COOKIE['LanguageID'];
    $params['id'] = $LanguageID;
    $up = $modx->runSnippet("UltimateParent", $params);
    //setcookie("LanguageID",$up,time()+604800, "/", "", 0);
    $modx->setPlaceholder('LanguageID',$up);
    }
    else {
    $debugMsg .= '<p>LanguageID Cookie is empty, get ID from Site start</p>'.$modx->config['site_start'];
    $params['id'] = $modx->config['site_start'];
    $up = $modx->runSnippet("UltimateParent", $params);
    //setcookie("LanguageID",$up,time()+604800, "/", "", 0);
    $modx->setPlaceholder('LanguageID',$up);
    }
    }

    $debugMsg .= 'LanguageID at finish: [+LanguageID+]<br />';

    $debugMsg .= '$language: '.$language.'<br />';
    $modx->setPlaceholder('debugMsg', $debugMsg);
    //echo $debugMsg;
    $modx->setPlaceholder('language', $language);
    if (file_exists("assets/languages/$language.php")) include_once "assets/languages/$language.php";?>

    Snippet Name: LanguageChooser
    Description: Shortcut für den wayfinder

    <?php
    $langMenu = $modx->runSnippet(
    "Wayfinder",
    array(
    "startId" => "0",
    "level"=>"1",
    "textOfLinks"=>"alias",
    "rowTpl"=>'flagAndLanguage',
    "outerTpl"=>'LanguageChooser'
    )
    );
    echo $langMenu;
    ?>

    Snippet name link_to_language
    DescriptionBeschreibung: erstellt den Link zur aktuellen Seite in den anderen Sprachen

    <?php
    if (! function_exists('getdocs_with_same_values')){
    function getdocs_with_same_values($id = 'default', $field = 'description')
    {
    global $modx;
    // Initialize ids
    $ids = array ();
    if ($id == 'default')
    {
    $id = $modx->documentIdentifier;
    }
    $table = $modx->getFullTableName('site_tmplvars');
    $result = $modx->db->select('id', $table, ' name = "'.$field.'"');
    $array_result = $modx->db->makeArray($result);
    if (count($array_result) > 0)
    {
    $tvid = $array_result[0]['id'];
    $table = $modx->getFullTableName('site_tmplvar_contentvalues');
    $result = $modx->db->select('*', $table, 'contentid = "'.$id.'" and tmplvarid = "'.$tvid.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0]['value'];
    $result = $modx->db->select('contentid', $table, 'value = "'.$fieldvalue.'"');
    $array_result = $modx->db->makeArray($result);
    foreach ($array_result as $value)
    {
    $ids[] = $value['contentid'];
    }
    }
    else
    {
    $table = $modx->getFullTableName('site_content');
    $result = $modx->db->select($field, $table, ' id = "'.$id.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0][$field];
    $table = $modx->getFullTableName('site_content');
    $result = $modx->db->select($field, $table, ' id = "'.$id.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0][$field];
    $result = $modx->db->select('id', $table, $field.' = "'.$fieldvalue.'"');
    $array_result = $modx->db->makeArray($result);
    foreach ($array_result as $value)
    {
    $ids[] = $value['id'];
    }
    }
    return $ids;
    }
    }

    $pages = getdocs_with_same_values('default','languageIdentifier');

    $langFolder = $modx->getDocumentObject('id', $id);
    $langFolderID = $langFolder['id'];
    $langFolderAlias = $langFolder['alias'];

    // set theURL to the root of the language
    $theURL = $modx->makeURL($id,'','','full');

    foreach ($pages as $page){
    //echo $page;
    // Now check if the id of the $value is a child of the UltimateParent
    $UltimateParent = $modx->runSnippet('UltimateParent', array('id' => $page));
    //echo "\n".$UltimateParent." ".$langFolderID;
    //$checks[$counter]['id'] = $value['id'];

    // if the UltimateParent is equal to to folderID make link to the actual page in the other language
    if ($UltimateParent == $langFolderID) {
    $theURL = $modx->makeURL($page,'','','full');
    }
    }

    return $theURL;
    ?>


    5. Chunks erstellen

    Chunk Name: flagAndLanguage
    Beschreibung: erstellt einen Link mit einer Länderflagge und der Sprache
    <li class="[+wf.classnames+]"><a href="[[link_to_language?id=`[+wf.docid+]`&link=`[+wf.link+]`&actualid=`[*id*]`]]"><img src="[(base_url)]assets/images/flags/gif/[+wf.linktext+].gif" alt="[+wf.linktext+]" /> [+wf.title+]</a></li>

    Chunk Name: LanguageChooser
    Description: Äußeres Template für die Sprachauswahl

    <ul [+wf.classes+] id="sprachwahl">
    [+wf.wrapper+]
    </ul>


    6. Seiten-Template modifizieren

    Der folgende Code muss in das Seiten-Template eingefügt werden.
    Noch vor die Doctype-Deklaration den Snippet Aufruf "[[language]]" (ohne die Anführungszeichen) schreiben

    <div id="languageselection">
    [[LanguageChooser]]
    </div>
    <div id="navigation">
    [!Wayfinder? &startId=`[+LanguageID+]`!]
    </div>

    Dieser Code enthält den Aufruf für die Sprachauswahl und eine PHP-Datei "assets/languages/currentlanguage.php" wobei currentlanguage der 2-Buchstaben-Ländercode ist. Damit erhält man das Navigationsmenü für die aktuell gewählte Sprache.

    6.1 Neue Platzhalter

    Es wird ein Platzhalter [+language+] bereit gestellt. Dieser kann z.B. verwendet werden, wenn in verschiedenen Sprachen der Website unterschiedliche Bilder verwendet werden sollen. Also zum Beispiel eine Grafik, in der Schrift enthalten ist.

    Der Platzhalter [+debugMsg+] dient zum Tracen des Sprach-Snippets.
    Ihr könnt ihn beliebig im Contentbereich einfügen und seht dann, welche SprachID und welche Sprache gesetzt sind.

    7. Download der Icons

    Dieser Schritt ist optional. Wer ihn überspringt, muss das flagAndLanguage-Snippet anpassen.
    Unter http://www.famfamfam.com/lab/icons/flags/ können die Flaggenicons passend zu den ISO-Country-Codes herunter geladen werden. Die Bilddateien müssen im Ordner assets/images/flags entpackt werden.

    8. Formulare

    Öffne die Sprachdatei unter assets/snippets/eform/lang und füge deine Variablen hinzu.

    $_lang['deinname'] = "Dein Name";
    Es können so viele Variablen wie benötigt hinzugefügt werden.
    Diese müssen dem Array "fields" übergeben werden damit eForm sie erkennt.

    Neues Snippet mit Namen "setPrompts" anlegen:
    <?php
    function setPrompts(&$fields) {
    global $_lang;
    $fields['yourname'] = $_lang['yourname'];
    return true;
    }
    ?>

    Wenn du den Chunk für das Formular erstellst, hast du Zugriff auf alle Platzhalter, die in dem setPrompts-Snippet definiert wurden.

    [+validationmessage+]
    <form method="post" action="[~[*id*]~]">
    <input type="hidden" name="formid" value="feedbackForm" />
    <label for="cf[+yourname+]">[+yourname+]: </label>
    <input name="Your Name" id="cf[+yourname+]" class="required text" type="text" eform="[+deinname+]::1:" />

    Jetzt kannst du das Formular auf der Kontakt-Seite einfügen.

    [[setPrompts]]

    [!eForm? &formid=`feedbackForm` &to=`my@email.com <mailto:my@email.com>`&eFormOnBeforeFormMerge=`setPrompts` &language=`german` &subject=`Web site feedback`!]


    9. Multilinguale Fehlerseite

    Erstelle einen neuen unveröffentlichten Ordner. Anschließend erstellst erstelle und veröffentlichst veröffentliche du darin ein neues Dokument mit dem Title "[+errorpage+]". Der Alias lautet "404".

    [[language]]
    [+errorpage+]
    [!Wayfinder? &startId=`[+LanguageID+]` &showDescription=`1`!]

    Nun füge in assets/languages/de.php Folgendes hinzu:

    <?php
    $modx->setPlaceholder("errorpage",'404 – Seite nicht gefunden');
    ?>

    Übersetze diesen Text in alle verwendeten Sprachen und füge Sie in den Sprachdateien im languages Ordner hinzu.
    Die mehrsprachige Fehlerseite ist damit erstellt und liefert eine Sitemap in der aktuellen Sprache.

    SO LEUTE DAS WAR ES SCHON!!!
    •  
      CommentAuthorstefan
    • CommentTime18.11.2008
     permalink
    Hallo aceman,

    habs jetzt nicht 100% durchgeschaut, aber eine Sache fällt gleich auf.
    keine händische Verküpfung der Seiten notwendig, da alles über identische Aliasnamen läuft
    Und wenn es doppelte Aliase gibt? sowas wie

    /produkte/uebersicht.html
    /ansprechpartner/uebersicht.html

    /products/overview.html
    /contact_persons/overview.html

    was passiert dann?

    ciao, Stefan
    •  
      CommentAuthorMarc
    • CommentTime18.11.2008
     permalink
    Halte ich auch für kritisch. Wenn dann ein anderes Feld, wobei es dann so oder so auch eine "händische Verknüpfung" (Eintragen des selben Namens) wäre. Aber vielleicht versteh ich auch was komplett miss.
    •  
      CommentAuthorJako
    • CommentTime18.11.2008
     permalink
    keine händische Verküpfung der Seiten notwendig, da alles über identische Aliasnamen läuft


    Das wird nach kurzem drüberschauen dann auf so etwas abgebildet:
    /de/produkts/overview.html
    /de/contact_persons/overview.html

    /en/produkts/overview.html
    /en/contact_persons/overview.html

    Was dem ganzen Ansatz der sprechenden URLs widerspricht. Insofern scheidet es für mich aus.
    •  
      CommentAuthorMarc
    • CommentTime18.11.2008
     permalink
    Naja, dann nehme ich halt das Feld "Beschreibung" und lasse den alias in Ruhe. Trozdem wäre es immer noch eine händische Verknüpfung imho. Das Problem liegt halt generell woanders leider...
    •  
      CommentAuthorJako
    • CommentTime18.11.2008
     permalink
    @aceman3000: Der Ansatz für die Mehrsprachigkeit von eForm scheint mir ganz interessant. Ich würde ihn aber nicht über die Language-Datei realisieren, da diese bei einem Snippet-Update überschrieben wird.

    @Marc: Vielleicht erwächst ja aus der Versionierung von Stefan ein Ansatz zur Mehrsprachigkeit.
    •  
      CommentAuthorMarc
    • CommentTime18.11.2008
     permalink
    @Marc: Vielleicht erwächst ja aus der Versionierung von Stefan ein Ansatz zur Mehrsprachigkeit.


    *hust*

    Henne oder Ei? Was war wohl zuerst da? Stefaaaaaaaaan?! :devil:
    • CommentAuthoraceman
    • CommentTime19.11.2008 bearbeitet
     permalink
    @ALLE: Ja das Thema sprechende URL habe ich etwas vernachlässigt. Meines Erachtens nach, ist das aber nicht ganz so schlimm, das die URLs nicht übersetzt werden. Für die Suchmaschinen spielt es nicht die größte Rolle dass die URL übersetzt wird, und die Lesbarkeit für den User ist zumindest in seiner nativen Sprache immer noch gegeben, bei den anderen Sprachen sieht der User, dass es Wörter sind und nicht irgendein kryptischer URL.

    Ihr habt mich jetzt allerdings noch mal zum Nachdenken gebracht und eventuell überarbeite ich den Ansatz auch noch mal, weiss nur noch nicht genau wie. Im Prinzip müssten die URLs dann ja übersetzt werden. Ich will mir aber auf jeden Fall die händische Zuordnung sparen. Hmmm. Lass ich mir mal durch den Kopf gehen.

    @Jako: Du hast Recht mit den Updates. Ich habe ja auch noch Textdateien im language-Verzeichnis (nicht das von eForm, sondern ein von mir angelegtes). Leider konnte ich die Variablen daraus nicht in eForm verwenden. Ich habe auch schon probiert in meinen language-Dateien (de.php) Platzhalter zu setzen, und diese zu verwenden. Leider klappte das auch nicht so richtig.

    @Stefan. Das ist kein Problem, denn es werden ja die Pfadangaben davor gesetzt. So kannst du problemlos in den verschiedenen Unterordnern sowie auch in den Sprachen die Seite "uebersicht.html" nennen. Allerdings wären die URLs nicht übersetzt wie in deinem Beispiel, sondern gleichlautend mit dem deutschen URL nur das dann halt das Länderkürzel vorne ausgetauscht wird:
    de/produkte/uebersicht.html
    en/produkte/uebersicht.html
    Dies ist auch gleichzeitig der Kritikpunkt, den die anderen hier angebracht haben.

    @Marc: Das hast du etwas verkehrt verstanden. Nachdem du deine erste Sprache fertiggestellt hast, duplizierst du sie einfach und nennst sie dann zum Beispiel um in "English". Die Aliase bleiben bei den Seiten erhalten.
    Die meisten anderen Multilingualen Lösungen basieren darauf, dass du in irgendeine Templatevariable schreibtst, welche ID deine aktuelle Seite in den anderen Sprachen hat. Zum Beispiel so: en:10,fr:20,es:34.
    Das meinte ich mit händischer Zuordnung. So muss man wenn man eine neue Seite anlegt, in jeder Sprache eingeben, wie die IDs für die anderen Sprachen sind. Da ich eine Seite in 7 Sprachen habe, wäre das *Ironie an* viel Spaß *Ironie aus*
    •  
      CommentAuthorMarc
    • CommentTime19.11.2008
     permalink
    @Marc: Das hast du etwas verkehrt verstanden. Nachdem du deine erste Sprache fertiggestellt hast, duplizierst du sie einfach und nennst sie dann zum Beispiel um in "English". Die Aliase bleiben bei den Seiten erhalten.


    Das würde die "Beschreibung" oder jede andere TV auch. Bei einer neuen Sprache muss ich das dann auch händisch nachpflegen, aber das ist klar.

    Dennoch: Sobald ich eindeutige Aliase angehakt habe in der Konfiguration, kriege ich richtige Probleme mit Deiner Lösung. Denn dann wird beim ersten Speichern eines Dokuments der Alias automatisch umgeschrieben von "produkte" in "produkte1", und Deine Lösung fliegt Dir um die Ohren. Deshalb muss das mit einem anderen Feld gelöst werden.

    Ja das Thema sprechende URL habe ich etwas vernachlässigt. Meines Erachtens nach, ist das aber nicht ganz so schlimm, das die URLs nicht übersetzt werden. Für die Suchmaschinen spielt es nicht die größte Rolle dass die URL übersetzt wird, und die Lesbarkeit für den User ist zumindest in seiner nativen Sprache immer noch gegeben, bei den anderen Sprachen sieht der User, dass es Wörter sind und nicht irgendein kryptischer URL.


    Ich würde einfach ein anderes Feld nehmen und den Alias dafür nutzen wofür er gedacht ist. Alle andere Diskussion ist müßig und als SEO-CMS kann ich nicht auf einmal sagen "URLs selbst bestimmen geht nicht mehr wegen Mehrsprachigkeit". ;-)

    Die meisten anderen Multilingualen Lösungen basieren darauf, dass du in irgendeine Templatevariable schreibtst, welche ID deine aktuelle Seite in den anderen Sprachen hat. Zum Beispiel so: en:10,fr:20,es:34.


    Jo, ist noch müßiger.

    Deine Lösung ist auf jeden Fall mal ein guter Ansatz, der mit der bestehenden Content-Struktur machbar und auch praktikabel ist. Jedoch - wie gesagt - würde ich ein anderes Feld nutzen. "Beschreibung" liegt sowieso meist brach.
    •  
      CommentAuthorganeshXL
    • CommentTime19.11.2008
     permalink
    Ein drag and drop Feature wie im DocManager beim sortieren wäre cool:

    Angenommen man arbeitet mit 3 Sprachen: Man könnte dann 3 Folders bestimmen, die Dokumente würden aufgelistet werden in 3 Spalten, und man könnte so die Zuordnung ohne mühsames eintippen in eine Text-TV regeln. Im Ajax-Zeitalter sollte das möglich sein (obwohl ich ehrlich gesagt auch nicht konkret wüsste wie das im Detail gehen würde).

    Oder... ein TV je Parallel-Sprache als Dropdown, wo man einfach auswählt. Idealerweise nicht eine alphabetische Auflistung, sondern gemäss Baum-Struktur (menuindex ASC). Mit visuellen Hilfsmitteln (Texteinschub oder Trennzeichen), damit man Container + Struktur im Dropdown auch sieht (was übrigens auch für das tinyMCE Menu praktisch wäre, wo man interne Links einfügen kann - es wäre 1000x übersichtlicher als einfach strikte alpabetische Auflistung).
    • CommentAuthoraceman
    • CommentTime21.11.2008
     permalink
    ok: hier jetzt meine neue Idee,
    ich habe überlegt, dass Beschreibungsfeld statt des alias-Feldes zu benutzen. Jetzt müsste ich also den kompletten Dokumentenbaum durchgehen und suchen wo die description der aktuellen Seite übereinstimmt in den anderen Sprachordnern.

    Ich weiß, dass dadurch wieder ein Feld (Beschreibung) wegfällt, aber sonst könnte man es auch notfalls wieder mit einer Templatevariablen lösen, wenn man das Feld unbedingt benötigt.

    Jetzt ist nur die Frage, wie mache ich das???
    Also im Prinzip will ich das hier:
    getIDs from documenttree where description = actual.description

    Dann bekomme ich die IDs von allen Dokumenten zurück und lasse per makeURL einfach die Links erzeugen, die ich dann als Sprachwahl ausgeben lasse.
    Irgendjemand eine Idee, wie ich das bewerkstelligen könnte?
    • CommentAuthorBruno
    • CommentTime21.11.2008 bearbeitet
     permalink
    Hier mal schnell zusammmengebastelt, noch nicht getestet, ne Erweiterung, damit Du auch ne beliebige TV verwenden kannst, kann ich Dir später noch nachliefern.
    function getdocs_with_same_values($id = 'default', $field = 'description')
    {
    global $modx;
    // Initialize ids
    $ids = array ();
    if ($id == 'default')
    {
    $id = $modx->documentIdentifier;
    }
    $table = $modx->getFullTableName('site_tmplvars');
    $result = $modx->db->select('id', $table, ' name = "'.$field.'"');
    $array_result = $modx->db->makeArray($result);
    if (count($array_result) > 0)
    {
    $tvid = $array_result[0]['id'];
    $table = $modx->getFullTableName('site_tmplvar_contentvalues');
    $result = $modx->db->select('*', $table, 'contentid = "'.$id.'" and tmplvarid = "'.$tvid.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0]['value'];
    $result = $modx->db->select('contentid', $table, 'value = "'.$fieldvalue.'"');
    $array_result = $modx->db->makeArray($result);
    foreach ($array_result as $value)
    {
    $ids[] = $value['contentid'];
    }
    }
    else
    {
    $table = $modx->getFullTableName('site_content');
    $result = $modx->db->select($field, $table, ' id = "'.$id.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0][$field];
    $table = $modx->getFullTableName('site_content');
    $result = $modx->db->select($field, $table, ' id = "'.$id.'"');
    $array_result = $modx->db->makeArray($result);
    $fieldvalue = $array_result[0][$field];
    $result = $modx->db->select('id', $table, $field.' = "'.$fieldvalue.'"');
    $array_result = $modx->db->makeArray($result);
    foreach ($array_result as $value)
    {
    $ids[] = $value['id'];
    }
    }
    return $ids;
    }


    Sag Bescheid wenns nicht klappt, Bruno
    • CommentAuthoraceman
    • CommentTime21.11.2008
     permalink
    Hey Bruno,
    klappt super. Danke für die schnelle Antwort. Sobald ich meine Website auf dieses Schema umgestellt habe und alles integriert habe, werde ich mein schönes Tutorial anpassen. Vielen Dank für eure Anmerkungen und Hilfe. Eventuell komme ich noch mal mit ein paar Fragen auf euch zu.

    Gruß
    Aceman
    • CommentAuthorBruno
    • CommentTime21.11.2008
     permalink
    Hab grad mal noch die Erweiterung für ne beliebige TV dazugebaut

    servus
    Bruno
    • CommentAuthoraceman
    • CommentTime25.11.2008 bearbeitet
     permalink
    So unter dem Link http://modxcms.com/forums/index.php/topic,29597.msg179898.html#msg179898 findet ihr die jeweils aktuelle Version, die nun eine Template Variable an Stelle von alias verwendet.
    So bleibt auch der Ansatz der sprechenden URLs erhalten.

    Danke auch noch mal an Bruno für seine Hilfe.

    :monkey: Freue mich natürlich über eure Rückmeldungen. :monkey:
    • CommentAuthoraceman
    • CommentTime16.02.2009
     permalink
    Hi Smartsoul, hab dir schon ne PM geschrieben übers englische Forum. Danke schon mal für die Arbeit. Wenn du mir den Text schickst, werd ich drüberlesen und korrigieren und ihn dann an dieser Stelle mit gebührendem Dank veröffentlichen.

    Gruß
    Aceman
    • CommentAuthorjofo
    • CommentTime18.02.2009
     permalink
    Hallo Zusammen,

    Deine Lösung find ich Super... nur mühsam das man in dieser ModX Version bei so großen Ideen auch so große kopier und Bastellarbeit hat .... aber dafür sind wir dann nicht gleich wieder bei der Hühnersuppe aus der Tüte :( ...

    Vielleicht komm ich ja selber dazu - aber mir fehlt da noch ein ganz entscheidenes Feature um einen DAU-Radakteur die Arbeit zu erleichtern.
    Man müsste ein kleines Modul bauen finde ich, das prüft in welchen Sprachen die jeweiligen Seiten verfügbar sind und so denn noch nicht in allen Sprachen eine Übersetzung verfügbar ist einen dicken fetten Button "Jetzt nach SpracheXYZ Überstezen" anbietet der das duplizieren in den entsprechenden Baum erledigt.

    Wie gesagt ... nur DAU Kosmetik ... wen ich die Tage dazu komme mich da mal dran zu machen poste ich das mal hier.
    •  
      CommentAuthorSmartsoul
    • CommentTime22.02.2009 bearbeitet
     permalink
    Habe gerade festgestellt, dass die Sprachordner veröffentlicht sein müssen, damit $language gesetzt wird. Na immerhin! ;-)

    Aber die Sprachauswahl taucht bei mir immer noch nicht auf. Stehe wahrscheinlich mal wieder wie der Ochs vorm Berg und sehe den Wald vor lauter Bäumen nicht.

    Bitte gebt mir einen Tipp. Bin das Tutorial nun schon dreimal durchgegangen und habe alles gecheckt, ohne drauf zu kommen.

    Wenn ich im Browser, den Ausgabequellcode anzeigen lasse, sieht er so aus ...
    <div id="languageselection"> LanguageID from cookie: 24<br />LanguageID at finish: 27<br />$language: fr<br /></div>


    Irgendwie kann der Aufruf [[LanguageChooser]] nicht interpretiert werden.

    Smartsoul
    •  
      CommentAuthorSmartsoul
    • CommentTime23.02.2009
     permalink
    Auf der weiteren Fehlersuche bin ich nun darauf gestoßen, dass ...
    [!Wayfinder? &startId=`[+LanguageID+]`!] ... funktioniert und gibt mir, wie vorgesehen, einen Baum mit Links zu den im Menü enthaltenen Seiten einer Sprache aus.

    Sobald ich aber versuche den Wayfinder mit ...
    [!Wayfinder? &startId=`0` &level=`1`!] ... aufzurufen, gibt es im Browser keine Ausgabe mehr. ???
    •  
      CommentAuthorSmartsoul
    • CommentTime23.02.2009
     permalink
    HEUREKA!

    Nachdem ich oben feststellen musste, dass die Sprachordner veröffentlicht sein müssen, damit $language gesetzt werden kann, weiß ich nun endlich, dass sie auch mit dem Häkchen bei "Im Menü anzeigen" versehen werden müssen.

    Eigentlich eh logisch! Der :devil: steckt wie immer im Detail.

    @aceman3000
    Vielleicht könntest du diese beiden Petitessen noch in das Tutorial integrieren, damit andere, die dieses nutzen wollen, sich meine Probleme ersparen? :wink:

    Erleichterte Grüße

    Smartsoul
    •  
      CommentAuthorSmartsoul
    • CommentTime23.02.2009
     permalink
    Das nächste Problem habe ich mit dem mehrsprachigen Formular.

    Snippet setPrompts ist angelegt und dem Array fields wurden eine Meng an Variablen übergeben, die ich im Formular verwenden möchte und in den Language-Dateien definiert habe.

    Bei der Verwendung der Variablen
    $_lang["email"] = "* E-Mail:";
    bekam ich immer eine Fehlermeldung: Ungültige oder unsichere Einträge wurden in Ihrem Formular entdeckt. Also den Inhalt der Variable "ef_mail_abuse_error". Und zwar schon beim Aufruf von [+email+] als Bezeichner für das Eingabefeld <label for="[+email+]">[+email+] ???

    Warum ist diese Zeichenkette gefährlich: * E-Mail
    •  
      CommentAuthorSmartsoul
    • CommentTime23.02.2009
     permalink
    Habe die Variable umbenannt in ...$_lang["emailadresse"] = "* E-Mail:";... und jetzt gibt es keine Fehlermeldung mehr.

    Weiß wer woran das liegt?
    •  
      CommentAuthorJako
    • CommentTime23.02.2009
     permalink
    Erstens: Weil eForm es nicht mag, wenn während der Verarbeitung eines Formulars Felder umbenannt/verändert werden. Zweitens (und entscheidender): email ist ein besonderer Feldname in eForm - dieser wird intern benutzt um an die Mailadresse darin eine Nachricht zu verschicken – also bitte nicht als Platzhalter für Sprachelemente benutzen.
    •  
      CommentAuthorSmartsoul
    • CommentTime23.02.2009 bearbeitet
     permalink
    @Jako

    Danke für die Erklärung! Das Leben steckt voller Fallstricke und Fußangeln :wink:

    Gruß

    Smartsoul
    •  
      CommentAuthorSmartsoul
    • CommentTime24.02.2009 bearbeitet
     permalink
    Mit Punkt 8 habe ich nun das nächste Problem. Wahrscheinlich gehe ich euch schon auf die Nerven, aber irgendwie funktioniert es nicht mit dem Formular.

    Wenn der Aufruf so aussieht ...[[setPrompts]]

    [!eForm? &formid=`ContactForm` &subject=`[+betreff+]` &to=`info@chris-ka.com` &ccsender=`1` &tpl=`ContactForm` &report=`ContactFormReport` &invalidClass=`invalidValue` &requiredClass=`requiredValue` &cssStyle=`ContactStyles` &gotoid=`13` &eFormOnBeforeFormMerge=`setPrompts` !]
    ... dann zeigt es mir auf der deutschen Kontaktseite das Formular mit allen Einträgen sauber an, aber auf der französischen Seite zeigt es mir kein Formular an, sondern gibt mir nur den Code für den Aufruf von setPrompts und das Formular aus.

    Wenn ich dann den $language-Parameter mit ... &language = 'german' ..., wie im Tutorial beschrieben, einbaue, bzw. mit 'francais' auf der französischen Kontaktseite, dann wird im Browser zwar in beiden Sprachen das Kontaktformular aufgebaut, aber ohne die Einträge, die in den Sprachfiles des eform-Snippets festgelegt sind.

    Offensichtlich können die Einträge german und francais nicht mit den Sprachfiles in Verbindung gebracht werden.

    Habe jetzt in den docs zu eform gelesen, dass eform dieselben language names verwendet wie MODx. Kann man die irgendwo nachschlagen?

    Danke für eure Hilfe!

    Smartsoul
    •  
      CommentAuthorJako
    • CommentTime24.02.2009
     permalink
    [!setPrompts!]


    Schätze ich mal.
    •  
      CommentAuthorSmartsoul
    • CommentTime24.02.2009
     permalink
    Nein, hat leider nicht geholfen!

    In der eform.inc.php hab ich jetzt den Sprachschaltungsteil gefunden ...
    #include other language file if set.
    $form_language = isset($language)?$language:$modx->config['manager_language'];
    if($form_language!="english" && $form_language!='') {
    if(file_exists($snipPath ."lang/".$form_language.".inc.php"))
    include_once $snipPath ."lang/".$form_language.".inc.php";
    else
    if( $isDebug ) $debugText .= "<strong>Language file '$form_language.inc.php' not found!</strong><br />"; //always in english!
    }


    Sieht ja ganz sauber aus. Wie kann ich denn den letzten Zweig anzeigen? Also das if ($isDebug) aktivieren? Gibt es einen Debug-Modus?
    •  
      CommentAuthorSmartsoul
    • CommentTime24.02.2009
     permalink
    Jetzt funktioniert's!

    Habe wieder &language='german' und &language='francais' reingeschrieben, die Formularseite ausnahmsweise im IE aufgerufen und plötzlich war es mit Sprachumschaltung da und anschließend auch im Firefox ?????

    Im Nebel stochern kommt mir gerade sehr viel einfacher vor als das zu verstehen.
    •  
      CommentAuthorSmartsoul
    • CommentTime27.02.2009
     permalink
    ZUR INFO FÜR ALLE!

    Sorry! Habe nicht &language='german' eingetragen, sondern &language=`german`. Das war wohl der entscheidende Punkt meines Problems!
    • CommentAuthoraceman
    • CommentTime03.03.2009
     permalink
    Hi Smartsoul,

    eigentlich ganz gut, dass du deine Probleme lösen konntest. Das hilft natürlich anderen, die gleiche Probleme haben. Ich hab das Tut etwas angepasst wegen deiner Anmerkung.

    Gruß
    aceman3000
    •  
      CommentAuthorSmartsoul
    • CommentTime03.03.2009
     permalink
    eigentlich ganz gut
    nicht nur "eigentlich" :grin:

    Danke nochmals für das Super-Tutorial!

    Gruß

    Smartsoul
    •  
      CommentAuthorGuido
    • CommentTime26.01.2010
     permalink
    Ich habe gerade schon im .com Forum gefragt. Vielleicht ist hier ja auch jemand am Werk :)

    Wie bekomme ich einen Unterzweig als Untermenü extrahiert?

    ->de
    -->willkommen
    -->seiten
    --->impressum
    --->kontakt
    ->en
    -->welcome
    -->pages
    --->imprint
    --->contact

    Ressources unter "seiten" / "pages" sollen in der Fußzeile auftauchen. Aber wie? Steh gerade aufm Schlauch.

    Grüße,

    Guido
    • CommentAuthorGertrud
    • CommentTime28.01.2010
     permalink
    Auf mich kommen mehrsprachige Seiten zu, und ich versuche auszuwählen, welches System das am besten kann...
    Da gibt es ja auch noch YAMS
    Dort kann man auch für jede Seite eine andere Sprache auswählen.
    Beispiel: http://www.athene-prosjekt.no/
    Wichtig wäre auch die Kompatibilität mit anderen Snippets und Modulen.

    Das Yams sieht doch auch gut aus und scheint mir nicht so kompliziert - liege ich da falsch???

    Gibt es neue Erfahrungen?
    •  
      CommentAuthorMarc
    • CommentTime28.01.2010
     permalink
    Kinners, macht doch für neue Fragen neue Themen auf.

    Ressources unter "seiten" / "pages" sollen in der Fußzeile auftauchen. Aber wie? Steh gerade aufm Schlauch.


    Nach welcher Methode ist bei dir die Mehrsprachigkeit aufgebaut?

    @Gertrud: YAMS ist auf jeden Fall der "bessere" Ansatz, da er eine echte Mehrsprachigkeit bringt. Allerdings muss beachtet werden:

    - Die Seiten sollten 1:1 übersetzt werden, für je nach Sprache individuelle Strukturen ist YAMS weniger geeignet/nicht gedacht.
    - Kompatibilität mit folgenden Snippets ist eigentlich gewährleistet (wenn auch mit Arbeit verbunden): Ditto, Wayfinder, eForm, Maxigallery.

    YAMS ist sehr komplex und man muss sich etwas reindenken. Außerdem ist auf die Performance zu achten, da durch das Anlegen und Abfragen von einigen zusätzlichen TVs schon einige Querys auflaufen.

    http://www.aureliusinvest.de habe ich damit gemacht, mein Fazit: Ich würde es wieder tun, aber vorher ganz klar mit dem Kunden festlegen, dass 1:1 zu übersetzen nicht nur am Anfang ein Ziel ist, sondern auch dauernd bedacht werden muss. Falls es nur eine Hauptsprache gibt und die weiteren Sprachen nur reduzierte Versionen sind, würde ich eher auf eine der Baum-Alternativen setzen.
    • CommentAuthorrasc
    • CommentTime28.01.2010
     permalink
    Erfahrung von mir: den Kunden dreimal(!) fragen, ob er wirklich gewillt ist, seine Seiten 1:1 zu übersetzen, also von der ersten Seite bis zur letzten News. Und erst dann die Mehrsprachigkeit mit YAMS oder anderen Mitteln umsetzen.

    Zögert der Kunde, redet man ihm besser ein schlägt man ihm besser vor, den Sprachwechsel über einen Link/Button jeweils zur anderssprachigen Startseite zu machen und die Strukturen darunter individuell aufzubauen/zu pflegen. Irgendwann hat fast jeder Kunde die Nase voll von den 1:1-Übersetzungen, so zumindest bei mir bisher gewesen.

    Argumente für die einfachere Variante:
    - Welcher Besucher will permanent zwischen den Sprachen wechseln?
    - Liefert eine (externe) Suchmaschine nicht in der Regel bereits eine sprachlich passende Seite, sodass ein Wechsel kaum nötig ist?
    - Komme ich auf eine fremdsprachige Unterseite (woher auch immer), nützt es mir, wenn ich auf die Unterseite meiner Muttersprache wechsle? Vielleicht merke ich erst dort, dass ich in der Struktur völlig falsch bin und doch besser auf der Startseite neu angefangen hätte.

    Wie gesagt: alles persönliche Meinungen/Erfahrungen.
    •  
      CommentAuthorMarc
    • CommentTime28.01.2010
     permalink
    Full ack.
    •  
      CommentAuthorGuido
    • CommentTime28.01.2010
     permalink
    Tutorial, nach dem ich gebaut habe. Ordnerbasiert.

    Also nach dem Tutorial wie hier.

    Kunden fragen erübrigt sich in meinem Fall, weil ich das selbst machen werde (ggf. noch hier und da übersetzen lasse).

    Grüße,

    Guido
    • CommentAuthorGertrud
    • CommentTime28.01.2010
     permalink
    ohh toll so gute Antworten genau das,w as ich wissen musste. ich hatt emir auch shcon überlegt, ob denn das sooo nötig oder gar sinnvoll ist, 1:1 wechseln zu können und dann deine Argumente rasc - süper!
    und, Marc, die von dir erwähnte Seite bringt wieder den schlagenden Beweis: der erste link, auf den ich klickte, brachte bei Englisch 404... (Blaupunkt) ;-)
    • CommentAuthorrasc
    • CommentTime28.01.2010
     permalink
    @Gertrud: Kunden bestellen oft mehr, als sie bewältigen können. Da geht's zu wie am all-inclusive-Buffet :grin:
    Hilfreich ist bei mir stets, dem Kunden eindringlich klarzumachen, dass bei bestimmten Wünschen seinerseits jede Menge Arbeit auf ihn zukommt. Hat er für sowas keine Vollzeitkraft beschäftigt, erledigen sich viele "haben wollen" schnell von ganz allein.
    •  
      CommentAuthorMarc
    • CommentTime29.01.2010
     permalink
    den schlagenden Beweis: der erste link, auf den ich klickte, brachte bei Englisch 404...


    ? wo genau?
    • CommentAuthorrasc
    • CommentTime29.01.2010 bearbeitet
     permalink
    Blaupunkt-News (hatte sie erwähnt): http://www.aureliusinvest.de/presse-news/pressemitteilungen-2009/Blaupunkt-kehrt-zurueck-zu-seinen-Wurzeln.html

    EDIT: da gibt's noch mehr: http://www.aureliusinvest.de/presse-news/pressemitteilungen-2009/GHOTEL-hotel-und-living-auf-Expansionskurs.html
    Ich weiß schon, warum ich meine Kunden auf-Deibel-komm-raus von sowas abbringen will :devil:
    • CommentAuthortalia
    • CommentTime29.01.2010
     permalink
    Ich steh auch vor einigen mehrsprachigen Projekten (1:1-Übersetzung). Habe das mit modx noch nicht umgesetzt und frage mich, welche Technik am besten geeignet ist: die von aceman oder YAMS. Klingt beides sehr vielversprechend.

    Wer kann mir eine Entscheidungshilfe geben?

    Marc, du hast geschrieben:

    @Gertrud: YAMS ist auf jeden Fall der "bessere" Ansatz, da er eine echte Mehrsprachigkeit bringt. Allerdings muss beachtet werden:

    - Die Seiten sollten 1:1 übersetzt werden, für je nach Sprache individuelle Strukturen ist YAMS weniger geeignet/nicht gedacht.
    - Kompatibilität mit folgenden Snippets ist eigentlich gewährleistet (wenn auch mit Arbeit verbunden): Ditto, Wayfinder, eForm, Maxigallery.


    Meinst du, dass YAMS besser geeignet ist als die Methode von aceman? Soll das heißen, dass ich mit aceman's Ansatz Probleme mit den Snippets bekomme :surprise:

    Ich könnte mir beide Ansätze vorstellen. Da es aber mein erstes zweisprachiges modx-Projekt ist und meine PHP-Kenntnisse eher bescheiden sind, sollte ich selbst was am Code anpassen müssen, würde ich mich am Anfang für die Technik entscheiden, die weniger Fehler anfällig ist.

    Noch eine (Anfänger-)Frage: kann ich mich bei mehrsprachigen Projekten, bei denen mit Klick auf die anders sprachige Version lediglich die Startseite erscheint, an dieses Wiki halten?

    Viele Grüße

    talia