Thread Meldeliste auf Website erstellen
(23 answers)
Opened by seemann at 2011-07-14 18:45
Zielsetzung:
Auf einer Webseite sollen sich Personen eintragen können und sehen, ob sie sich eingetragen haben. Gebraucht wird:
Mögliche Probleme: Es werden Persönliche Daten eingetragen, die nicht für jeden einsehbar sein sollten (mit Name Anschrift und Email-Adresse kann man schon einigen Unsinn im Netz anstellen). Aus diesem Grund sollte der Zugang begrenzt werden. Ein Passwort, das der Nutzer bei der ersten Anmeldung eingibt würde schon helfen. Da das hier nirgendwo angesprochen wurde werde ich auch kein Passwort vorsehen. Je nach Umfang der Daten kann es günstig sein ein Datenbank zu benutzen um diese zu speichern. Wenn Daten nur eingetragen aber nicht gelöscht oder geändert werden, so kann man auch ein einfache Datei nutzen, um die Daten zu speichern. Ich gehe davon aus, dass es nur wenige Nutzer geben wird und das keine Änderungen vorgenommen werden sollen. Weshalb man problemlos auf eine Datei setzen kann. Was soll das Script können:
Daraus folgt das zwei grundsätzliche Funktionen gebraucht werden:
Beginnen werde ich mit der Funktion speicher_person: An sie über geben werden muss
Geprüft werden muss ob folgende Angaben existieren: Vornamen, Name, Wohnort, Mailadresse Wenn eine davon nicht existiert, soll die Eingabemaske mit einer Warnung angezeigt werden. Wenn die Kombination aus Vornamen, Name oder die Mailadresse in der Datei schon existiert, so soll die Eingabemaske mit einer Warnung angezeigt werden. Wenn die Prüfung erfolgreich war sollen die Daten gespeichert werden und die Liste mit den Namen angezeigt werden. Nun ist schon ersichtlich, dass eine weitere Funktion gebraucht wird um die Eingabemaske zusammen mit einer Möglichen Meldung anzuzeigen. Ich werde diese Funktion zeige_maske nennen. zeige_maske hat als einzigen Parameter eine Mögliche Meldung. Machen wie Funktion speicher_person etwas genauer:
Zu zeige_personen
Man kann schon sehen, dass die Datei mehrfach gelesen wird. Es wäre hier günstig Zu betrachten was alles mit der Datei gemacht wird. Die Datei wird gelesen, durchsucht und es werden Daten angehängt. So wie es jetzt aussieht wird die Datei zweimal gelesen, einmal wenn die Eingaben geprüft werden und ein anderes mal wenn die Daten Ausgeben werden. Um das zu verhindern sollte man Die Dateizugriffe kapseln und die Zugriffe auf die Daten zu abstrahieren. Hier bietet sich ein Objekt an, das es erlaubt:
das hat auch weiterhin den Vorteil, das man Das Objekt intern wahlweise mit DB-Zugriffen oder mit Datei-Zugriffen realisieren kann. Ich werde es PersonenDB nennen. [EDIT]Nicht vorhandenen Gedankengänge ergänzt Es werden Methoden gebraucht, mit der man Die Daten sortieren lesen, suchen und schreiben kann. Es wird also so etwas wie ein read sort get_by get_all und add gebraucht. Mit read sollen die Daten geladen werden. Mit sort sollen die Daten im Speicher sortiert werden, sodass sie bei der Ausgabe durch get_by und get_all sortiert sind. An add sollen alle Daten übergeben werden, die für eine Person wichtig sind. Da bietet sich ein Hash, als Übergabeparameter an, da es viele Parameter sind und eine Sortierung nicht nötig. Das bedeutet aber dass die Klasse alle Erlaubten ParemeterNamen kennen muss, damit das Objekt sie in der richtigen Reihenfolge in die Datei schreiben kann und prüfen kann welche Parameter vorhanden sind. Da bei der Prüfung auch Fehler auftreten können ist es günstig diese im Objekt zu speichern und über eine Methode abfragbar zu machen. Als Mame der Methode bietet sich error an. Fasse ich mal zusammen: gebraucht werden: Klassenparameter:
Methoden:
Nun werden noch die Objekt-Parameter gebraucht. Das wäre zum einen eine Liste mit allen Personen, ein Parameter um die Fehler zu speichern und einer um den Dateinamen vor zu halten. Will man nun beginnen die Methode read zu schreiben muss man sich Gedanken über das Dateiformat machen. Das einfachste ist ein CSV-Artiges Format zu nutzen. Dar Nachteil dabei ist, dass ASCII-Zeichen als Feldtrenner genutzt werden, die auch in den Feldern vorkommen können. Man kann sie entweder verbieten, oder ersetzen. Ich werde mich für das ersetzen entscheiden. Dazu muss ich alle Zeichen die Feldtrenner oder Zeilentrenner sind durch ein Folge von Zeichen ersetzen, die diese repräsentiert das wird im allgemeinen "entwerten" oder "quoten" genannt. Wenn ich als Feldtrenner ";" und als Zeilentrenner "\n" (bzw "\x0A") Benutzte, muss ich diese In den Feldern entwerten. Dazu nehme ich den ASCII wert der s zeichen als dreistellige zahl und setze ein % davor. das bedeutet auch dass % entwertet werden muss. Es wird eine Methode gebraucht die Alle Zeichen entwertet und eine die alle Entwertungen rückgängig macht. Quoteund unquote Das Lesen gestaltet sich nun wie folgt: read:
das schreiben: add
sort
get_by
Wenn man nun weiter konsequent weitermacht kann man zu einer Klasse ähnlich der die unten gezeigt wird kommen. [/EDIT] Jetzt wäre es nötig Die Klasse zum Objekt zu gestalten. Das kürze ich ab und springen direkt zur Implementation dieser zentralen Funktionalität: PersonenDB.pm: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 package PersonenDB; use strict; use warnings; use IO::File; use Fcntl qw(:flock :seek); use utf8; # Trenner my $separator=";"; # Zeilenende my $lineend="\x0A"; my @force_names=qw(vorname nachname address); my @optional_names=qw(person website email dienstzeit dienstgrad dienststellung einheit nummer typ); my @all_names=(@force_names,@optional_names); my @typen=( ['Minenleger', 'KSS Projekt 1159 (Koni-class)' ], ['Minenleger', 'MSR Projekt 89.2 (Kondor-class)' ], ['U-Jagd', 'U-Jagd Projekt 133 (Parchim-class)'], ['Landungsschiff', 'LSM Projekt 108 (Frosch-class)' ], ); sub typen{ return @typen; } sub key_names{ return @all_names; } # PersonenDB->new($filename); sub new { my $class=shift; my $filename=shift; my $self={}; $self->{filename}=$filename; $self->{data} =undef; $self->{fh} =undef; $self->{error} =''; bless($self,$class); $self->read(); return $self; } sub error { my $self=shift; my $err=$self->{error}; $self->{error}=''; return $err; } # Benutzer Sortieren sub sort { my $self=shift; @{$self->{data}}=sort __sort @{$self->{data}}; return 1; } # generisches Golen von Nutzern sub get_by { my $self=shift; my $key=shift; my $val=shift; return __filter($self->{data},$key,$val); } # alle benutzer mit dem Vornamen sub get_by_vorname { my $self=shift; my $name=shift; return __filter($self->{data},'vorname',$name); } # alle Benutzer mit dem Nachnamen sub get_by_nachname { my $self=shift; my $name=shift; return __filter($self->{data},'nachname',$name); } # alle nutzer mit dem Vormanem und namen sub get_by_name { my $self=shift; my $vorname=shift; my $nachname=shift; my @l=__filter($self->{data},'nachname',$vorname); @l=__filter(\@l,'vorname',$nachname); return @l; } # allen Nutzter mit der Email sub get_by_email { my $self=shift; my $email=shift; return __filter($self->{data},'email',$email); } # Existiert person? sub exists { my $self=shift; my $user=shift; my @l=$self->get_by_name($user->{vorname},$user->{nachname}); unless(@l) { @l=$self->get_by_email($user->{email}); return 0 unless(@l); } return 1; } # daten lesen sub read { my $self=shift; # Datei öffnen: return 0 unless($self->_open()); my $fh=$self->{fh}; # Datei sperren flock($fh,LOCK_EX); # zum Anfang der Datei $fh->seek(0,SEEK_SET); # Liste leeren $self->{data}=[]; # format: # Vorname\0Name\0Wohnort\0Webseite\0Mailadresse\0Dienstzeit\0Dienstgrad\0Dienststellung\x0A # zeilen die mir '\s*#' starten werden ignoriert! local $/=$lineend; while(my $line=<$fh>) { chomp($line); next if($line=~/^\s*#/); $line=~s/^\s*//; next unless($line); my @data=map{__unquote($_)}split($separator,$line); push(@{$self->{data}},{map{$all_names[$_] => $data[$_]}(0..$#all_names)}); } # Datei entsperren flock($fh,LOCK_UN); # Liste sortieren: $self->sort(); return 1; } # Person hinzufügen sub add { my $self=shift; my $data=shift; # nicht hinzufügen wenn nicht alle wichtigen daten vorhanden for(@force_names) { unless($data->{$_}) { $self->{error}.= sprintf("%s ist Leer!\n",$_); return 0; } } # unnötige werde auf '' setzen. for(@optional_names) { $data->{$_}='' unless($data->{$_}); } # testen ob die Emailadersse korrekt ist if($data->{'email'}) { unless($data->{'email'}=~/^[\w._%+-]+@[\w.-]+\.\w{2,4}$/) { $self->{error}.= sprintf("%s ist keine korrekte Emailadresse!\n",$data->{'email'}); return 0; } } # nicht hinzufügen wenn schon vorhanen if($self->exists($data)) { $self->{error}.= "Der Name ist schon Eingetragen!\n"; return 0; } # Datei öffnen wenn nicht schon offen: return 0 unless($self->_open()); # Daten serialisieren my $string=" ".join($separator,map{__quote($data->{$_})}@all_names).$lineend; my $fh=$self->{fh}; # Datei sperren flock($fh,LOCK_EX); # zum Ende der Datei: $fh->seek(0,SEEK_END); # schreiben $fh->print($string); #das schreiben der Daten erzwingen $fh->flush(); $fh->sync(); # Datei Entsperren flock($fh,LOCK_UN); # zur Liste hinzufügen push(@{$self->{data}},$data); # sortieren $self->sort(); return 1; } # alle Daten sub all { my $self=shift; return @{$self->{data}}; } ######################################################################## # privat sub _open { my $self=shift; # Datei öffnen wenn nicht offen $self->{fh}=IO::File->new() unless($self->{fh}); if(!$self->{fh}->opened()) { unless($self->{fh}->open($self->{filename},"+>>")) { $self->{error}.= "Die Datenbank lässt sich nicht öffnen!\n"; return 0; } } return 1; } # sortierung sub __sort { for (qw(nachname address vorname)) { my $x=lc($a->{$_}) cmp lc($b->{$_}); return $x if($x != 0); } return 0; } # Geschützte Zeichen Entwerten sub __quote { my $val=shift; $val=~s/(%|\Q$separator\E|\Q$lineend\E)/'%'.join('%',map{sprintf('%03u',ord($_))}split('',$1))/egs; return $val; } # Entwertung rückgängig machen sub __unquote { my $val=shift; $val=~s/%(\d\d\d)/chr($1)/egs; return $val; } sub __filter { my @liste=@{shift()}; my $key=shift; my $value=shift; for my $pos (reverse(0..$#liste)) { my $v=$liste[$pos]; splice(@liste,$pos,1) if(!exists($v->{$key}) || $v->{$key} ne $value); } return @liste; } 1; [EDIT]Gedanken ergänzt: Wie man sehen kann ist die gesamte Prüfung in den Code für die DB gewandert. Dadurch entfallen sämtliche Prüfungen im Script. Diese muss nur noch prüfen, ob eine Aktion erfolgreich war. Außerdem mache ich einen "Lock" auf die Datei, um Kornkurierende Schreib/Lesezugriffe zu kontrollieren. Das verhindert zerstörte Einträge wenn zwei Personen sich gleichzeitig eintragen wollen. [/EDIT] Die Klasse sollte man auch gleich testen: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #!/usr/bin/perl use strict; use warnings; use PersonenDB; # Für Tastausgaben use Data::Dumper; my $db = PersonenDB->new('test.dat'); #print Dumper($db); exit(); $db->add({ vorname => 'Test', nachname => 'Tester', address => 'TestStr 1', website => 'www.test.de/test2', email => 'mail@test.de', dienstzeit => 100, dienstgrad => '1', dienststellung => '1965.1.12', einheit => 'rable', nummer => 837, typ => 4, person => 'das ist nur ein test!', }) || print "ERROR:".$db->error()."\n"; $db->add({ vorname => 'Toto', nachname => 'Testerito', address => 'TestStr 22', website => 'www.test.de/test1', email => 'mail1@test.de', dienstzeit => 100, dienstgrad => '2', dienststellung => '1965.1.12', einheit => 'blub', nummer => 837, typ => 2, person => 'das ist nur ein test!', }) || print "ERROR:".$db->error()."\n"; $db->add({ vorname => 'Tranta', nachname => 'Tester', address => 'TestStr 1', website => 'www.test.de/test3', email => 'mail2@test.de', dienstzeit => 100, dienstgrad => '3', dienststellung => '1923', einheit => 'bla', nummer => 11234, typ => 1, person => 'das ist nur ein test!', }) || print "ERROR:".$db->error()."\n"; $db->add({ vorname => 'Karl', nachname => 'Boratis', address => "Rabenweg 19293\n12345 Braurig", website => 'www.test.de/test3', email => 'mail3@test.de', dienstzeit => 100, dienstgrad => '4', dienststellung => "2.11.1968", einheit => 'bla', nummer => 4, typ => 4, person => 'das ist nur ein test!', }) || print "ERROR:".$db->error()."\n"; $db->add({ vorname => 'Henry', nachname => 'Boratis', address => "Rabenweg 19293\n12345 Braurig", website => 'www.test.de/test4', email => 'xxx???&test.??', dienstzeit => 100, dienstgrad => '4', einheit => 'luba', nummer => 55, typ => 3, person => 'das ist nur ein test!', }) || print "ERROR:".$db->error()."\n"; print Dumper([$db->all()]); Damit wäre die Datenbank fertig. Nun wird es Zeit sich über das HTML Gedanken zu machen. Es ist günstig HTML und Code zu trennen, das erleichtert nicht nur Übersichtlichkeit es erleichtert auch die Pflege und verhindert Fehler. Ich werte HTML::Template::Compiled nutzen. Zuerst die Webseite zum eintragen der Personen: input.tmpl Code (html): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 <?xml version="1.0" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Kameradenfinder/Meldeliste für Besatzungsmitglieder</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="Kameradenfinder/Meldeliste für Besatzungsmitglieder" /> <style type="text/css"> body { background-color:#ffffea; color:#ffff91; font-family:verdana; text-align:left; } #all { position:absolute; top:0px; left:50%; width:0px; } #document { position:relative; left:-350px; padding:0em; margin-top:3em; background-color:#000000; border-width:9px; border-style:outset; border-color:gray; width:700px; } #document_top { padding-top:2em; margin-bottom:2em; text-align:center; } #document_form { margin-top: 3em; padding:0em; } #document_send { margin-bottom:2em; margin-left:1em; margin-right:1em; padding-left:0em; padding-right:0em; padding-top:2em; padding-bottom:2em; border-left-width:0em; border-right-width:0em; border-top-width:0.2em; border-bottom-width:0.2em; border-color:#ffff91; border-style:solid; text-align:center; } #title { font-family:verdana,tahoma,arial; font-size:2em; margin-right:2em; font-weight:bold; } .link { font-family:verdana; color:#ffff91; font-size:1.2em; } #form_list { list-style-type:none; list-style-position:outside; } #form_list > li { padding: 0.2em; } .form_text { font-size:0.9em; text-align:left; width:13em; float:left; white-space:nowrap; font-weight:bold; } .form_input { float:none; } .form_input > input { font-size:0.5em; background-color: #ffffe1; font-weight: bold; width:40em; } .form_input > textarea { font-size:0.5em; background-color: #ffffe1; font-weight: bold; width:40em; height:10em; } .form_input > select { font-size:0.5em; background-color: #ffffe1; font-weight: bold; width:40em; } #form_send { cursor: pointer; background-color: #00ff00; color: #00004a; font-family: verdana; font-weight: bold; padding:0.3em; margin-right:2em; } #form_reset { cursor: pointer; background-color: #ff0000; color: #00004a; font-family: verdana; font-weight: bold; padding:0.3em; margin-right:4em; } </style> </head> <body><div id="all"> <div id="document"> <div id="document_top"> <span id="title">Meldeformular</span> <a class="link" href="<TMPL_VAR ACTION_SHOW>" title="Meldeliste lesen...">Meldeliste lesen...</a> </div> <form action="<TMPL_VAR ACTION_SEND>" method="post"> <input type="hidden" name="action" value="send" /> <div id="document_form"> <ul id="form_list"> <li> <div class="form_text" >Name:</div> <div class="form_input"><input name="nachname" maxlength="30" size="50" value="<TMPL_VAR nachname>" /></div> </li> <li> <div class="form_text" >Vorname:</div> <div class="form_input"><input name="vorname" maxlength="30" size="50" value="<TMPL_VAR vorname>" /></div> </li> <li> <div class="form_text" >Wohnort:</div> <div class="form_input"><input name="address" maxlength="30" size="50" value="<TMPL_VAR address>" /></div> </li> <li> <div class="form_text">E-Mail:</div> <div class="form_input"><input name="email" maxlength="30" size="50" value="<TMPL_VAR email>" /></div> </li> <li> <div class="form_text" >Homepage:</div> <div class="form_input"><input name="website" maxlength="30" size="50" value="<TMPL_VAR website>" /></div> </li> <li> <div class="form_text" >Zur Person:</div> <div class="form_input"><textarea name="person" rows="4" cols="50" ><TMPL_VAR person></textarea></div> </li> <li> <div class="form_text" >Dienstzeit:</div> <div class="form_input"><input name="dienstzeit" maxlength="30" size="50" value="<TMPL_VAR dienstzeit>" /></div> </li> <li> <div class="form_text" >Dienstgrad:</div> <div class="form_input"><input name="dienstgrad" maxlength="30" size="50" value="<TMPL_VAR dienstgrad>" /></div> </li> <li> <div class="form_text" >Dienststellung:</div> <div class="form_input"><input name="dienststellung" maxlength="30" size="50" value="<TMPL_VAR dienststellung>" /></div> </li> <li> <div class="form_text" >Einheit/Schiff:</div> <div class="form_input"><input name="einheit" maxlength="30" size="50" value="<TMPL_VAR einheit>" /></div> </li> <li> <div class="form_text" >Schiff - Bordnummer:</div> <div class="form_input"><input name="nummer" maxlength="30" size="50" value="<TMPL_VAR nummer>" /></div> </li> <li> <div class="form_text" >Schiff - Projekt:</div> <div class="form_input"><select name="typ" size="1" title="Typ auswählen"> <option value="0" selected title="Schiffstyp auswählen">------------ Schiffstyp auswählen --------->>></option><TMPL_LOOP SELECT> <option value="<TMPL_VAR VALUE>" title="<TMPL_VAR TITLE>"> <TMPL_VAR TEXT></option></TMPL_LOOP> </select></div> </li> </ul> </div> <div id="document_send"> <input id="form_send" title="Ich möchte mich in die Meldeliste eintragen." type="submit" value="EINTRAGEN"> <input id="form_reset" title="Alles Mist noch mal neu." type="reset" value="LÖSCHEN"> <a class="link" href="<TMPL_VAR ACTION_SHOW>" title="Meldeliste lesen...">Meldeliste lesen...</a><br /> <p><TMPL_VAR MESSAGE></p> </div> </form> </div></div> </body> </html> nun noch das HTML für die Liste: show.tmpl Code (html): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 <?xml version="1.0" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Kameradenfinder/Meldeliste für Besatzungsmitglieder</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="Kameradenfinder/Meldeliste für Besatzungsmitglieder" /> <style type="text/css"> a { font-family:verdana; color:#ffff91; font-size:1em; } body { background-color:#ffffea; color:#ffff91; font-family:verdana; text-align:left; } #all { position:absolute; top:0px; left:50%; width:0px; } #document { position:relative; left:-350px; padding:0em; margin-top:3em; background-color:#000000; border-width:9px; border-style:outset; border-color:gray; width:700px; } #document_top { padding-top:2em; margin-bottom:2em; text-align:center; } #document_form { margin-top: 3em; padding:0em; } #personen_short { margin-bottom:2em; margin-left:1em; margin-right:1em; padding-left:0em; padding-right:0em; padding-top:2em; padding-bottom:2em; border-left-width:0em; border-right-width:0em; border-top-width:0.2em; border-bottom-width:0.2em; border-color:#ffff91; border-style:solid; text-align:left; } #personen_short ul { list-style-type: none; } #personen_short li { display: inline; } #personen_short li > a { min-width: 9em; display: -moz-inline-box; display: inline-block; } #personen_long { list-style-type: none; margin: 0em; padding: 0em; } #personen_long > li { padding-bottom:1em; margin: 1em; border-left-width:0em; border-right-width:0em; border-top-width:0em; border-bottom-width:0.2em; border-color:#ffff91; border-style:solid; } #personen_long > li > ul { margin: 0em; padding: 0em; list-style-type: none; } #document_bottom { margin-top:2em; margin-left:1em; margin-right:1em; padding-bottom:2em; padding-top:2em; border-left-width:0em; border-right-width:0em; border-top-width:0em; border-bottom-width:0.2em; border-color:#ffff91; border-style:solid; text-align:center; } #title { font-family:verdana,tahoma,arial; font-size:2em; margin-right:2em; font-weight:bold; } .link { font-size:1.2em; } .p_typ { font-size:0.8em; text-align:left; width:13em; float:left; white-space:nowrap; } .p_txt { float:none; font-size:0.8em; width:40em; } </style> </head> <body><div id="all"> <div id="document"> <div id="document_top"> <span id="title">MeldeListe</span> <a class="link" href="<TMPL_VAR ACTION_INPUT>" title="Person Eingeben...">Person Eingeben...</a> </div> <div id="personen_short"> <a name="TOP">NAMEN:</a> <ul><TMPL_LOOP PERSON> <li><a href="#<TMPL_VAR ANKER>"><TMPL_VAR KURZNAME></a></li></TMPL_LOOP> </ul> </div> <ul id="personen_long"> <TMPL_LOOP PERSON> <li> <a name="<TMPL_VAR ANKER>" href="#top">Nach Oben</a> <ul> <li> <div class="p_typ" >Name:</div> <div class="p_txt"><TMPL_VAR nachname></div> </li> <li> <div class="p_typ" >Vorname:</div> <div class="p_txt"><TMPL_VAR vorname></div> </li> <li> <div class="p_typ" >Wohnort:</div> <div class="p_txt"><TMPL_VAR address></div> </li> <li> <div class="p_typ">E-Mail:</div> <div class="p_txt"><TMPL_VAR email></div> </li> <li> <div class="p_typ" >Homepage:</div> <div class="p_txt"><TMPL_VAR website></div> </li> <li> <div class="p_typ" >Zur Person:</div> <div class="p_txt"><TMPL_VAR person></div> </li> <li> <div class="p_typ" >Dienstzeit:</div> <div class="p_txt"><TMPL_VAR dienstzeit></div> </li> <li> <div class="p_typ" >Dienstgrad:</div> <div class="p_txt"><TMPL_VAR dienstgrad></div> </li> <li> <div class="p_typ" >Dienststellung:</div> <div class="p_txt"><TMPL_VAR dienststellung></div> </li> <li> <div class="p_typ" >Einheit/Schiff:</div> <div class="p_txt"><TMPL_VAR einheit></div> </li> <li> <div class="p_typ" >Schiff - Bordnummer:</div> <div class="p_txt"><TMPL_VAR nummer></div> </li> <li> <div class="p_typ" >Schiff - Projekt:</div> <div class="p_txt"><TMPL_VAR typ></div> </li> </ul> </li></TMPL_LOOP> </ul> <div id="document_bottom"> <a class="link" href="<TMPL_VAR ACTION_INPUT>" title="Person Eingeben...">Person Eingeben...</a> </div> </div></div> </body> </html> Und nun zum eigentlichen Code. durch die Verwendung einer Klasse, das die Dateizugriffe kapselt, verändern sich die Parameter, die an die Funktionen übergeben werden und die Abläufe ein wenig. Im großen und ganzen bleiben die Funktionalitäten aber erhalten. Da man sich schon Geadnken über den Aufbau gemacht hat, ist die Implementation nicht mehr so schwehr. Durch die saubere Abtrennung der Datenhaltung und dem HTML ist der Code sehr übersichtlich und ist nur die Verbindung zwischen den Daten und dem HTML liste.pl Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 #!/usr/bin/perl use strict; use warnings; use HTML::Template::Compiled; use CGI; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use PersonenDB; use utf8; # die benötigten Dateien my $input_tmpl='input.tmpl'; my $show_tmpl='show.tmpl'; my $db_file='test.dat'; # Die Objkete erzeugen. my $cgi = CGI->new(); my $db = PersonenDB->new($db_file); # Ausgabe beginnen print $cgi->header(-type=>"text/html", -charset=>"UTF-8"); # warungen in den Browser Ausgeben warningsToBrowser(1); # die gewünscht aktion bestimmen my $action=lc($cgi->param('action') || ''); # wenn es keine bekannte Aktion ist, dann soll es 'show' sein $action='show' unless(grep{$action eq $_}qw(show input send)); # Eingabemaske Zeigen if($action eq 'input') { zeige_maske($cgi,$db,$input_tmpl,{},''); } # Daten senden elsif($action eq 'send') { speicher_person($cgi,$db); } # Daten Anzeigen else { zeige_personen($cgi,$db,$show_tmpl); } # Eingabemaske generiegen und anzeigen sub zeige_maske { my $cgi=shift; my $db=shift; my $file=shift; my $user=shift || {}; my $message=shift || ''; my $tmpl = HTML::Template::Compiled->new( cache => 0, filename => $file, ); my %data; for my $key ($db->key_names()) { $data{$key}=$user->{$key} || ''; } my @tmp=$db->typen(); my @sel; for(1..@tmp) { my $v=shift(@tmp); push(@sel,{ VALUE => $_, TITLE => $v->[0], TEXT => $v->[1], }); } $tmpl->param( MESSAGE => $message, ACTION_SHOW => $cgi->script_name()."?action=show", ACTION_SEND => $cgi->script_name(), SELECT => \@sel, %data, ); print $tmpl->output(); return 1; } # Daten lesen und Person speichern sub speicher_person { my $cgi=shift; my $db=shift; my %nutzer; for my $key ($db->key_names()) { $nutzer{$key}=$cgi->param($key); } if($db->add(\%nutzer)) { zeige_personen($cgi,$db,$show_tmpl); } else { zeige_maske($cgi,$db,$input_tmpl,\%nutzer,$db->error()); } } # Liste Generieren und anzeigen sub zeige_personen { my $cgi=shift; my $db=shift; my $file=shift; my $tmpl = HTML::Template::Compiled->new( cache => 0, filename => $file, ); my @typen=$db->typen(); my $cnt=0; my @personen; for ($db->all()) { my $person={%$_}; $person->{ANKER}="anker$cnt"; $person->{KURZNAME}="$person->{vorname} $person->{nachname}"; if($person->{typ}<=0 || $person->{typ}>@typen) { $person->{typ}=''; } else { my $t=$typen[$person->{typ}-1]; $person->{typ}="$t->[1] ($t->[0])"; } push(@personen,$person); $cnt++; } $tmpl->param( ACTION_INPUT => $cgi->script_name()."?action=input", PERSON => \@personen, ); print $tmpl->output(); } Es ist alles nicht so schwehr. Last edited: 2011-07-18 14:22:16 +0200 (CEST) |