Joomla-Modul ein bisschen aufgebohrt – mit Benutzereingaben

Ich hab ja in diesem Artikel ein WordPress-Widget erstellt, das die Gesamtzahl der veröffentlichten Rezepte sowie die Anzahl der Rezepte einer frei wählbaren Kategorie anzeigt. So nach dem Muster:

312 Rezepte insgesamt

46 davon Vegetarisch

Ob das mit unserem Joomla-Modul auch hinzukriegen ist?

Anzahl der Beiträge der Kategorie Rezepte

Meine Rezeptkategorie hat die ID 8, das kann man in der Tabelle #__categories nachschauen. Dazu hab ich folgendes Code Snippet gefunden:

$model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', 8); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category

Kommt mir ein bisschen arg umständlich vor, aber wenns funktioniert…

Ich möchte jetzt aber natürlich auswählen können, zu welcher Kategorie die Gesamtzahl der Beiträge ausgegeben werden soll, weil ich in Joomla so schöne Möglichkeiten habe, über die Kategorisierung meine Ausgabe auf der Webseite zu strukturieren. Das heißt aber, wir brauchen ein Eingabefeld (Dropdown), in dem der Benutzer anwählen kann, welche Kategorie ausgegeben werden soll.

Eingabefelder für eigene Module in Joomla

Sind nicht arg schwer zu realisieren, die Joomla-Doku zu dem Thema ist schon mal recht gut, schaut mal hier rein:

https://docs.joomla.org/J3.x:Creating_a_simple_module/Adding_Form_Fields

Ich machs aber hier nochmal step by step, damit man es auch nachvollziehen kann. Wir setzen auf unser Hallo-Welt Modul aus dem vorigen Beitrag auf und erweitern die mod_helloworld.xml, in der kann man ein einfaches Texteingabefeld so erstellen:

 <config>
    <fields name="params">
        <fieldset name="basic">
            <field name="param1" type="text" default="" label="Bitte Titel eingeben" description=""></field>
           </fieldset>
    </fields>
    </config>

Die Felddefinition muss innerhalb der config-Tags stehen. Wenn man sich jetzt mal das Modul aschaut, müsste das Feld eigentlich schon da sein:

texteingabefeld

texteingabefeld

Wie kommt man jetzt an den Inhalt des Feldes ran, den unser Benutzer eiingegeben hat? Das passiert in der mod_helloworld.php, und zwar so:

$variable = $params->get('param1');

Die $variable kann man jetzt an die helper-Klasse übergeben:

$hello = modHelloWorldHelper::getHello($variable);

Und da kann man dann damit weiterarbeiten. Bevor ich da noch weiter darauf eingehe, erstmal:

Die Anforderungen

Den Titel des Moduls kann der Anwender beim Erstellen unter Erweiterungen->Module->neu->Mein Hallo-Welt Modul selber eingeben, den fragen wir nicht nochmal extra ab. Dafür brauchen wir aber ein Dropdown-Feld, in dem die Kategorie (z.B. „Rezepte“) ausgewählt werden kann, für die die Gesamtzahl der Beiträge ausgegeben soll. Und wir brauchen noch ein zweites Dropdownfeld für das „featured tag“ (z.B. „Vegetarisch“, aber dazu kommen wir später. Jetzt werfen wir erstmal einen Blick auf:

Die vordefinierten Form Field Types

Da bietet Joomla etwas wirklich praktisches an, es gibt eine ganz Latte von vordefinierten Formularfeldern, hier die Doku dazu: https://docs.joomla.org/Standard_form_field_types

Da klemmen wir uns gleich mal den Formularfeldtyp „Kategorie„, der macht nämlich genau das was wir brauchen. In der XML-Datei sieht das so aus:

<field name="mycategory" type="category" extension="com_content" label="Eine Kategorie auswählen" description="" />

In der mod_helloworld.php holen wir uns den Inhalt mit:

$kat = $params->get('mycategory');

Und im Modul-Backend kriegen wir unsere Dropdown-Liste mit den Kategorien:

dropdown_kategorien

dropdown_kategorien

In der übergebenen Variablen steckt übrigens die numerische ID der Kategorie Rezepte, die können wir gleich direkt weiterverwerten, und zwar in der helper.php:

public static function getHello($params)
    {
        $model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', $params); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category
        
        echo "Insgesamt ".$num_articles." Rezepte<br>";    
        
        
        
    }

Voraussetzung dafür ist natürlich, dass wir sie in der mod_helloworld.php auch als Parameter an die Helper-Klasse übergeben haben, aber dazu gleich mehr, zuerst schauen wir uns mal die Ausgabe an:

insgesamt_rezepte

insgesamt_rezepte

Das paßt soweit, jetzt müssen wir nur noch den Ausgabetext dynamisch anpassen, es kann ja auch jemand die Kategorie „Kochbücher“ angewählt haben, dann darf da nicht „Rezepte“ stehen. Das machen wir so:

//Name der Kategorie zur ID holen
        $db = JFactory::getDbo();
        $db->setQuery("SELECT cat.title FROM #__categories cat WHERE cat.id='".$params->kat."'"); 
        $category_title = $db->loadResult();
        
        echo "Insgesamt ".$num_articles." ".$category_title."<br>";

Nicht dran stören dass hier „.$params->kat.“ steht, das kommt daher, dass ich ein Array von Parametern übergeben habe, mehr dazu gleich. Jedenfalls wird jetzt auch der richtige Kategoriename angezeigt:

2kochbuecher

2kochbuecher

Mehr als ein Formularfeld, mehrere Parameter zum Übergeben

Wir brauchen aber noch ein zweites Formularfeld für die Tags, und dazu werfen wir einen kurzen Blick darauf, wie wir mehr als eine Variable an die Helper-Klasse übergeben können. Kurze Erinnerung, wie die zwei Felddefinitionen in der XML-Datei aussehen:

<fields name="params">
        <fieldset name="basic">
            <field name="param1" type="text" default="" label="Bitte Text eingeben" description=""></field>
            
                
            <field name="mycategory" type="category" extension="com_content" label="Eine Kategorie auswählen" description="" />
            
           </fieldset>
    </fields>

Die Inhalte der Felder holen wir uns in der mod_helloworld.php über die Feldnamen:

$kat = $params->get('mycategory');
$variable = $params->get('param1');

Dann packen wir sie in ein Standardobjekt und übergeben dieses an die Helper-Klasse:

$data = new stdClass();
//Objekt füllen
$data->kat = $kat;
$data->variable = $variable;

        
$hello = modHelloWorldHelper::getHello($data);

In der helper.php holen wir uns die übergebenen Variablen, die ja in unserem Objekt stecken, mit ihrem Namen, also z.B. $params->kat. Das $params stammt aus der Funktionsdefinition der public static function getHello($params)) wer da etwas anderes stehen hat, muss das entsprechend anpassen. Hier nochmal die komplette function:

public static function getHello($params)
    {
        //Anzahl der Artikel zur übergebenen Kategorie-ID holen
        $model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', $params->kat); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category
        
        //Name der Kategorie zur ID holen
        $db = JFactory::getDbo();
        $db->setQuery("SELECT cat.title FROM #__categories cat WHERE cat.id='".$params->kat."'"); 
        $category_title = $db->loadResult();
            
        echo "Insgesamt ".$num_articles." ".$category_title."<br>";
        
        
    }

Das sieht jetzt schon ziemlich gut aus. Leider habe ich für die Tags keinen vordefinierten Formularfeldtyp gefunden, da müssen wir was basteln, aber dazu gibt es einen neuen Beitrag.