Die Entwickler-Dokumentation zum webconf-Paket




Version 0.4.0




Christian Würdig
eisfair@chriswue.de




Inhalt

Webconf

Einführung

Einleitung

Damit die Oberfläche möglichst einheitlich aussieht, werden die Formulare über sogenannte Formulardateien erzeugt, in denen der formale Aufbau beschrieben ist. Im Paket ist ein Pseudodienst namens `webcnfex' enthalten, anhand dessen man sich anschauen kann, wie das Ganze dann im Browser aussieht.

Funktionsumfang

Es sollte zur Zeit bereits möglich sein, die komplette Administration eines Dienstes über den Browser durchzuführen[*]. Die Funktionen `Package administration' und `User administration' aus dem Setup sind noch nicht im Paket integriert.

Allgemeine Unterstützung zur Administration des Paketes

Beim Klick auf den Punkt `Service administration' werden alle Dateien aus /var/install/form gelesen, die auf `.main' enden. Das sind die sogenannten Menüdateien, die den Ausgangspunkt darstellen und aus denen die Liste der Links erstellt wird, die dann zur konkreten Konfiguration führen.
In der Menüdatei wird festgelegt, wie das Konfigurationsformular und die Dokumentation des Paketes heißen, sowie welche Funktionen zur Administration bereitstehen und welche Formulardatei für welche Funktion zuständig ist. In unserem Beispiel benötigen wir also erstmal die Datei /var/install/form/webcnfex.main.

Die Menüdatei

Syntax und Semantik

<menuname>Servicename</menuname>
<doc name="Menüpunktname" file="Dokumentation"/>
<config form="Formular"/>
<option name="Optionsname" form="Formular"/>
<empty/>
...
<option .../>

<menuname>Servicename</menuname>
Legt fest, unter welchem Namen der Servicedienst in der Hauptauswahl erscheint [*].

<doc ...>
Zeigt eine Textdatei als HTML-Seite an. Die einzelnen Optionen:
name
Hier kann der Name des Menüpunktes angegeben werden. Falls diese Option fehlt wird als Menüname `View documentation' verwendet.
file
Der Name der Textdatei. Es wird der Dateiname mit der kompletten Pfadangabe erwartet.

<config ...>
Hier wird der Menüpunkt zum Editieren der Konfigurationsdatei angelegt. Die Option:
form
Der Name der Formulardatei, die relativ zu /var/install/form gesucht wird.

<option ...>
Für jede administrative Funktion, die der Dienst bereitstellen soll, wird so ein Tag benötigt.
Die einzelnen Optionen des Tags:
name
Legt fest, unter welchem Namen die Funktion in der Unterauswahl erscheinen soll[*].
form
Bezeichnet die Formulardatei (muß in /var/install/form liegen), aus welcher das Formular erzeugt wird, das für die Funktion zuständig ist.

<empty/>
Dieser Tag bewirkt die Erzeugung einer Leerzeile und kann an beliebiger Stelle stehen.

Die Reihenfolge der Tags ist relevant und sollte immer wie oben angegeben lauten, damit eine einheitliche Menüführung gewährleistet wird. Der Tag <menuname ...> ist zwingend, alle anderen sind optional und können entfallen.

Kommentare sind möglich und werden mit `#' eingeleitet. Alles ab diesem Zeichen wird, genauso wie Leerzeilen, ignoriert, es sei denn es steht innerhalb eines Tags.

Ein Beispiel

<menuname>Webconf Service example</menuname>
<doc file="/usr/share/doc/webconf/webcnfex.txt"/>
<doc name="Alternative Doc" file="/usr/share/doc/webconf/webcnfex-alt.txt"/>
<empty/>
<config form="webcnfex"/>
<empty/>
<option name="Part One" form="webcnfex.one"/>
<option name="Part Two" form="webcnfex.two"/>
<option name="Part Three" form="webcnfex.three"/>
<option name="Part Four" form="webcnfex.four"/>

Unterstützung für die Konfigurationsdateien

In der Menüdatei wird im Tag <config ...> angegeben, wie das Konfigurationsformular heißt, das zum Anpassen der Konfiguration zuständig ist (siehe Die Menüdatei). Dabei ist zu beachten, daß diese Datei genauso heißen muß, wie die Konfigurationsdatei, die sich in /etc/config.d befinden muß. Desweiteren wird nach einer Hilfedatei (Syntax Hilfedatei) gesucht, die ebenfalls genauso heißen und sich in /var/install/help befinden muß. Wenn diese Hilfedatei gefunden wird, dann wird zu jeder Variablen ein Hilfepunkt angelegt.
Nach dem Absenden des Formulars werden die Variablen in der Konfigurationsdatei gespeichert. Falls der Benutzer `Apply' gewählt hat, wird versucht das zugehörige Skript aus /var/install/config.d aufzurufen, welches wiederum den gleichen Namen[*] haben muß wie das Konfigurationsformular. Falls `Reload' gewählt wurde, dann wird das Formular mit den neuen Inhalten neu erzeugt.

Das Konfigurationsformular

Syntax und Semantik

<group name="Gruppenname">
   <option name="Optionsname" type="Optionstyp" master="Master-Option" ro="yes|no">
      <val>Select-Value</val>
      <match>Match-Pattern</match>
      <errormsg>Eigene Fehlermeldung, falls Match-Pattern nicht zutrifft.</errormsg>
      <file>Konfigurationsdatei</file>
      <ref>Referenzvariable</ref>
   </option>
   ...
   <option ...>
   ...
   </option>
</group>
...
<group ...>
...
</group>
<group ...>
Dient zur Gruppierung von Variablen, ist optional und kann entfallen. Die Gruppe wird mit `Gruppenname' auf dem Formular gekennzeichnet. Es sind beliebig viele Gruppen möglich (man kann also bei Bedarf pro Option eine Gruppe anlegen, was aber etwas sinnlos wäre).
Falls die Option `name' entfällt wird kein Name auf dem Formular vergeben.

<option ...>
Für jede Variable muß ein <option ...>-Tag existieren.
Die einzelnen Optionen des Tags:
name
Die Zuordnung zur richtigen Variable wird über diese Option geregelt, d.h. `Optionsname' muß gleich einem Variablennamen in der Konfigurationsdatei sein.
type
Legt den Typ des Formularfeldes fest. Gültige Werte für `Optionstyp' sind `LINE', `YESNO', `SELECT' und `REF'.
Bei `LINE' wird ein normales, einzeiliges Eingabefeld erzeugt und mit `YESNO' ein Auswahlfeld mit `yes' und `no' als Einträgen. `SELECT' erzeugt eine Auswahlliste, deren Inhalt mit dem Tag <val> festgelegt wird. `REF' ist als Referenz zu anderen Master-Variablen[*] gedacht. Wenn man z.B. in seinem Paket auf die verschiedenen eingestellten Netzwerkkartentreiber zugreifen will, dann kann man die Variablen ETH_DRV_x dazu verwenden. Damit der Benutzer nur Werte für x angibt, die auch eingestellt sind, kann man den Typ `REF' dazu verwenden. Mit <file ...>' wird die Konfigurationsdatei angeben, in der die Variablen stehen und mit <ref ...> gibt man die Master-Variable an, in diesem Beispiel wäre das ETH_DRV_N. Damit wird eine Auswahlbox erzeugt, die nur Werte von 1 bis Wert der Master-Variablen enthält. Der Benutzer kann auch mehrere Einträge auswählen, diese werden mit Leerzeichen getrennt in die Konfigurationsvariable geschrieben.
master
Diese Option findet nur bei Variablen Verwendung, die in veränderlicher Anzahl auftreten. Dazu ein kleines Beispiel:
In der Basis-Konfigurationsdatei gibt es eine Variable ETH_DRV_N, die die Anzahl von ETH_DRV_x festlegt. Damit das Skript weiß, von welcher Variablen ETH_DRV_x abhängt muß man die sogenannte `Master-Option' angeben, in diesem Fall also:
master=``ETH_DRV_N''
Als `Optionsname' wird der der normale Variablenname angegeben und an die Stelle, an der die veränderliche Nummer steht, muß ein '#' gesetzt werden. In diesem Beispiel sähe das dann so aus:
name=``ETH_DRV_#''
Nun gibt es auch doppelt abhängige Variablen, wie z.B. im Mail-Paket. Dort existieren die Variablen SMTP_LIST_N, SMTP_LIST_x_USER_N und
SMTP_LIST_x_USER_y. Die Variable SMTP_LIST_x_USER_y ist so eine doppelt abhängige. Hierbei wird als `Optionsname' der normale Variablenname angegeben, an die Stelle der ersten Abhängigkeit ein '#' und an die Stelle der zweiten Abhängigkeit ein '##' gesetzt. In diesem Beispiel also:
name=``SMTP_LIST_#_USER_##''
Die `Master-Option' wäre hier:
master=``SMTP_LIST_#_USER_N''
Abhängigkeiten über mehr als zwei Ebenen werden nicht unterstützt.
readonly
Bewirkt, daß das Formularelement schreibgeschützt ist und nicht vom Anwender verändert werden kann. Hat bei abhängigen Variablen keine Auswirkungen.

<val>Select-Value</val>
Ist typspezifisch und findet nur bei type=``SELECT'' Verwendung, dabei ist für jeden Eintrag in der Auswahlliste ein <val>-Tag anzugeben.

<match>Match-Pattern</match>
Dient der Syntaxüberprüfung der Eingabewerte, ist optional und kann entfallen. Falls er vorhanden ist, dann werden die Werte nach dem Absenden geprüft. Falls ein Mismatch auftaucht wird die Konfigurationsdatei nicht gespeichert und es gibt eine Fehlermeldung. `Match-Pattern' wird als regulärer Ausdruck nach Perl-Syntax aufgefasst oder es wird ein vordefinierter regulärer Ausdruck verwendet (siehe dazu: Vordefinierte reguläre Ausdrücke).

<errormsg>Fehlermeldung</errormsg>
Falls der Tag <match ...> verwendet wird, dann kann man hier die Fehlermeldung angeben, die ausgegeben werden soll, falls der `Match-Pattern' nicht trifft. Der Tag ist optional und kann entfallen, dann wird eine Standardfehlermeldung ausgegeben.

<file>Konfigurationsdatei</file>
Ist typspezifisch und findet nur bei
type=``REF'' Verwendung. `Konfigurationsdatei' ist dabei der Name der Konfigurationsdatei, relativ zu /etc/config.d, in der die referenzierte Variable steht.

<ref>Referenzvariable</ref>
Ist typspezifisch und findet nur bei type=``REF'' Verwendung. `Referenzvariable' ist dabei der Name der Variablen, die referenziert wird. Es wird hier eine Master-Variable, erwartet, die eine Anzahl von abhängigen Variablen steuert.

Falls die Tags <val> und <match> für eine Option nicht benötigt werden, dann kann auch der </option>-Tag entfallen und statt dessen wird der öffnende <option ...>-Tag am Ende mit `/' geschlossen (z. B. <option name=``foobar''
type=``YESNO''/>
).

Weiterhin gibt es noch einen <empty/>-Tag, welcher bewirkt, daß eine Leerzeile an der Stelle im Formular erzeugt wird, an der sich dieser Tag im Konfigurationsformular befindet.

Die Reihenfolge der Optionen in den Tags und die Reihenfolge von <val> und <match> ist egal. Leere Zeilen und Kommentare sind erlaubt und werden ignoriert. Ein Kommentar wird eingeleitet durch `#' (außer `#' steht innerhalb eines Tags, dann gilt es nicht als Kommentar) und reicht bis zum Zeilenende.

Ein Beispiel

Beispiel ist das mitgelieferte Konfigurationsformular von webcnfex:

<group name="General settings">
   <option name="WEBCNFEX_START" type="YESNO"/>
   <option name="WEBCNFEX_COMMENT" type="LINE"/>
   <option name="WEBCNFEX_TYPE" type="SELECT">
      <val>auto</val>
      <val>user</val>
      <val>random</val>
   </option>
   <option name="WEBCNFEX_LIMIT" type="LINE">
      <match>#dec_10_s#</match>
   </option>
   <option name="WEBCNFEX_REF" type="REF">
      <file>base</file>
      <ref>ETH_DRV_N</ref>
   </option>
</group>
<empty/>
<group name="Aliases">
   <option name="WEBCNFEX_ALIAS_N" type="LINE">
      <match>#dec_0_s#</match>
   </option>
   <option name="WEBCNFEX_ALIAS_#" type="LINE" master="WEBCNFEX_ALIAS_N"/>
</group>
<empty/>
<group name="Lists">
   <option name="WEBCNFEX_LIST_N" type="LINE">
      <match>#dec_0_s#</match>
   </option>
   <option name="WEBCNFEX_LIST_#_NAME" type="LINE" master="WEBCNFEX_LIST_N">
      <match>#domain_s#</match>
   </option>
   <option name="WEBCNFEX_LIST_#_USER_N" type="LINE" master="WEBCNFEX_LIST_N">
      <match>#dec_0_s#</match>
   </option>
   <option name="WEBCNFEX_LIST_#_USER_##_SURNAME" type="LINE" master="WEBCNFEX_LIST_#_USER_N"/>
   <option name="WEBCNFEX_LIST_#_USER_##_LASTNAME" type="LINE" master="WEBCNFEX_LIST_#_USER_N"/>
   <option name="WEBCNFEX_LIST_#_USER_##_TRAFFIC" type="SELECT" master="WEBCNFEX_LIST_#_USER_N">
      <val>low</val>
      <val>middle</val>
      <val>high</val>
   </option>
   <option name="WEBCNFEX_LIST_#_ADMIN" type="LINE" master="WEBCNFEX_LIST_N">
      <match>#email_s#</match>
   </option>
   <option name="WEBCNFEX_LIST_#_ERRORS" type="LINE" master="WEBCNFEX_LIST_N">
      <match>#email_s#</match>
   </option>
   <empty/>
   <option name="WEBCNFEX_LIST_GOD" type="LINE">
      <match>#email_s#</match>
   </option>
</group>
<empty/>
<group name="Accounts">
   <option name="WEBCNFEX_ACCOUNT_N" type="LINE">
      <match>#dec_0_s#</match>
   </option>
   <option name="WEBCNFEX_ACCOUNT_#_NAME" type="LINE" master="WEBCNFEX_ACCOUNT_N"/>
   <option name="WEBCNFEX_ACCOUNT_#_PASS" type="LINE" master="WEBCNFEX_ACCOUNT_N"/>
   <option name="WEBCNFEX_ACCOUNT_#_HOME" type="LINE" master="WEBCNFEX_ACCOUNT_N">
      <match>#dir_s#</match>
   </option>
   <option name="WEBCNFEX_ACCOUNT_#_GROUP" type="LINE" master="WEBCNFEX_ACCOUNT_N">
      <match>#group_s#</match>
   </option>
   <option name="WEBCNFEX_ACCOUNT_#_TRUSTED" type="YESNO" master="WEBCNFEX_ACCOUNT_N"/>
</group>

Unterstützung für die Serviceadministration

In der Menüdatei wird im Tag <option ...> für jede Servicefunktion angegeben, wie das Serviceformular heißt, das für die jeweilige Funktion zuständig ist (siehe Die Menüdatei). Dabei ist zu beachten, daß diese Dateien relativ zu /var/install/form gesucht werden.

Das Serviceformular

Syntax und Semantik

<form name="Servicename" prep="Skript" help="Helpfile">
   <subform name="Subformname" button="Buttonname" script="Skript" target="Target">
      <option name="Optionsname" vname="Variablenname" hname="Helpoption" type="Typ">
         <match>Match-Pattern</match>
         <size>Size</size>
         <align>LEFT|RIGHT|CENTER|BLOCK</align>
         <source>Sourcefile</source>
         <sourcerange>Range</sourcerange>
         <item>Item</item>
         <text>
            Text
         </text>
      </option>
      ...
      <option ...>
      ...
      </option>
   </subform>
   ...
   <subform ...>
   ...
   </subform>
</form>

<form ...>
Leitet das Formular ein.
Die einzelnen Optionen des Tags:
name
Hiermit wird die Überschrift des Formulars festgelegt.
prep
Das hier angegebene Skript muß unter /var/install/prep liegen und wird ausgeführt, bevor das Formular erzeugt wird (so kann man Felder vorbelegen). Ist optional und kann entfallen.
help
In dieser Datei wird nach den Hilfen zu den einzelnen Optionen gesucht. Sie muß unter /var/install/help liegen (siehe unten: Die Hilfedatei), Da die Zuordnung der Hilfetexte über `Optionsname' erfolgt, kann die komplette Hilfe in einer einzigen Datei untergebracht werden (muß aber nicht).

Die Reihenfolge der Optionen im Tag ist egal.

<subform ...>
Leitet ein Unterformular ein. Jedes Formular besteht aus mindestens einem Unterformular.
Die einzelnen Optionen des Tags:
name
Das ist der Name des Unterformulars (i.d.R. eine kurze Bezeichnung der Funktion).
button
Zu jedem Unterformular existiert ein Absende-Button, dessen Beschriftung hier angegeben werden kann. Ist optional und kann entfallen, dann wird er mit `submit' bezeichnet.
script
Nach dem Absenden des Formulars werden die Formulardaten von einem Skript analysiert (evtl. Eingabefehler etc.), auseinandergenommen und die einzelnen Werte in die Datei `/var/config/tmp/service_form.res' geschrieben und zwar in dieser Form: Variablenname='inhalt'. Dann wird das hier angegebene Skript ausgeführt. Das kann dann auf diese Datei zugreifen und die Formulardaten verwerten. Das Skript muß entweder unter /var/install/servadm liegen und kann ein Binary, Shell- oder Perl-Skript sein, oder die Angabe lautet folgendermaßen: `#Formularname#'. Im zweiten Fall wird die angegeben Formulardatei geparst und ein neues Formular erzeugt.
target
Gültige Werte für `Target' sind `NEW', `FRAME' und `FORM'. Bei der Verarbeitung des Skriptes (genau obendrüber) wird eine Ausgabe erzeugt. Mit `NEW' erscheint diese in einem neuen Fenster, mit `FRAME' unten im Ergebnis-Frame und mit `FORM' wird im aktuellen Fenster das Formular überschrieben und die Ausgabe erscheint dort[*].

Die Reihenfolge der Optionen im Tag ist egal.

<option ...>
Leitet ein Formularelement ein. Jedes Unterformular hat mindestens ein Element.
Die einzelnen Optionen des Tags:
name
Das ist der Name, der vor dem Formularelement erscheint.
vname
Da der Name des Formularelementes auch Leerzeichen und andere Sonderzeichen enthalten kann, kann man hier einen einfachen Bezeichner für das Formularelement vergeben (der wird dann in /var/config/tmp/service_form.res verwendet, siehe oben $ \Rightarrow$ <subform ...>). Ist optional und kann entfallen, dann wird `Optionsname' als Bezeichner verwendet.
hname
Hier wird der Bezeichner angegeben, unter dem der Eintrag in der Hilfedatei zu finden ist, die oben angeben wurde. In der Hilfedatei werden die <help ...>-Tags durchsucht und der entsprechende Eintrag (falls er existiert) ausgegeben.
type
Legt den Typ des Formularelementes fest. Gültige Werte für `Typ' sind `TEXT', `FIELD', `LINE', `SELECT', `SELECT_M', `CHECKBOX' und `CHOICE'. Bei `TEXT'[*] wird einfacher Text ausgegeben, bei `FIELD' wird ein mehrzeiliges Eingabefeld erzeugt, bei `LINE' ein einzeiliges. `SELECT' bewirkt eine Auswahlbox mit Einfachauswahl[*] und `SELECT_M' eine mit Mehrfachauswahl. `CHECKBOX' erzeugt ein oder mehrere Checkboxen und `CHOICE' ein oder mehrere Radiobuttons.

Die Reihenfolge der Optionen im Tag ist egal.

<match>Match-Pattern</match>
Hierfür gilt das Gleiche, wie für `Match-Pattern' beim Konfigurationsformular. Auch die vordefinierten regulären Ausdrücke sind die gleichen (siehe unten: Vordefinierte reguläre Ausdrücke). Ist optional und kann entfallen, dann wird keine Überprüfung durchgeführt. Wenn ein `Match-Pattern' angegeben wurde, und die Eingabe des Benutzers ist verkehrt, dann wird bei der Analyse der Formulardaten ein Fehler ausgegeben, die Werte werden nicht gespeichert und das Skript (<subform ...>) wird nicht ausgeführt.

<size>Size</size>
Ist optional, typspezifisch, kann entfallen und definiert die Größe des Formularelementes. Falls der Tag entfällt gibt es Standardwerte für die einzelnen Typen.
Bei type=``TEXT'' wird die Angabe nicht benötigt, bei type=``FIELD'' erfolgt die Angabe als CxR (C-Spalten, R-Zeilen) (Standard: 80x10), bei type=``LINE'' als C (C-Spalten) (Standard: 50), bei type=``SELECT'' und type=``SELECT_M'' als R (R-Zeilen) (Standard: 1). Bei type=``CHECKBOX'' und type=``CHOICE'' gibt es vier Möglichkeiten (Standard: `h'):

<align>LEFT|RIGHT|CENTER|BLOCK</align>
Ist optional, typspezifisch und kann entfallen. Findet nur bei type=``TEXT'' Verwendung, und legt die Textausrichtung fest (Standard: `LEFT').

<source>Sourcefile</source>
Falls das Formularelement Vorbelegungen enthalten soll, dann kann hier die Datei angegeben werden, wo der entsprechende Text gefunden werden kann. Ist optional und kann entfallen.

<sourcerange>Range</sourcerange>
Entfällt, wenn <source> entfällt. Gilt für alle Typen. Hier kann angegeben werden, welcher Bereich von `Sourcefile' als Vorbelegung benutzt werden soll. Wenn dieser Tag weggelassen wird, aber <source> existiert, dann wird die komplette Datei als Vorbelegung gewählt. Die Angabe erfolgt immer als `r1-r2'[*]. Falls `r1' == 0, dann wird die ganze Datei als Vorbelegung gewählt; falls `r2' = `x', dann wird die Datei von `r1' bis Dateiende als Vorbelegung gewählt. Falls type=``LINE'' dann wird eine Zahl erwartet, die die Zeilennummer angibt, in der der Text steht, der als Vorbelegung gewählt werden soll. Steht dort 0 oder entfällt der Tag, dann wird die erste Zeile genommen, falls <source> existiert.

<item>Item</item>
Ist typspezifisch und findet nur bei type=``SELECT'',
type=``SELECT_M'', type=``CHECKBOX'' und type=``CHOICE'' Verwendung. Ist als Alternative zu <source> gedacht, falls eine Auswahl direkt festgelegt werden soll. Für jeden Listeneintrag und jede Checkbox bzw. jeden Radiobutton ist ein <item>-Tag zuständig. Es sollte entweder <source> oder <item> gewählt werden, wenn eine Vorbelegung erwünscht ist, falls doch beide angegeben werden, dann überschreibt <source> <item>.

<text>
Ist typspezifisch und findet nur bei type=``TEXT'' Verwendung. Ist als Alternative zu <source> gedacht. Der Text, so wie er zwischen Anfangs- und End-Tag steht, wird als Vorbelegung übernommen.
HINWEIS: Nach HTML-Standard werden mehrere Leerezeichen hintereinander zu einem einzigen zusammengefaßt. Tags werden unverändert übernommen.
Für <text> vs <source> gilt das Gleiche, wie für <item>.

Es gibt noch einen <empty/>-Tag, der eine Leerzeile im Formular erzeugt. Für Kommentare und Leerzeilen im Formfile gilt das Gleiche, wie beim Konfigurationsformular.

Die Tags innerhalb <option> dürfen in beliebiger Reihenfolge stehen.

Beispiele

Beispiel 1 (webcnfex.one):

<form help="webcnfex" name="webconfex one">
   <subform name="subform one of part one" button="here we go" script="dump.sh" target="FRAME">
      <option type="TEXT">
         <text>
            This is only a little text. Nothing interesting in. Don't know what
            to say.<br>
            This is only a little text. Nothing interesting in. Don't
            know what to say. This is only a little text. Nothing interesting
            in. Don't know what to say.<br>
            (It's boring, isn't it?).<br>
            This is only a little text.<br>
            Nothing interesting in.<br>
            Don't know what to say.<br>
            This is only a little text. Nothing interesting in. Don't know what 
            to say. Yeah, really boring.
         </text>
         <align>left</align>
      </option>
      <option type="TEXT">
         <text>
            This is only a little text. Nothing interesting in. Don't know what
            to say. This is only a little text. Nothing interesting in. Don't
            know what to say. This is only a little text. Nothing interesting
            in. Don't know what to say. (It's boring, isn't it?). This is only
            a little text. Nothing interesting in. Don't know what to say. This
            is only a little text. Nothing interesting in. Don't know what to
            say. Yeah, really boring.
         </text>
         <align>BLOCK</align>
      </option>
      <empty/>
      <empty/>
      <option name="multi-select" vname="msel" type="SELECT_M" hname="help1">
         <size>4</size>
         <item>this</item>
         <item>is a</item>
         <item>multi</item>
         <item>select</item>
         <item>box</item>
      </option>
      <option name="single-select" vname="ssel" type="SELECT" hname="help2">
         <size>1</size>
         <item>you</item>
         <item>can</item>
         <item>choose</item>
         <item>only</item>
         <item>one</item>
      </option>
      <empty/>
      <empty/>
      <option type="TEXT">
         <text>
            This is only a little text. Nothing interesting in. Don't know what
            to say.<br>
            This is only a little text. Nothing interesting in. Don't
            know what to say. This is only a little text. Nothing interesting
            in. Don't know what to say.<br>
            (It's boring, isn't it?).<br>
            This is only a little text.<br>
            Nothing interesting in.<br>
            Don't know what to say.<br>
            This is only a little text. Nothing interesting in. Don't know what 
            to say. Yeah, really boring.
         </text>
         <align>RIGHT</align>
      </option>
      <option type="TEXT">
         <text>
            This is only a little text. Nothing interesting in. Don't know what
            to say.<br>
            This is only a little text. Nothing interesting in. Don't
            know what to say. This is only a little text. Nothing interesting
            in. Don't know what to say.<br>
            (It's boring, isn't it?).<br>
            This is only a little text.<br>
            Nothing interesting in.<br>
            Don't know what to say.<br>
            This is only a little text. Nothing interesting in. Don't know what 
            to say. Yeah, really boring.
         </text>
         <align>CENTER</align>
      </option>
   </subform>
</form>
Beispiel 2 (webcnfex.two):
<form help="webcnfex" prep="webcnfex.two.prep" name="webconfex two">
   <subform name="subform one of part two" button="click me" script="dump.sh" target="NEW">
      <option type="TEXT">
         <text>
            input-line with regex-check
         </text>
      </option>
      <option name="type sth." vname="ts1" type="LINE" hname="help3">
         <size>30</size>
         <source>/tmp/webcnfex.two.source1</source>
         <match>#ip_s#</match>
      </option>
      <option name="type sth." vname="ts2" type="LINE" hname="help4">
         <size>30</size>
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>1</sourcerange>
         <match>#dir_s#</match>
      </option>
   </subform>
   <empty/>
   <empty/>
   <empty/>
   <subform name="subform two of part two" script="dump.sh" target="FRAME">
      <option name="checkboxes t1" vname="cbt1" type="CHECKBOX" hname="help5">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>2-5</sourcerange>
         <size>v</size>
      </option>
      <empty/>
      <option name="checkboxes t2" vname="cbt2" type="CHECKBOX" hname="help6">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>2-5</sourcerange>
         <size>h</size>
      </option>
      <option name="checkboxes t3" vname="cbt3" type="CHECKBOX" hname="help7">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>2-5</sourcerange>
         <size>h3</size>
      </option>
      <option name="checkboxes t4" vname="cbt4" type="CHECKBOX" hname="help8">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>2-5</sourcerange>
         <size>v3</size>
      </option>
   </subform>
   <empty/>
   <empty/>
   <empty/>
   <subform name="subform three of part two" script="dump.sh" target="FRAME">
      <option name="buttons t1" vname="ct1" type="CHOICE" hname="help9">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>6-10</sourcerange>
         <size>v</size>
      </option>
      <empty/>
      <option name="buttons t2" vname="ct2" type="CHOICE" hname="help10">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>6-10</sourcerange>
         <size>h</size>
      </option>
      <option name="buttons t3" vname="ct3" type="CHOICE" hname="help11">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>6-10</sourcerange>
         <size>h3</size>
      </option>
      <option name="buttons t4" vname="ct4" type="CHOICE" hname="help12">
         <source>/tmp/webcnfex.two.source1</source>
         <sourcerange>6-10</sourcerange>
         <size>v3</size>
      </option>
   </subform>
</form>

Zusätzliche Unterstützung in den Formularen

Wie weiter oben schon angedeutet, ist es möglich Hilfepunkte in die Formulare zu integrieren, um dem Benutzer zusätzliche Unterstützung zu geben. Dies geschieht mit der Hilfedatei.
Desweiteren können die Formulare per CSS gestaltet werden.

Die Hilfedatei

Die Hilfedateien müssen sich in /var/install/help befinden. Im Falle der der Hilfedatei zur Konfiguration muß diese genauso heißen wie das Konfigurationsformular (siehe oben: Das Konfigurationsformular). Im Falle der Hilfedatei zur Serviceadministration kann der Name frei festgelegt werden (siehe oben: Das Serviceformular). Weiterhin kann jede Servicefunktion eine eigene Hilfedatei haben, man kann aber auch die gesamte Hilfe in einer einzigen Datei zusammen mit der Hilfe für die Konfiguration unterbringen. Die letzte Variante ist sicher zu bevorzugen.

Syntax und Semantik

<help name="Optionsname">
   Hilfetext
</help ...>
...
<help>
...
</help>

Für jeden Hilfepunkt muß ein <help ...>-Tag existieren. Dabei wird der Hilfetext der richtigen Variablen über `Optionsname' zugeordnet, d.h. `Optionsname' muß gleich dem Optionsnamen (im Falle des Konfigurationsformulars) bzw. gleich dem Variablennamen (im Falle des Serviceformulars) sein, der auch in der entsprechenden Formulardatei angegeben wurde, zu der der Hilfetext gehören soll.
Desweiteren werden in `Hilfetext' folgende Ersetzungen vorgenommen:

Wenn die Zeichen `<', `>', `&' und `"' so direkt ausgegeben werden sollen, dann müssen sie also vorher mit ` \' maskiert werden, sonst kann es zu Fehlern bei der Darstellung kommen. Da die Hilfe eine Webseite ist, können auch HTML-Tags in der Hilfe verwendet werden. Leere Zeilen in der Hilfedatei sind erlaubt und werden ignoriert. Wichtig ist, daß die Tags alleine in einer Zeile stehen. Bsp.:
<help name="Optionsname"> Ich bin
ein kleiner
</help> Hilfetext.
$ \Rightarrow$falsch

<help name="Optionsname">
Ich bin ein kleiner Hilfetext.
</help>
$ \Rightarrow$richtig

Ein Beispiel

Als Beispiel dient ein Teil der mitgelieferten webcnfex-Hilfedatei:

<help name="WEBCNFEX_START">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_COMMENT">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_TYPE">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIMIT">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_ALIAS_N">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_ALIAS_#">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_N">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_#_NAME">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_#_USER_N">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_#_USER_##_SURNAME">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_#_USER_##_LASTNAME">
Too lazy to put sth. ingenious here.
</help>

<help name="WEBCNFEX_LIST_#_USER_##_TRAFFIC">
Too lazy to put sth. ingenious here.
</help>

<help name="help1">
this is help.
</help>

<help name="help2">
help?
</help>

Unterstützung von CSS

Zur Gestaltung der Formulare wird CSS verwendet. Dabei kann man den verschiedenen HTML-Elementen Klassen zuordnen. Damit bei Bedarf jede Hauptseite anders gestaltet werden kann, habe ich den verwendeten Elementen dafür jeweils eine eigene Klasse zugewiesen. Folgende Klassen wurden verwendet:

index
Indexseite (die Startseite)
result
Ergebnisseite (i.d.R. der untere Frame)
error
Fehlerseite
chooseserv
Seite auf der die Dienste zur Administration ausgewählt werden können
chooseopt
Seite auf der einzelnen Optionen eines Dienstes ausgewählt werden können
help
Hilfeseite
confform
Formular zum Editieren der Konfigurationsdatei
button-confform
Absendeknopf im Konfigurationsformular
opt-confform
Tabellenspalte in der die Daten der Variablen im Konfigurationsformular stehen
optname-confform
Tabellenspalte in der die Variablennamen im Konfigurationsformular stehen
text-confform
Eingabefeld im Konfigurationsformular
servform
Formular zu Service Administration
button-servform
Absendeknopf im Serviceformular
check-servform
Checkboxen im Serviceformular
radio-servform
Radiobuttons im Serviceformular
opt-servform
Tabellenspalte in der die Daten der Variablen im Serviceformular stehen
optname-servform
Tabellenspalte in der die Variablennamen im Serviceformular stehen
text-servform
Eingabefeld im Serviceformular

Für die einzelnen Klassen können jeweils folgende HTML-Elemente definiert werden:

index
a, body, h1, hr, li, ol, span
result
b, body, pre
error
a, body, h1, hr, p, span
chooseserv
a, body, h1, hr, li, ol, p, span
chooseopt
a, body, h1, hr, li, ol, p, span
help
b, body, p, pre
confform
a, body, fieldset, form, h1, hr, legend, option, select, span, table, tr
button-confform
input
opt-confform
td
optname-confform
td
text-confform
input
servform
a, body, fieldset, form, h1, hr, legend, option, p, select, span, table, textarea, tr
button-servform
input
check-servform
input
radio-servform
input
opt-servform
td
optname-servform
td
text-servform
input

Das Stylesheet muß sich unter /usr/local/webconf/CSS befinden. Es kann entweder eine einzelne Datei sein (z.B. `foobar.css') oder ein Verzeichnis. Das Verzeichnis muß genauso heißen wie die Datei, nur ohne `.css' (z.B. /usr/local/webconf/CSS/foobar/). In diesem Verzeichnis befindet sich dann das eigentliche Stylesheet `foobar.css' und die weiteren Dateien (z.B. Bilder). Der Name des Stylesheets, der dann in der Konfigurationsdatei von Webconf angegeben wird ist dann `foobar'.

Eine gute Einführung in HTML und CSS bietet u.a. http://selfaktuell.teamone.de/

Ein Beispiel

h1.index { text-align:center; }
ol.index { margin-left:40%; }

h1.error { text-align:center;
           color:#FF0000; }
p.error  { text-align:justify;
           margin-left:5%; }

h1.chooseserv { text-align:center; }
ol.chooseserv { margin-left:40%; }

h1.chooseopt { text-align:center; }
ol.chooseopt { margin-left:40%; }

h1.confform           { text-align:center; }
input.button-confform { text-align:left; }
input.text-confform   { font-family:Courier, monospace;
                        font-weight:bold; }
textarea.confform     { font-family:Courier, monospace;
                        font-weight:bold; }
select.confform       { font-family:Courier, monospace;
                        font-weight:bold; }
td.optname-confform   { text-align:right; 
                        vertical-align:top;
                        margin-left:10px;
                        font-family:'lucidabright', 'Lucida Console', monospace; }
legend.confform       { font-weight:bold; } 
table.confform        { margin:10px; }

h1.servform           { text-align:center; }
legend.servform       { font-weight:bold; }
input.button-servform { text-align:left; }
input.text-servform   { font-family:Courier, monospace;
                        font-weight:bold; }
textarea.servform     { font-family:Courier, monospace;
                        font-weight:bold; }
select.servform       { font-family:Courier, monospace;
                        font-weight:bold; }
td.optname-servform   { text-align:right; 
                        vertical-align:top;
                        margin-left:10px;
                        font-family:'lucidabright', 'Lucida Console', monospace }
p.servform            { font-family:Verdana, Lucida, Courier, monospace; 
                        margin-left:10px;
                        margin-right:10px; 
                        margin-top:10px;
                        margin-bottom:10px; }
table.servform        { margin:10px; }


Vordefinierte reguläre Ausdrücke

Es gibt folgende vordefinierte reguläre Ausdrücke:

#ip#
Prüft auf `byte.byte.byte.byte', wobei `byte' für eine Zahl von 0-255 steht.

#subnet#
Prüft auf `#ip#/subnetmask', wobei `subnetmask' für eine Zahl von 0-32[*] oder `#ip#'[*] steht.

#file#
Prüft auf `/?filename(/filename)*', wobei `filename' für eine Zeichenkette steht, die alle Zeichen außer `/' und das Nullbyte (` \0') enthalten darf.

#dir#
Prüft auf `/' und `/?filename(/filename)*/?', wobei `filename' für eine Zeichenkette steht, die alle Zeichen außer `/' und das Nullbyte (` \0') enthalten darf.

#file_exist#
Prüft auf `#file#' und ob die Datei existiert[*].

#dir_exist#
Prüft auf `#dir#' und ob das Verzeichnis existiert[*].

#file_notexist#
Prüft auf `#file#' und ob die Datei nicht existiert[*].

#dir_notexist#
Prüft auf `#dir#' und ob das Verzeichnis nicht existiert[*].

#email#
Prüft auf 'localpart@domain' nach RFC819[*]. Dabei steht `localpart' für eine Zeichenkette bestehend aus den ASCII-Zeichen \32d- \126d außer ' \', `:', `,', `;', `@', `(', `)', `[', `]', '' oder für einen in '' eingfaßten String, in dem entweder alle ASCII-Zeichen \0d- \127d mit ` \' maskiert vorkommen dürfen, oder alle ASCII-Zeichen \0d- \127d außer ` \10d', ` \13d', '', ` \'.
domain steht für `#ip#', `[#ip#]', oder `name(.name)*', wobei `name' für eine Zeichenkette steht, die mit einem Zeichen aus [a-zA-Z] anfangen, mit einem Zeichen aus [a-zA-Z0-9] enden muß und ansonsten Zeichen aus [a-zA-Z0-9-] enthalten darf.

#domain#
Prüft auf `domain' aus `#email#'.

#hex#
Prüft auf `0x[a-zA-Z0-9]+'.

#cron#
Prüft auf `min hour day_of_month month day_of_week( cmd)?' entsprechend crontab(5).

#ng#
Prüft auf `name(.name)*' entsprechend Son of RFC1036[*]. `name' steht dabei für eine Zeichenkette, die mit einem Zeichen aus [a-z] anfangen, mit einem Zeichen aus [a-z0-9] enden muß und ansonsten Zeichen aus [a-z0-9+_-] enthalten darf.

#dec_X#
Prüft auf ` \d{1,X}'. Wenn `X' == 0, dann sind beliebig viele Stellen erlaubt.

#port#
Prüft auf eine Zahl von 0-65535.

#user#
Prüft auf `user', wobei user als Benutzer auf dem System existieren muß.

#group#
Prüft auf `group', wobei group eine auf dem System existierende Gruppe sein muß.

#mode#
Prüft auf `[0-7]{3,4}|([rwx-]3)3'.

#memsize#
Prüft auf ` \d+[kmgt]?'.

Die vordefinierten Pattern können beliebig mit normalen regulären Ausdrücken kombiniert werden und es kann jeder noch mit einem Suffix versehen werden (innerhalb von `#...#'). Das Suffix `_e' (empty) bewirkt, daß der Inhalt auch leer sein darf, `_s' (strict) erzwingt einen Match auf die ganze Zeile und `_se' bzw. `_es' kombiniert beides.

Die Funktionsweise von regulären Ausdrücken unter Perl kann man auf http://www.perldoc.comunter dem Kapitel `perlre' nachlesen. Falls das komplette Perlpaket auf dem eigenen System installiert ist, kann man diese Dokumentation auch mit dem Aufruf `perldoc perlre' aufrufen. Man beachte, daß `perldoc' in dem Perlpaket für eisfair nicht enthalten ist.



Fußnoten

... durchzuführen[*]
die nötige Skripte vorausgesetzt
... erscheint[*]
analog zur ersten Zeile in /var/install/menu/setup.services.<package>.menu
... soll[*]
analog der Namen in /var/install/menu/setup.services.<package>.menu
... Namen[*]
mit Endung `.sh' wird es auch erkannt
... Master-Variablen[*]
Variablen, die die Anzahl von anderen Variablen bestimmen
... dort[*]
sinnvoll für die '#Formularname#'-Angabe
... `TEXT'[*]
ist kein direktes, verwertbares Formularelement
... Einfachauswahl[*]
nur ein Element kann ausgewählt werden
... Reihe
... `r1-r2'[*]
Zeile r1 bis Zeile r2 wird als Vorbelegung genommen, die erste Zeile von `Sourcefile' ist 1
... 0-32[*]
die Anzahl der gesetzten Bits in der Netzmaske
... `\#ip\#'[*]
die ausgeschriebene Netzmaske
... existiert
... existiert
... RFC819[*]
http://www.ietf.org/rfc/rfc0819.txt
... RFC1036[*]
http://www.karlsruhe.org/rfc/son1036.txt
Christian Wuerdig 2003-06-15