German Unix User Group e.V.
Postfach 25 01 23
D-44739 Bochum
Tel. +49-89-380 125 95 0
Fax +49-89-380 125 95 9
kontakt@guug.de
Impressum
Letzte Änderung: 2006-03-06

Ein Wiki in 52 Zeilen Perl

Grundlagen

step01.pl


 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # + ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # + Data::Dumper zur Ausgabe der Datenstruktur
 8
 9  use Data::Dumper;
10
11  my $wiki;                                 # Ein Wiki als Hash-Referenz def.
12  $wiki->{FrontPage} = q/Hallo Welt!/;      # einen Eintrag erzeugen und
13  $wiki->{ImpresSum} = q/Ronnie Neumann/;   # einen weiteren Eintrag erzeugen.
14
15  print Dumper $wiki;                       # Ausgabe mit der Dumper-Funktion

step02.pl

    
 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # Data::Dumper zur Ausgabe der Datenstruktur
 8  # + Storable zur einfachen Serialisierung der Datenstruktur
 9
10  use Data::Dumper;
11  use Storable;
12
13  my $wiki          =  -e "step02.db" ?        # existiert step02.db im cwd?
14                       retrieve("step02.db") : # dann lade das wiki von dort,
15                       {} ;                    # ansonsten ein leeres Hash
16
17  $wiki->{FrontPage} = q/Hallo Welt!/;
18  $wiki->{ImpresSum} = q/Ronnie Neumann/;
19
20  print Dumper $wiki;
21
22  store $wiki, "step02.db" or                  # $wiki in Datei serialisieren
23     die "Can't store step02.db: $!\n";        # oder Abbruch mit Fehlermeld.

step03.pl


 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # Data::Dumper zur Ausgabe der Datenstruktur
 8  # Storable zur einfachen Serialisierung der Datenstruktur
 9
10  use Data::Dumper;
11  use Storable;
12
13  my $wiki       = -e "step02.db" ? retrieve("step02.db") : {} ;
14
15  print Dumper $wiki; # Funktioniert das speichern und laden?
16

step04.pl

    
 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # Data::Dumper zur Ausgabe der Datenstruktur
 8  # Storable zur einfachen Serialisierung der Datenstruktur
 9  # + Ueberprüfung von WikiWorten mit regulaeren Ausdruecken
10
11  use Data::Dumper;
12  use Storable;
13
14  my $wiki       = -e "step02.db" ? retrieve("step02.db") : {} ;
15
16  my $wikiwords  = qr/\b([A-Z]\w+[A-Z]\w+)/;   # WikiWoerter beginnen GROSS
17                                               # gehen klein weiter, dann
18                                               # wieder GROSS und wieder klein
19
20  $wiki->{Fehler} = 'Kein WikiWort!';          # ein Eintrag der kein WikiWort
21                                               # als Schluessel hat
22
23  foreach my $word (keys %$wiki) {             # wir schauen nach
24     if ($word =~ /$wikiwords/) {
25        print $word, " ist ein WikiWort!\n";
26     } else {
27        print $word, " ist KEIN WikiWort!\n";
28     }
29  }

CGI

step05.pl

    
     1  #!/usr/bin/perl
     2
     3  use strict;
     4  use warnings;
     5
     6  # ein Wiki als Schluessel-Werte Paare in einem Hash
     7  # Data::Dumper zur Ausgabe der Datenstruktur
     8  # Storable zur einfachen Serialisierung der Datenstruktur
     9  # + CGI um Formulardaten abfragen zu koennen und Header auszugeben
    10  # + CGI::Carp um Fehlermeldungen an den Browser statt ins Logfile zu senden
    11  # + FindBin zum 'finden' des aktuellen Pfades in $Bin
    12
    13  use Data::Dumper;
    14  use Storable;
    15  use CGI;
    16  use CGI::Carp qw/fatalsToBrowser/;
    17  use FindBin qw/$Bin/;
    18
    19  my $q           = new CGI;                  # wir benoetigen ein CGI-Objekt
    20  my $form        = $q->Vars();               # um die Formulardaten abzufragen
    21  my $action      = $form->{'action'};        # wurde eine Aktion angefragt?
    22
    23  my $wiki        = -e "$Bin/wiki.db"         # liegt hier eine wiki.db rum?
    24                  ? retrieve("$Bin/wiki.db")  # dann laden wir diese Datei
    25                  : {} ;                      # ansonsten beginnen wir mit 
    26                                              # einem leeren Wiki!
    27
    28  my $actions = {
    29                                              # wir beginnen ohne Aktionen
    30  };
    31
    32  sub show {
    33          return  $q->header(),               # Ausgabe von HTTP-Header und
    34                  Dumper $wiki,               # einem Dump des Wikis,
    35                  Dumper $form;               # sowie des Formulars
    36  }
    37
    38  print   $actions->{$action}                 # haben wir eine Aktion?
    39          ? $actions->{$action}()             # dann führen wir diese aus
    40          : show();                           # ansonsten wird show() genutzt

step06.pl

    
 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # Data::Dumper zur Ausgabe der Datenstruktur
 8  # Storable zur einfachen Serialisierung der Datenstruktur
 9  # CGI um Formulardaten abfragen zu koennen und Header auszugeben
10  # CGI::Carp um Fehlermeldungen an den Browser statt ins Logfile zu senden
11  # FindBin zum 'finden' des aktuellen Pfades in $Bin
12  # + eine einfache Aktion registrieren 
13
14  use Data::Dumper;
15  use Storable;
16  use CGI;
17  use CGI::Carp qw/fatalsToBrowser/;
18  use FindBin qw/$Bin/;
19
20  my $q           = new CGI;                  # wir benoetigen ein CGI-Objekt
21  my $form        = $q->Vars();               # um die Formulardaten abzufragen
22  my $action      = $form->{'action'};        # wurde eine Aktion angefragt?
23
24  my $wiki        = -e "$Bin/wiki.db"         # liegt hier eine wiki.db rum?
25                  ? retrieve("$Bin/wiki.db")  # dann laden wir diese Datei
26                  : {} ;                      # ansonsten beginnen wir mit 
27                                              # einem leeren Wiki!
28
29  my $topic       = $form->{topic}            # 'Frontpage' ist der Topic
30                  || 'FrontPage';             # wenn keiner via Formular
31                                              # angefragt wird
32
33  my $entry       = $form->{entry}            # Eintrag wird entweder aus dem
34                  || $wiki->{$topic};         # Formular erfragt, oder aus dem
35                                              # Wiki ausgelesen
36
37  my $actions = {
38          'index' => sub {                    # eine einfache Uebersicht gen.
39                  $entry = join "<br />\n",   # durch verketten aller 
40                           sort keys %$wiki;  # Wikiwoerter mit <br /> 
41                  $topic = 'OverView';        # 'Overview' als Topic setzen
42                  show();                     # und per show() ausgeben
43          },
44  };
45
46  sub show {
47          return  $q->header(),               # Ausgabe von HTTP-Header und
48                  "<h1>", $topic, "</h1>",    # dem Topic als Ueberschrift
49                  $entry;                     # sowie des Eintrags
50  }
51
52  print   $actions->{$action}                 # haben wir eine Aktion?
53          ? $actions->{$action}()             # dann fuehren wir diese aus
54          : show();                           # ansonsten wird show() genutzt

Templating

step07.pl


 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  # ein Wiki als Schluessel-Werte Paare in einem Hash
 7  # Data::Dumper zur Ausgabe der Datenstruktur
 8  # Storable zur einfachen Serialisierung der Datenstruktur
 9  # CGI um Formulardaten abfragen zu koennen und Header auszugeben
10  # CGI::Carp um Fehlermeldungen an den Browser statt ins Logfile zu senden
11  # FindBin zum 'finden' des aktuellen Pfades in $Bin
12  # + HTML::Template einbinden 
13
14  use Data::Dumper;
15  use Storable;
16  use CGI;
17  use CGI::Carp qw/fatalsToBrowser/;
18  use FindBin qw/$Bin/;
19  use HTML::Template;                         # HTML::Template Modul einbinden
20  use Text::Textile qw(textile);              # Textile-Modul fuer Wikisyntax
21                                              # einbinden
22
23  my $q           = new CGI;                  # wir benoetigen ein CGI-Objekt
24  my $form        = $q->Vars();               # um die Formulardaten abzufragen
25  my $action      = $form->{'action'};        # wurde eine Aktion angefragt?
26
27  my $wiki        = -e "$Bin/wiki.db"         # liegt hier eine wiki.db rum?
28                  ? retrieve("$Bin/wiki.db")  # dann laden wir diese Datei
29                  : {} ;                      # ansonsten beginnen wir mit 
30                                              # einem leeren Wiki!
31
32  my $wikiwords   = qr/\b([A-Z]\w+[A-Z]\w+)/; # WikiWoerter beginnen GROSS
33                                              # gehen klein weiter, dann
34                                              # wieder GROSS und wieder klein
35
36  my $topic       = $form->{topic}            # 'Frontpage' ist der Topic
37                  || 'FrontPage';             # wenn keiner via Formular
38                                              # angefragt wird
39
40  my $entry       = $form->{entry}            # Eintrag wird entweder aus dem
41                  || $wiki->{$topic};         # Formular erfragt, oder aus dem
42                                              # Wiki ausgelesen
43
44  my $actions = {
45          'index' => sub {                    # eine einfache Uebersicht gen.
46                  $entry = join "<br />\n",   # durch verketten aller 
47                           sort keys %$wiki;  # Wikiwoerter mit <br />. 
48                  $topic = 'OverView';        # 'Overview' als Topic setzen
49                  show();                     # und per show() ausgeben
50          },
51  };
52
53  my $template    = HTML::Template->new(      # ein Template-Objekt erzeugen. 
54      filename => "$Bin/wiki.html"            # im Verzeichnis des Skripts 
55  );                                          # nach dem Template suchen
56
57  sub show {
58          $entry =~ s#$wikiwords#<a href="wiki.pl?topic=$1">$1</a>#g; # im $entry
59                                              # WikiWorte durch Links ersetzen
60          $template->param(
61              topic => $topic,                # topic und
62              entry => textile($entry)        # entry als Parameter an $template
63          );                                  # uebergeben
64
65          return $q->header(),                # HTTP-Header und
66                 $template->output();         # verarbeitetes Template uebergeb. 
67  }
68
69  print   $actions->{$action}                 # haben wir eine Aktion?
70          ? $actions->{$action}()             # dann fuehren wir diese aus
71          : show();                           # ansonsten wird show() genutzt

Aktionen

step08.pl


  1  #!/usr/bin/perl
  2
  3  use strict;
  4  use warnings;
  5
  6  # ein Wiki als Schluessel-Werte Paare in einem Hash
  7  # Storable zur einfachen Serialisierung der Datenstruktur
  8  # CGI um Formulardaten abfragen zu koennen und Header auszugeben
  9  # CGI::Carp um Fehlermeldungen an den Browser statt ins Logfile zu senden
 10  # FindBin zum 'finden' des aktuellen Pfades in $Bin
 11  # HTML::Template einbinden 
 12  # + fehlende Aktionen ergaenzen
 13
 14  use Storable;
 15  use CGI;
 16  use CGI::Carp qw/fatalsToBrowser/;
 17  use FindBin qw/$Bin/;
 18  use HTML::Template;                         # HTML::Template Modul einbinden
 19  use Text::Textile qw(textile);              # Textile-Modul fuer Wikisyntax
 20                                              # einbinden
 21
 22  my $q           = new CGI;                  # wir benoetigen ein CGI-Objekt
 23  my $form        = $q->Vars();               # um die Formulardaten abzufragen
 24  my $action      = $form->{'action'};        # wurde eine Aktion angefragt?
 25
 26  my $wiki        = -e "$Bin/wiki.db"         # liegt hier eine wiki.db rum?
 27                  ? retrieve("$Bin/wiki.db")  # dann laden wir diese Datei
 28                  : {} ;                      # ansonsten beginnen wir mit 
 29                                              # einem leeren Wiki!
 30
 31  my $wikiwords   = qr/\b([A-Z]\w+[A-Z]\w+)/; # WikiWoerter beginnen GROSS
 32                                              # gehen klein weiter, dann
 33                                              # wieder GROSS und wieder klein
 34
 35  my $topic       = $form->{topic}            # 'Frontpage' ist der Topic
 36                  || 'FrontPage';             # wenn keiner via Formular
 37                                              # angefragt wird
 38
 39  my $entry       = $form->{entry}            # Eintrag wird entweder aus dem
 40                  || $wiki->{$topic};         # Formular erfragt, oder aus dem
 41                                              # Wiki ausgelesen
 42
 43  my $template    = HTML::Template->new(      # ein Template-Objekt erzeugen. 
 44      filename => "$Bin/step08.html"          # im Verzeichnis des Skripts 
 45  );                                          # nach dem Template suchen
 46
 47  my $actions = {
 48
 49          'index' => sub {                    # eine einfache Uebersicht gen.
 50                  $entry = join "<br />\n",   # durch verketten aller 
 51                           sort keys %$wiki;  # Wikiwoerter mit <br />. 
 52                  $topic = 'OverView';        # 'Overview' als Topic setzen
 53                  show();                     # und per show() ausgeben
 54          },
 55
 56          'new'   => sub {                    # Die new-Aktion bewirkt, dass
 57                  $template->param(           # das Template mit leerem $topic
 58                      edit => 1,              # und $entry im edit-Modus
 59                      topic => '',            # aufegrufen wird
 60                      entry => ''
 61                  );
 62                  return $q->header(),
 63                         $template->output();
 64          },
 65
 66          'edit'  => sub {                    # Die edit-Aktion bewirkt, dass
 67                  $template->param(           # zu einem bestimmten $topic und
 68                      edit => 1,              # $entry das Template im 
 69                      topic => $topic,        # edit-Modus ausgegeben wird
 70                      entry => $entry
 71                  );
 72                  return $q->header(),
 73                         $template->output();
 74          },
 75
 76          'update'=> sub {                    # Die update-Aktion folgt auf die
 77                  die "No topic no entry!\n"  # new- oder edit-Aktion, wenn
 78                      unless $topic;          # ein gueltiger $topic angegeben
 79                  die "Topic $topic isn't a WikiWord!\n" # wurde
 80                      unless
 81                      $topic =~ m/^[A-Z]\w+[A-Z]\w+$/;
 82
 83                  $wiki->{$topic} = $entry;   # der Eintrag im $wiki-Hash wird
 84                  store $wiki, "$Bin/wiki.db" # ergaenzt und gespeichert
 85                      or die "Can't store wiki.dat: $!\n"; # wenn moeglich
 86                  show();
 87          },
 88
 89  };
 90
 91  sub show {
 92          $actions->{'edit'}() unless $entry; # + Die edit-Aktion aufrufen, wenn
 93                                              # + der Eintrag leer ist
 94
 95          $entry =~ s#$wikiwords#<a href="step08.pl?topic=$1">$1</a>#g; # im $entry
 96                                              # WikiWorte durch Links ersetzen
 97          $template->param(
 98              topic => $topic,                # topic und
 99              entry => textile($entry)        # entry als Parameter an $template
100          );                                  # uebergeben
101
102          return $q->header(),                # HTTP-Header und
103                 $template->output();         # verarbeitetes Template uebergeb. 
104  }
105
106  print   $actions->{$action}                 # haben wir eine Aktion?
107          ? $actions->{$action}()             # dann fuehren wir diese aus
108          : show();                           # ansonsten wird show() genutzt

Das fertige Wiki in 52 Zeilen

wiki.pl

    
 1  #!/usr/bin/perl
 2
 3  use strict;
 4  use warnings;
 5
 6  use CGI;
 7  use CGI::Carp qw/warningsToBrowser fatalsToBrowser/;
 8  use HTML::Template;
 9  use FindBin qw/$Bin/;
10  use Storable;
11  use Text::Textile qw(textile);
12
13  my $q           = new CGI;
14  my $form        = $q->Vars();
15  my $action      = $form->{'action'};
16  my $wiki        = -e "$Bin/wiki.db" ? retrieve("$Bin/wiki.db") : {} ;
17  my $wikiwords   = qr/\b([A-Z]\w+[A-Z]\w+)/;
18  my $topic       = $form->{topic} || 'FrontPage';
19  my $entry       = $form->{entry} || $wiki->{$topic};
20  my $template    = HTML::Template->new(filename => "$Bin/wiki.html");
21
22  my $actions = {
23          'index' => sub {
24                  $entry = join "<br />\n", sort keys %$wiki;
25                  $topic = 'OverView';
26                  show();
27          },
28          'new'   => sub {
29                  $template->param( edit  => 1, topic => '', entry => '' );
30                  return $q->header(), $template->output();
31          },
32          'edit'  => sub {
33                  $template->param( edit  => 1, topic => $topic, entry => $entry );
34                  return $q->header(), $template->output();
35          },
36          'update'=> sub {
37                  die "No topic no entry!\n" unless $topic;
38                  die "Topic $topic isn't a WikiWord!\n"
39                    unless $topic =~ m/^[A-Z]\w+[A-Z]\w+$/;
40                  $wiki->{$topic} = $entry;
41                  store $wiki, "$Bin/wiki.db" or die "Can't store wiki.dat: $!\n";
42                  show();
43          },
44  };
45
46  sub show {
47          $actions->{'edit'}() unless $entry;
48          $entry =~ s#$wikiwords#<a href="wiki.pl?topic=$1">$1</a>#g;
49          $template->param( topic => $topic, entry => textile($entry) );
50          return $q->header(), $template->output();
51  }
52
53  print $actions->{$action} ? $actions->{$action}() : show();

Veranstaltungen
FFG2012
Frühjahrsfachgespräch 2012
28.02.-02.03 2012 in München
Kalender
7.Februar 2012
KWMoDiMiDoFrSaSo
30 31 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 1 2 3 4
10  5 6 7 8 9 10 11
GUUG News