Javascript ist Toll!

2. Februar 2008 - 17:18

WordPress und Javascript

Nachtrag: 11.11.2009

Das meiste was in dem Artikel steht, scheint für die Version 2.8.x hinfällig zu sein. Die Funktion wptexturize() hat endlich einen Trigger auf das Code-Tag und vermurkst nicht mehr den Javascript Code. Aber es werden nach wie vor die &-Zeichen umgewandelt. D.h. das Plugin Textcontrol ist nach wie vor notwendig. auch die Änderung in der Funktion convert_chars() muss noch gemacht werden.

Es ist aber auf jeden Fall ein bisschen einfacher geworden, mit wordpress einen Javascript Blog zu betreiben

ab hier beginnt der alte Artikel

Seit ich dieses Blog angelegt habe, kämpfe ich mit einer - für mich - lästigen Eigenschaft von WordPress. Um die Ausgabe der Artikel immer Browserkonform zu machen, werden Sonderzeichen in Texten mit Hilfe diverser Funktionen umgewandelt. Das ist nützlich für normale Texte, da ich mir so keine Gedanken darum machen muss, führt aber dazu, dass es schwierig wird wenn ich ein Sonderzeichen z.b. in einem Javascriptblock einfügen möchte.

Es ist zwar an sich besser auf Inline Skripte zu verzichten und diese in JS Dateien auszulagern, aber ich möchte nicht für jeden Zweizeiler eine eigene JS Datei anlegen müssen.

Das folgende (sinnlose) Beispiel zeigt wie WP arbeitet. Aus der Codezeile:

if(x && y) alert('');

... macht WordPress:

if(x &#038;&#038; y) alert('&#8217;);<br />

Es werden also die &-Zeichen in ASCII Entities umgewandelt (Das & hat den ASCII Code 38) und die Zeilenumbrüche in das HTML Pedant. Im HTML Code macht diese Umwandlung Sinn, da manche Zeichen eine spezielle Bedeutung haben und deshalb nicht dargestellt werden, wenn sie direkt in den Quellcode geschrieben werden. In einem JS Block dagegen erzeugt die Umwandlung in Entities eine Fehlermeldung:

Fehler: illegal character
Quelldatei: xxx
Zeile: 214, Spalte: 6
Quelltext:
if(x &amp;#038;&amp;#038; y) alert('&amp;#8217;);<br />

Verbesserung schafft z.b. das Plugin Textcontrol mit dem sich die automatischen Formatierungen ganz abschalten lassen. Der erzeugte Code sieht dann so aus:

<script type="text/javascript">
if(x &#038;& y) alert('');
</script>

Es bleibt aber bei der Fehlermeldung, weil WP hier trotzdem eingreift und das doppelte &-Zeichen trotzdem noch einmal umwandelt. Hier blieb mir bei meinem bisherigen Kenntnisstand nur übrig im Quellcode von WP rumzupfuschen (der bessere Weg wäre wohl ein Plugin). Einmal ist für dieses Verhalten die Funktion wptexurize() in der Datei include/formatting.php verantwortlich. Diese habe ich um eine Prüfung ergänzt, damit in einem script-Block keine Ersetzung stattfindet:

function wptexturize($text) {
	global $wp_cockneyreplace;
	$next = true;
	$output = '';
	$curl = '';
        $script = false;
 
	$textarr = preg_split('/(<.*>)/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
	$stop = count($textarr);
 
	// if a plugin has provided an autocorrect array, use it
	if ( isset($wp_cockneyreplace) ) {
		$cockney = array_keys($wp_cockneyreplace);
		$cockney_replace = array_values($wp_cockneyreplace);
	} else {
		$cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause");
		$cockneyreplace = array("&#8217;tain&#8217;t","&#8217;twere","&#8217;twas","&#8217;tis","&#8217;twill","&#8217;til","&#8217;bout","&#8217;nuff","&#8217;round","&#8217;cause");
	}
 
	$static_characters = array_merge(array('---', ' -- ', '--', 'xn&#8211;', '...', '``', ''s', '''', ' (tm)'), $cockney); 
	$static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', 'xn--', '&#8230;', '&#8220;', '&#8217;s', '&#8221;', ' &#8482;'), $cockneyreplace);

	$dynamic_characters = array('/'(dd(?:&#8217;|')?s)/', '/(s|A|")'/', '/(d+)"/', '/(d+)'/', '/(S)'([^'s])/', '/(s|A)"(?!s)/', '/"(s|S|Z)/', '/'([s.]|Z)/', '/(d+)x(d+)/');
	$dynamic_replacements = array('&#8217;$1','$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1&#8220;$2', '&#8221;$1', '&#8217;$1', '$1&#215;$2');	
 
	for ( $i = 0; $i < $stop; $i++ ) {
 		$curl = $textarr[$i];
 
		if (isset($curl{0}) && '<' != $curl{0} && $next && !$script) { // If it's not a tag
			// static strings
			$curl = str_replace($static_characters, $static_replacements, $curl);
 
			// regular expressions
			$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
        } elseif ( strstr($curl, '<script') ) {
            $script = true;
            $next = true;
        } elseif (strstr($curl, '</script') ) {
            $script = false;
            $next = true;
	} elseif ( strstr($curl, '<code') || strstr($curl, '<pre') || strstr($curl, '<kbd') || strstr($curl, '<style')  ) { 
			$next = false;
		} else {
			$next = true;
		}
 
        if(!$script) $curl = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/', '&#038;$1', $curl);
		$output .= $curl;
	}
 
  	return $output;
}

Die Änderungen machen nichts weiter, als eine zusätzliche Kontrollvariabel $script einzuführen, die auf true gesetzt wird, wenn ein <script Tag gefunden wird und false ist, wenn es geschlossen wurde und damit wird in der folgenden Zeilen die Umwandlung verhindert:

        if(!$script) $curl = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/', '&#038;$1', $curl);

Leider gibt es noch eine Stelle, wo eine Umwandlung stattfindet. In der gleichen Datei formatting.php (aktuell Zeile 384 in der Funktion convert_chars):

	// Converts lone & characters into &#38; (a.k.a. &amp;)
	$content = preg_replace('/&([^#])(?![a-z1-4]{1,8};)/i', '&#038;$1', $content);

... muss die zweite Zeile auskommentiert werden. Dann lassen sich auch Inline Skripte in einen Text einfügen. Das ganze ist aber extrem lästig, da bei jedem update diese Änderung wieder eingefügt werden muss.

Und wie ich heute festellen musste, tritt das gleiche Problem auf wenn die Seite XHTML Valide sein soll, da der CDATA Kommentar ebenfalls umgewandelt wird, ich habe aber noch nicht rausgefunden wo. Ich habe zwar die folgende Seite gefunden, wo zumindest eine Stelle erwähnt wird (in einem Kommentar), hat aber bei meinen Tests nicht geholfen.

Der Text dient in erster Linie mir zur Erinnerung, da ich bei jedem Update diese Änderungen wieder einpflegen muss und vielleicht verirrt sich mal jemand hierher der ein Plugin weiß, dass dieses Verhalten unterbindet.

ähnliche Artikel

Comments (3)
4651 mal gelesen.

3 Kommentare

Leave a comment »

Seiten:

1. Kommentar von: Andi
3. Februar 2008: 9:00

Hi,

schau dir das mal an, ich habe einfach Codeteile von WordPress ausdokumentiert: http://aka-fotos.de/blog/ist-wordpress-schlau

Wesentlich einfacher ;)

2. Kommentar von: Struppi
3. Februar 2008: 18:18

Das ist natürlich auch eine Möglichkeit, ändert aber nichts an der Tatsache, dass nach jedem Update diese Änderung vorgenommen werden muss. Daher wäre ein Plugin am besten.

Übrigens hilft dein Trick nur zum Teil, die zweite Änderung (in Zeile 398) musst du auch noch vornehmen.

3. Kommentar von: Richard
22. Mai 2008: 9:48

Es gibt so viele Dinge an WordPress, für die ich gerne Plugins hätte, es aber keine gibt, dass von meinen Original-WordPress-Quellcode vielleicht noch 2/3 übrig sind.

Updates nehme ich daher nur bei großen Versionssprüngen vor.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Powered by WordPress Stop Spam Harvesters, Join Project Honey Pot
marketing-bankruptcy
marketing-bankruptcy
marketing-bankruptcy
marketing-bankruptcy