Cookie Consent in TYPO3
Es bietet sich an Variablen für Cookie Consent in TypoScript sprachabhängig zu setzen.
lib.cookieconsent = COA
lib.cookieconsent {
10 = TEXT
10.value (
<script src="/path-to-js/cookieconsent.js"></script>
<script>
window.addEventListener("load", function() {
window.cookieconsent.initialise({
"position": "top",
"static": true,
"content": {
"message": "{$cookieconsent.message_de}",
"dismiss": "{$cookieconsent.dismiss_de}",
"link": "{$cookieconsent.linkText_de}",
"href": "{$cookieconsent.href_de}"
}
})
});
</script>
)
}
Zusätzlich empfiehlt es sich, das Skript gar nicht mehr mitzuschicken, sobald der Benutzer eingewilligt hat. Auf das Einwilligungscookie kann man in TypoScript wie folgt reagieren:
[globalVar = _COOKIEcookieconsent_status = dismiss]
lib.cookieconsent >
[global]
Kategorien von News vom Typ "Interner Link" auslesen, die auf der aktuellen Seite gelistet sind.
Angenommen, man möchte – ob nun aus Notwendigkeit oder weil es so einfacher wird – News vom Typ "Interner Link" verwenden, die ja auf ganz normale Inhaltsseiten verweisen. Gleichzeitig sollen am Fuß dieser Seiten die Kategorien angezeigt werden, am besten noch mit Links zu Newsübersichten mit der jeweiligen Kategorie. Am schönsten wäre es, wenn die Kategorien dazu nicht auf den Seiten selber gepflegt werden müssten, sondern nur in den Newsdatensätzen – wie es bei Standard-News ja auch gemacht wird.
Nichts leichter als das! (*hust)
10 = CONTENT
10 {
wrap (
<p>
<span class="news-legend">Categories:</span>
<span class="news-list-category"></span>
</p>
)
table = sys_category
select {
pidInList = 1
recursive = 99
selectFields = sys_category.uid, sys_category.parent, sys_category.title
join = sys_category_record_mm ON (sys_category_record_mm.uid_local = sys_category.uid) JOIN tx_news_domain_model_news ON (sys_category_record_mm.uid_foreign = tx_news_domain_model_news.uid)
where.dataWrap = sys_category_record_mm.tablenames='tx_news_domain_model_news' AND tx_news_domain_model_news.internalurl = 't3://page?uid={TSFE:id}' AND tx_news_domain_model_news.hidden = 0
where.noTrimWrap = AND (sys_category.parent = 16 OR sys_category.uid IN (1,2,3,4,5))
}
renderObj = COA
renderObj {
10 = TEXT
10 {
field = title
typolink {
parameter = 123
additionalParams.data = field:uid
additionalParams.wrap = &tx_news_pi1[overwriteDemand][categories]=
useCacheHash = 1
}
wrap =
}
}
}
Mehrsprachigkeit in TYPO3
Beim Erstellen von mehrsprachige Websites geht es nicht allein darum, den Besuchern die Seiteninhalte in ihrer präferierten Sprache zu präsentieren. Besonders wichtig ist auch die einfache Pflege der mehrsprachigen Inhalte.
In TYPO3 sind Inhalte in mehreren Sprachen kein Problem. Steht fest, welche Sprachen verwendet werden sollen, muss sich für eine Sprache als Standardsprache entschieden werden. Nun ist es möglich, alle Sprachversionen einer Seite nebeneinander anzuzeigen, wobei auch klar wird, welche Elemente noch ihrer Übersetzung harren. Inhalte, die nur in einer Sprache verfügbar sind, können entweder ausgeblendet oder in der Standardsprache abgebildet werden.
Auch die Bedienung des TYPO3-Backends stellt für fremdsprachige Redakteure keine Hürde dar. Nach Installation der notwendigen Sprachpakete (derzeit werden 51 Sprachen unterstützt) kann das Backend in der gewünschten Sprache dargestellt werden.
Menüpunkte mal einzeilig und mal mehrzeilig
Was tun, wenn der gleiche Menüpunkt einmal zweispaltig (im Desktop-Menü) und einmal einspaltig (im Mobil-Menü oder der Sitemap) dargestellt werden soll und man dabei noch die Stelle des Umbruchs kontrollieren möchte? Die Lösung besteht in folgender Konstruktion für den Menüpunkt:
<li>Hydropower &<span> <br/></span> Water Resources</li>
Die Stelle des Umbruchs wird durch das br-Tag kontrolliert, das man bei Bedarf per CSS verstecken kann. Dass es zusammen mit einem Leerzeichen in span-Tags eingeschlossen ist, verhindert ein Zusammenfallen, in unserem Beispiel also die Ausgabe von „&Water“ ohne Leerzeichen.
Die Ausgabe von Tags muss natürlich dazu erlaubt sein, im Falle der Sitemap z. B. mit tt_content.menu.20.2.1.NO.stdWrap.htmlSpecialChars = 0
News: Nur verwendete Tag ausgeben
Wie findet man alle Tags aus einem bestimmten Ordner, die auch tatsächlich in News verwendet werden, und rendert sie in eine versteckte Liste? So:
lib.tags = CONTENT
lib.tags {
wrap = <div class="tags" aria-hidden="true" hidden></div>
table = tx_news_domain_model_tag
select {
pidInList = 1234567890
selectFields = tx_news_domain_model_tag.uid, tx_news_domain_model_tag.title
join = tx_news_domain_model_news_tag_mm ON (tx_news_domain_model_news_tag_mm.uid_foreign = tx_news_domain_model_tag.uid) JOIN tx_news_domain_model_news ON (tx_news_domain_model_news_tag_mm.uid_local = tx_news_domain_model_news.uid)
where = tx_news_domain_model_news.hidden = 0
andWhere = tx_news_domain_model_news.deleted = 0
groupBy = tx_news_domain_model_tag.title
}
renderObj = COA
renderObj {
wrap = <div></div>
10 = TEXT
10 {
field = title
case = lower
wrap = <span class="title"></span>
}
}
}
Powermail: Textfelder richtig validieren
Die Standardvalidierung „Zeichen“ erlaubt keine Umlaute oder überhaupt diakritische Zeichen. Man kann aber alle Textfelder auf die Validierung mit folgendem regulärem Ausdruck umstellen:
[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇߨøÅ寿œ ]+
Wenn man jetzt aber noch Felder hat, die einen anderen regulären Ausdruck brauchen, stößt man womöglich auf ein weiteres Problem: Man kann in Powermail nur eine Fehlermeldung für alle Felder des gleichen Typs definieren. Das Problem lässt sich jedoch leicht lösen, weil die Fehlermeldungen in einem Data-Attribut in den HTML-Quelltext geschrieben werden und dort natürlich per JavaScript auch einfach veränderbar sind; ausgegeben werden sie letztlich auch per JavaScript, nämlich über die Parsley-Bibliothek.
Kurz: Einfach das Attribut data-parsley-error-message abhängig von anderen Kriterien wie dem Input-Namen per JavaScript überschreiben.
Powermail: Kategorien als Select-Options, E-Mail-Adressen aus den Kategorien verwenden
Im folgenden Szenario möchten wir aus redaktionell pflegbaren Kategorien (sys_category) ein select-Dropdown in Powermail erzeugen. Die ausgewählte Kategorie soll natürlich im Zwischenschritt zur Formularbestätigung bis zum finalen Absenden der Werte erhalten bleiben und dabei in einer Weise angezeigt werden, die den Benutzer nicht verwirrt. Die E-Mail-Benachrichtigung soll dann an die Adresse gesendet werden, die in der Kategorie hinterlegt ist. Klingt einfach, kann kompliziert werden.
Wir bauen uns zunächst die Optionen zusammen:
lib.messages_options = CONTENT
lib.messages_options {
table = sys_category
select {
andWhere = parent = 0
orderBy = title
pidInList = {$contentpage.categoriesFacilities}
}
renderObj = COA
renderObj {
10 = LOAD_REGISTER
10.parentTitle.dataWrap = {field:title}
15 = TEXT
15.value = -Einrichtung des Bewohners-[\n]
20 = CONTENT
20 {
table = sys_category
select {
andWhere.dataWrap = parent = {field:uid}
orderBy = title
pidInList = {$contentpage.categoriesFacilities}
}
renderObj = COA
renderObj {
10 = TEXT
10.data = register:parentTitle
10.noTrimWrap = –
20 = TEXT
20.field = title
30 = TEXT
30.value =
40 < .10
41 < .20
50 = TEXT
50.field = uid
50.wrap = []
stdWrap.wrap = [\n]
}
}
30 = RESTORE_REGISTER
}
}
Diese lib.messages_options müssen im Formularfeld dann in „Aus TypoScript generieren“ eingetragen werden. Dabei kommt ein Wert nach dem Schema OptionstextOptionstext[id der Option] heraus. Diesen Wert muss man für die sichtbare Ausgabe auf Bestätigungsseiten, Mails usw. filtern:
plugin.tx_powermail.settings.setup. manipulateVariablesInPowermailAllMarker {
confirmationPage {
// manipulate values by given marker (e.g. firstname, email, referrer) with TypoScript - available fieldnames (access with .field=): value, valueType, uid, pid
// Manipulate FE output of facility marker
facility = TEXT
facility {
// Fill with GET data from facility field, which has
// the uid appended in brackets for recipient mail selection
data = GP:tx_powermail_pi1fieldfacility
split {
token = [
// Option split 1 2 needed because we want to access the
// facility name and the uid separately. With just
// cObjNum = 1 the parts before and after the split token
// would be treated the same.
cObjNum = 1 2
// Display the part before the split token …
1.current = 1
// … but not the part after: 2.current = 1 is not used.
}
}
}
submitPage.facility < .confirmationPage.facility
receiverMail.facility < .confirmationPage.facility
senderMail.facility < .confirmationPage.facility
optinMail.facility < .confirmationPage.facility
}
Für die Verarbeitung und Auswahl der richtigen E-Mail muss wiederum die id der Option vom Rest gefiltert werden. Man beachte auch den im Kommentar genannten Fluid-Code, der ins Powermail-Formular eingetragen werden muss (anders als oben reicht lib.messages_receiver alleine nicht aus):
// The select values from lib.resident_messages_options contain both the
// facility name, which is a compound of two category titles, and the uid in
// brackets. We remove the brackets for display in FE above in
// manipulateVariablesInPowermailAllMarker, and in a similar way we remove
// anything but the uid here to select the proper category and from that
// the e-mail address set therein.
// Mails are sent to all e-mail addresses from the category field notification_emails
// if the following is filled in the recipient field of the form:
// {f:cObject(typoscriptObjectPath:'lib.messages_receiver')}
lib.messages_receiver = CONTENT
lib.messages_receiver {
table = sys_category
select {
andWhere {
wrap = sys_category.uid=
data = GP:tx_powermail_pi1fieldfacility
split {
token = [
cObjNum = 1 2
2.current = 1
2.intval = 1
}
}
orderBy = title
pidInList = {$contentpage.categoriesFacilities}
}
renderObj = TEXT
renderObj {
field = notification_emails
}
}
Suche mit EXT:ke_search und schöner Realurl der ersten Seite
Beim Absenden des Suchformulars wird die Realurl-Konfiguration ignoriert, sodass die URL der ersten Ergebnisseite mit all ihren Parametern in Rohform aufgerufen wird. Bei der anschließenden Navigation in den Suchergebnissen wird die Realurl-Konfiguration dann berücksichtigt. Damit ist es auch möglich, die Seite 1 der Suchergebnisse aufzurufen, und dies machen wir uns zunutze. Mit etwas JavaScript ändern wir das action-Attribut des Formulars ab, damit es ausdrücklich die Seite 1 der Suchergebnisse anfordert. Das sieht etwa so aus:
function initSearchSubmitForRealURL() {
$('#form_kesearch_pi1').submit(function(evt) {
evt.preventDefault();
evt.stopImmediatePropagation();
var sword = '';
var elSword = $('#ke_search_sword');
if (!elSword.length)
return;
sword = elSword.val();
if (!sword.length)
return;
var href = $(this).attr('action');
if (!href.length)
return;
href = href.replace('.html', '');
href = href.replace(/\/?$/, '/');// add trailing slash
href += 'suchbegriff/' + sword + '/ergebnisseite/1.html';
document.location.href = href;
});
}
Auf die Abfrage, ob elSword existiert, könnte auch verzichtet werden, ich neige aber dazu, lieber einmal zu oft zu prüfen anstatt JS-Fehler zu riskieren. Die Realurl-Konfiguration ist passenderweise natürlich:
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['postVarSets']['_DEFAULT'] => array( 'suchbegriff' => array( array( 'GETvar' => 'tx_kesearch_pi1[sword]', ), ), 'ergebnisseite' => array( array( 'GETvar' => 'tx_kesearch_pi1[page]', ), ), );