vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Tag 17

Komplexe Techniken: Benutzerdaten verfolgen und verwenden

Wenn ein Benutzer Daten in ein Formular auf einer Website eingibt, dann dient das nicht immer nur einer Online-Umfrage oder zum Ausfüllen eines Auftragsformulars - es könnte sich vielmehr auch um Informationen handeln, die der Benutzer für sich selbst speichern will. Beispielsweise ist es möglich, eine Website anzulegen, auf der die Benutzer eigene Homepages anlegen können, indem sie ein paar Formulare ausfüllen. Nur zu oft geht man fälschlicherweise davon aus, dass es ausschließlich dem Marketing dient, wenn eine Website Daten sammelt.

Dieses Kapitel zeigt Ihnen, wie Sie Websites anlegen, die Informationen von einem Benutzer entgegennehmen und seine Browsing-Umgebung entsprechend anpassen. Gewissermaßen bieten Sie den Benutzern die Möglichkeit, ihre eigene, angepasste Version der Website anzulegen. Die Themen des heutigen Tages:

17.1 Benutzerdefinierte Websites

Haben Sie schon einmal eine Website besucht, auf der es die Möglichkeit gab, die Site nach Ihren eigenen Vorstellungen abzuändern? Das ist eine extrem beliebte Technik, die bei korrekter Anwendung einem Benutzer unglaublich viel Kontrolle über die Umgebung einer Site bietet. Wenn Sie eine Website haben, die mehrere Dienste anbietet (verschiedene Nachrichtentypen, Einkaufsmöglichkeiten usw.), gewinnen Sie wiederholte Besucher, wenn Sie ihnen auf einer Seite genau das zeigen, was sie sehen wollen.

Beispielsweise besuche ich zwei- bis dreimal in der Woche eine bekannte DVD-Site im Internet. Anfangs war ich gezwungen, ihre wöchentlichen Angebote anzuzeigen, bevor ich den Abschnitt Neuerscheinungen erreichte, um zu finden, wonach ich suchte. Ich überlegte, dass es viel besser wäre, wenn ich auf die Homepage käme und sofort sähe, was ich suchte. Glücklicherweise wurde dieses Funktionsmerkmal bei einer Überarbeitung der Site eingebaut. Statt mich jetzt durch mehrere Seiten klicken zu müssen, die mich nicht interessieren, erscheint das für mich wirklich Interessante, sobald ich die erste Seite lade.

In diesem Kapitel erfahren Sie, wie Sie genau dieses Verhalten auf Ihrer Website unterstützen. Später können Sie es auf beliebige Sites anwenden, um sie attraktiver zu machen.

Als Erstes sollten Sie sich fragen: »Welche Komponenten der Site sollen vom Benutzer angepasst werden können?« Es gibt unterschiedliche Ebenen, die Sie dem Betrachter bieten können, abhängig vom Typ Ihrer Site. Wie Sie bereits erfahren haben, können Sie beispielsweise beliebige Tag-Attribute auf einer Site zu einem dynamischen Element machen, indem Sie das Objekt im Dokument markieren und den Eigenschafteninspektor öffnen.

Von der standardmäßigen benutzerfreundlichen Ansicht der Palette wechseln Sie zur Attributliste, indem Sie auf die zweite Registerkarte auf der linken Seite der Tabelle klicken. Dieser Teil der Palette, den Sie in Abbildung 17.1 sehen, ermöglicht Ihnen, einem Tag schnell und einfach Attribute zuzuweisen, die beim Laden der Seite aus einer Datenbank abgerufen werden.

Abbildung 17.1:  Alle Tag-Attribute können dynamisch gesetzt werden.

Alles, was Sie in einem Tag manuell setzen können, kann auch dynamisch aus der Datenbank gesetzt werden:

Sie können eine Site einrichten, die ihr gesamtes Look&Feel aus einer externen Datenbank lädt - ohne überhaupt etwas codieren zu müssen.

Sie sollten einen Nachteil in Betracht ziehen, wenn Sie eine dynamische Site entwerfen - die Site als solche kann keinerlei dynamische Elemente enthalten. Wenn Sie beispielsweise das HTML speichern, um eine ganze Tabelle in einem Datensatz einer Datenbank abzulegen, können Sie den Spieß nicht umdrehen und diesem HTML dynamische Tags hinzufügen - die Tags werden nicht rekursiv interpretiert.

Der Extremfall einer durch den Benutzer anpassbaren Website erlaubt dem Benutzer nicht nur die Tag-Attribute, sondern auch den Inhalt der Site zu ändern. Dies ist gebräuchlich auf Portalsites, die abhängig von den Auswahlen des Benutzers speziell auf ihn ausgelegte Nachrichten anzeigen. Das heutige Kapitel versucht, diesem Ansatz zu folgen und eine völlig anpassbare Portalsite anzulegen, wo der Benutzer steuert, welche Informationen angezeigt werden.

Der Plan der konfigurierbaren Website

Überraschenderweise wird ein Großteil der Arbeit auf dieser Site vom Datenbankserver und ein paar einfachen Abfragen erledigt. Die Entwicklung der Oberfläche, über die der Benutzer seine Software anpassen kann, dauert vermutlich länger, als den eigentlichen Portal-Bildschirm zu entwickeln. Um die Site nutzen zu können, durchläuft ein Benutzer in seinem Browser einige Registrierungsschritte, in denen er seine Einstellungen für die Website festlegt. Nach der Registrierung wird auf seinem Computer ein Cookie gespeichert, das dafür sorgt, dass der Benutzer nach der Rückkehr auf die Site wieder genau das vorfindet, was er eingestellt hat - jederzeit. Eine grundlegende Sitemap für das Registrierungssystem und das Portal sehen Sie in Abbildung 17.2.

Einige von Ihnen werden Websites erstellen wollen, die diese Dienste anbieten sollen, ohne sich mit einem Anmeldesystem herumschlagen zu müssen. Das ist zwar möglich, indem das Registrierungssystem weggelassen wird (es würde nur ein Cookie verwendet, um den Benutzer zu identifizieren), aber der Benutzer verliert damit die Möglichkeit, auf seine Seite zurückzugehen und die Einstellungen zu ändern. Wenn der Benutzer an einem anderen Computer arbeitet, gelangt er ebenfalls nicht zu seinen vorhergehenden Einstellungen zurück.

Aber warum können wir nicht all diese Dinge in Cookies ablegen, statt uns mit einer Datenbank herumzuschlagen? Um diese Frage wirklich beantworten zu können, müssen Sie sich überlegen, wie viele Elemente auf Ihrer Site Sie dynamisch machen wollen. Eines? Zwei? Zehn? Fünfhundert? Wann muss der Benutzer aufhören, seine Umgebung anzupassen?

Durch die Verwendung von Cookies für die Konfigurationsdaten beschränken Sie die Anzahl der Daten, die dynamisch manipuliert werden können. Cookies sind am besten dazu geeignet, kleine Datenmengen zu speichern, wie beispielsweise Benutzer-IDs. Außerdem müssen Sie bei jedem Einfügen eines neuen Elements den Code ändern, der dieses Element unterstützt, oder ein etwas komplexeres, generischeres Cookie- Konfigurationsprogramm entwickeln, bevor Sie anfangen. Verstehen Sie mich nicht falsch - wenn Sie einen oder zwei Werte ablegen wollen, dann stellen Cookies eine ausgezeichnete Lösung dar; wenn Sie dagegen alle Werte für die Konfiguration einer ganzen Website darin ablegen wollen, könnte das problematisch sein.v

Abbildung 17.2:  Der größte Teil der Site besteht aus dem  Registrierungsabschnitt.

Ein ausschließlich auf Cookies ausgelegter Ansatz zwingt einen Benutzer außerdem, seine Einstellungen erneut zu registrieren, wenn er in einem anderen Browser oder an einem anderen Computer arbeitet, was nicht besonders benutzerfreundlich ist. Eine Datenbank, die über eine einzige Benutzer-ID angesprochen wird, die in einem Cookie abgelegt wurde, bietet sehr viel mehr Flexibilität und ein erweiterbares System. Auf dem Rechner des Clients wird nur ein einziger Wert abgelegt - dieser Wert kann jedoch beliebig vielen Datenbankeinträgen zugeordnet werden, die Sie für eine perfekte Site brauchen.

Die Verwendung von Cookies zum Speichern von Benutzer-IDs ist ausgezeichnet dafür geeignet, Dinge wie beispielsweise die Einstellungen für eine Website zu verwalten - aber sie ist nicht für Sites mit gesichertem Zugriff geeignet. Das Witzige an dem heutigen Thema ist, dass die resultierende Site nicht vollständig gesichert sein muss. Es werden keine privaten Informationen gespeichert, und auch sonst nichts, womit der Benutzer nichts zu tun haben sollte. Wäre dies der Fall, könnten wir eine mehr auf dem Zufall basierende Methode verwenden, eine Benutzer-ID einzurichten, als die Datenbank eine automatische Nummerierung für uns vornehmen zu lassen. Sichere Cookies enthalten normalerweise verschlüsselte Informationen, die nur für sehr kurze Zeitintervalle gültig sind.

17.2 Tabellendefinitionen

Die Tabellendefinitionen für die Site sind sehr interessant. Wir beginnen mit der einfachsten - der Tabelle für die Benutzerinformationen.

Benutzerauthentifizierung und Voreinstellungen

Benutzer brauchen eine Möglichkeit, sich am System anzumelden und ihre Einstellungen festzulegen. Das wird durch eine einfache Benutzertabelle realisiert, die die Benutzer-IDs automatisch erzeugt und sie zusammen mit Benutzernamen und Kennwörtern ablegt:

create table tblUserInfo (
userID int not null auto_increment,
username varchar(50) not null,
password varchar(50) not null,
primary key (userID)
)

Die zweite Tabelle bezieht sich ebenfalls auf den Benutzer, ist aber wesentlich komplexer als eine Tabelle mit reinen Benutzerinformationen. Im ersten Ansatz könnte man sich vielleicht vorstellen, eine Tabelle für die Einstellungen eines Benutzers enthält für jede Funktion, für die ein dynamischer Wert festgelegt werden kann, ein Feld. Das würde sicherlich funktionieren, bietet aber nicht die von uns gewünschte Funktionalität. Statt dessen brauchen wir einen Ansatz, der es ermöglicht, zusätzliche Optionen im System bereitzustellen, ohne dass wir ständig neue Felder erstellen müssen.

Aus welchen Werten besteht nun eine dynamische Option? Überlegen wir, was wir für die Tabelle mit den Einstellungen brauchen:

  1. Die Funktionalität, für die wir eine Einstellung speichern (Seitenfarbe, Bildposition usw.)
  2. Die Benutzer-ID der Person, die das Funktionsmerkmal festlegt
  3. Den Funktionswert - das ist der zugehörige dynamische Wert

Ein Beispiel für ein solches Funktionsmerkmal ist die Hintergrundfarbe der Webseite. Um die Funktionalität speichern zu können, brauchen wir eine Liste der Funktions-IDs, die mit der Weiterentwicklung der Site auch anwachsen kann. Die anderen Felder sind selbsterklärend. Die Benutzer-ID gibt die Person an, die die Einstellung speichern will, und der Funktionswert enthält die dynamischen Daten (wie beispielsweise eine Farbe #FFBBFF).

Dieser Ansatz für das System bietet zwar die höchste Flexibilität, stellt aber auch die höchste Belastung für den Server dar. Statt alle Einstellungen in einer einzigen Abfrage zurückgeben zu können, muss jede Einstellung durch eine separate Abfrage abgerufen werden.

Fass Ihr Server und die Site keine Probleme mit dem erhöhten Datenbankverkehr haben, verwenden Sie diese Methode. Andernfalls sollten Sie vielleicht eine flache Tabellenstruktur verwenden, um die Feldwerte abzulegen.

Anhand dieser Information können wir die folgende Tabellenstruktur für die Benutzereinstellungen einrichten:

create table tblPreference (
featureID int not null,
userID varchar(50) not null,
optionValue text,
primary key (featureID,userID)
)

Funktionen und Optionen

Als Nächstes stellen wir eine Master-Tabelle mit den Funktionsmerkmalen bereit, aus denen der Benutzer auswählen kann. Das muss nicht unbedingt durch eine Datenbanktabelle gestützt werden, aber dieser Ansatz macht dem Administrator das Leben sehr viel leichter. Wenn Sie 100 oder mehr Optionen haben, können Sie sie nicht mehr verwalten, indem Sie sie auf einem Stück Papier aufschreiben. Statt dessen verwenden Sie eine weitere Tabelle in der Datenbank, um die Optionen und die entsprechenden Funktions-IDs zu verwalten.

create table tblOption (
featureID int not null,
optionName varchar(50) not null,
optionValue text,
primary key (featureID,optionName)
)

Erstellen Sie die Datenbanktabellen erst, nachdem wir am Ende dieses Abschnitts die endgültige Datendefinition vorliegen haben. In der Zwischenzeit werden noch einige wesentliche Änderungen vorgenommen.

An dieser Stelle ein paar Erklärungen. Statt über die Feldwerte zu sprechen, wollen wir einige potenzielle Werte betrachten:

featureID:    1
optionName: Blue
optionValue: #0000FF

featureID: 1
optionName: Red
optionValue: #FF0000

featureID: 1
optionName: Green
optionValue: #00FF00

featureID: 1
optionName: Yellow
optionValue: #FFFF00

Dies sind offensichtlich Farbnamen und der entsprechende HTML-codierte Wert. Sie werden über die Funktions-ID (featureID) angesprochen. Funktion 1 beispielsweise könnte die Hintergrundfarbe der Webseite sein - das bleibt völlig Ihnen überlassen.

Anhand dieser Struktur können Sie dynamisch die Liste der Einstellungen für den Benutzer erstellen. Damit ersparen Sie sich zur Entwurfsphase etwas Schreibarbeit und bleiben flexibel, sodass Sie Ihrer Datenbank schnell neue Optionen hinzufügen können und diese unmittelbar auf der Webseite angezeigt werden.

Selbst mit der Optionstabelle müssen Sie die Funktionen irgendwie verwalten, für die die Optionen angelegt werden. Momentan werden sie nur durch eine einzige Funktions-ID identifiziert, und Sie werden schnell die Übersicht verlieren, wenn Sie keine Tabelle oder eine andere Möglichkeit haben, die Information zu speichern. Das ist zwar für die eigentliche Web-Applikation nicht nötig, aber Sie sollten sich dennoch eine Tabelle in der Datenbank Ihrer Web-Applikation anlegen, um die Werte zu speichern.

Nun haben wir die Datenbankstruktur - aber was wollen wir darin ablegen? Für diese Applikation brauchen wir nur ein paar Optionen, die der Benutzer auswählen kann. Aber wie sollen diese Optionen aussehen?

Antworten Sie nicht zu schnell. Die Optionen, die wir hier wählen, steuern die Entwicklung der Website. Wir wollen, dass der Benutzer auswählen kann, welche Daten er auf dem Bildschirm sieht. Darüber hinaus bieten wir ihm die Möglichkeit, die Position der Seite festzulegen, die die Informationen enthält.

Aber wie ist das möglich? Ganz einfach - wir verwenden dazu Techniken ähnlich denen, die Sie in Kapitel 10, »Datenbankgestützte Webseiten entwickeln«, kennen gelernt haben. Ebenen bieten höchste Flexibilität, die wir nutzen können, um sehr komplexe Sites anzulegen, die komplett durch die Einstellungen des Benutzers gesteuert werden.

Welche Funktionen wollen wir einem Benutzer für diese Site anbieten?

Die beiden ersten Punkte sind selbsterklärend - Sie ändern einfach dynamisch einige der Farb-Tags im Dokument. Die anderen sind (scheinbar) nicht so einfach.

Es gibt mehrere Inhaltsbereiche, aus denen ein Benutzer auswählen kann, um sie auf seiner Seite anzuzeigen, wenn er die Site besucht. Diese Inhaltsbereiche sind in einzelne Ebenen aufgeteilt, die die variablen Informationen enthalten.

Die wichtigste Entscheidung betrifft die Implementierung der Ebenen, die vorhanden sein müssen, um dem Benutzer die Wahl zu bieten, jederzeit jeden beliebigen Inhalt zu präsentieren. Die beiden folgenden Ansätze führen zu einer Lösung des Problems:

Offensichtlich ist die zu bevorzugende Technik, alles in der Datenbank abzulegen. Damit verfügen Sie über eine zentrale Position, von der aus Aktualisierungen des Seiteninhalts vorgenommen werden können. Nach dem ersten Ansatz müsste die Seite ständig bearbeitet werden, um neuen Inhalt zu präsentieren. Ich denke, es ist höchst unwahrscheinlich, dass Nachrichtenseiten wie beispielsweise MSN ständig einen HTML- Editor geöffnet haben und darauf warten, dass ein Artikel zu verfassen ist.

Eine optimierte Struktur

Leider haben wir ein Problem mit der Datenbankstruktur, die wir zuvor entworfen haben. Angenommen, auf dem Bildschirm befinden sich vier Inhaltsbereiche, aber es gibt sechs mögliche Inhalte, die in diesen Bereichen angezeigt werden können. Um den gesamten Inhalt in allen Bereichen zur Verfügung zu stellen, geben wir insgesamt 24 Einträge in die Optionstabelle ein. Diese Wiederholung der Daten wird sehr schnell zum Albtraum, wenn die Informationen aktualisiert werden müssen.

Um dieses Redundanzproblem zu beheben, kürzen oder ändern wir die Optionstabelle wie folgt:

create table tblFeatureOption (
featureID int not null,
optionID int not null,
primary key (featureID,optionID)
)

Statt einem Optionsnamen und dem Wert eine Funktions-ID zuzuordnen, wird ihnen eine Options-ID zugewiesen. Schließlich brauchen wir noch eine letzte Tabelle, die die Informationen aufnimmt, die wir soeben aus der ehemaligen Optionstabelle entfernt haben. Sie werden in einer neuen Optionstabelle angeordnet:

create table tblOption (
optionID int not null,
optionName varchar(50),
optionValue text,
primary key (optionID)
)

Jetzt kann eine Option mehreren Funktionen zugeordnet werden, ohne die eigentliche Information zu wiederholen. Das erfordert zwar mehr Arbeit für die Abfragen, aber das Endergebnis ist auf lange Sicht besser zu verwalten.

Damit sind wir jedoch gezwungen, die Tabelle mit den Einstellungen noch einmal zu überprüfen. Weil die Optionen jetzt über eine Options-ID angesprochen werden, kann diese jetzt anstelle des Optionswert gespeichert werden:

create table tblPreference (
featureID int not null,
userID int not null,
optionID int not null,
primary key (featureID,userID)
)

Abbildung 17.3 zeigt die endgültige Definition der Datenbanktabelle.

Abbildung 17.3:  Die endgültige Definition der Datenbank setzt sich aus vier Tabellen zusammen.

Im letzten vorbereitenden Schritt legen wir einige Site-Funktionen und -Optionen fest. Zuerst die Optionen. Die Farben, die ich zuvor aufgelistet habe, sollten ausreichend sein, um die verschiedenen Farbelemente für die Seite zu demonstrieren, deshalb werden sie dem System hinzugefügt:

insert into tblOption values (1,'Blue','#0000FF');
insert into tblOption values (2,'Red','#FF0000');
insert into tblOption values (3,'Green','#00FF00');
insert into tblOption values (4,'Yellow','#FFFF00');

Auch Schwarz und Weiß sind vielleicht ganz praktisch:

insert into tblOption values (5,'White','#FFFFFF');
insert into tblOption values (6,'Black','#000000');

Jetzt wollen wir ermöglichen, die Position der Ebenen zu verändern, die den Inhalt aufnehmen sollen, deshalb fügen wir der Liste der verfügbaren Optionen einige Koordinaten hinzu:

insert into tblOption values (7,'Top Left','left: 45px; top: 38px');
insert into tblOption values (8,'Top Right','left: 336px; top: 38px');
insert into tblOption values (9,'Bottom Left','left: 45px; top: 325px');
insert into tblOption values (10,'Bottom Right','left: 336px; top: 325px');

Die hier der Datenbank hinzugefügten Positionskoordinaten habe ich nicht einfach erfunden. Statt dessen habe ich eine Seite mit vier rechteckigen Ebenen entworfen, die entsprechend dimensioniert sind, und dann ihre Positionsinformation kopiert und in die Datenbank eingetragen.

Bereitstellen der verfügbaren Optionen

Schließlich brauchen wir Inhalt für das System. Sie können für diesen Teil des Projekts eigene Datensätze verwenden, aber auch das, was ich hier bereitstelle:

insert into tblOption values (11,'Lokales Wetter',
'<h3>Cleveland-Wetter</h3>Heiß und feucht, mit einer gewissen
Wahrscheinlichkeit für einen Hurrikan oder ein Erdbeben. <br><br><CENTER>
<FONT COLOR="#FF0000">Keine Überlebenschance</FONT></CENTER>');

insert into tblOption values (12,'Web Links',
'<h3>Hot Links</h3>Wenn Sie ein paar der besten Sites im Web suchen,
dann sehen Sie hier nach!<br><br><a href="http://www.cnn.com">CNN</a><br>
<A href="http://www.macnn.com">MacNN</a><br>
<a href="http://www.maccentral.com/">MacCentral</A>');
insert into tblOption values (13,'US News',
'<h3>Top Stories</h3>Riesige Monster sind in Redmond eingefallen und
übernehmen die Weltherrschaft. Die Anführer werden als "Gates" bezeichnet und
fürchten sich nur vor Fenstern');
insert into tblOption values (14,'Local
News','<h3>Lokalnachrichten</h3>Lokalredakteur fällt ins Koma, während er
Reality-TV um 11 sieht');
insert into tblOption values (15,'TV-Shows','<h3>Was läuft im
Fernsehen</h3>Heute gibt es einen Bericht über die Präsidentschaftswahl 2001
in Atlantis. Viele favorisieren den jüngsten Kandidaten, Mr.Teedles, der
versprochen hat, eine Form von Unterwassverviehherden zu entwickeln.');

Dies sind offensichtlich keine realistischen Inhalte, aber sie sollten ausreichen, um den Zweck dieser Site zu demonstrieren.

Beachten Sie, dass diese Optionsdatensätze Inhalt mit HTML enthalten. Das scheint auf den ersten Blick recht seltsam, aber es ist kein Problem, HTML in Ihrer Datenbank abzulegen. Er wird genauso dargestellt wie statische HTML-Seiten, nachdem er aus der Datenbank geladen und dann in Ihr Dokument eingefügt wurde.

Nachdem die Optionen in die Datenbank eingetragen wurden, legen Sie ein paar Einträge für tblFeatureOption an - diese verknüpfen die Optionen mit einer bestimmten Funktion (bzw. mehreren Funktionen). Für unsere Beispiel-Site gibt es 10 Funktionen, die der Benutzer anpassen kann:

1 - Hintergrundfarbe für die Seite

2 - Hintergrundfarbe für den Inhaltsbereich

3-6 - Inhalt für den Inhaltsbereich (für jeden der vier Inhaltsbereiche)

7-10 - Position der Inhaltsbereiche (für jeden der vier Inhaltsbereiche)

Verknüpfen Sie diese Funktionen mit den entsprechenden Optionen für diese Datenbankeinträge.

Zuerst der Seitenhintergrund. Sie verknüpfen die Farboptionen mit der Funktions-ID 1, die wir für die Hintergrundfarbe der Seite verwenden.

insert into tblFeatureOption values (1,1);
insert into tblFeatureOption values (1,2);
insert into tblFeatureOption values (1,3);
insert into tblFeatureOption values (1,4);
insert into tblFeatureOption values (1,5);
insert into tblFeatureOption values (1,6);

Jetzt kommt der Hintergrund der Inhaltsbereiche. Ähnlich dem Seitenhintergrund wird dabei die Funktions-ID 2 denselben verfügbaren Farboptionen zugeordnet.

insert into tblFeatureOption values (2,1);
insert into tblFeatureOption values (2,2);
insert into tblFeatureOption values (2,3);
insert into tblFeatureOption values (2,4);
insert into tblFeatureOption values (2,5);
insert into tblFeatureOption values (2,6);

Und jetzt wird es lustig - mit dem Inhalt der Inhaltsbereiche. Es wurden vier Inhaltsbereiche definiert (Funktions-IDs 3 bis 6). Jeder dieser Bereiche sollte die fünf definierten Inhaltsbereiche aufnehmen können (Options-IDs 11 bis 15). Verknüpfen Sie die Optionen für diese Funktionen mit diesen Einträgen:

insert into tblFeatureOption values (3,11);
insert into tblFeatureOption values (3,12);
insert into tblFeatureOption values (3,13);
insert into tblFeatureOption values (3,14);
insert into tblFeatureOption values (3,15);

insert into tblFeatureOption values (4,11);
insert into tblFeatureOption values (4,12);
insert into tblFeatureOption values (4,13);
insert into tblFeatureOption values (4,14);
insert into tblFeatureOption values (4,15);

insert into tblFeatureOption values (5,11);
insert into tblFeatureOption values (5,12);
insert into tblFeatureOption values (5,13);
insert into tblFeatureOption values (5,14);
insert into tblFeatureOption values (5,15);

insert into tblFeatureOption values (6,11);
insert into tblFeatureOption values (6,12);
insert into tblFeatureOption values (6,13);
insert into tblFeatureOption values (6,14);
insert into tblFeatureOption values (6,15);

Außerdem müssen vier Inhaltspositionen gesetzt werden. Jeder der Inhaltsbereiche kann an einer von vier Positionen angezeigt werden. Damit müssen für alle möglichen Positionen jedes Inhaltsbereichs den verfügbaren Options-IDs neue Funktions-IDs zugeordnet werden:

insert into tblFeatureOption values (7,7);
insert into tblFeatureOption values (7,8);
insert into tblFeatureOption values (7,9);
insert into tblFeatureOption values (7,10);

insert into tblFeatureOption values (8,7);
insert into tblFeatureOption values (8,8);
insert into tblFeatureOption values (8,9);
insert into tblFeatureOption values (8,10);

insert into tblFeatureOption values (9,7);
insert into tblFeatureOption values (9,8);
insert into tblFeatureOption values (9,9);
insert into tblFeatureOption values (9,10);

insert into tblFeatureOption values (10,7);
insert into tblFeatureOption values (10,8);
insert into tblFeatureOption values (10,9);
insert into tblFeatureOption values (10,10);

Bevor Sie sich den Kopf darüber zerbrechen, was da gerade passiert ist, stellen Sie sich das Ganze anhand eines Inhaltsbereichs vor.

Für einen einzelnen Bereich gibt es sowohl eine Positionsfunktion als auch eine Inhaltsfunktion. Diese Funktion wird mit mehreren Optionen verknüpft. Wenn wir dem System einen weiteren Inhaltsbereich hinzufügen, muss er auch eine eigene Funktions-ID haben, die seinen Inhalt und seine Position beschreibt, weil er völlig unabhängig vom ersten ist. Bei vier Inhaltsbereichen hat also jeder davon eine Positions-Funktions-ID und eine Inhalts-Funktions-ID, die mit den entsprechenden Optionen in der Datenbank verknüpft werden müssen.

Standardeinstellungen

Der letzte Schritt bei der Vorbereitung der Datenbank ist die Einrichtung einer generischen Benutzer-ID, die als Standard-Benutzer-ID für alle verfügbaren Einstellungsabfragen verwendet wird. Auf diese Weise können die Benutzer die Site unter Verwendung der Standardeinstellungen betrachten, bevor sie eigene Einstellungen gesetzt haben.

Als Erstes richten Sie ein generisches Benutzerkonto ein. Dieses Konto wird nie geändert und es erfolgt nie eine Anmeldung dafür - es dient nur als Platzhalter für die Benutzer-ID 0:

insert into tblUserInfo values (0,'guest','wirstdunieerraten');

Anschließend fügen Sie einige Standardwerte ein, die die Benutzer-ID 0 mit einer Option verknüpfen - für jede der 10 verfügbaren Funktionen:

insert into tblPreference values (1,0,5);
insert into tblPreference values (2,0,5);
insert into tblPreference values (3,0,11);
insert into tblPreference values (4,0,12);
insert into tblPreference values (5,0,13);
insert into tblPreference values (6,0,14);
insert into tblPreference values (7,0,7);
insert into tblPreference values (8,0,8);
insert into tblPreference values (9,0,9);
insert into tblPreference values (10,0,10);

Um eine Einstellung aus der Einstellungstabelle auszuwählen, verknüpfen wir die Einstellungstabelle mit der Optionstabelle. Das folgende SQL dient als Grundlage für alle Abfragen der Einstellungsdatenbank:

SELECT tblOption.optionValue FROM tblPreference,tblOption 
WHERE tblPreference.featureID='<The Feature ID>'
AND tblPreference.optionID=tblOption.optionID
AND tblPreference.userID='<The User ID>'

Jetzt können wir die eigentliche Site aufbauen. Für die fertige Site müssen drei Komponenten bereitgestellt werden - das Anmeldungssystem, die Einstellungen und die Inhaltsseite. Sie werden überrascht sein, dass die Anmeldungsseiten der eigentliche Schlüssel für die Site sind und dass ihre Erstellung auch am längsten dauert. Der zweitschwierigste Teil ist die Festlegung der Einstellungen. Es ist vielleicht nicht ganz einfach, aber letztlich mit einigen Serververhalten erledigt. Richten Sie Ihre Datenbankverbindung in einem neuen UltraDev-Projekt ein, bevor Sie weiterarbeiten.

17.3 Die Registrierung und das Anmeldungssystem

Für das Anmeldungssystem dieser Site brauchen wir vier verschiedene Seiten - zwei für den Anmeldungsprozess und zwei für die Benutzerregistrierung. Nach dem Registrierungsprozess kann der Benutzer die Site unter Verwendung der Standardeinstellungen anzeigen oder seine eigenen festlegen. Für die vier Seiten zur Einrichtung des Benutzerkontos brauchen wir die folgenden Funktionen:

Jetzt müssen auf einigen dieser Seiten noch kleine Anpassungen vorgenommen werden, aber größtenteils sind der Entwurf und die Implementierung ganz einfach.

Die Registrierungsseiten

Als Erstes stellen wir die Registrierungsseite fertig. Sie nimmt einen möglichen Benutzernamen entgegen, mit dem die Tabelle UserInfo der Seite register2 abgefragt wird. Auf dieser Seite gibt es kein Serververhalten.

Wir fangen mit der ersten Seite der Site an. Sie soll ein Feld und eine Senden- Schaltfläche enthalten, um die Daten an die nächste Seite senden zu können. Fügen Sie Ihrer Seite ein Formularobjekt hinzu und anschließend die benötigten Formularelemente. Geben Sie dem Texteingabefeld den Namen username, und setzen Sie die Formularaktion auf register2.asp (verwenden Sie dafür die für Ihre Serverplattform geeignete Dateinamenerweiterung) - damit werden die Daten aus dem Formular an die zweite Seite weitergegeben, die die Verarbeitung übernimmt. Ihr Formular sollte etwa wie in Abbildung 17.4 gezeigt aussehen.

Abbildung 17.4:  Das erste Formular nimmt nur einen Benutzernamen entgegen, der überprüft wird.

Jetzt zum zweiten Teil des Registrierungsprozesses - wir legen register2.asp an. Ähnlich der ersten Seite besteht dieses Dokument aus einem Formular mit einem einzigen (sichtbaren) Feld und einer Senden-Schaltfläche. Anders als das erste Formular muss es jedoch wirklich Arbeit leisten.

Zunächst legen wir ein Formular auf der Seite an, das ein Feld namens password und eine Senden-Schaltfläche enthält. Sie brauchen keine Formularaktion festzulegen, aber geben Sie dem Formular der Klarheit halber den Namen registerName. Außerdem sollten Sie ein verborgenes Feld mit einem dynamischen Wert einfügen, das den Benutzernamen enthält. Weil der Benutzername von der ersten Seite übergeben wurde, müssen wir dem UltraDev-Projekt eine neue Anforderungsvariable-Datenbindung hinzufügen - damit können wir direkt mit dem Benutzernamenfeld zusammenarbeiten, das von der ersten Seite übertragen wurde:

  1. Öffnen Sie die Palette Datenbindungen.
  2. Klicken Sie auf das Plussymbol (+), und wählen Sie in der Liste den Eintrag Anforderungsvariable.
  3. Konfigurieren Sie die Anforderungsvariable mit dem Typ Anforderung und dem Namen username.

Abbildung 17.5 zeigt den Konfigurationsdialog Anforderungsvariable.

Jetzt fügen Sie dem System ein verborgenes Feld hinzu. Stellen Sie sicher, dass Ihre Einfügemarke innerhalb Ihres Formulars platziert ist, und fügen Sie dann das verborgene Feld ein. Öffnen Sie den Eigenschafteninspektor für das Feld und setzen Sie seinen Namen auf username.

Um den Benutzernamenwert zu diesem verborgenen Feld zu binden, markieren Sie es und öffnen Sie den Eigenschaftendialog.

  1. Wechseln Sie innerhalb der Eigenschaftenpalette in die Attributansicht.
  2. Fügen Sie ein neues Wertattribut hinzu, indem Sie auf das Plussymbol (+) klicken.
  3. Klicken Sie auf das Blitzsymbol rechts vom Feld Wert.
  4. Wählen Sie im Dialogfeld für die Datenbindung die Anforderungsvariable username aus.

    Abbildung 17.5:  Setzen Sie den Namen der Anforderungsvariablen auf username.

Wir stellen das Formular fertig, indem wir dem System das Serververhalten Datensatz einfügen hinzufügen. Die folgenden Schritte fügen die vollständige Registrierung in die Tabelle userInfo ein:

  1. Öffnen Sie die Palette Serververhalten.
  2. Klicken Sie auf das Plussymbol (+), und wählen Sie das Verhalten Datensatz einfügen.
  3. Wählen Sie die Verbindung für das aktuelle Projekt und die Tabelle tblUserInfo, in die die Aktualisierungen eingetragen werden sollen.
  4. Stellen Sie sicher, dass alle Felder aus dem HTML-Formular mit den Feldern der Datenbank übereinstimmen.
  5. Konfigurieren Sie das Verhalten so, dass nach der Registrierung die Seite login.asp ausgeführt wird.

Das Verhalten sollte jetzt ähnlich dem in Abbildung 17.6 gezeigten Konfigurationsbildschirm aussehen.

Abbildung 17.6:  Fügen Sie den Benutzernamen und das Kennwort in die Tabelle UserInfo ein.

Um den Registrierungsprozess abzuschließen, müssen wir die Bedingung berücksichtigen, dass ein Benutzer auf der ersten Seite möglicherweise einen Namen eingegeben hat, der in der Benutzerdatenbank bereits existiert. Um diesen Status zu erkennen, führen wir eine einfache Abfrage für die Datenbank aus, die alle Datensätze auswählt, deren Benutzernamenfeld in tblUserInfo gleich der Anforderungsvariablen username ist.

Öffnen Sie die Palette Serververhalten und fügen Sie eine neue Datensatzgruppe ein. Falls Sie dabei in den erweiterten Modus gelangen, klicken Sie auf die Schaltfläche Einfach, um in den einfachen Abfragemodus zu wechseln. Hier entwerfen Sie eine einfache Datensatzgruppe namens rsUsername, die alle Datensatzgruppen-Variablen in tblUserInfo auswählt, die abhängig von dem Datenbankfeld für den Benutzernamen gefiltert werden, das gleich der Formularvariablen username ist. Abbildung 17.7 zeigt die fertige Datensatzgruppe.

Abbildung 17.7:  Definieren Sie eine einfache Abfrage, um die Datensätze entsprechend dem Benutzernamen aus dem ersten Formular auszuwählen.

Basierend auf dieser Datensatzgruppe können wir das Registrierungsformular verbergen, falls der Benutzername bereits existiert - oder, um in der UltraDev-Terminologie zu bleiben: den Bereich anzeigen, falls die Datensatzgruppe nicht existiert. Mit der Überprüfung, ob in der Datensatzgruppe Daten enthalten sind, stellen wir fest, ob es in der Datenbank bereits wirklich einen identischen Benutzernamen gibt:

  1. Markieren Sie in der Dokumententwurfsansicht das gesamte Formular.
  2. Öffnen Sie die Palette Serververhalten.
  3. Klicken Sie auf das Plussymbol (+), und wählen Sie im Untermenü Bereich anzeigen den Eintrag zeigen, wenn Datensatzgruppe leer ist.
  4. Wählen Sie die Datensatzgruppe rsUsername aus.

Jetzt brauchen wir nur noch einen weiteren Bereich im Dokument, der angezeigt wird, falls der Benutzername existiert. Dabei kann es sich um eine einfache Meldung handeln, die darauf hinweist, dass ein ungültiger Benutzername eingegeben wurde, in Kombination mit einem Link zurück auf die erste Registrierungsseite. Gehen Sie vor wie oben gezeigt, um das Registrierungsformular für diesen neuen Bereich anzuzeigen, wobei der Bereich nur angezeigt wird, Wenn die Datensatzgruppe nicht leer ist. Die Bedingung »nicht leer« zeigt an, dass der Benutzername zuvor bereits verwendet wurde.

Damit sind die Registrierungsseiten fertig. Jetzt wollen wir uns mit dem Anmeldeprozess beschäftigen. Abbildung 17.8 zeigt den endgültigen Entwurf für den zweiten Registrierungsbildschirm.

Abbildung 17.8:  Der endgültige Registrierungsbildschirm sollte etwa so aussehen.

Die Anmeldeseiten

Der erste Anmeldebildschirm (login.asp) ist wie der erste Registrierungsbildschirm nur ein Formular mit einem Feld für den Benutzernamen und das Kennwort, das Daten an den zweiten Anmeldebildschirm (login2.asp) weitergibt, wo die eigentliche Verarbeitung stattfindet. Legen Sie dieses Formular jetzt an. Verwenden Sie gegebenenfalls die Datei register.asp als Vorlage für dieses Dokument, und nehmen Sie die folgenden Änderungen vor:

  1. Fügen Sie ein Kennwortfeld hinzu.
  2. Die Aktion für das Formular sollte die Daten an login2.asp senden (oder an eine äquivalente Datei auf Ihrem Server).

Abbildung 17.9 zeigt ein Beispiel für einen fertigen Anmeldebildschirm.

Abbildung 17.9:  Das erste Anmeldeformular sollte ähnlich wie der erste Registrierungsbildschirm entworfen werden, wobei hier aber ein Kennwortfeld bereitgestellt wird.

Der zweite Anmeldebildschirm verwendet das Verhalten Bereich anzeigen sowie eine Datensatzgruppe, um Meldungen für eine gültige und eine ungültige Anmeldung anzuzeigen - ähnlich dem zweiten Registrierungsbildschirm.

Legen Sie diesen Bildschirm jetzt an. Fügen Sie dem Dokument zwei Bereiche mit zwei unterschiedlichen Meldungen hinzu:

Danke für die Anmeldung am System. Klicken Sie hier, um auf die nächste Seite zu gelangen.

Der Benutzername oder das Kennwort sind fehlerhaft. Klicken Sie hier, um die Eingabe zu wiederholen.

Die erste Meldung sollte zum Bildschirm content.asp führen, den wir im nächsten Abschnitt dieses Kapitels erstellen, während die zweite Meldung zum ersten Anmeldebildschirm zurückführt.

Um diese Dokumente zu verbergen bzw. anzuzeigen, definieren wir eine Datensatzgruppe, um die Benutzerinformation auszuwählen, die registriert wurde, indem wir einen Filter abhängig von der Eingabe des Benutzernamens und des Kennworts auf dem Anmeldeformular setzen. Falls sich die Datensatzgruppe als leer erweist, wurden Benutzer oder Kennwort fehlerhaft eingegeben. Fügen Sie diese Datensatzgruppe jetzt ein:

  1. Öffnen Sie die Palette Serververhalten.
  2. Klicken Sie auf das Plussymbol (+), und wählen Sie Datensatzgruppe (Abfrage).
  3. Wechseln Sie in die erweiterte Ansicht, falls sie sich noch nicht dort befinden.
  4. Wählen Sie eine geeignete Verbindung für dieses Projekt.
  5. Fügen Sie das SQL ein: SELECT * FROM tblUserInfo WHERE username='varUsername' AND password='varPassword'.
  6. Klicken Sie auf das Plussymbol (+), und fügen Sie eine neue UltraDev-Variable in die Abfrage ein, varUsername.
  7. Setzen Sie den Standardwert für die Variable auf einen nicht existierenden Benutzernamen und den Laufzeitwert auf "Request("username")".
  8. Wiederholen Sie die Schritte 6 und 7 für die Variable varPassword - und achten Sie dabei darauf, wirklich varPassword anstelle von varUsername anzugeben.
  9. Klicken Sie auf OK. Die endgültige Definition für die Datensatzgruppe sehen Sie in Abbildung 17.10.

Nachdem Sie die Datensatzgruppe definiert haben, ist die Vervollständigung der Seite ähnlich dem Prozess für die Registrierungsseite. Definieren Sie im Dokument zwei Bereiche, die abhängig davon angezeigt werden, ob die Anmeldung korrekt war oder nicht.

Bei einer fehlerhaften Anmeldung soll dem Benutzer eine Möglichkeit bereitgestellt werden, zum Anmeldebildschirm zurückzugelangen, damit er seine Eingaben korrigieren kann. Wählen Sie aus, wo auf dem Bildschirm diese Meldung und ein entsprechender Link erscheinen sollen, und fügen Sie dem Dokument das Serververhalten Bereich anzeigen hinzu. Dieses Serververhalten sollte ausgewählt werden, damit der Inhalt angezeigt wird, wenn die neue rsUserInfo-Datensatzgruppe nicht leer ist.

Abbildung 17.10:  Definieren Sie eine erweiterte Abfrage, um Datensätze abhängig von dem angegebenen Benutzernamen und dem Kennwort auszuwählen.

Der Text und der Link für die gültige Anmeldung werden ganz ähnlich eingerichtet. Wählen Sie diese Information aus und wenden Sie ein weiteres Serververhalten Bereich anzeigen an, mit der Bedingung, dass der Bereich angezeigt wird, falls die Datensatzgruppe nicht leer ist. Den endgültigen Entwurf des login2-Bildschirms sehen Sie in Abbildung 17.11.

Abbildung 17.11:  Der endgültige Entwurf für den zweiten Anmeldebildschirm soll Meldungen für gültige und fehlerhafte Anmeldungen enthalten.

Nachdem Sie diese Serververhalten eingefügt haben, ist das Dokument so gut wie fertig. Wir müssen jedoch noch eine winzige Ergänzung vornehmen. Weil wir ein Cookie setzen müssen, wäre es sinnvoll, die Cookie-Information direkt in das Dokument zu schreiben, und zwar an derselben Position, an der der Bereich Gültige Anmeldung angezeigt wird.

Leider ist das nicht möglich. Ein Cookie muss gesetzt werden, bevor irgendetwas anderes an den Browser geschickt wird, weil sonst ein Fehler auftritt. Eine mögliche Lösung wäre, der Inhaltsseite die Benutzer-ID des in der Datensatzgruppe ausgewählten Datensatzes zu übergeben. Das ist jedoch keine besonders gute Idee - sie ermöglicht einem Benutzer, die ID eines anderen zu übernehmen, indem er einfach die Benutzer-ID in der URL-Zeile ändert.

Selbst wenn diese Site keine erhöhte Sicherheit benötigt, wollen wir das vermeiden. Wir wählen einen anderen Ansatz - wir setzen eine Sitzungs-ID für diese Seite und dann das Cookie auf die Sitzungs-ID, wenn der Benutzer auf die Inhaltsseite geht. Das ist eine einfache Lösung für unser Problem.

Suchen Sie den Code für die gültige Anmeldung - er sollte in etwa wie folgt aussehen:

1      <% If Not rsUserInfo.EOF Or Not rsUserInfo.BOF Then %>
2 <table width="100%" border="0" cellspacing="0" cellpadding="2">
3 <tr>
4 <td><font face="Arial, Helvetica, sans-serif">Glückwunsch,
5 Sie haben sich erfolgreich angemeldet! <br>
6 Um ins System zu gelangen, klicken Sie bitte <a href="content.asp">hier.
7 </a></font></td>
8 </tr>
9 </table>
10 <% End If ' end Not rsUserInfo.EOF Or NOT rsUserInfo.BOF %><br>

Fügen Sie in diesen Bereich (zwischen den Zeilen 1 und 2) die Sitzungsvariable tempUserID ein, und setzen Sie sie auf das Benutzer-ID-Feld aus der Datensatzgruppe rsUserInfo. Dazu verwenden Sie beispielsweise den folgenden Code:

<% Session("tempUserID")=(rsUserInfo.Fields.Item("userID").Value) %>

Der Code für eine gültige Anmeldung sieht dann schließlich wie folgt aus:

1    <% If Not rsUserInfo.EOF Or Not rsUserInfo.BOF Then %>
2 <% Session("tempUserID")=(rsUserInfo.Fields.Item("userID").Value) %>
3 <table width="100%" border="0" cellspacing="0" cellpadding="2">
4 <tr>
5 <td><font face="Arial, Helvetica, sans-serif">Glückwunsch,
6 Sie haben sich erfolgreich angemeldet! <br>
7 Um ins System zu gelangen, klicken Sie bitte <a href= "content.asp">hier.
8 </a></font></td>
9 </tr>
10 </table>
11 <% End If ' end Not rsUserInfo.EOF Or NOT rsUserInfo.BOF %><br>

Der Code für die Sitzungsvariable wird in Zeile 2 des obigen Codebeispiels gesetzt.

Damit ist die Anmeldeseite fertig. Wir können nun die eigentliche Inhaltsseite anlegen. Weil wir bereits einen temporären Benutzer mit Einstellungen angelegt haben, können wir diesen Bildschirm diesen temporären Einstellungen gemäß entwerfen - und das Projekt dann mit den Werten für die Einstellungen fertig stellen.

17.4 Der Inhaltsbildschirm

Jetzt wollen wir den Inhaltsbildschirm einrichten - hier wird festgelegt, was der Benutzer sieht, nachdem er sich am System angemeldet hat, oder ob ein Cookie auf seiner Maschine gesetzt wird. Im Wesentlichen handelt es sich dabei um nichts weiter als mehrere Abfragen, die in den HTML-Code eingebettet werden. Eigentlich ist es ganz einfach, diesen Bildschirm zu erstellen. Wir brauchen dazu jedoch einigen benutzerdefinierten Code, bevor wir mit der Entwicklung der Abfragen beginnen können.

Im vorigen Abschnitt haben wir dem Benutzer ermöglicht, sich anzumelden und ein neues Konto einzurichten. Anschließend haben wir abhängig von der Sitzungs-ID eine Sitzungsvariable eingerichtet. Bevor wir irgendetwas auf dieser Seite unternehmen können, müssen wir ein Cookie setzen, das die Benutzer-ID für zukünftige Besuche registriert. Außerdem müssen wir den Benutzer umleiten, wenn noch kein Cookie für ihn gesetzt wurde.

Wie stellt man sich das vor? Der Pseudocode könnte wie folgt aussehen:

if (session("tempUserID") existiert) then
set cookie("UserID")=session("tempUserID")
set strUserID=session("tempUserID")
end if
if (cookie("UserID") existiert nicht) then
auf die Seite login.asp umleiten
else
set strUserID=Cookie("UserID")
end if

Dies können wir jetzt in ASP-Code übersetzen, den wir der Seite hinzufügen:

1 <% If (not (Session("tempUserID")="")) Then
2 Response.Cookies("UserID")=Session("tempUserID")
3 Response.Cookies("UserID").Expires=#12/31/2030#
4 strUserID=Session("tempUserID")
5 End If
6 If (Request.Cookies("UserID")="") Then
7 Response.Redirect("login.asp")
8 Else
9 strUserID=Request.Cookies("UserID")
10 End If
11 %>

Leider hat UltraDev in der Entwicklungsumgebung keine Vorkehrungen für Cookies getroffen. Sie müssen diesen Code manuell bereitstellen, wenn Sie einen Cookie oder eine Sitzungsvariable setzen wollen.

Dieser Code übernimmt die meiste Arbeit auf dieser Site. Im Wesentlichen garantiert er uns, dass die Variable strUserID gesetzt ist, wenn wir auf die Webseite gelangen (Zeile 2), oder dass der Benutzer auf den Anmeldebildschirm umgeleitet wird (Zeilen 6 bis 7). Das Ablaufdatum des Cookies wird auf 12/31/2030 gesetzt (Zeile 30), was für die meisten Applikationen ausreichend sein sollte.

Nachdem Sie diesen Code in die grundlegende Seite eingetragen haben, erstellen Sie vier Ebenen, die den Inhalt für die Webseite aufnehmen. Wenden Sie nicht zu viel Zeit für den Entwurf der Seite auf, weil letztlich ohnehin alles von der Datenbank gesteuert wird. Abbildung 17.12 zeigt, wie eine für diese Zwecke geeignete Seite aussehen könnte.

Abbildung 17.12:  So könnte eine einfache Beispielseite mit vier Bereichen aussehen - machen Sie sich jedoch nicht zu viele Gedanken über die Ausrichtung der Dinge.

Und jetzt kommt das Vergnügen - die Entwicklung der Abfragen für alle Einstellungen, die der Benutzer vornehmen kann. Das ist nicht schwierig, aber müßig. Um das Ganze zu vereinfachen, nummerieren wir die Datensätze, die angelegt werden müssen, weil sie je einer Funktions-ID entsprechen:

Wir richten jetzt eine dieser Datensatzgruppen ein. Die anderen Datensatzgruppen können Sie nach diesem Muster selbst anlegen. Dies ist eine komplexe Abfrage, die die von uns angelegte Variable strUserID direkt im Code verwendet. Die Datensatzgruppen für die einzelnen Funktionen unterscheiden sich nur in Hinblick auf Funktions-ID und Datensatzgruppennamen.

Öffnen Sie die Palette Serververhalten und fügen Sie dem Dokument eine neue Datensatzgruppe hinzu. Gehen Sie durch Anklicken der Schaltfläche Erweitert in den erweiterten Modus. Geben Sie der Datensatzgruppe einen der unterstützten Funktion entsprechenden Namen. Geben Sie dieses SQL in die Datensatzgruppe ein:

SELECT tblOption.optionValue FROM tblPreference,tblOption 
WHERE tblPreference.featureID='1'
AND tblPreference.optionID=tblOption.optionID
AND (tblPreference.userID='varUserID'
OR tblPreference.userID=0)
ORDER BY tblPreference.userID DESC

Beachten Sie, dass dies nicht genau die Abfrage ist, die wir am Kapitelanfang definiert haben. Die folgenden Ergänzungen wurden vorgenommen:

tblPreference.userID='varUserID' OR tblPreference.userID=0

Damit werden die Einstellungen für die aktuelle Benutzer-ID sowie die Einstellungen für die Benutzer-ID 0 (die wir bereits in die Einstellungstabelle eingetragen haben), ausgewählt. Weil wir nicht wissen, ob ein Benutzer überhaupt Einstellungen vornehmen wird, müssen wir irgendetwas verwenden, um die Seite überhaupt anzeigen zu können. Durch Auswahl beider Datensätze haben wir für jede Funktion garantiert immer einen Wert. Möglicherweise werden mehrere Werte zurückgegeben, aber wir verwenden keinen wiederholten Bereich, deshalb wird jeweils nur der erste Datensatz aus der Datensatzgruppe angezeigt. Aber woher wissen wir, welcher Datensatz der erste ist? Dazu verwenden wir den folgenden Code:

ORDER BY tblPreference.userID DESC

Damit werden die Datensätze nach der Benutzer-ID in absteigender Reihenfolge sortiert. Weil ein Benutzer garantiert eine Benutzer-ID größer 0 hat, geht der zugehörige Datensatz den Einstellungen aus dem Datensatz für den Benutzer 0 immer voraus - wenn es den Benutzer also gibt, ist er der erste in der Datensatzgruppe.

Die restliche Abfrage ist relativ einfach. Die Funktions-ID wird ausgewählt:

featureID='1'

Die Benutzer-ID wird mit der varUserID verglichen, um den Einstellungswert für den Benutzer auszuwählen, der die Site besucht:

tblPreference.userID='varUserID'

Die Variable varUserID muss übrigens noch definiert werden. Klicken Sie auf die Schaltfläche mit dem Plussymbol (+) in der erweiterten Abfrageansicht, um eine neue UltraDev-Variable einzufügen. Setzen Sie ihren Namen auf varUserID, den Standardwert auf 0 und den Laufzeitwert auf strUserID. Zur Erinnerung: Der Wert strUserID wurde am Seitenanfang gesetzt, als wir das Cookie userID ausgewertet und gesetzt haben.

Abbildung 17.13 zeigt die endgültige Definition der Datensatzgruppe.

Abbildung 17.13:  Die Definition der Datensatzgruppe rsPageColor sollte aussehen wie hier gezeigt.

Nachdem Sie die erste Datensatzgruppe angelegt haben, gehen Sie für die anderen neun Datensatzgruppen ähnlich vor. Nachdem Sie fertig sind, sollte Ihre Datenbindungspalette ähnlich aussehen wie in Abbildung 17.14 gezeigt.

Datensatzgruppen werden mithilfe von Bearbeiten > Kopieren kopiert. Auf diese Weise können Sie das Erstellen mehrerer ähnlicher Datensatzgruppen wesentlich beschleunigen.

Nachdem Sie alle 10 Datensatzgruppen angelegt haben, ordnen Sie den Objekten Attribute zu. Das erste Attribut ist die Hintergrundfarbe der Webseite. Markieren Sie in Ihrer HTML-Ansicht das Body-Tag und öffnen Sie die Eigenschaftenpalette.

Gehen Sie in der Eigenschaftenpalette in die Attributansicht, indem Sie auf die Registerkarte unten links klicken. Fügen Sie das Attribut bgcolor ein, falls dieses noch nicht existiert - und dann gehen Sie in das linke Wertefeld und klicken auf das Blitzsymbol, um es zu einem dynamischen Attribut zu binden. UltraDev fordert Sie auf, eine Datensatzgruppe anzugeben - verwenden Sie rsPageColor und dann optionValue, wie in Abbildung 17.15 gezeigt.

Abbildung 17.14:  Ihr fertiges Dokument enthält  insgesamt 10 Datensatzgruppen.

Abbildung 17.15:  Wählen Sie optionValue aus derselben Datensatzgruppe.

Das hätten wir also geschafft. Jetzt müssen die anderen Attribute festgelegt werden. Das ist ein bisschen einfacher, weil wir sie dem Dokument manuell hinzufügen können, statt Bindungen zu Attributen herzustellen. Wenn Sie das HTML betrachten, sehen Sie, dass die Hintergrundfarbe für den Seitenrumpf durch die folgende Zeile eingefügt wird:

<%=(rsPageColor.Fields.Item("optionValue").Value)%>

Bereich 1 ist wie folgt beschrieben:

Der Inhalt:

<%=(rsRegion1Content.Fields.Item("optionValue").Value)%>

Die Position:

<%=(rsRegion1Location.Fields.Item("optionValue").Value)%>

Alle anderen Bereichsattribute können nach demselben Muster definiert werden (natürlich mit einer anderen Nummer).

Anhand dieser Information können wir eine Vorlage für alle Ebenen anlegen - fügen Sie diese Codeabschnitte einfach wie folgt in die Ebenendefinition ein:

<div id="Layer1" style="position:absolute;width:270px;height:268px; z-index:1;
<%=(rsRegion1Location.Fields.Item("optionValue").Value)%>; background-color:
<%=(rsContentColor.Fields.Item("optionValue").Value)%>; layer-background-color:
<%=(rsContentColor.Fields.Item("optionValue").Value)%>; border: 1px none
#000000"><%=(rsRegion1Content.Fields.Item("optionValue").Value)%></div>

Weil alle wichtigen Attribute der Ebene in der Datenbank definiert werden, können Sie diese Definition einfach dreimal kopieren und einfügen - und dabei jeweils die Bereichsnummer ändern. Der zweite Bereich sieht beispielsweise wie folgt aus:

<div id="Layer2" style="position:absolute;width:270px;height:268px; z-index:1;
<%=(rsRegion2Location.Fields.Item("optionValue").Value)%>; background-color:
<%=(rsContentColor.Fields.Item("optionValue").Value)%>; layer-background-color:
<%=(rsContentColor.Fields.Item("optionValue").Value)%>; border: 1px none
#000000"><%=(rsRegion2Content.Fields.Item("optionValue").Value)%></div>

Damit können Sie ohne weitere Probleme erkennen, wie die beiden nächsten Bereiche aussehen sollten. Jeder dieser Bereiche kann an beliebiger Stelle des Inhaltsbereichs im HTML-Dokument angelegt werden. Sie können sie manuell eingeben - die Alternative ist, die Nutzung des sehr beschränkten Platzes der Attributansicht für eine Ebene zu nutzen, um alle dynamischen Attribute zu setzen.

Wissen Sie was? Die Inhaltsseite ist fertig! Jetzt fehlt aber noch etwas - ein Link auf die Konfigurationsseite. Fügen Sie unten auf der Seite den Link Einstellungen ein, der auf die Seite preferences.asp führt.

Damit sollten Sie in der Lage sein, den Registrierungsprozess zu durchlaufen und die Inhaltsseite anzuzeigen (mit den Standardeinstellungen für die Benutzer-ID 0). Abbildung 17.16 zeigt die letzte Ansicht. Sie könnten sie noch etwas verschönern, aber grundsätzlich funktioniert sie!

Bevor Sie weitermachen, öffnen Sie den Quellcode des Dokuments und stellen sicher, dass sich die benutzerdefinierte Programmierung zum Setzen des Cookies immer noch am Dokumentanfang befindet. Andernfalls schneiden Sie sie aus und fügen sie an der richtigen Stelle wieder ein, sodass sie sich oberhalb des gesamten von UltraDev erstellten Codes befindet.

Damit sind wir beim letzten Teil der Seite - den Einstellungen.

Abbildung 17.16:  Die Inhaltsseite ist nicht besonders attraktiv, aber sie funktioniert.

17.5 Die Einstellungen

Der erste Bildschirm für die Einstellungen setzt noch keine Attribute, sondern stellt die Links auf die Seite bereit, auf der die Einstellungen vorgenommen werden. Diese Links müssen eine ID an eine zweite Seite weitergeben, preferences2.asp, die angibt, was der Benutzer setzen will. Beispielsweise wird für die Seitenhintergrundfarbe der folgende Link bereitgestellt:

preferences2.asp?featureID=1

Damit wird der URL-Parameter featureID mit dem Wert 1 an die Seite preferences2.asp übergeben. Richten Sie jetzt Ihre Linkliste ein. Abbildung 17.17 zeigt eine Beispielseite mit den verfügbaren Einstellungen.

Abbildung 17.17:  Die Funktionen werden zusammen mit einem Link auf die zweite Einstellungenseite aufgelistet.

Stellen Sie sicher, dass alle Ihre Links korrekt angelegt sind, bevor Sie weitermachen. Die zweite Einstellungenseite ist die letzte Seite für dieses Dokument, und Sie sollten sicherstellen, dass alles funktioniert, bevor wir sie entwerfen.

In dieser Applikation müssen wir die Funktions-ID manuell der zweiten Einstellungenseite übergeben. Wenn es in der Datenbank eine Tabelle gäbe, in der Funktionsname und ID aufgelistet sind, könnten wir die Tabelle mit den Links manuell erstellen. Darüber können Sie jedoch später nachdenken.

Darüber hinaus ist die Methode, mit der wir die Links setzen, sehr schnell. Wenn Sie jedoch lieber in der UltraDev-Umgebung bleiben wollen, verwenden Sie Modifizieren > Link erstellen und klicken dann auf die Schaltfläche Parameter, um den Parameter featureID zu setzen.

Jetzt kommen wir zum letzten Bildschirm. Legen Sie das neue Dokument preferences2.asp an. Diese Seite enthält ein sehr einfaches Formular mit einem datenbankgestützten Popup-Menü, zwei verborgenen Feldern mit der Benutzer-ID und der Funktions-ID und einer Senden-Schaltfläche.

Um das Popup-Menü zu erstellen, brauchen wir eine Abfrage, die alle für die der Seite übergebenen Funktions-ID verfügbaren Optionen zu ermitteln:

  1. Öffnen Sie die Palette Serververhalten.
  2. Klicken Sie auf das Plussymbol (+), und fügen Sie das neue Verhalten Datensatzgruppe (Abfrage) ein.
  3. Wechseln Sie in den erweiterten Abfragemodus.
  4. Geben Sie der Datensatzgruppe den Namen rsFeatureOptions, und setzen Sie die Projektverbindung.
  5. Verwenden Sie das folgende SQL: SELECT tblOption.optionID,tblOption.optionName FROM tblFeatureOption,tblOption WHERE tblFeatureOption.optionID =tblOption.optionID AND tblFeatureOption.featureID='varFeatureID'
  6. Fügen Sie die neue UltraDev-Variable varFeatureID ein, die auf den Laufzeitwert "Request("featureID")" gesetzt wird.
  7. Klicken Sie auf OK.

Jetzt fügen Sie der Seite das Formularobjekt hinzu. In diesem Formular fügen Sie ein neues Listen/Menü-Objekt ein - daraus machen wir die dynamisch erstellte Popup-Liste der verfügbaren Optionen. Geben Sie diesem Popup-Menü den Namen optionID.

Um das Popup-Menü zu einer dynamischen Abfrage zu binden, könnten wir das Serververhalten Dynamische Elemente in das Dokument einfügen oder eine alternative Methode zum Anlegen einer Datenbindung verwenden. Dies ist zwar nicht so benutzerfreundlich wie die Methode, die wir in den meisten anderen Projekten verwendet haben, aber Sie werden sich immer mehr an diese Technik gewöhnen. Sie spart Zeit und Sie brauchen dazu den Komfort der UltraDev-Oberfläche nicht zu verlassen.

Markieren Sie in der Entwurfsansicht das Popup-Menü und gehen Sie in die Datenbindungenpalette. Wählen Sie das Feld OptionName aus der Datensatzgruppe und betrachten Sie das Popup-Menü, das jetzt unten in der Palette Datenbindungen erscheint - wählen Sie elementbez. und klicken Sie auf die Schaltfläche Binden. Damit binden Sie das Feld optionName zu den Namen der Einträge im Popup-Menü. Dasselbe können Sie für die Options-ID wiederholen. Wählen Sie für die Bindung jedoch elementwert. Abbildung 17.18 zeigt die Palette Datenbindungen, nachdem diese Einstellungen vorgenommen wurden.

Abbildung 17.18:  Einträge können direkt von der Datenbindungenpalette aus zu Attributen gebunden werden.

Um die beiden verborgenen Felder zu setzen, verwenden wir dieselbe Technik, nach der wir den Datenbindungen das userID-Cookie und die featureID-Anforderungsvariable hinzugefügt haben:

  1. Öffnen Sie die Palette Datenbindungen.
  2. Klicken Sie auf das Pluszeichen (+), und wählen Sie Anforderungsvariable.
  3. Geben Sie userID ein und klicken Sie auf OK.

Wiederholen Sie diesen Prozess für die Anforderungsvariable featureID. Jetzt sollten beide Variablen in der Datenbindungen-Ansicht erscheinen.

Jetzt fügen Sie dem Dokument die beiden verborgenen Felder hinzu. Geben Sie dem einen den Namen featureID, dem anderen userID. Binden Sie den Wert dieser Felder zu der Anforderungsvariablen featureID und zum Cookie userID und gehen Sie dabei nach derselben Technik vor, nach der wir das Popup-Menü zu der Datensatzgruppe gebunden haben. Markieren Sie in der Entwurfsansicht das Tag für das entsprechende verborgene Feld und klicken Sie auf den zugehörigen Eintrag im Fenster Datenbindungen. Wählen Sie input.value als Bindung und klicken Sie auf Binden.

Schließlich fügen Sie dem Formular noch eine Senden-Schaltfläche hinzu, mit deren Hilfe die Einstellungen gespeichert werden.

Jetzt müssen Sie nur noch die Daten in der Einstellungsdatenbank speichern. Fügen Sie das Verhalten Datensatz einfügen ein:

  1. Öffnen Sie die Palette Serververhalten.
  2. Klicken Sie auf das Plussymbol (+), und wählen Sie das Verhalten Datensatz einfügen.
  3. Setzen Sie die Verbindung auf die Datenquelle Ihres Projekts.
  4. Wählen Sie tblPreference für die Tabelle, in der die Aktualisierung vorgenommen werden soll (In Tabelle einfügen).
  5. Wählen Sie das auf der Seite definierte Formular, und ordnen Sie die Elemente aus dem Formular den Spalten der Datenbank zu.
  6. Nachdem Sie mit dem Einfügen fertig sind, gehen Sie auf content.asp, sodass der Benutzer seine Änderungen unmittelbar sieht.

Abbildung 17.19 zeigt die vollständige Aktion Datensatz einfügen.

Abbildung 17.19:  Fügen Sie die Einstellungen in die Einstellungsdatenbank ein.

Moment! Was passiert, wenn der Benutzer bereits eine Einstellung für die Seite vorgenommen hat? Das System erzeugt einen Fehler, wenn der Benutzer bereits eine Einstellung für eine der Funktionen vorgenommen hat und dann versucht, sie zu überschreiben. Wenn Sie möchten, können Sie eine Aktualisierungsmöglichkeit in das System einfügen. Ein einfacherer Ansatz wäre, eine existierende Einstellung zu löschen, bevor eine neue eingefügt wird.

Suchen Sie in Ihrem Dokument den Code, der für das Einfügen zuständig ist:

' Einfügen ausführen
Set MM_editCmd = Server.CreateObject("ADODB.Command")
MM_editCmd.ActiveConnection = MM_editConnection
MM_editCmd.CommandText = MM_editQuery
MM_editCmd.Execute

Unmittelbar vor diesem Code fügen Sie Folgendes ein:

  ' SQL fertigstellen und ausführen
Set deleteRec = Server.CreateObject("ADODB.Command")
deleteRec.ActiveConnection = MM_editConnection

deleteRec.CommandText = "delete from tblPreference where userID='" &
Request("userID") & "' AND featureID='" & Request("featureID") & "'"
deleteRec.Execute

Dieser ASP-Block richtet eine Verbindung zu der Datenbank ein und löscht gegebenenfalls einen bereits existierenden Parameterdatensatz.

Damit sollte das System vollfunktional sein. Probieren Sie es aus und setzen Sie ein paar Einstellungen. Verlassen Sie Ihren Browser, starten Sie ihn neu und laden Sie die Inhaltsseite. Alle Ihre Einstellungen werden ohne weitere Maßnahmen geladen.

Die Technik, mit der ich einen Datensatz lösche, bevor ich versuche, einen neuen einzufügen, wird nur verwendet, weil die hier verwendeten Daten trivial sind. Handelte es sich dagegen um ein System, in dem die Informationen extrem wichtig sind, würden Sie das Verhalten Datensatz aktualisieren verwenden oder die neue Einstellung manuell in einen temporären Datensatz einfügen und ihn nach dem Speichern an die richtige Stelle verschieben. Wenn das Programm in seiner jetzigen Version zwischen den Befehlen delete und insert abstürzt, verliert der Benutzer alle vorherigen Einstellungen. Das ist jedoch sehr unwahrscheinlich.

17.6 Zusammenfassung

Dieses Kapitel hat mehr ein Konzept als ein wirklich vollständiges Nachrichtenportal vorgestellt. Mithilfe von Cookies können Sie Ihre Sites für die Benutzer so einstellen, dass sie eine Umgebung erhalten, in der sie sich zu Hause fühlen und wo sie alle Informationen und Funktionen haben, die sie benötigen. Gleichzeitig können Sie die Einstellungen daraufhin auswerten, was die Benutzer an Ihrer Seite mögen und wie sie es gerne anzeigen.

Offensichtlich gibt es noch Verbesserungsmöglichkeiten, aber hier war vor allem das Gesamtkonzept wichtig. Die Bereichspositionen beispielsweise sind momentan auf vier Einstellungen beschränkt, wobei die Inhaltsbereiche nur übereinander gestapelt werden können. Hier könnten Sie ganz einfach ein sehr viel interessanteres Layout anlegen. Darüber hinaus sollten Sie jetzt überlegen, wie Sie in anderen Projekten vorgehen, um sich einzelne Benutzer zu merken und dynamisch darauf zu reagieren.

17.7 Workshop

Der Workshop dient dazu, den gelesenen Stoff mithilfe von gezielten Fragen und Übungen zu vertiefen. Die Antworten finden Sie in Anhang A, »Quiz-Antworten«.

Fragen und Antworten

Frage:
Warum können nicht alle Einstellungen gleichzeitig gesetzt werden?

Antwort:
Das ist meiner Meinung nach das größte Problem mit der Site. Aufgrund der Erweiterbarkeit des Systems eignet sich die Tabellenstruktur nicht, alle Attribute auf einer einzigen Seite anzuzeigen. Hätten wir ein System angelegt, das alle Benutzereinstellungen in einem einzigen Tabelleneintrag ablegt, könnten Sie eine Seite aufbauen, die alle Attribute gleichzeitig setzt.

Frage:
Wozu kann die Steuerung der Ebenenpositionen sinnvoll sein?

Antwort:
Wir haben in diesem Kapitel zwar mehr eine Technologiedemonstration präsentiert als alles andere, aber die dynamischen Positionen könnten genutzt werden, um dem Benutzer unterschiedliche Bildschirmlayouts für seine Informationen zu präsentieren.

Frage:
Was passiert, wenn ein Benutzer versucht, von einem anderen Computer als dem mit dem Cookie aus auf die Site zuzugreifen?

Antwort:
Die Site zwingt den Benutzer, sich erneut anzumelden. Damit wird ein neues Cookie mit der Benutzer-ID im Browser des Benutzers gesetzt.

Frage:
Was passiert, wenn der Benutzer die Cookies deaktiviert hat?

Antwort:
Wenn der Benutzer die Cookies deaktiviert hat, kann kein Zugriff auf die Site erfolgen. Das Cookie wird vor der Anzeige des Seiteninhalts überprüft. Falls es nicht existiert, wird der Browser zum Anmeldebildschirm umgeleitet.

Quiz

  1. Welche Sitzungsvariable wird für dieses Projekt verwendet?
  2. Wie fügen Sie eine Cookie-Datenbindung ein?
  3. Warum sind Ebenen für benutzerdefinierbare Seiten so praktisch?
  4. Wie lange merkt sich der Server die Einstellungen des Benutzers?
  5. Warum werden die Einstellungen des Benutzers nicht alle in einer einzigen großen Tabelle gespeichert?

Übungen

  1. Aktualisieren Sie den Bildschirm für die Auswahl der Einstellungen, sodass die aktuell ausgewählte Funktionsoption im Popup-Menü angezeigt wird, wenn der Benutzer es aufruft.
  2. Fügen Sie eine zusätzliche Funktionstabelle ein, die die Funktions-IDs mit einer Beschreibung dieser Funktion vergleicht. Auf diese Weise können Sie einen dynamisch erstellten Einstellungsbildschirm einfügen - statt der momentan verwendeten statischen Tabellenversion.
  3. Ändern Sie eine Ihrer existierenden Sites so ab, dass sie die heute beschriebenen Funktionsmerkmale verwendet. Beispielsweise könnten Sie das Nachrichtensystem so abändern, dass es sich merkt, welche Nachrichten Ihre eigenen sind, oder wie Ihr Name und Ihre E-Mail-Adresse lauten.
  4. Nachdem Sie Kapitel 18 gelesen haben, sollten Sie noch einmal in dieses Kapitel zurückkehren und versuchen, das Anmelde- und Registrierungssystem mithilfe des Benutzer-Authentifizierungssystems von UltraDev neu zu implementieren.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


© Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH