PagesetterFormulare

Guite edited this page Nov 12, 2014 · 2 revisions

== Formulare anpassen ==

Guppy ist der Name des Formularsystems, dass in Pagesetter die Eingabeformulare erzeugt.

Überblick

Das Guppy Framework ist ein Formular-Verarbeitungssystem, welches dem normalen HTML-Formularen eine Reihe Extrafunktionen hinzufügt. Es ermöglicht dem Programmierer ein Webformular mit ein paar XML-Dateien zu konfigurieren - genauer gesagt bestimmen 2 XML-Dateien + PHP-Handler das Aussehen des Formulars.

Die relativ einfachen XML-Spezifikationen entlasten von der Last eine Menge HTML und JavaScript zu benutzen - Allerdings ein wenig auf Kosten der Flexibilität.

Guppy kann verschiedene Komponenten erzeugen:

{| border=1 class="wikitable" !Cards !zeigen einen einzigen Eintrag |- | Tables | zeigen mehrere Einträge |- | Tree | zeigen verzweigte Einträge |}

Jede dieser Kompontenten kann ein oder mehrere verschiedene Felder enthalten. Felder sind Eingabefelder für Booleans (Checkboxen), Integers, Reals, Daten, Zeiten, Strings, HTML und Auswahlboxen.

Die Vorteile von Guppy sind: **Einfachere Erzeugung von Formularen **Automatische Validierung der Eingaben **Automatische Verarbeitung von mehreren Einträgen mit Einfügen und Löschen von Datensätzen **Automatischer Umgang mit verzweigten Daten in Baumstruturen **WYSIWYG-Editor (Xinha) **Datumsauswahl über einen kleinen Kalender **Trennung von Formularspezifikationen und Layout **Konsistentes Look&Feel in allen Guppy-Modulen

'''ACHTUNG! - Mittlerweile ist mit pnForm ein neues Formular-Framework direkt in Zikula enthalten. Natürlich ist Guppy noch in Pagesetter enthalten. In eigenen Modulen sollte aber pnForm genutzt werden.''' Guppy kann per /pagesetterExtraPGForm umgangen werden, mit diesem zusätzlichen Modul ist es möglich die Formulare per Template zu erstellen anstatt von Guppy

=== Formulare === Pagesetter kann für jeden Publikationstyp und jeden Status eines Workflows ein eigenes Eingabeformular einsetzen. Dazu muss in den Ordner …/publications/ ein dem Namen des Publikationstypen entsprechendes Unterverzeichnis erstellt werden. Hier werden nun für die einzelnen Workflow-Stati die Dateien mit Namen StatusnameFormLayout.xml abgelegt (Beispielsweise newFormLayout.xml für neue Artikel und waitingFormLayout.xml für wartende Artikel).

Liegt keine spezifische Formulardatei vor, so werden die Formulare unter …/forms/ benutzt.

Das Layout XML ist eine rekursive Struktur, welche ermöglicht die Kompontenten in einem Raster (einer Tabelle) zu platzieren - so wie man es auch in einer normalen HTML-Tabelle machen könnte. Ein Layout beginnt mit dem layout-Tag


 

... Layout ...

Mit dem layout-Tag beginnt das Raster (so wie mit dem table-Tag eine Tabelle in HTML beginnt) - folglich muss der Inhalt in Zeilen definiert werden. Dazu benutzt man das row-Tag.


 

  
    ... Zeilen Layout ...
  

In eine Zeile kann man nun den Inhalt einfügen. Das wichtigste Tag hier ist das component-Tag, mit dem man festlegt, wo die Komponente angezeigt werden soll. Außerdem muss das Tag aussagen, zu welcher Komponente es gehört.

In diesem Beispiel wird das Pagesetter “Publikation ändern”-Formular benutzt, welches eine Komponente “pubedit” enthält. In XML sieht das so aus:


  
    
      .. Komponenten Layout ...
    
  

Innerhalb einer Komponente können Felder nach Belieben angeordnet werden. Zunächst muss allerdings eine Struktur in der Komponente festgelegt werden.

Wieder benutzt man hier das layout-Tag und beginnen ein neues Raster innerhalb der Kompontente. Auch hier fährt man dann mit row-Tags fort:


  
    
      
        
        
      
    
  

Wie man sieht, muss man auch den Feldern Namen geben, die wiederum auf Felder des Publikationstypen verweisen. Dabei muss man nicht erwägen, was für ein Feldtyp das ist, denn Guppy weiß das und wird das richtige Feld erzeugen. Fast immer, jedenfalls. Man muss nur spezifizieren, wie ein Text-Feld angezeigt werden soll. Es kann als Zeile, Text-Area oder mit HTML-Editor angezeigt werden. Dazu benutzt man das view-Attribut. Außerdem demonstriert das folgende Beispiel gleich die Möglichkeit die Größe von Text-Feldern anzupassen:


  
    
      
        
        
      
    
  

Zumindest einen Titel eingeben zu müssen, ist wohl logisch. Deswegen wir das Feld als “mandatory”(Pflichtfeld) markiert und auf eine Breite von 400 Pixeln gesetzt.


  
    
      
        
        
      
    
  

Als letztes in diesem Kapitel soll das Formular noch um Benutzerinteraktion erweitert werden. Dazu platziert man einige Buttons im Formular. Pagesetter liefert drei Buttons mit:

**Vorschau (Preview) **Aktualisieren (Update) **Abbruch (Cancel)


  
    
      
        
        
      
      
        
        
        
      
    
  

Die Buttons können nur am Ende des Formulars stehen. Das liegt daran, dass Pagesetter eventuell dynamisch Workflow-Informationen dazwischenfügt. Referenz

Aus welchen Bestandteilen setzt sich ein Guppy-Formular zusammen?

##'''button''' - Mit dem button-Tag platziert man einen einfachen Knopf im Layout. Mindestens muss der Name des Knopfs definiert sein. Attribute: ***'''name''' - Name des Knopfs ***'''title''' - Titel des Knopfs. Wenn keiner definiert ist, wird der Standardtitel benutzt. ***'''hint''' - Ein Hinweis, wofür dieser Knopf gut ist. Wenn keiner definiert ist, wird der Standardhinweis benutzt. Der Hinweis wird im title-Tag des erzeugten HTMLs benutzt. ##'''buttonsBottom''' - Hiermit definiert man den Container für die Buttons - Es muss innerhalb einer Komponente benutzt werden. Knöpfe, die in diesem Tag definiert werden, zeigt Guppy unterhalt der Komponente an. ##'''buttonsTop''' - Hiermit definiert man den Container für die Buttons - Es muss innerhalb einer Komponente benutzt werden. Knöpfe, die in diesem Tag definiert werden, zeigt Guppy über der Komponente an. ##'''field''' - Legt ein Eingabefeld an. Attribute: ***'''name''' - Name des Feldes ***'''kind''' - Die Art des Feldes. Standard: “Input” - kann aber auch “action” sein, wenn man auf eine Aktion verweisen will. ***'''title''' - Titel des Feldes, der im title-Tag angezeigt wird. Wenn keiner definiert ist, wird der Standardtitel benutzt. ***'''width''' - Breite in Pixeln ***'''height''' - Höhe in Pixeln ***'''colspan''' - Über wieviele Spalten erstreckt sich das Feld ***'''view''' - Legt fest, wie ein Feld angezeigt werden soll. Kann sein: “string” (Standard), “text” oder “html” ***'''hint''' - noch ungenutzt ***'''mandatory''' - Pflichtfeld festlegen. Entweder “true” oder “yes” ***'''readonly''' - In dieses Feld soll nicht geschrieben werden. Entweder “true” oder “yes” ##'''island''' - Das island-Element zeigt einen Rahmen um alle enthaltene Elemente. Attribute: ***'''title''' - Titel des Elements. Wenn keiner definiert ist, wird der Standardtitel benutzt. ***'''colspan''' - Über wieviele Spalten erstreckt sich das Element ##'''layout''' - Das Layout-Element definiert Anfang und Ende eines Rasters. ##'''row''' - Dieses Element definiert eine Zeile in einem Raster und muss Zellen-Elemente enthalten. ##'''title''' - Dieses Element fügt einem anderen Element einen Titel hinzu. Dazu muss es auf den Namen des anderen Elements verweisen. Attribute: ***'''title''' - Titel des Elements. Wenn keiner definiert ist, wird der Standardtitel benutzt. ***'''colspan''' - Über wieviele Spalten erstreckt sich das Element

'''Beispiel''' Wir haben einen Publikationstyp mit ein paar Feldern:

/Datei:pagesetterpubtype.gif

Ohne weitere Anpassungen erhält man beim Anlagen einer neuen Seite die Standardmaske:

/Datei:pagesetterform.gif

Eine Reihe an Feldern benötigt man vielleicht gar nicht (z.B. die Topics), andere möchte man in anderer Reihenfolge anzeigen, zusammenfassen o.ä. Dafür legt man eine eigene Guppy-Definitionsdatei an. Unsere Beispielpublikation hat als “Form Name” (oben rechts bei der Definition) “eintrag” stehen. Darum ist der richtige Platz für die Definitionsdatei das Verzeichnis modules/pagesetter/publications/eintrag, welches man zunächst natürlich anlegen muss. Die Datei selbst muss den Namen newFormLayout.xml haben. Wir hinterlegen folgenden Inhalt:


 

  
    
      
        
        
        
      
 
      
        
          
            
              
            
            
              
            
            
              
              
            
          
        
 
        
          
            
              
            
            
              
            
 
          
        
 
        
          
            
              
            
            
              
            
          
          
            
              
            
            
              
            
          
        
      
 
      
        
        
        
      
 
    
  

Die Bedeutung dieser Tags ist in der Guppy-Dokumentation erläutert, deshalb hier nur so viel: mit


beginnt man eine neue Zeile.


...

schliesst verwandte Felder in einen Rahmen ein. Die Elemente haben wir sinngemäß gruppiert, und störendes weggelassen.

Und so sieht das Ergebnis aus:

/Datei:pagesettercustomform.gif

'''Standardformulare zu breit für das Theme'''

Für einige Themes (vor allem mit tabellenfreien Layouts) sind die Standard-Formulare von Pagesetter zu breit, das Layout wird dann “zerschossen”. Die Übeltäter sind dann die XML-Dateien unter …/forms/. In den *Layout.xml und *Spec.xml Dateien müssen dann in folgenden Dateien Änderungen vorgenommen werden.

*history.xml *pubList.xml *pubEdit.xml

Hier sind nicht bei allen “field”-Beschreibungen die Anzeigeweite “width” gesetzt. Nach dieser Änderung sind alle Listen unter 750px breite, das reicht, um das Theme nicht mehr zu sprengen.

=== Event Handling ===

Das Guppy-System ist Event-basiert. Der Programmierer legt drei Dateien an:

##Die Formular Spezifikationen in einer XML-Datei ##Das Layout in einer XML-Datei ##Den Event-Handler (aka. PHP-Handler) in einer PHP-Datei

Guppy erzeugt daraus das HTML und benutzt je nach Usereingaben die Funktionen aus dem PHP-Handler.

Der Event-Handler ist ein Object, dass von der GuppyDecodeHandler-Klasse erbt. An dessen Methoden werden die Events als Objekt weitergereicht. Durch die Vererbung ist sichergestellt, dass $this auf den Guppy Command-Handler verweist, der alle Ausgaben von jedem Event-Handler behandeln muss. Event-Handling

Bei jeder Benutzung von Guppy wird als erstes guppy_decode aufgerufen, um zu testen, ob es von Guppy oder woanders aus aufgerufen wurde. Wenn Guppy nicht von einem Event gestartet wurde, gibt es einfach true zurück. Andernfalls sendet es ein Array mit folgendem Inhalt:

##'''action''' - Ein Array mit der Beschreibung des aktuellen Events. Elemente: ***'''kind''' - Ein String mit der Beschreibung des Events. Meistens ist die Beschreibung namensgleich mit der Methode des Aufrufs ***'''component''' - Name der Kompontent in der z.B. der Button liegt ***'''rowIndex''' - Zeilennummer ***'''button''' - Name des aktivierten Buttons ***'''buttonKind''' - Art des Buttons ***'''action''' - Name der Aktion ***'''clickHeader''', menuAction, treeXXX - und einiges mehr ##'''data''' - Dieses Array ist identisch mit den Daten, die an guppy_open übergeben werden, aber inklusive der Änderungen, die der User durchgeführt hat. ##'''extra''' - Dieses sind die Daten, die über das “Extra”-Attribut an guppy_open übergeben wurden. Diese Daten können frei verwendet werden, um jegliche Art von Extradaten zu übergeben, die für die Gehandlung des Formulars benötigt werden.

=== Plugins === Mit Plugins lässt sich Guppy und eigene Feldtypen erweitern. Das Guppy-System ermöglicht es jedem Programmierer mit PHP-Kenntnissen und einigem Verständnis von objektorientierter Programmierung, eigene Input-Typen zu erstellen. Dieses System basiert auf Ideen aus Smarty und ASP.NET - leider ist es aber noch nicht so komplett, wie es sein könnte. Bisher wurden mit dem Pluginssystem schon die Typen “Datetime”, “E-Mail” und “URL” erstellt, die seither in Pagesetter enthalten sind.

Guppy und Pagsetter sind noch nicht vollständig voneinander getrennt, so dass die Plugins jeweils auf Methoden von Pagesetter und Guppy zugreifen. Guppy setzt der Funktionalität von Plugins keine Grenzen. Pagesetter kann allerdings nicht mit allem umgehen.

Die Idee hinter diesem System ist es, dass ein Plugin für jeden Input in ein entsprechendes Feld Methoden aufrufen kann, die dann verschiedene Dinge mit den Inhalten anstellt. Das kann verändern, validieren oder decodieren sein. Plugin Struktur

Ein Guppy-Plugin ist folgendermaßen aufgebaut:

#php
class GuppyInput_MyPlugin extends GuppyInput
{
  var $ID;          // HTML Dokumenten ID
  var $name;        // Name des Formular-Elements
  var $title;       // Titel (Label) wie im XML files
  var $value;       // Freier Platz zum Speichern des Ergebnisses
  var $mandatory;   // Mandatory wie im XML files
  var $readonly;    // Readonly wie im XML files
  var $hint;        // Hint wie im XML files
  var $width;       // Width wie im XML files
  var $height;      // Height wie im XML files
  var $error;       // Freier Platz zum Speichern einer Fehlernachricht

  function render($guppy)
  {
    // Mit echo, print, usw. kann man ausgeben 
    // was auch immer man braucht.
  }

  function decode()
  {
    // Liest die ''POST'' Variablen und gibt den Wert dessen zurück
    // was der benutzer eingeben hat.
  }

  function validate()
  {
    // Gibt ''true'' oder ''false'' zurück, je nachdem, ob
    // der Inhalt valide war oder nicht.
  }

  function getErrorMessage()
  {
    // Gibt eine Fehlermeldung zurück, falls validate() ''false'' zurückgibt.
  }
}

Was hier passiert ist folgendes:

##Guppy erstellt aus den XML-Dateien Tabellen usw. Jedesmal, wenn es auf den Feldtyp eines Plugins trifft, ruft es $plugin→render() des Plugins auf. Dadurch wird jeweils eine Instanz des Plugins erzeugt. ##Der Benutzer gibt etwas ein und sendet es ab. Guppy verarbeitet alle Eingaben und ruft $plugin→decode() für die Plugin-Feldtypen auf. Diese Methode liest die vom Anwender eingegebenen Werte aus dem $_POST-Array, und übergibt sie in korrekten (d.h. in der Datenbank speicherbaren) Format zurück. ##Direkt nach der Verarbeitung durch decode() ruft Guppy $plugin→validate() auf - wenn dieses true zurückgibt, ist alles in Ordnung - Wenn false zurückgegeben wird, ruft Guppy $plugin→getErrorMessage() auf, um eine richtige Fehlermeldung zu erhalten.

Im Verzeichnis guppy/plugins liegen einige Beispiele. Pagesetter Methods

Pagesetter benötigt folgende Methoden in den Plugins: class GuppyInput_MyPlugin extends GuppyInput

#php
{
  // ... Guppy Kram ...


  function active()
  {
    // Gibt true oder false zurück um zu zeigen, ob
    // das Plugin von Pagesetter benutzt wird oder nicht.
  }

  function getTitle()
  {
    // Gibt den Titel des Plugins zurück
  }

  function getSqlType()
  {
    // Gibt die MySQL Typen Definition für das DB-Feld zurück, in dem
    // die Daten gespeichert werden sollen.
  }

  function getSqlFormat()
  {
    // Gibt den SQL Aufruf zurück, mit dem man Daten von dem Plugin bekommt.
    // Mit "$columnName" spricht man die Spalte an
    // Gibt ''NULL'' zurück, wenn es nicht gebraucht wird.
  }
}

Dabei ist zu beachten, dass Pagesetter nur ein Datenbank-Feld pro Plugin zur Verfügung stellt.

=== Internes ===

Die XML-Dateien für die Formularspezifikationen werden in der guppy_parser.php geparst. Diese Datei erzeugt ein großes assoziatives Array, welches das Formular beschreibt. Die Daten sind in der PHP Session gespeichert. Neue Attribute für die XML-Struktur müssen hier eingefügt werden.

In der guppy.php werden die Benutzereingaben behandelt. Neue Attribute aus dem XML-Parser müssen hier entgegen genommen werden.

99% aller Zikula-abhängigen Funktionen ist in der guppy_postnuke.php implementiert. Dadurch könnte man Guppy auch in anderen Umgebungen benutzen.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.