Button on Demand

Wir unterbrechen dieses Weblog für einige technische Anmerkungen:

Bis reichlich in der Frühe habe ich in der letzten Nacht daran gesessen, Marc Stenzels Google+1-Button, der sich nur auf Anforderung einblendet (Update: Inzwischen ruft Google den Buttons selbst mit JavaScript auf – siehe Ende des Beitrages), sauber in diese Seiten einzubauen. Das Problem lag dabei nicht an Stenzels Code, sondern daran, dass er offensichtlich für einzelne Seiten geschrieben ist, nicht für blogtypische Übersichtsseiten mit mehreren Artikeln, die alle einen eigenen Google-Button mit eigenem Zähler haben wollen. Die Folge: Beim Anklicken eines der Platzhalterbuttons wurden zwar alle „echten“ Google+1-Buttons geladen, weil damit das dazu erforderliche Script von Google geladen wurde; es verschwanden aber nicht alle Platzhalter, sondern nur einer – und komischerweise (den Grund habe ich bisher nicht herausbekommen) nicht derjenige, den ich angeklickt hatte, sondern immer der erste auf der Seite.

Die Lösung ist für mich, weil WordPress eine eigene jQuery-Bibliothek enthält (wann ist die eigentlich zum Standard geworden?), die Platzhalter mit Hilfe von jQuery verschwinden zu lassen. Dazu habe ich den Code von Marc Stenzel verwendet und wie folgt angepasst (Im Interesse aller weniger Betroffenen habe ich den technischen Teil auf die eigentliche Artikel-Seite ausgelagert):

Die jQuery-Library wird von meiner WordPress-Installation und meinem Theme automatisch geladen, muss also nicht gesondert gespeichert und aufgerufen werden.

Im <head> der Seite habe ich die folgende einfache Funktion hinzugefügt:

<script type="text/javascript">
   jQuery(document).ready(function(){
   jQuery("a.gp").click(function(){
      jQuery(".gplus").css("display", "none");
   });
});
</script>

Damit wird beim Anklicken eines Links der Klasse .gp (= des Google+1-Platzhalters) allen Elementen der Klasse .gplus die CSS-Eigenschaft display:none zugewiesen, und sie verschwinden, ohne dass die Seite neu geladen werden muss. An ihre Stelle treten dann die eigentlichen Google-Buttons mit dem Zähler.

Und warum habe ich mit diesen simplen Zeilen eine halbe Nacht verbracht? Nun, ich hatte überall, wo in dem Schnipsel jQuery(... steht, die dafür übliche Kurzform $(... verwendet. Das hätte ich nicht machen sollen, denn die WordPress-Macher wissen, was Plugin-Schreiber und User mit der Einbindung anderer Javascript-Bibliotheken alles anrichten können, und lassen ihre jQuery im sogenannten „no conflict„-Modus laufen – und der verlangt eben, dass man jQuery jedesmal mit Namen anspricht. Hätte ich das gleich gewusst, wäre ich gestern früher ins Bett gekommen.

Desweiteren habe ich nun die angepassten Zeilen von Marc Stenzel dort in die Templates eingebaut, wo die Platzhalter-Buttons und nachfolgend der Google-Button erscheinen sollen:

<script type="text/javascript">
function loadScript(jssource) {
  var jsnode = document.createElement('script');
  jsnode.setAttribute('type','text/javascript');
  jsnode.setAttribute('src',jssource);
  document.getElementsByTagName('head')[0].appendChild(jsnode);
  /* document.getElementById('call+1').innerHTML = ""; // Zeile von M. Stenzel,
  mit der er einen Platzhalter ausblendete; wird mit jQuery nicht mehr
  benötigt */
  }
var plus1source = "https://apis.google.com/js/plusone.js";
</script>
<div class="gplus"><a class="gp" href="javascript:loadScript(plus1source)">
<img width="38" height="24" src="http://[PFAD-ZUM-SPEICHERORT]/plusone-h24-nc.png">
</a></div>
<g:plusone href="<?php the_permalink(); ?>"></g:plusone>

Anstelle PFAD ZUM SPEICHERORT (excuse me for yelling!) ist natürlich was einzutragen? Richtig, der vollständige URL-Pfad zum Speicherort der Buttongrafik.

Den Platzhalter-Button habe ich in ein eigenes div verpackt, damit er sauber über dem Google-Button steht, wenn er aus welchem Grund auch immer nicht ausgeblendet wird. div und a-Link bekamen die im ersten Code-Schnipsel verwendeten Klassen-Namen, der Google-eigene g:plusone-Tag bekommt noch den Permalink des Artikels mit. Auf einzelnen Seiten ist das zwar nicht nötig, weil der Google+1-Button hier den URL der Seite automatisch erkennt; für die Übersichtsseiten ist das jedoch unabdingbar, weil sich sonst alle eingeblendeten Buttons für die ganze Seite, nicht für den einzelnen Artikel verantwortlich fühlen.

Anmerkung: Da das hier verwendete Theme reichlich viele Template-Dateien hat, die ich nicht jedesmal einzeln anfassen will, habe ich die Funktionen als custom functions in eine eigene functions.php ausgelagert; von dort werden sie mit WordPress-Hooks gerufen. Aber das ist eine ganz andere Geschichte, die im folgenden Update erzählt wird.

Update am 31. August 2011: Inzwischen hat Google den Button mit einigen Neuerungen ausgestattet und verwendet nun selbst ein JavaScript, um den Button aufzurufen. Deshalb hier, wie ich den Button jetzt in der functions.php meines Themes mit dem Google-eigenen Script aufrufe – zunächst der Aufruf von jQuery, mit dem der Platzhalterbutton nach dem Klick ausgeblendet wird:

function jquery_buttons() {
?>
<script type="text/javascript">
   jQuery(document).ready(function(){
   jQuery("a.gp").click(function(){
      jQuery(".gplus").css("display", "none");
   });
});
</script>
<?
}
add_action('wp_head', 'jquery_buttons');

Und hier die Funktion, die den eigentlichen Google+-Button aufruft:

function add_gplus_button($content) {
	if(!is_feed() && !is_page()) {
		$content = $content.'
		<script type="text/javascript">
  window.___gcfg = {lang: \'de\'};
function loadScript() {
  (function() {
    var po = document.createElement(\'script\'); po.type = \'text/javascript\';
             po.async = true;
    po.src = \'https://apis.google.com/js/plusone.js\';
    var s = document.getElementsByTagName(\'script\')[0];
             s.parentNode.insertBefore(po, s);
  })();
}
</script>
<div class="gplus"><a class="gp" href="javascript:loadScript()">
<img width="38" height="24" src="http://[PFAD-ZUM-SPEICHERORT]/plusone-h24-nc.png">
</a></div>
<g:plusone href="'.get_permalink().'" annotation="inline"></g:plusone>';
	}
	return $content;
}
add_filter('the_content', 'add_gplus_button');

Nochmal: Diese beiden Codeschnipsel stehen nicht mehr, wie oben beschrieben, in den Templates, sondern in der functions.php des Themes; deshalb sehen sie ein wenig anders aus als in den ersten Beispielen.