F.A.Q. Baker Plus

Angeregt durch die Frage von Olaf Dreier, wie man eine FAQ-Seite etwas übersichtlicher gestalten könnte, habe ich das Modul „F.A.Q. Baker“ (Autoren: Craig Rodway, R. Smith, M. Gallas, ploc, thorn, doc) für WebsiteBaker um etwas jQuery-Magie erweitert. Das angepasste Modul verbirgt zunächst die Antworten und klappt diese erst bei Klick auf die entsprechende Frage aus.

Grundlage für die Anpassungen war das Tutorial von Alexander Bogomolov, vielen Dank dafür!

Hinweis: Dies ist keine offizielle Weiterentwickung des Modules „F.A.Q. Baker“! Ich habe mir auch nicht die Mühe gemacht, einen neuen Modulpfad in allen Dateien zu ergänzen – diese Anpassung lässt sich also nicht parallel zum Original installieren sondern ersetzt diese gegebenenfalls. Die Nutzung dieses Modules geschieht auf eigene Gefahr.

frontend.js & frontend.css

Das Original-Modul enthielt keinerlei Javascript und CSS, daher habe ich die Dateien „frontend.js“ und „frontend.css“ im Modulverzeichnis neu angelegt. Gemäß den Modul-Spezifikationen von WebsiteBaker werden diese Dateien beim Aufruf der Modulseite automatisch geladen. Hierfür muss das eingesetzte WebsiteBaker-Template jedoch die entsprechende Funktion enthalten:

<?php 
	// automatically include optional WB module files (frontend.css, frontend.js)
	if (function_exists('register_frontend_modfiles')) {
		register_frontend_modfiles('css');
		register_frontend_modfiles('jquery');
		register_frontend_modfiles('js');
	} 
?>

Der Aufruf register_frontend_modfiles(‚jquery‘); steht jedoch erst ab WebsiteBaker 2.8.x zur Verfügung, ist allerdings für die Modulerweiterung nicht unbedingt nötig – dazu aber gleich noch mehr.

Damit das angepasste Modul auch unter älteren WB-Installationen vor 2.8.x läuft, habe ich den kompletten jQuery-Core in die frontend.js übernommen. Wer WB 2.8.x nutzt, kann diesen Teil aus der frontend.js entfernen, sofern er jQuery über register_frontend_modfiles(‚jquery‘); in die Seite lädt. Nutzer von WB 2.7.x und WB 2.6.x lassen einfach alles wie es ist.
Am Ende der frontend.js ist der eigentliche Aufruf notiert:

$(document).ready(function() {
    // Macht den Mauszeiger zum "pointer"
    $('.mod_faqbaker dl dt').mouseover(function() {
      $(this).css('cursor', 'pointer')
    });
    // Fährt die Menüpunkte ein und aus
    $('.mod_faqbaker dl dd').hide();
    $('.mod_faqbaker dl dt').click(function() {
      $(this).next('dd').slideToggle('fast').siblings('dd').slideUp('fast');
      $(this).toggleClass('down');
    });

    //Gibt den Inhalt des DDs in das title-Attr. von DT
    $('.mod_faqbaker dl dt').mouseover(function() {
      var ddText = $(this).next('dd').text();
      $(this).attr('title', ddText)
    });
  });

Dieser Aufruf stammt wie gesagt aus dem Tutorial von Alexander Bogomolov und sorgt für das verstecken (hide) der Antworten und das Aufklappen nach dem Klick  auf die Frage – bzw. für das Zuklappen nach dem zweiten Klick (slideToggle). Zudem werden hier ausgeklappte Elemente mit via toggleClass() mit der CSS-Klasse „down“ versehen, um sie gesondert formatieren zu können.

Zur Kennzeichnung zusammen- und aufgeklappter Elemente habe ich noch zwei PNG-Grafiken mit kleinen Pfeilen in den Modulordner gelegt.

Damit nun Antworten und Fragen der FAQ über jQuery angesprochen werden können, müssen diese in einer bestimmten Syntax verpackt werden. Alexander Bogomolov nutzt hierfür Definitionslisten(<dl>) welche sich für diesen Zweck sehr gut anbieten. Eine solche Definitionsliste mit Fragen und Antworten sieht dann in etwa so aus:

<dl>
    <dt>Die erste Frage</dt>
    <dd>Die Antwort auf die erste Frage</dd>
</dl>
<dl>
    <dt>Die zweite Frage</dt>
    <dd>Die Antwort auf die zweite Frage</dd>
</dl>

Dass die Definitionsliste nach jedem Frage-Antwort-Paar geschlossen wird, ist vielleicht semantisch nicht die beste Lösung aber man kann sicher gut damit Leben.

add.php

Die Syntax für die Ausgabe der Fragen und Antworten lässt sich im Backend des Modules ja beleibig manuell anpassen. Damit man diese Anpassung jedoch nicht bei jeder neuen FAQ-Seite wiederholen muss, habe ich die neue Schreibweise als Standardwerte in der add.php ergänzt:

/* Ab Zeile 28 gehts los*/

$template_summary = '<div class="mod_faqbaker_cat">
[category]
<strong></strong>
<br /><br />
<ul>
[question]
<li style="padding:2px 0px;">
<a href=""></a>
</li>
[/question]
</ul>
[/category]
</div>';

$template_details = '[category]
<h3></h3>
<div class="mod_faqbaker">
[question]
<dl>
  <dt><a name=""></a></dt>
  <dd>

  </dd>
</dl>
[/question]
</div>
[/category]';

/* Hier gehts ganz normal weiter*/

View.php

Weiter ging es in der view.php, die für die Ausgabe der FAQ im Frontend zuständig ist. Hier befand sich ein<hr> (horizontale Linie) im Quelltext, was natürlich kein gültiges XHTML ist. Dieses <hr> habe ich also ersetzt:

<hr class="mod_faqbaker_div" />

Zudem habe ich diese Linie noch mit einer Klasse (mod_faqbaker_div) versehen, um sie via CSS stylen zu können.

Das Original-Modul gibt über den Frage-Antwort-Paaren eine Zusammenfassung aller Fragen aus – im Kontext mit einklappbaren Antworten macht diese aber meiner Meinung nach wenig Sinn. Allerdings wollte ich diese Ausgabe auch nicht komplett entfernen sondern nur unsichtbar machen. Zu diesem Zweck habe ich in der view.php noch ein zusätzliches DIV mit der Klasse „mod_faqbaker_summary“ um diese Ausgabe gelegt, um sie später via CSS zu verstecken (display:none;). Diese Ergänzungen befinden sich in den Zeilen 91 und 109 der view.php:

/* los gehts in Zeile 91*/

// hier wird das neue DIV geöffnet
echo '<div class="mod_faqbaker_summary">';
	while($cat = $query_cats->fetchRow())
	{
		echo strtr($category_summary_first, array('' => $admin->strip_slashes($cat['cat_name'])));
		$query_quests = $database->query("SELECT * FROM `".TABLE_PREFIX."mod_faq_questions` WHERE cat_id='".$cat['cat_id']."' and section_id='".$section_id."' ORDER BY pos ASC");
		if($query_quests->numRows() > 0)
		{
			while($quest = $query_quests->fetchRow())
			{
				$question=$admin->strip_slashes($quest['question']);
				$wb->preprocess($question);

				$replace_pattern = array('' => $question, '' => "#question_".$quest['question_id']);
				echo strtr($question_summary_final, $replace_pattern);
			}
		}
		echo $category_summary_last;
	}
// hier wird das neue DIV geschlossen	
echo '</div>';

/* und hier gehts wieder ganz normal weiter */

Selbstverständlich folgt diese Anpassung dem Prinzip des „Progessive Enhancements“ – das heißt dass das Modul durch Javascript aufgewertet wird aber auch ohne einwandfrei funktioniert. Nutzer mit abgeschaltetem Javascript sehen alle Antworten von Anfang an aufgeklappt und gelangen somit problemlos an die Informationen.

Ich habe das Modul unter WebsiteBaker 2.7.x und 2.8.x getestet, im Internet Explorer 6 bis 8, Firefox 3 (PC und Mac) sowie im Safari auf dem Mac.

Die von mir vergebene Versionsnummer des Modules ist 1.47. Ich möchte aber nochmals darauf hinweisen, dass es sich dabei nicht um eine offizielle Weiterentwicklung handelt. Wenn die Entwickler des Original-Moduls meine Modifikationen übernehmen möchten: sehr gern :-)


LETZE STABILE VERSION

faqbaker 1.5 (inoffiziell)

Hinweis: Dies ist keine offizielle Weiterentwickung des Modules „F.A.Q. Baker“! Ich habe mir auch nicht die Mühe gemacht, einen neuen Modulpfad in allen Dateien zu ergänzen – diese Anpassung lässt sich also nicht parallel zum Original installieren sondern ersetzt diese gegebenenfalls. Die Nutzung dieses Modules geschieht auf eigene Gefahr.


Changelog

V1.5, 06.03.2012

Pfad zu Backend-Icons geändert, damit das Modul auch in aktuellen Versionen von WebsiteBaker und LEPTON korrekt funktioniert. In älteren Versionen lagen die Icons (Modify, move up, move down, delete) unter admin/images – in neuen Version sind diese jedoch im Verzeichnis des jeweiligen Backend-Themes hinterlegt (damit sie optisch zum Theme passen). In der view.php des Moudles wurde also ADMIN_URL durch THEME_URL ersetzt. Die Icons werden nun wieder korrekt im Backend des Modules angezeigt.

3 Kommentare Schreibe einen Kommentar

  1. Danke Andre, nach deinem Hinweis hatte ich, nach Überprüfung, entdeckt dass der Aufruf bis auf die Zeile „register_frontend_modfiles(‚jquery‘);“ bereits im „Head“ enthalten war – somit dann z.T. doppelt vorhanden !

  2. Danke für diese tolle Modifikation. Beim Praxistest auf (m)einer Testseite klappt die Antwort allerdings immer sofort wieder ein. (Wo) Muss noch etwas angepasst werden? LG, Peter

    • Hallo Peter, leider weiß ich darauf keine einfache Antwort. Eigentlich funktioniert das Modul „Out-Of-The-Box“ ohne weitere Anpassungen. Ich habe das modifizierte Modul auf vier WB-Installationen getestet, dort lief es ohne Probleme. Es kann natürlich sein, dass jQuery mit einem von Dir eingesetzten Javascript kollidiert – aber das ist nur gemutmaßt. Kannst Du mir eine URL zur Seite schicken, damit ich mir den Quelltext mal anschauen kann? Beste Grüße, André

Schreibe einen Kommentar