mit HMENU (special = language) ein Sprachmenü erstellen

Viele Agenturen und Entwickler verwenden für das Sprachmenü immer noch eine Extension. In diesem Artikel wird gezeigt, wie man ein Sprachmenü nur mit TypoScript und CSS erstellt.

Keine Extension für das Sprachmenü

Auch wenn die Extension sr_language_menu ziemlich viel kann und wohl für die meisten ausreicht, ist man bei Projekten welche über 20 Sprachen und Läder Kombinationen haben froh, wenn man das ganze Menü per typoscript aufgebaut hat. Mit typoscript kann man über ein HMENU bereits ein Sprachmenü erstellen, da braucht es nicht extra eine Extension.

Ausserdem bin ich kein Fan von Extensions (wie auch sr_language_menu), welche sich per Default noch immer über die alte Weise mit den Dateien ext_typoscript_setup.txt und ext_typoscript_constants.txt in TYPO3 einbinden und man keine Kontrolle darüber hat. Bei TYPO3 Projekten in welchen mehr als 1 Webseite läuft ist das definitiv nicht akzeptabel. Wenn nicht jede Webseite Mehrsprachig ist, sollte auch der Code der Extension nicht geladen werden.

Mir ist bewusst, dass dies eine Ansichts- und Performance Frage ist, aber das ist auch der Grund weshalb bei mir in den Templates bei <Statische Template-Dateien aus Erweiterungen:> nicht Standard, sondern <Nie vor diesem Template-Datensatz einschließen> steht.

Damit der Setup Code flexibel bleibt, wird im folgenden Code Beispiel das Menü über Constanten konfiguriert.

TypoScript Constanten


menu.language {
	# ID der Sprache, komma getrennt
	keys = 0,1,2,3
	# Labels für Menü pro Sprache, komma getrennt	
	labels = DE,EN,FR,IT
	# ID der Seite für Link, wenn keine Ãœbersetzung 
	uid.home = 1
}
constants.txt

TypoScript Setup


# file: language.ts
# info: Sprachwahl Navigation mit HMENU
# code: by thefox.ch

# SET Constants !
# -------------------------
# menu.language {
#  keys = 0,1,2,3
#  labels = DE,EN,FR,IT
#  uid.home = 1
# }

# Sprachmenü
lib.menu.language = COA
lib.menu.language {

		# load language menu data
	1 = LOAD_REGISTER
	1 {
		queryParams = &{getIndpEnv : QUERY_STRING}
		queryParams {
			if.isTrue.data = getIndpEnv : QUERY_STRING
			insertData = 1
		}
	}

		# Titel über Navigation
	5 = TEXT
	5 {
		# Nur für DEMO - Labels sollte man besser in XML auslagern.
		insertData = 1
		value (
			<h2 class="hidden">Sprache wählen</h2>
		)
	}

		# Navigation Sprachwahl
	10 = HMENU
	10 {
		wrap = <ul id="languageNavigation" class="language">|</ul>

		special = language
		special.value = {$menu.language.keys}
		special.normalWhenNoLanguage = 0

		1 = TMENU
		1 {
			noBlur = 1

			NO = 1
			NO {
				allWrap = <li class="first">|</li>||<li>|</li>
				doNotLinkIt = 1
				doNotShowLink = 1
				stdWrap2 {
					cObject = COA
					cObject {

						1 = LOAD_REGISTER
						1 {
							lParam.cObject = TEXT
							lParam.cObject {
								value = {$menu.language.keys}
								listNum {
									stdWrap.data = register:count_HMENU_MENUOBJ
									stdWrap.wrap = |-1
									splitChar = ,
								}
							}
							lLabel.cObject = TEXT
							lLabel.cObject {
								value = {$menu.language.labels}
								listNum {
									stdWrap.data = register:count_HMENU_MENUOBJ
									stdWrap.wrap = |-1
									splitChar = ,
								}
							}
						}

						10 = TEXT
						10 {
							typolink {
								useCacheHash = 1
								parameter.data = TSFE:id
								additionalParams.dataWrap = {register:queryParams}&L={register:lParam}

								title {
									current = 1
									setCurrent = {register:lLabel}
									setCurrent.insertData = 1
								}

								ATagParams = class="lang{register:lParam}"
								ATagParams.insertData = 1
							}
							current = 1
							setCurrent = {register:lLabel}
							setCurrent.insertData = 1
						}

						99 = RESTORE_REGISTER
					}
				}
			}

				# Aktive gewählte Sprache
			ACT < .NO
			ACT = 1
			ACT.allWrap = <li class="first cur">|</li>||<li class="cur">|</li>

				# Keine Ãœbersetzung vorhanden
			USERDEF1 < .NO
			USERDEF1 = 1
			USERDEF1 {
				allWrap = <li class="first na">|</li>||<li class="na">|</li>
				stdWrap2 {
					cObject {
						10 >

						10 = TEXT
						10 {
							typolink {
								parameter = {$menu.language.uid.home}
								additionalParams.dataWrap = &L={register:lParam}
								title {
									current = 1
									setCurrent = {register:lLabel}
									setCurrent.insertData = 1
								}
								ATagParams = class="lang{register:lParam}"
								ATagParams.insertData = 1
							}
							current = 1
							setCurrent = {register:lLabel}
							setCurrent.insertData = 1
						}

						99 = RESTORE_REGISTER
					}
				}
			}
		}
	}

	4 = RESTORE_REGISTER
}
language.ts
Varianten Setup

# wenn keine Ãœbersetzung, nicht verlinken ( per setup )
lib.menu.language.10.1.USERDEF1.stdWrap2.cObject.10.typolink >
lib.menu.language.10.1.USERDEF1.stdWrap2.cObject.10.dataWrap = <span class="lang{register:lParam}">|</span>

# wenn keine Ãœbersetzung, nicht anzeigen ( per setup )
lib.menu.language.10.1.USERDEF1.allWrap >
lib.menu.language.10.1.USERDEF1.stdWrap2 >

CSS Code


ul.language {
	margin: 0;
	padding: 0;
	list-style-type: none;
}

ul.language li {
	display: inline;
}

ul.language li a,
ul.language li.na span {
	padding: 0 5px;
	text-decoration: none;
	/*border-left: 1px solid #ccc;*/
}

ul.language li.first a {
	/*border-left-width: 0;*/
	padding: 0 5px 0 0;
}

/* variante mit flaggen */
ul.language li a,
ul.language li.na span {
	background-repeat: no-repeat;
	background-position: 4px 2px;
	text-indent: -999em;
	color: transparent;
}

ul.language li .lang0 {
	background-image: url(/typo3/sysext/t3skin/images/flags/de.png);
}

ul.language li .lang1 {
	background-image: url(/typo3/sysext/t3skin/images/flags/gb.png);
}

ul.language li .lang2 {
	background-image: url(/typo3/sysext/t3skin/images/flags/fr.png);
}

ul.language li .lang3 {
	background-image: url(/typo3/sysext/t3skin/images/flags/it.png);
}

/* wenn keine Ãœbersetzung, nicht anzeigen ( per css ) */
ul.language li.na {
	display: none;
}
CSS Beispiel Code für dieses Sprachmenü