Filter mal zum “Filtern” benutzen:

Mit der “outputfilter.note.php” kann man auch sinnvollere Sachen anstellen, als hartnäckige Shop-System-Hinweise unter die HTML-Ausgabe zu pappen. Ein Trick ist ganz einfach - hat aber große Wirkung …

Der Smarty-Outputfilter durchsucht die gesamte HTML-Ausgabe eines Shops und “macht irgendwas damit”. Standardmäßig wird nichts großartiges angestellt, in der üblichen Installation von xt:Commerce sorgt die Datei “outputfilter.note.php” (zu finden im Ordner “includes/classes/Smarty_2.6.14/plugins”) lediglich dafür, dass ganz am Ende die Geschichte von wegen “eCommerce Engine © 2006 xt:Commerce Shopsoftware” angezeigt wird.

 

“Marker-System”:

Spaßig wird die Sache dann, wenn man bestimmte Textmuster aus der HTML-Ausgabe entfernt. Denn auf die Weise kann man ein eigenes “Marker-System” zurechtbasteln, mit dem ein paar Sachen ganz plötzlich ganz einfach werden.

Mein Vorschlag: Alles, nach dem Muster {#irgendwas#} darf nicht angezeigt werden. Dazu einfach (kurz vor Ende) Folgendes einfügen:

$tpl_output = preg_replace("/({#[^#}]*#})/",'',$tpl_output);

Und das war’s im Prinzip schon. Der Rest sei der eigenen Phantasie überlassen.

 

Anwendungs-Möglichkeiten:

Angenommen, Sie haben einen B2B-Shop, bei dem nicht eingeloggte Benutzer keine Preise sehen dürfen. Das funktioniert je nach Kundengruppen-Einstellungen auch prächtig. Was aber, wenn Sie ein Komplett-Set aus mehreren Artikeln anbieten - und in der Artikelbeschreibung den eigentlichen Warenwert anzeigen möchten und darunter den “echten” Preis - um zu zeigen, was man beim Kauf sparen würde?

Ein Beispiel » hier

Eingeloggte Kunden würden anstatt der Fragezeichen Preisangaben sehen. Und das funktioniert so - Man “erfindet” eine neue “Marker-Regel” und schreibt im Artikeltext:

… lalala, alles Mögliche …
{#price#}Das ist nur für Kunden, die Preise sehen dürfen{#/price#}
{#noprice#}Das ist nur für Besucher, die keine Preise sehen dürfen{#/noprice#}
… lalala, und hier der ganze Rest …

Ungefiltert könnte man alles lesen. Wollen wir aber nicht.

Daher müssen wir dafür sorgen, dass alles zwischen
{#price#} und dem nächsten {#/price#}
für “normale Besucher” entfernt wird, und dass alles zwischen
{#noprice#} und {#/noprice#}
für “berechtigte” Besucher entfernt wird.

Das kann dann in im Outputfilter etwa so aussehen:


if($_SESSION['customers_status']['customers_status_show_price']) {
	$tpl_output = preg_replace("/(\{\#noprice\#\}[^\{]*\{\#\/noprice\#\})/usi",'',$tpl_output);
} else {
	$tpl_output = preg_replace("/(\{\#price\#\}[^\{]*\{\#\/price\#\})/usi",'',$tpl_output);
}

… Wem das zu “riskant” ist (Denn wenn einer der “schließenden” Marker vergessen oder falsch geschrieben wurde, fehlt eventuell die Hälfte des Shops) - der kann sich stattdessen aus der Geschichte einen Smarty-Modifier basteln und diesen auf die Products-Description anwenden.

Kommt prinzipiell aufs gleiche hinaus, fängt aber fehlerhafte Eingaben besser ab.

 

Weitere Ideen …

Es kann auch mal sein, dass man innerhalb von Artikeltexten oder ContentManager-Seiten auf weitere Shop-Seiten verlinken möchte. Die meisten Browser haben auch kein Problem damit, wenn man den Link “einfach so” in den Text einfügt.

Sauberer wäre aber eine Lösung, die “brav” mit der Funktion xtc_href_link(); arbeitet, damit die Session-ID nicht flöten geht. Bei manchen Browsern loggt man sich sonst nämlich versehentlich aus. Warenkorb ist wieder leer - Kunde sauer, muss nicht sein.

Allerdings wird PHP-Code in Artikeltexten, Kategorien-Beschreibungen und ContentManager-Seiten nicht interpretiert. Daher muss man sich etwas anderes einfallen lassen. Also wieder ein bisschen mit den “Markern” herumtricksen.

Mein Lösungs-Ansatz: Okay, dieses Code-Beispiel ist unvollständig, aber auch nur als Anregung gedacht …


function gunnartLinkHandler($Before,$LinkContent,$After) {
	if(preg_match("/\{#(.*)#\}/",$LinkContent,$Treffer)) {
		if(preg_match("/coid=(\d*)/i",$Treffer[1],$ContentManagerLink)) {
			$LinkContent=getContentManagerLink($ContentManagerLink[1]);
		} elseif(preg_match("/pid=(\d*)/i",$Treffer[1],$ProductsLink)) {
			$LinkContent=getProductsLink($ProductsLink[1]);
		} elseif(preg_match("/cat=(\d*)/i",$Treffer[1],$CategoryLink)) {
			$LinkContent=getCategoryLink($CategoryLink[1]);
		} elseif(preg_match("/(.*\.php)(.*)/i",$Treffer[1],$LinkedScript)) {
			if(file_exists($LinkedScript[1]))
				$LinkContent=xtc_href_link($LinkedScript[1]).$LinkedScript[2];
		}
	}
	return stripcslashes($Before.$LinkContent.$After);
}

function gunnartLinkFilter($Text){
	$LinkFilterSearch = '#(<a [^>]*href=["\'])((.*)([^"\']*))(["\'][^>]*>)#ismeU';
	return preg_replace($LinkFilterSearch,"gunnartLinkHandler(\"$1\",\"$4\",\"$5\")",$Text);
}

$tpl_output = gunnartLinkFilter($tpl_output);

	

… die Funktionen getContentManagerLink, getProductsLink und getCategoryLink fehlen hier … Sorry.

Das Prinzip sollte dennoch deutlich werden:

Statt wie bisher …

<a href="http://meinShop.de/index.php?cat=c34_Testkategorie-3-3.html">Testkategorie 3.3</a>

… schreibt man …

<a href="{#cat=34#}">Testkategorie 3.3</a>

… and that’s it. Keine vergurkten Session-IDs mehr, keine ungewollt geleerten Warenkörbe, weniger Gefriemel, kein Generve von wegen “unsichere Elemente” (bei http-Links auf https-Seiten) - Und wenn Link “ungültig ist” (Stichwort “Kundengruppen-Berechtigung”, “Kategorie/Produkt ist inaktiv” etc.) kann man in den “Link-generierenden Funktionen” dafür sorgen, dass auf eine Hilfe-Seite oder die Sitemap, auf die Startseite oder irgendwo-noch-ganz-woanders-hin-verlinkt wird …

Ist doch schick, oder?

Noch mal zum Code oben: Alle {#coid=123#} werden in Links zu ContentManager-Seiten umgewandelt, alle {#pid=234#} werden zu Produkt-Links umgewandelt, alle {#cat=456#} entsprechend zu Kategorien-Links. Und zu “Funktions-Seiten” (wie z.B. “account.php”) kann ebenfalls verlinkt werden, die Syntax wäre dann {#einScript.php#} bzw. {#einOrdner/einScript.php#}

 

Basteleien:

Oder: Man versteckt irgendwo in der Kategorienbeschreibung ein {#color:green#} - und (Schwupp) ist alles grün, wenn man die Kategorie gewählt hat.

Oder: Man schreibt einen Modifier, der meinetwegen {#quatsch#} durch das Bild
<img src="http://www.bloedebilder.de/huepfende_wollmilchsau.gif" />
ersetzt. Nicht ganz praxisnah, aber denkbar.

Das funktioniert: Denn der Outputfilter ändert nicht die ursprünglichen Inhalte von Smarty-Tags, sondern wirkt sich erst auf das “HTML-Gesamt-Ergebnis” aus. Es ist also egal, dass der Outputfilter alle “Marker” entfernt, man kann mit ihnen arbeiten, obwohl sie via Filter allesamt vor der Ausgabe gelöscht werden.

Oder: Man legt eine Kategorie “Mein Konto” an, schreibt {#account.php#} irgendwo mit rein - und schon hat man den “Mein Konto”-Link schön zusammen mit allen Kategorien in EINER Navigation drin. Wenn man das denn so will …

Mehr zu diesem Thema kommt bald - Zusammen mit der neuen “Advanced Show Category ZwoKommaNull”, die Beta gibt’s schon mal » hier
Nein, Sorry - inzwischen gibt’s die » hier!

 

Fazit:

Die “outputfilter.note.php” kennt sämtliche bekannten Funktionen. Das heißt - Wenn Sie irgendwo ein paar eigene Extra-Funktionen definiert haben sollten - Kann auch im Template sein - dann weiß die “outputfilter.note.php” schon davon.

In den meisten Fällen hat man also keinen weiteren Stress mit “require wowardenndasnoch/keinplan.inc.php”. Und mit ein paar Ideen kann man (ohne zusätzliche Datenbank-Felder etc.) seinem Shop mit einfachen Such- und Ersetz-Regeln Etliches an Zusatz-Funktionen beibringen.

:-)

Und wenn’s die entsprechende Zusatz-Funktion noch nicht gibt, macht’s auch nichts: Die Marker können ja (dank Outputfilter) nicht angezeigt werden.

Have Phun!