RewriteRule nur für nicht vorhandene Dateien

… oder wie stelle dynamische Inhalte in statischen webEdition Seiten dar?

Die Apache RewriteRule kennt wohl jeder, der etwas mehr mit Webseiten macht. RewriteCond sollte auch bekannt sein, allerdings hatte ich bisher diese beiden Direktiven nicht in dieser Form miteinander verbunden.

Das Problem:

Ursächlich war, dass ich in webEdition Seiten dynamische Inhalte anzeigen wollte. Die Inhalte kommen von extern und somit wollte ich a) die Seite nur einmal bauen und b) einen Teil der Inhalte von ausßen dynamisch füllen (z.B. die neuesten Twitter-Feeds oder oder oder).

Nun merke ich schnell: Ist eine webEdition Seite einmal als “statisch” definiert, dann ist diese auch genau das: statisch. Es ist HTML, webEdition zieht alle Informationen die es braucht in dem Moment aus alles Quellen und schreibt eine .html-Seite. Mehr nicht. Aber genau das soll webEdition ja auch machen. Also kein Grund zum meckern … oder? Bedingt.

Ja, webEdition macht rein technisch alles richtig, nur will ich doch in einer Sidebar dynamische Inhalte haben 🙁

Okay, Seite auf “dynamisch” umstellen und dann: Lasse ich die Dateiendung auf .html, dann sehe ich nur PHP-Code.

Sicher, ich könnte nun die Dateiendung umstellen – auf .php funktioniert das ganze wie gewünscht – aber das ist weder Sinn der Übung, noch ist das gewünscht; Stichwort Kundenwunsch!

Lösungsvorschläge:

Also, hier der andere Weg: mod_rewrite.

Der einfachste Weg: Alles, was .php heißt in .html umleiten, aber Halt! Der erfahrende Mensch sieht: Das geht schief, denn es können durchaus .php Dateien auf dem Server liegen, die auch ausgeführt werden wollen.

Lösungsvorschlag 1:

AddHandler-Direktive nutzen.
Man könnte die AddHandler Direktive nutzen und allen .html-Code als PHP ausführen lassen. Bei statischen Seiten würde dies nur sehr geringen Zeitverlust bedeuten und es würden die .html-Seiten auch korrekt ausgeführt, die PHP-Code beinhalten (also unsere dynamischen webEdition Seiten).

Lösungsvorschlag 2:

Bedingtes Umleiten!
Funktioniert Lösung 1 nicht (warum auch immer) oder ist dieser Weg nicht gewünscht (der Kunde ist doch König), dann sollte man es so versuchen – und kommen damit wieder zur Überschrift zurück (was für ein Handlungsbogen).
Man leitet alle Anfragen auf .html-Seiten, die nicht existieren, auf .php-Seiten um, die exakt so heißen, wie die .php Version.

Schritt 1: Zuerst werden die webEdition-Seiten geparkt, als dynamisch markiert und dann als xyz.php gespeichert.

Schritt 2: In der .htaccess wird folgende neue RewriteCond mit folgender RewriteRule ergänzt … ich habe diese ganz ans Ende gepackt, kommt aber immer auf den individuellen Fall an:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html $1.php [L]

So werden nun nur die .html-Aufrufe an .php-Scripte übergeben, deren .html-Datei nicht real auf dem Dateisystem des Servers existiert.

Viel Erfolg…

flattr – Social Payment System

So, auch ich bin dabei, bei flattr; flattr, das ist ein Online-Bezahldienst … “*gähn* Kenn ich” kommt jetzt. Klar, PayPal, Moneybookers usw. kennt ihr, aber flattr ist etwas anderes, aber um das zu erklären, muss ich etwas ausholen:

Wie war es bisher?
Bisher sah man ein tolles Angebot und dachte “*wow* DAS ist wert, dass ich was dafür gebe” (z.B. Hilfe bei einem Problem, der in einem guten Blogeintrag ausführlich erklärt und gelöst wird) und dann konnte man

a) etwas aus der Amazon-Wunschliste für denjenigen bestellen, dass war aber alles zu teuer oder
b) per PayPal etwas “spenden”, aber da wollte PayPal wieder was von haben und überhaupt muss man da ja eh mindestens drölfundzwanzig Mark fuffzich bezahlen … und das ist zu teuer oder
c) man finden eine möglichkeit c) überhaupt.

Und nun?
Nun gibt es flattr. Bei flattr zahlst du monatlich einen kleinen Beitrag ein (ab 2 Euro je Monat) und die werden dann verteilt. Verteilt? Wohin? Eben! flattr bietet flattr-Buttons an, die ein Macher eines “Dings” – so heißen die Sachen, die man flattrn kann (dazu gleich mehr) – auf seiner Homepage einbauen kann.

Klickst du nun auf so einen flattr-Button, so wird dein monatliches Salär geteilt und zwar gleichmäßig auf alle flattr-Buttons, die du in diesem Monat geklickt hast.

Beispiel: Du hast dein monatliches Limit bei 2 Euro und klickst bei 20 Sachen auf den flattr-Button. Dann bekomt jeder der 20 Anbieter deine 2 Euro durch 20 geteilt, also 10 cent.

Das ist einfach für dich, weil du nur einmal anstatt 20 mal was überweist und das ist einfach für den Anbieter, weil der nur einmal den Code einbauen muss.

Rechts in der Menüleiste habe ich auch so einen flattr-Button und möchte mal sehen, wieviel sowas bringt.

Nun noch 2 negative Sachen zu flattr, die mir auffallen:

  1. Wenn ich in einem Monat nix anklicke, dann gehen mir trotzdem die 2 Euro flöten (für “charity”, wie es bei flattr in den FAQ heißt). Ich muss also zahlen, um mitmachen zu dürfen. Very social 🙁
  2. Aus 1 folgt 2: Ich muss etwas einzahlen. In der Hoffnung, etwas “Belohnung” aus Blog, Software oder wtf-auch-immer zu ziehen, muss ich erstmal bezahlen. Erinnert mich an die Simpsons-Folge wo Homer einen Internetprovider aufmacht und auf Nachfrage, ob er denn diese oder jene Sachen anbietet die Antwort gibt: “Bitte zahlen Sie erst…”

Ich werde flattr testen, erwarte aber nichts davon. Wahrscheinlich sind die 2 Euro, die ich investeirt habe, reines Lehrgeld. Du merkst schon, ich bin nicht so der flattr-Fan, lasse mich aber gern überzeugen.

webEdition kann PHP nur eingeschränkt

Das webEdition – CMS ist bekannt dafür, dass es einiges kann und viel Arbeit erzeugen kann. Dafür ist es u.a. möglich, beliebigen PHP Code in die Templates zu schreiben.

Dachte ich …

Allerdings kann webEdition PHP nur eingeschränkt, was ich am Beispiel eines Quellcodes verdeutlichen will. Ebenfalls soll hier eine Liste entstehen, was ich wann entdecke und wann es ggf. behoben wird.

  1. [28.05.2010] && und AND
    Die Verkettungsoperatoren && und AND sind ja für die “normale” Programmausführung relativ gleich (es wird eine UND-Verknüpfung erstellt), lediglich der Rang der Operator-Rangfolge ist anders (&& ist “(ge)wichtiger”).
    webEdition kennt AND überhaupt nicht, obwohl beide zum PHP-Sprachkern gehören.
    Bringt man nun in einem webEdition Template z.B. eine if-Abfrage mittels AND ein, so gibt webEdition für alles nach (!) dem ersten Ausdruck true zurück. Wählt man den ersten Ausdruck also etwas unglücklich, kommt im betreffenden if immer true zurück und somit wird Code ausgeführt, den man eigentlich erst unter bestimmten Bedingungen ausführen wollte.

Mal schauen, wann das webEdition Team das ganze behebt. Eine Rückmeldung an mich wäre toll, da ich das ganze nicht jeden Tag gegenprüfe.

webEdition xmlfeed, xmlnode und xpath

Möchte Mensch in webEdition bei Benutzung der xmlnode mehr als nur die Standard Methoden aus XPath verwenden, muss Mensch wirklich aufpassen. Ein Fehler in der Verarbeitung der Eingaben führt zu einer Kuriosität, die Mensch wissen sollte.

Folgender Code zu Testzwecken:



Title:

Wer XPath kennt, der weiß, was passieren soll. Innerhalb des XML gibt es den Punkt “/rss/channel” , unter diesem Punkt existieren beliebig viele “item” Knoten, von diesen sollen nur die ersten beiden ausgelesen werden.

Allerdings: Der o.a. Code führt zu

Parse error: syntax error, unexpected ‚}‘ in /home/user/public_html/webEdition/we/tmp/c9dc681659bd7c5703d6223dfd485587 on line 186

Generell ist der Code aber korrekt, ein Fehler in webEditions Verarbeitung des “xpath” Attributs verhindert aber die Ausführung.

Der korrekte Code für die Zeile der 2ten xmlnode lautet:

Mensch sieht also sofort: Hier müssen die XPath Argumente HTML Encoded werden.

Nur zur Info …

Templates einbinden mit webEdition

Das schöne an webEdition ist, dass man sog. Mastertemplates verwenden kann. Das noch viel schönere ist, dass diese Mastertemplates wiederrum wieder Mastertemplates haben können – die Master rufen sich dann sozusagen rekursiv auf, bis es ein “normales” Template gibt, dass die Inhalte eingibt.

Auch schon gelöst ist, dass man in einem webEdition Template andere Templates einbinden kann – mittels we:include, dem man entweder die ID des Template gibt, dass eingebunden werden soll oder eben den sog. path, also den Pfad inklusive Namen und Erweiterung des Templates. Schöne Sache, das.

Weniger schön ist dagegen ein webEdition Projekt, welches – bedingt durch über ein halbes dutzend Sprachen und vielen, vielen Vorlagen – eine 3 stellige Template Zahl beinhaltet und das ist unzählbar vielen Ordnern. Wow.

Und nun der eigentliche Punkt: Ein Blick in das deutsche Mastertemplate zeigt:

Okay, und nun? Ich muss eine Änderung an diesem Template durchführen, aber welches ist nun Template 1308? Es bleibt einem nichts anderes übrig, als mit der Maus über jedes Element zu fahren, um im Hover dann die ID zu sehen. #Nerv.

Daher: Bitte, bitte, liebe webEdition Template Editoren: Benutzt NICHT das ID-Tag, nehmt das path-Attribut des we:include.

Ich finde, das hier sieht schon viel freundlicher aus und läßt sich, zumindest meiner bescheidenen Meinung nach, viel besser und schneller finden:

Ist zwar mehr Tipparbeit, aber grade im Team sehr hilfreich. Denkt auch daran, was passiert, wenn ihr nach 2 Jahren mal wieder so ein Projekt pflegen müsst und zwischendurch 18 andere Projekte bearbeitet wurden … ihr blickt wahrscheinlich selbst nicht mehr durch und fragt euch, welcher Idiot da das ID-Tag ben…oh, das war ja ich *ups*

In diesem Sinne…

Erste Einsendeaufgabe ist zurück …

… und ich habe 100 von 100 Punkten.

Eine kleine Anmerkung vom Korrektor war dabei, ansonsten hieß ist überall “alles korrekt”.

Das sind dann schon mal die ersten 5 Bonuspunkte für die Klausur. Ich erwarte natürlich nicht, dass das bei allen EA’s so weitergeht, aber es motiviert einen schon mal.

Derzeit sitze ich an EA2 und muss noch die letzten beiden Aufgaben erledigen; dafür habe ich nun noch 4 Abende Zeit – heute eingerechnet.

FROM_UNIXTIME mit negativen Werten berechnen

Benutzt man die mySQL Funktion FROM_UNIXTIME mit negativen Werten, so gibt diese null zurück (zumindest ab einer Version nach 4.0.x).

Der Tip oder besser Workaround lautet: Berechnet das Datum dann doch bitte in der Anwendung, nicht in der Datenbank.

Ich bin generell kein Freund von Workarounds, da diese das Gefühl von “Hilfskrampe” hinterlassen. Also habe ich mal länger geforscht und bin dabei auf diese Sinnvolle Konstruktion gestoßen, die mir das gewünschte Datum korrekt zurückliefert. Das ganze kann man auch schön in mySQL auch mit DATE_FORMAT formatieren.

Im Prinzip ist es recht simpel: Ist das Feld positiv (inklusive 0), dann einfach die funktionierende Variante benutzen, ist es negativ, dann ausgehend vom UNIX_TIMESTAMP(0) via DATE_ADD in Sekundenschritten zurück gehen.

Der UNIX_TIMESTAMP steht in meinem Beispiel im Feld “geburtstag” und gibt entweder direkt den Wert zurück oder den umformatierten:

IF (geburtstag>=0,FROM_UNIXTIME(geburtstag),DATE_ADD(FROM_UNIXTIME(0),INTERVAL geburtstag SECOND) )

Ich hoffe, ich erspare auf diesem Weg dem ein oder anderen langes suchen.

Smarty und der dynamische Zugriff auf Arrays

Innerhalb einer Smarty {section} muss auf ein Array zugegriffen werden, allerdings mit dem Array-Index eines anderen Arrays. Abhängig von der Position der {section} kommt also immer ein anderer index.

Beispiel:

{section name=”num” loop=$data1}
  {$data1[num].ID}
{/section}

In {$data[num].ID} steht der Index des Arrays “data2”, auf den ich zugreifen möchte.

Allerdings, so ein Konstrukt funktioniert dann nicht:

{section name=”num” loop=$data1}
  {$data2.daten[$data1[num].ID]}
{/section}

{$data2.daten} ist wiederrum ein array und dort stehen dann die Daten drin. Leider funktioniert diese Methode nicht.

Nach kurzem und scharfen Nachdenken kam ich dann drauf, man setzt eine temporäre Smarty-Variable, abhängig vom Wert der {section} und das geht mit {assign}:

{section name=”num” loop=$data1}
{assign var=”meineID” value=$data1[num].ID}
  {$data2.daten[$meineID]}
{/section}

Gut zu wissen…

IE8 erkennt den CSS Child Selector nicht

Das Problem: In IE8 funktioniert der CSS Child Selektor > nicht. Warum auch immer. In den “Entwicklertools (F12)” wird im Reiter “Layout” eine “width” von 290px gezeigt, im Reiter “Format” steht ganz klar die “width” auf “500px !important;”.

Was nun?

Nach langer Suche die Lösung und zwar bei Microsoft direkt.

Note   Combinators are enabled only in standards-compliant mode (strict !DOCTYPE).

Quelle: http://msdn.microsoft.com/en-us/library/aa358819.aspx

Und in meinem Fall war es dann so, dass es eine alte “Debugausgabe” gab, die dann den IE8 wohl daran hinterte, den !DOCTYPE richtig zu erkennen. Somit wurden eben viele Funktionen deaktiviert, auch die Child Selektoren.

Debug ausgabe raus, !DOCTYPE rutscht in die erste Zeile, Ausgabe stimmt, alles okay.

POST Parameter in JavaScript benutzen

Nachdem der letzte Beitrag wohl etwas irreführend war, hier mal ein Bericht mit dem Ziel, POST Parameter in JavaScript zu benutzen.

Nachdem man ja GET-Parameter relativ leicht auslesen kann, will ich hier nur auf die POST-Parameter eingehen.

Zunächst einmal muss man beschreiben, was denn nun bei einem POST-Request passiert und warum man nicht einfach per JavaScript darauf zugreifen kann.

Ganz kurz: Per POST werden Daten vom Browser (Client) an den Webserver (Server) gesendet, wo diese dann ausgewertet werden können. Der Client “wartet” solange auf Antwort, bis der Server diese sendet. In der ganzen Zeit kann man mit “normalem” JavaScript nix anfangen, da der Client-Code ja noch gar nicht im Browser ist. Sendet der Server nun eine Antwort, so erhält der Browser einfach neue Parameter, ähnlich wie beim GET, nur sind die POST-Paramater nicht zugänglich, weil diese in dem Moment nirgendwo mehr gesetzt sind.
Soviel zur Basis.

“Und wie komme ich nun an die Parameter ran?”
Gute Frage und ebenso leicht zu beantworten. Den POST muss Serverseitig ja irgendeine Serverseitige Scriptsprache entgegennehmen (nehmen wir mal rein zufällig … ähm … PHP) und diese kann dann auf die Eingabe reagieren und eine neue Seite bauen.

Damit ich nun Clientseitig wieder die POST-Daten habe, muss ich mir von PHP aus die POST-Daten irgendwohin in die Antwort an den Browser schreiben, wo JavaScript auch was damit anfangen kann.

Beispiel, ein Kontaktformular (ganz simpel):

<form action="formular.php" method="POST">
<input name="meinname" type="text" />
<input name="senden" type="submit" value="absenden!" />
</form>

Wir möchten nun, nachdem das Formular abgesendet wurde, auf der Antwortseite eine alert-Box aufpoppen lassen, die “Danke, xyz” sagt (ist wirklich ein sehr einfaches Beispiel, oder?)

Okay, der Code für formular.php

<?php if (isset($_POST['meinname'])) { ?>
<script>
var derNameLautet = <?=$_POST['meinname']?>;
alert('Danke, ' + derNameLauetet);
</script>
<?php } ?>

So, nun wird, wenn ein POST vorliegt, der POST-Wert in eine JavaScript Variable geschrieben. Diese kann ich dann für vieles Benutzen, ich hoffe, das Prinzip ist klar.

Aber ich habe einen AJAX-POST, wie mache ich das denn da?
Noch einfacher, der AJAX-POST verlässt ja die Seite nicht, d.h. die Werte, die per POST gesendet wurden, liegen ja noch immer vor und können recht einfach weiterbenutzt werden.

So, diesmal sollte das ganze Prinzip klarer sein, warum ein Auslesen der POST-Variablen in JavaScript mittels

<script>
var meinePOSTVariable = POST[‘postVariable’];
</script>

schlicht nicht möglich ist.