Du bist nicht angemeldet. Der Zugriff auf einige Boards wurde daher deaktiviert.

#1 16. Mai 2015 06:19

Andynium
Moderator
Ort: Dohna / SN / Deutschland
Registriert: 13. September 2010
Beiträge: 7.018
Webseite

Smarty Delimiter selbst definieren

Smarty Delimiter - was ist das?

Delimiter, zu gut Deutsch Trennzeichen, markieren den Beginn und das Ende einer Smarty-Anweisung. Voreingestellt sind die geschweiften Klammer, neudeutsch Brackets, also {Smarty}.

Schön und gut, wo ist aber nun das Problem?

Es dürfte allgemein bekannt sein, dass nicht nur in Smarty, sondern zum Beispiel auch in Javascript und CSS die geschweiften Klammern verwendet werden

<script type="text/javascript">
        $(document).ready(function () {
            $('ul.tree li:last-child').addClass('last');
        });
    </script>

Beim Einfügen in die Templates oder Inhalte von CMSMS hätte dies zur Folge, dass Smarty versuchen würde, alles in den geschweiften Klammern enthaltene als Anweisung auszuführen. Da Smarty aber mit Javascript hier nix am Hut hat, geht das natürlich schief.

Was tun? sprach Zeus.

Hierfür bringt Smarty die sogenannten literal Tags mit, die so eingesetzt werden

{literal}
    <script type="text/javascript">
        $(document).ready(function () {
            $('ul.tree li:last-child').addClass('last');
        });
    </script>
{/literal}

Stößt Smarty auf eine solche literal Anweisung, wird vereinfacht gesagt der in diesem Block stehende Inhalt von Smarty ignoriert.

Mit Smarty 3 wurde eine weitere Möglichkeit geschaffen, Javascript u.ä. einzufügen, und zwar so

Wer die Neuerung nicht auf Anhieb erkennen kann - nach der öffnenden und vor der schließenden Klammer findet sich ein Leerzeichen (Whitespace). Auch dieses Zeichenmuster veranlasst Smarty, nunmehr den Blockinhalt zu ignorieren.

Jedoch hält Smarty noch eine dritte Möglichkeit bereit - die Definition eigener Delimiter.

Diese Möglichkeit wurde bei CMSMS für den Einsatz von Smarty in den Stylesheets genutzt, wo zum Beispiel dies

zu sehen ist. Die geschweiften Klammern wurden durch doppelte eckige Klammern ersetzt. Was genau dafür getan wurde, findet sich in /plugins/function.cms_stylesheet.php

	// Smarty processing
	$smarty->left_delimiter = '[[';
	$smarty->right_delimiter = ']]';

Da dies nur für die Stylesheets gelten soll, wird dies nach Verarbeitung der Stylesheets auf den Smarty Standard zurückgesetzt.

	$smarty->left_delimiter = '{';
	$smarty->right_delimiter = '}';

Das ganze lässt sich natürlich auch systemweit einsetzen. Ansatzpunkt ist hier /lib/classes/class.Smarty_CMS.php

Dort einfach an diesen Block

        // Set template_c and cache dirs
        $this->setCompileDir(TMP_TEMPLATES_C_LOCATION);
        $this->setCacheDir(TMP_CACHE_LOCATION);
        $this->assign('app_name','CMS');

folgendes anfügen

	// Smarty processing
	$this->left_delimiter = '[[';
	$this->right_delimiter = ']]';

Anschließend ALLE Smarty-Anweisungen auf [[Smarty]] ändern und - ganz wichtig - die Verzeichnisse /tmp/cache und /tmp/template_c manuell leeren!

Fertig!

Bei der Wahl der Delimiter seid ihr relativ frei - so könntet ihr wie von anderen Template Engines bekannt doppelte geschweifte Klammern ({{Smarty}}), aber auch Zeichenmixe wie {#Smarty#} verwenden.

Jedoch solltet ihr unbedingt darauf achten, keine PHP-seitig vorbelegte Zeichen zu verwenden wie zum Beispiel __Smarty__ (womit Konstanten gekennzeichnet werden).

PS: Sämtliche o.g. Zeilen des cms_stylesheet Plugins werden nicht mehr benötigt, und sollten deshalb unbedingt auskommentiert werden (einfach # jeder Zeile voran stellen).

Offline

#2 19. Mai 2015 12:43

Andynium
Moderator
Ort: Dohna / SN / Deutschland
Registriert: 13. September 2010
Beiträge: 7.018
Webseite

Re: Smarty Delimiter selbst definieren

Übrigens - die Smarty Delimiter kann man sich auch anzeigen lassen ... mit den Tags {ldelim} für den linken und {rdelim} für den rechten Trenner.

Ist ganz nützlich, wenn man z.Bsp. in auf einer Seite die Verwendung von Smarty-Befehlen erklären möchte (wo ja der Smarty-Anweisung eben gerade nicht ausgeführt werden soll).

Hier dazu ein Beispiel aus den letzten News auf der .de

http://www.cmsmadesimple.de/news/131/173/CMSMS-1-12-Pohnpei-veroeffentlicht/d,cmsms_detail.html schrieb:

... sollten Sie unbedingt die Smarty-Anweisung {ldelim}eval} sowohl aus allen Zusammenfassungs- als auch Detail-Templates entfernen ...

Oder auch für Javascript, was nicht von Smarty verarbeitet werden soll

<script type="text/javascript">
        $(document).ready(function () {ldelim}
           $('ul.tree li:last-child').addClass('last');
        });
    </script>

Entscheidend dabei ist, dass nur der linke Delimiter entsprechend ersetzt wird.

Offline

#3 20. Februar 2016 16:04

Andynium
Moderator
Ort: Dohna / SN / Deutschland
Registriert: 13. September 2010
Beiträge: 7.018
Webseite

Re: Smarty Delimiter selbst definieren

cyberman schrieb:

Übrigens - die Smarty Delimiter kann man sich auch anzeigen lassen ... mit den Tags {ldelim} für den linken und {rdelim} für den rechten Trenner.

... oder auch etwas performanter über die Variablen {$smarty.ldelim} und {$smarty.rdelim} wink.

Und der Vollständigkeit halber hier der Link zur Smarty-Dokumentation

http://www.smarty.net/docs/en/language.escaping.tpl

Offline

#4 07. April 2016 23:38

Andynium
Moderator
Ort: Dohna / SN / Deutschland
Registriert: 13. September 2010
Beiträge: 7.018
Webseite

Re: Smarty Delimiter selbst definieren

cyberman schrieb:

Beim Einfügen in die Templates oder Inhalte von CMSMS hätte dies zur Folge, dass Smarty versuchen würde, alles in den geschweiften Klammern enthaltene als Anweisung auszuführen. Da Smarty aber mit Javascript hier nix am Hut hat, geht das natürlich schief.

Eine weitere und eher unbekannte Option für das Einfügen von Javascript ist ein Nutzerdefinierter Tag bzw. auch als UDT bekannt. Dessen ganzes Geheimnis ist es, dass UDT's (anders als die Globalen Blöcke) von Smarty NICHT verarbeitet werden und damit für diesen Zweck ebenso geeignet sind.

In der Praxis sieht das so aus

?>
<script language="JavaScript" type="text/javascript"> 
if (window.print) {
document.write('<a href="javascript:window.print()">Drucken</a>');
}
</script>
<?php

Ja, richtig erkannt - als erstes wird die Verarbeitung durch PHP gestoppt (?>) und nach Abarbeitung des Scripts wieder gestartet(<?php). Dadurch kann dazwischen so ziemlich alles erscheinen, was auf einer Webseite möglich ist, HTML, CSS, Javascript etc.

Ein positiver Nebeneffekt dieser Vorgehensweise ist, dass man sich die echo Befehle für die Ausgabe des Javascripts spart (und damit auch die ansonsten erforderliche Maskierung der Anführungszeichen) wink ...

Offline

#5 15. September 2016 10:50

Andynium
Moderator
Ort: Dohna / SN / Deutschland
Registriert: 13. September 2010
Beiträge: 7.018
Webseite

Re: Smarty Delimiter selbst definieren

cyberman schrieb:

Bei der Wahl der Delimiter seid ihr relativ frei - so könntet ihr wie von anderen Template Engines bekannt doppelte geschweifte Klammern ({{Smarty}}), aber auch Zeichenmixe wie {#Smarty#} verwenden.

Der Vollständigkeit halber - die Delimiter beschränken sich natürlich nicht nur auf die genannten Zeichen, sondern lassen sich sowohl in Art und Länge relativ frei wählen.

So wäre es z.Bsp. möglich, die Delimiter wie einen HTML-Tag aussehen zu lassen (der natürlich nicht belegt sein darf wink)

	// Smarty processing
	$this->left_delimiter = '<CMSMS>';
	$this->right_delimiter = '</CMSMS>';

dessen praktischer Einsatz dann so aussieht

Offline