Archiv der Kategorie: PHP

Inhaltsverzeichnis A-Z mit Links

Ich hatte im ersten Ansatz die Funktion drupal_get_path_alias($node) verwendet, noch g’wandter aber gehts mit url($node). Da die gesamte Inhaltsverzeichnis-Funktion nicht besonders kompliziert ist, hier mal der komplette Code:

function ivz_kompakt(){
    
    $alfa = array(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z);
    foreach ($alfa as $akt_buchstabe){
    
            $buchstabe = $akt_buchstabe;
            
            $anzahl = db_query("SELECT nid, title, type, status from node where title like '".$buchstabe."%' order by title");
            $records = $anzahl->fetchAll();
            $gefunden = count($records);
            
            if ($gefunden == 1) {
            echo "<h2>".strtoupper($buchstabe)." ".$gefunden." Rezept</h2><br>";
            }
            
            if ($gefunden > 1) {
            echo "<h2>".strtoupper($buchstabe)." ".$gefunden." Rezepte</h2><br>";    
            }
            
            if ($gefunden > 0){
                        
                foreach ($records as $record) {
            
                      $akt_id = $record->nid;
                      //echo $record->title."<br>";
                      $url = url('node/' . $akt_id);
                      //echo $url."<br>";
                      echo "<a href = '".$url."'>".$record->title."</a><br>";
                                        
                } //end foreach
            } // end gefunden > 0
    }    // end alfa
    
} //end function ivz_kompakt

Was hab ich gemacht? Ich bastel mir zuerst mal ein Array mit allen Buchstaben des Alfabets. Durch dieses Array steppe ich mit einem foreach durch, und der aktuelle Buchstabe kommt jeweils in unsere Query, und mit count() wird die Anzahl der gefundenen Datnsätze abgefragt:

 $anzahl = db_query("SELECT nid, title, type, status from node where title like '".$buchstabe."%' order by title");
$records = $anzahl->fetchAll();
            $gefunden = count($records);

Dann frage ich mit if ab, ob einer oder mehr als ein Artikel gefunden wurde und gebe dementsprechend aus „1 Rezept“ oder „X Rezepte“.
Wenn ich mehr als 0 Beiträge mit meiner Query gefunden habe, steppe ich durch diese wieder mit einem foreach durch. Ich hole mir mit der nid aus der Query die URL des aktuellen Beitrags:

$akt_id = $record->nid;
$url = url('node/' . $akt_id);

Und bastle mir daraus den Link zum Rezept.

echo "<a href = '".$url."'>".$record->title."</a><br>";

Das wars! Ich hab jetzt mal in der Query noch nicht die Einschränkung auf Where status=1 und type = blog gemacht, weil ich ein bisschen Material zum Ausgeben haben wollte und so einfach alle Nodes alfabetisch ausgebe, die Where-Klausel kann sich jeder selber anpassen. Mein Output sieht ganz sauber so aus:

ivz_kompakt
ivz_kompakt

Schicke Sache, nicht wahr? Das ist 1:1 mein Inhaltsverzeichnis wie im Original-Inselfisch-Kochbuch. Jetzt lege ich mir noch einen neuen Menüpunkt vom Typ einfache Seite an, stelle den Textfilter auf PHP-Code und platziere dort meinen Funktionsaufruf:

<?php ivz_kompakt();?>

Fertig! Also, ich muss sagen, das mit dem Einbinden eigener Funktionen über das simple Modul nach diesem Muster macht einem die Arbeit echt einfach, das gefällt mir sehr gut.

Jetzt wärs natürlich schick, wenn wir mehr Rezepte zum Ausgeben hätten, aber ich hack die nicht per Copy&Paste rein. Ich geh mal suchen, wie es mit den Import-Fähigkeiten von Drupal aussieht, und melde mich dann wieder mit einem neuen Beitrag.

 

Da macht es einem Drupal einfach: die erste Datenbankabfrage

Wir schreiben uns jetzt eine Funktion, die die node-Tabelle abfragt und ein paar basic Daten ausgibt. Das sieht im ersten Ansatz ganz einfach so aus:

$query = db_query("SELECT nid, title, type, status FROM node");
$records = $query->fetchAll();

Mit db_query kann man einen ganz straighten statischen Select absetzen, mehr dazu hier in der Drupal-Dokumentation. Der fetchall() ist auch ganz geradlinig, ich zitiere:

// Retrieve all records into an indexed array of stdClass objects.
$result->fetchAll();

Über das $records-Array kann man jetzt ganz normal mit einem Foreach iterieren:

foreach ($records as $record) {

  echo $record->nid;
  echo $record->type;
  echo $record->status;
  echo $record->title."<br>";
  
}


Das gibt eine (unformatierte) Liste der selektierten Felder aus:

simpelselect
simpelselect

Ist noch nicht besonders schön, hat aber Potential. Was lernen wir daraus, die Erste:

  • der Status ist hier immer 1, das steht für published, 0 wäre unpublished
  • wir haben die Typen page, article und blog

Für das Inhaltsverzeichnis wollen wir natürlich nur den Typ blog und den Status 1, das kommt in die Where-Klausel. Jetzt wollen wir aber auch einen Link zum Rezept, und dazu brauchen wir im Zweifelsfall den Alias-Pfad. Den holen wir uns mit der eingebauten Drupal-Funktion drupal_get_path_alias(). Die möchte mit node/[nid] gefüttert werden, wobei nid natürlich die ID des entsprechenden Nodes ist. Ich packs mal in unsere Foreach mit rein:

foreach ($records as $record) {
  
  echo $record->nid;
  
  $akt_id = $record->nid;
  
  echo $record->type;
  echo $record->status;
  echo $record->title."<br>";
  
  $alias = drupal_get_path_alias('node/'.$akt_id);

  echo $alias."<br>";
  
} 

Damit kriegen wir bei den Nodes, für die ein textueller Pfad vergeben wurde, diesen auch angezeigt:

node_pfad
node_pfad

Daraus können wir uns später die Links auf die Rezepte konstruieren. Jetzt muss ich mir erstmal überlegen, wie ich die Logik für das schön strukturierte Inhaltsverzeichnis nach Drupal portiert kriege, aber ich hab da schon einen Plan. Mehr dazu im nächsten Beitrag.

Wie man Drupal eigenen PHP-Code unterschiebt

Das ist sehr einfach und nahezu überall möglich, man muss nur unter Module den PHP Filter aktivieren. Dann bekommt man bei den Editoroptionen unter Textformate die Option PHP-Code:

textformat_php_code
textformat_php_code

Und das wars auch schon. Beliebigen Code eingeben, php-Tags nicht vergessen:

<?php echo „Hallo Welt!“; ?>

Produziert die erwartete Ausgabe:

php_hallo_welt
php_hallo_welt

Weder besonders aufregend noch besonders handlich, das ist nicht besser und nicht schlechter als der Sourcerer in Joomla. Für wenige Codezeilen tuts das, für längere Scripte ist es völlig untauglich. Aber ich bin durch fleissiges Googlen auch auf einen eleganteren und doch simplen Weg gekommen, eigene PHP-Funktionen in Drupal einzubinden. Dazu basteln wir uns:

Das erste eigene Modul

Ich habe mich an diese Anleitung hier von BobbyMods gehalten, die Sache aber noch ein bisschen weiter vereinfacht. Um ein eigenes Modul zu erstellen, braucht es nicht viel. Man erzeugt ein neues Unterverzeichnis unter sites->all->modules und benennt es z.B. mit „myfunctionlib“. Da hinein kommen zwei Dateien, eine namens myfunctionlib.info, die enthält folgenden Code:

name = My Function Library
description = This module contains my PHP helper functions.
core = 7.x
package = "MyFunctions"
version = "7.1-1.1"

Dann brauchen wir noch die Datei myfunctionlib.module, die sieht ganz stark vereinfacht so aus:

<?php
/**
* Function Description
* @param function_parameter
* @returns function output description
*/

function sayhello($name){
    echo "Hallo liebe ".$name;
}

Wir haben nur eine Function namens sayhello(), die hat einen Parameter, den Namen. Jetzt mussen wir nur noch unser:

Modul aktivieren

es taucht nämlich unter Module bereits auf:

modul_myfunctions
modul_myfunctions

Wenn das passiert ist, hat man Zugriff auf die eigenen Funktionen, ich kann dann auf einer Seite beispielsweise meine sayhello-Funktion aufrufen (Textformat auf PHP Code stellen nicht vergessen):

<?php sayhello(„Evi Silvia“); ?>

Und der Output ist wie erwartet:

sayhello
sayhello

Das eröffnet natürlich jede Menge Möglichkeiten, ganz ähnlich wie die geniale PHP-Bridge für Joomla. Jetzt können wir, ich schau mal wie weit ich mit meinem schöner formatierten Inhaltsverzeichnis komme, aber dazu gibt es einen neuen Beitrag.