Text begrenzen, aber richtig!

16. März 2010

Text begrenzen, aber richtig!
Texte bei der Ausgabe in ihrer Länge zu begrenzen ist nun wirklich eine immer wiederkehrende Aufgabe. Daher ist es nicht verwunderlich, dass es zahlreiche Funktionen gibt, die ein solches Abschneiden gewährleisten sollen. Aber was leisten diese Truncate Funktionen wirklich?

Die allgemeine Verfahrensweise solcher Funktionen ist denkbar einfach: Es muss zunächst getestet werden, ob ein String überhaupt länger ist, als die vorgegebene maximale Länge. Ist dieses der Fall, so wäre der String an entsprechender Stelle abzuschneiden, und diese Kürzung ggf. durch eine Zeichenfolge wie zu kennzeichen. Nur was heisst an entprechender Stelle?

Basis vieler Truncate Funktionen in PHP ist die substr Funktion, über die sich ein beliebig langer Text an einer definierten Stelle abschneiden lässt. Berücksichtigt wird bei substr jedes Zeichen, ganz gleich ob es sich um Satzzeichen, Buchstaben oder Leerzeichen handelt.
Aus Gründen der Lesbarkeit kann es aber sinnvoller sein nicht exakt auf eine bestimmte Zahl an Einzelzeichen zu kürzen, sondern stattdessen das nächste Wort- oder Satzende zu finden. Ein Artikel bei the art of web liefert gleich eine ganze Reihe solcher Funktionen. Bei dieser Art von truncate Funktionen wird wahlweise mit einem regulären Ausdruck oder einer Kombination aus substr und strrpos gearbeitet.

Und was passiert, wenn es sich bei dem Text nicht um einfachen Plain-Text, sondern um eine HTML Struktur handelt? Schneidet man solche Texte an der falschen Stelle ab, kann es einem im schlimmsten Fall das gesamte Layout der Seite zerstören, man muss nur das Pech haben einen geöffneten Tag innerhalb der gekürzten Version zu haben, der nicht wieder geschlossen wird. Und selbst wenn das nicht der Fall sein sollte, so werden bei HTML Code die nicht dargestellten Tags als Zeichen mitgezählt, die ausgebene Länge entspricht also gar nicht der gewünschten maximalen Ausprägung. Auch ein Aufteilen eines solchen HTML-Textes an Leerzeichen hilft nicht – viele Tags enthalten Leerzeichen – die Konsequenz wäre damit die Gleiche.

Selbst wenn man vorab alle HTML Tags durch strip_tags entfernt, bleibt ggf. noch das Problem von vorhandenen Entities: Wie schaut es aus wenn ein ä nach &au abgeschnitten wird? Vom dadurch enstehenden Wegfall an Informationen wie Bildern, Verweisen oder anderen Formatierungen durch den HTML Code ganz zu schweigen.

Sobald man es mit HTML zu tun hat, und dieser Code in seiner Struktur auch nach der Kürzung erhalten bleiben soll, wird die Aufgabe deutlich komplexer. Weder substr oder ein regulärer Ausdruck sind ausreichend, denn alle geöffneten Tags müssen (in umgekehrter Reihenfolge) wieder sauber geschlossen werden. Alle Tags dürften keinen Einfluss auf die maximale Anzeigelänge haben und HTML Entities dürften nur als ein Zeichen gewertet werden.

Der “geöffnete Tags”-Problematik nehmen sich noch einige Funktionen an. Bei DZone gibt es ein entsprechendes Snipplet (die ausgereifteren Lösungen findet man in den Kommentaren zum Snipplet) und für die Template-Engine SMARTY gibt es auch einen entsprechenden Modifier. Die Problematik der “wirklichen maximalen Länge”, oder die Entities werden in den meisten Fällen aber nicht mit berücksichtigt.

Die meines Erachtens ausgereifteste Lösung findet man bei CakePHP, dieses Snipplet gewährleistet wirklich eine reibungslose Kürzung von HTML, inklusive Entities und korrekter Längenberechnung.

Die Bedeutung des wmode bei Flash

15. Februar 2010

Flashplayer
Man lernt nicht aus, oder kleine Änderung mit großer Wirkung. Ein Flashmovie auf einer Seite einzubinden, das dann von anderen Elementen optisch überlagert werden kann, dass bedeutete für mich bis heute immer das Attribut wmode mit der Einstellung “transparent” zu setzen. Völlig falsch, und erzeugt dazu noch unnötige Last.

In der Dokumentation zum Flashplayer von Adobe heißt es:

By using the Opaque property you can use JavaScript to move or resize movies that don’t need a transparent background. Opaque mode makes the movie hide everything behind it on the page. Additionally, opaque mode moves elements behind Flash movies (for example, with dynamic HTML) to prevent them from showing through.

Frei übersetzt Beim Wert opaque überlagert das Flashmovie alle anderen Elemente auf der Seite – damit kam diese Option für mich nicht in Frage, stattdessen setze ich den Wert von wmode auf transparent, denn in der Dokumentation heißt es weiter:

Transparent mode allows the background of the HTML page, or the DHTML layer underneath the Flash movie or layer, to show through all the transparent portions of the movie. This allows you to overlap the movie with other elements of the HTML page. Animation performance might be slower when you use this value.

Was blieb einem auch anderes übrig, Performance hin oder her, das Movie soll ja von anderen HTML-Elementen überlagert werden können. Dadurch, dass die Flashdatei transparent dargestellt wird, müssen Browser und Flash aber deutlich mehr rechnen als ohne diese Einstellung. Dies kann im schlimmsten Fall sogar den ganzen Browser lahmlegen. Wmode mit der Einstellung transparent zeichnete bei älteren Playerversion auch für Fehler verantwortlich, die man eigentlich gar nicht mit dem Flashmovie in Verbindung bringen würde. So wurde das @-Zeichen in Eingabefeldern plötzlich nicht mehr dargestellt. Gleiches galt für den Cursor innerhalb eines Textfeldes. Auch wenn diese Phänomene mittlerweile (soweit ich weiß) der Vergangenheit angehören – die Performance Problematik bleibt, da kann die Prozessorlauslastung schon mal auf 50% und mehr steigen. Was schreibt Adobe:

If windowless mode is used, performance can be affected to some degree. If fastest performance is a top priority, you may consider other design options.

Doch genug der Vorrede: Mir ging es nie um die “echte Transparenz” des Films. Nicht der Hintergrund war wichtig, sondern der Z-Index sollte berücksichtigt werden. Elemente mit einer höheren Schichtung sollten davor, alle anderen hinter dem Movie liegen. Eben das geht auch mit der Einstellung opaque – auch wenn die Dokumentation sich da sehr mißverständlich ausdrückt. Und so schaut ab heute meine XHTML 1.0 Strict Fassung zum Eindinden einer Flash Datei aus (eine minimal erweiterte Fassung des Flash Satay):

<object type="application/x-shockwave-flash"
  data="movie.swf" width="400" height="300">
    <param name="movie" value="movie.swf" />
    <param name="wmode" value="opaque" />
    <img src="noflash.gif" alt="No Flash!" />
</object>
Seite 9 von 13Anfang...7891011...Ende