Wir wünschen frohe Weih­nachten und ein kreatives 2026 voller Ideen, Chancen und vielen schönen Momenten.

von 2D zu 3D

Wir haben weihnachtliche 3D-Animationen im neuen magenta-Look auf unseren Social-Kanälen für euch vorbereitet. Schaut mal rein und folgt uns!

Unsere Socials

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 = _COOKIE­cookieconsent_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 &amp;<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 Optionstext­Optionstext[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_pi1­field­facility
			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_pi1­field­facility
            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]',
		),
	),
);