Tag 24 – Abschluss

Nun ist es geschafft. Ich schreibe nun den letzten Artikel für meinen Adventskalender. Als Resümee kann ich sagen – es gibt noch viel zu tun bis mein Projekt endlich einsatzbereit ist. In den letzten Artikeln habe ich ja schon mal angedeutet was ich alles noch gern drin haben würde. Ich hoffe ich werde in der nächsten Zeit Zeit finden meine Wünsche umzusetzen.

Auf jeden Fall hat es riesig viel Spaß gemacht mein eigenes CMS zu entwickeln und dazu eine kleine Dokumentation zu schreiben. Auch wenn ich wiedermal den Aufwand, gerade für das Schreiben der Dokumentation, unterschätzt habe.

Ich hoffe euch, meine Leser, hat das Lesen meiner Artikel auch Freude bereitet und ihr habt vielleicht zusätzlich auch noch was neues gelernt.

Nun wünsche ich euch ein besinnliches Weihnachtsfest und einen guten Rutsch ins neue Jahr.

Zum Abschluss meiner REDcms Dokumentation bekommt ihr natürlich auch nochmal den gesamten REDcms 17, einschließlich dem Datenbank-Backup.

Tag 23 – Mehrbenutzer- und Rechtesystem

Am vorletzten Tag meines Adventskalenders möchte ich mich nochmals mit den Erweiterungen meines REDcms beschäftigen. Fast jedes Redaktionssystem wird von mehreren Mitarbeitern betreut und so möchte auch ich in naher Zukunft mein System mit diesem Feature ausstatten. Zusätzlich möchte ich, dass jeder registrierte Benutzer seine Rechte, also das was er im System alles machen darf, individuell eingestellt bekommt.

Mehrbenutzer-System

Um in meinem System auch mit mehreren Benutzern Arbeiten zu können, sollte natürlich als erstes die Anmeldung am System und damit verbunden die Verwaltung der Benutzer geändert werden.

Zur Zeit wird die Anmeldung, also der Benutzername und das Kennwort innerhalb der „Login“-Klasse verwaltet. Wenn es jetzt mehrere Benutzer geben soll, dann wäre es sinnvoller die Benutzernamen und Passwörter in die Datenbank auszulagern. Wenn sich dann ein Benutzer am System anmelden möchte wird in der Datenbank nachgesehen ob es den Benutzer mit dem dazugehörigen Passwort auch gibt. Falls ja können zum Beispiel dann weitere Informationen aus der Datenbank geladen werden, wie bspw. der Vor- und Zuname des Benutzers. So können die Benutzernamen Nicknamen, also fiktive Name, sein und der Benutzer wird trotzdem mit seinem richtigen Namen angesprochen. Auch könnte dann automatisch beim Schreiben neuer Seite bzw. neuer Boxen der Name des Redakteurs eingetragen werden und nicht wie zur Zeit von Hand.

Das schöne an der OOP ist das die „Login“-Klasse in ihrer Benutzung wahrscheinlich nicht geändert werden bräuchte, denn auch weiterhin wird man sich darüber an- und abmelden können. Selbst die Anfrage ob der Benutzer schon angemeldet ist, die von den verarbeitenden Klasse an die „Login“-Klasse gestellt wird, wird bleiben. Hinzukommt eigentlich nur, dass in der Session zusätzliche Angaben, wie den Vor- und Zunamen, hinzugefügt werden.

Rechte-System

Auch die Erweiterung meines REDcms mit einem Rechte-System wird aller Voraussicht nach gar nicht so schwer. Ich könnte mir bei der Rechtevergabe zwei Funktionsarten vorstellen.

Auf der einen Seite wäre da die individuelle Rechtevergabe für jeden einzelnen Benutzer des Systems. Der Vorteil wäre die völlig freie Einstellbarkeit der Rechte für jeden Benutzer. Aber das kann gerade bei sehr vielen Benutzern schnell auch sehr aufwendig werden. Vor allem wenn ständig die Berechtigungen der Benutzer sich ändert.

Auf der anderen Seite könnte die Rechtevergabe gruppenspezifisch geschehen, dass heißt jeder Gruppe bekommt individuelle Berechtigungen und jeder Benutzer kann dann einer oder mehreren Gruppen zugewiesen werden. Aber auch dieses Vorgehensweise hat Nachteile. Zum einen ist der Aufwand zum Erstellen eines solchen Systems viel höher und zum anderen müssen gerade bei vielen individuellen Benutzereinstellungen jedes mal eine neue Gruppe angelegt werden. Was den Aufwand schnell wieder hoch treibt.

Ich werde mich aber wahrscheinlich für die letztere Möglichkeit entscheiden, da sie aus meiner Sicht heraus am praktikabelsten ist.

Tag 22 – Bild-Upload und RSS-Feed

Heute möchte ich über 2 mögliche Erweiterungen meines Systems schreiben. Zum einen ist das die Möglichkeit Dateien auf den Server hochzuladen, das ist zwar schon durch die „CKfinder“-Erweiterung des „FCKeditor“ zum Teil abgedeckt, aber die kostenlose Version blendet immer eine kleinen, störenden Hinweis ein. Zum anderen das Erstellen von RSS-Feeds um REDcms auch als kleines Blog-System nutzen zu können.

Datei-Upload

In meinen verwendeten Online-Editor gibt es eine nette Erweiterung mit deren Hilfe man Bild, Flash-Dateien und andere Format auf den Server hochladen kann. Da diese Erweiterung für kommerzielle Projekte nicht kostenlos ist, könnte ich mir vorstellen in einer der nächsten Versionen die Möglichkeit des Uploads selber zu schreiben und in das System zu integrieren. So wäre ich davon unabhängig. Auch den Editor könnte ich in diesem Zuge selber erstellen, aber ich habe mich schon mehrfach daran gesetzt dies zu machen und habe es wegen des Aufwandes immer wieder abgebrochen. Naja vielleicht klappt es doch noch.

RSS-Feeds

RSS-Feeds sind zwar nicht die neue Form von Newsletter, aber man könnte sie damit vergleichen. Auf der eigenen Website gibt man den Besucher die Möglichkeit einzelne Seiten bzw. die gesamte Website als RSS-Feed zu abonnieren. Wenn dann Änderungen an diesem Feed entstehen werden diese in einer separaten XML-Datei abgespeichert.

Mit einer geeigneten Software, ich benutze dazu „Windows Live Mail“ kann man dann die Abos anfordern und bekommt die neuen Meldungen angezeigt. Das Praktische als Besucher der Website daran ist, dass man seinen Email-Account nicht veröffentlichen muss, denn man selber stellt dieses Abo in seiner Software ein. So ist auch das Abbestellen kinderleicht, denn man löscht ganz einfach in seiner Software das Abo und schon bekommt man keine Neuigkeiten mehr.

In einer der nächsten Überarbeitungen meines REDcms möchte ich diese Erweiterung des Abonnierens mit anbieten. Dass heißt das beim Anlegen und Ändern von Seite und Boxen die XML-Datei geändert werden muss. Dabei gibt es aber folgendes zu beachten. Was passiert wenn der Administrator des Systems eine Box von der Seite 1 in die Seite 2 verschiebt? Bekommen dann die Abonnenten die komplette Überarbeitung der XML-Datei zugeschickt?

Also gerade bei späteren Änderungen von abonnierten Informationen sollte ich mir genauere Gedanken machen. Vielleicht könnt ihr als Leser meines RSS-Feeds mir dabei helfen und ein paar Tipps im Kommentar hinterlassen.

Tag 21 – Erweiterung durch AJAX

Um den Bedienungskomfort der Seite zu verbessern, habe ich mir gedacht das die Administration am besten immer innerhalb eines Popups.

Also wenn man z.B. eine neue Seite hinzufügen möchte, sollte nicht eine neue Browser-Seite geladen werden, wie es zur Zeit der Fall ist, sondern besser wäre es wenn über die Thickbox-Erweiterung das Formular innerhalb einer darübergelegten Ebene angezeigt wird. Eigentlich könnte jede Modifikation am System damit erweitert werden. So auch eine Zwischenabfrage vor dem Löschen eines Menüpunktes, einer Box oder gar einer gesamten Seite – auch könnten verlinkte Bilder in dieser neuen Ebene angezeigt werden.

So schön dies klinkt, einen kleinen Nachteil hätte diese Erweiterung allerdings doch. Wenn JavaScript deaktiviert ist, könnte es zu Problemen kommen, da ja AJAX bekanntlich auf JavaScript aufbaut. Aus diesem Grund empfehle ich bewusst zur Zeit solche Erweiterungen nur im kontrollierten Rahmen anzuwenden. In meinem Fall wäre das der Administrationsbereich. Hier sollte JavaScript schon aus dem Grund aktiviert sein, um den Online-Editor zu benutzen. Im Frontend-Bereich wo jeder Besucher die Links benutzen möchte, ist es vielleicht zu viel verlangt.

Auch habe ich zur Zeit die Thickbox-Erweiterung nicht mit integriert, um die Übersichtlichkeit und damit die Verständlichkeit nicht zu gefärhden.

Tag 20 – CSS-Design

Heute möchte ich etwas über das verwendete Design schreiben. Da das Projekt Schulungszwecken dient, habe ich mich für ein recht einfaches Design entschieden. Auch muss ich zugeben bin ich nicht der wirkliche Kreative in diesem Bereich.

Screen-Design

Das Design besitzt den klassischen Aufbau eines 2spaltigen Layouts mit einem Kopfbereich und einer Fußzeile. So können alle wichtigen Informationen übersichtlich untergebracht werden.

+------------------------------------+
| Website-Titel                      |
| Slogan                             |
+---------------+--------------------+
| Seitentitel   | Sidebar            |
| Einführung    | +----------------+ |
| +-----------+ | | Navigation     | |
| | Box-Titel | | +----------------+ |
| | Box-Text  | | +----------------+ |
| +-----------+ | | Administration | |
|               | +----------------+ |
+---------------+--------------------+
| Copyright                          |
+------------------------------------+

Reset-Datei

Um die unterschiedlichen CSS-Werte der verschiedenen Browser besser in den Griff zu bekommen, wird als erstes eine Reset-Datei geladen die alle wichtigen Style-Angaben für mich vordefiniert.

  1. body, div, dl, dt, dl, ul, ol, li, h1, h2, h3, h4, h5, h6,
  2. pre, form, fieldset, input, p, blockoute, th, td {
  3. margin:0;
  4. padding:0;
  5. }
  6. h1, h2, h3, h4, h5, h6 {
  7. font-size:100%;
  8. }
  9. ol, ul {
  10. list-style:none;
  11. }
  12. adress, caption, cite, code, dfn, em, strong, th, var {
  13. font-style:normal;
  14. font-weight:normal;
  15. }
  16. table {
  17. border-collapse:collapse;
  18. border-spacing:0;
  19. font-size:100%;
  20. }
  21. fieldset, img {
  22. border:0;
  23. }
  24. caption, th, td {
  25. text-align:left;
  26. vertical-align: top;
  27. }
  28. q:before, q:after {
  29. content:;
  30. }

Bei umfangreicheren Designs im Webbereich hat sich weiterhin eingebürgert, dass man das Layout der Site vom Design getrennt behandelt. Auch ich habe zwei separate Datei („layout.css“ und „design.css“) dazu erstellt.

Layout-Datei

Als Erstes möchte ich das Layout erklären. Um die Website zu zentrieren, habe ich um den gesamten Inhaltsbereich eine „div“-Container erstellt. Somit kann ich alles gut mittig mit einer Breite von 720 Pixeln platzieren.

  1. body {
  2. margin: 0;
  3. padding: 0;
  4. text-align: center;
  5. }
  6. #page {
  7. width: 720px;
  8. margin: 0 auto;
  9. text-align: left;
  10. }

Die Überschriften innerhalb meines Kopfbereichen sind jetzt sehr nah am Rand weswegen ich ihnen etwas Abstand gegeben habe.

  1. #branbing {
  2. padding: 5px;
  3. }

Im Prinzip werde ich jedem „div“-Container diesen Abstand geben. Ich habe ihn bewusst in die Layout-Datei und nicht in die Design-Datei geschrieben, weil er die Breiten der „div“-Container beeinflusst.

Um die zwei Spalten zu platzieren, habe ich beide per „float“-Befehl angeordnet, ihnen Breiten und Abstände gegeben.

  1. #content {
  2. float: left;
  3. width: 500px;
  4. margin-right: 10px;
  5. padding: 5px;
  6. }
  7. #sidebar {
  8. float: left;
  9. width: 190px;
  10. padding: 5px;
  11. }

Damit der Fußbereich dann auch wieder unterhalb dieses Bereiches weiterläuft, habe ich auch ihn in der Layout-Datei ein paar Werte gegeben.

  1. #copyright {
  2. clear: both;
  3. padding: 5px;
  4. }

Zum Schluss habe ich noch den Inhalt der Administrationsbox layoutet. Dabei rücke ich den Code per Tab weiterein je tiefer die Verschachtelung ist.

  1. #content .adminBox {
  2. font-size: 0.8em;
  3. }
  4. #content .adminBox p {
  5. margin: 0;
  6. }
  7. #content .adminBox li {
  8. display: inline;
  9. }
  10. #content .adminBox li a {
  11. float: left;
  12. display: block;
  13. }

Design-Datei

Zur Zeit habe ich nur wenige design-technische Änderungen vorgenommen. Als erstes habe ich allgemeinen Definitionen erstellt.

  1. body {
  2. color: #FFF;
  3. background-color: #CCC;
  4. font: 14px/1.4em “Trebuchet MS”, Arial, Helvetica, sans-serif;
  5. }
  6. input:focus, textarea:focus, select:focus {
  7. color: #000;
  8. background: #fff;
  9. border: 1px solid red;
  10. }
Div-Page

Der „page“-Container bekommt zusätzlich noch eine kleine Überarbeitung.

  1. #page {
  2. color: #000;
  3. background-color: #FFF;
  4. }
Div-Branding

Da in meinem Fall der Kopfbereich nur Angaben über das Projekt enthalten soll besteht dieser nur aus zwei Überschriften.

  1. <div id="branding">
  2. 	<h1>RE-Design</h1>
  3. 	<h2>REDcms Advents</h2>
  4. </div>

In der CSS-Datei wird dann folgende Formatierung darauf angewendet:

  1. #branding {
  2. background-color: #333;
  3. color: #FFF;
  4. font-family: Georgia,”Time New Roman”, Times, serif;
  5. font-style: italic;
  6. }
  7. #branding h1 {
  8. font-size: 3em;
  9. line-height: 1em;
  10. }
  11. #branding h2 {
  12. font-size: 1.5em;
  13. line-height: 1em;
  14. color: #3C0;
  15. }
Div-Content

Als nächstes werden alle wichtigen Tags im „content“-Container definiert.

  1. #content h2, #content h3, #content h4, #content h5, #content h6 {
  2. font-family: Georgia,”Time New Roman”, Times, serif;
  3. font-style: italic;
  4. line-height: 1em;
  5. margin-bottom:0.5em;
  6. }
  7. #content h2 {
  8. font-size: 2em;
  9. }
  10. #content h3 {
  11. font-size: 1.4em;
  12. }
  13. #content h4 {
  14. font-size: 1.2em;
  15. }
  16. #content h5 {
  17. font-size: 1.1em;
  18. }
  19. #content h6 {
  20. font-size: 1em;
  21. }
  22. #content p {
  23. margin-bottom: 1em;
  24. text-align: justify;
  25. }

Zusätzlich werden noch die Listen der Metaangaben gestylt.

  1. #content ul.meta {
  2. font-size: 0.8em;
  3. }
  4. #content ul.meta li {
  5. margin-bottom: 0.5em;
  6. }

Auch die angezeigten Formulare sind nicht von der Überarbeitung durch das Design-CSS verschont geblieben.

  1. #content .add fieldset {
  2. border: 1px solid #333;
  3. padding: 5px;
  4. margin-bottom: 1em;
  5. }
  6. #content .add legend {
  7. border: 1px solid #333;
  8. background-color: #CCC;
  9. padding: 0 1em;
  10. }
  11. #content .add label {
  12. font-size: 0.8em;
  13. }
  14. #content .add label.before {
  15. display: block;
  16. }
  17. #content .add input,
  18. #content .add textarea {
  19. width: 470px;
  20. font-family: sans-serif;
  21. font-size: 1em;
  22. padding: 5px;
  23. }
  24. #content .add option:hover {
  25. background-color: #CCC;
  26. }
Div-Sidebar

Da in der Sidebar mehrere Boxen existieren können, habe ich als erstes grundlegende Einstellungen vorgenommen.

  1. #sidebar .box {
  2. border:1px solid;
  3. margin-bottom: 1em;
  4. }
  5. #sidebar .box h4 {
  6. background-color:#333;
  7. color: #FFF;
  8. text-align: center;
  9. margin-bottom: 0.2em;
  10. }

Für die Navigation gab es dann noch separate Einstellungen.

  1. #sidebar #navigation {
  2. }
  3. #sidebar #navigation ul {
  4. margin: 5px 5px 1em 5px;
  5. }
  6. #sidebar #navigation ul ul {
  7. margin: 0 0 0 1.5em;
  8. }

Ebenso für den Login bzw. das Logout und die Box „über mich“.

  1. #sidebar #login {
  2. }
  3. #sidebar #login p {
  4. font-size: 0.8em;
  5. margin: 5px;
  6. }
  7. #sidebar #login legend {
  8. font-style: italic;
  9. margin: 0;
  10. padding: 0;
  11. text-transform: uppercase;
  12. }
  13. #sidebar #login strong {
  14. font-weight: bold;
  15. text-transform: uppercase;
  16. }
  17. #sidebar #login ul {
  18. margin: 5px;
  19. }
  20. #sidebar #login a {
  21. padding-left: 20px;
  22. }
  23. #sidebar #login .page {
  24. background: transparent url(“/REDcms/templates/images/icons/page.png”) no-repeat;
  25. }
  26. #sidebar #login .box {
  27. background: transparent url(“/REDcms/templates/images/icons/box.png”) no-repeat;
  28. border: none;
  29. }
  30. #sidebar #login .menu {
  31. background: transparent url(“/REDcms/templates/images/icons/menu.png”) no-repeat;
  32. }
  33. #sidebar #about_us {
  34. }
  35. #sidebar #about_us p {
  36. font-size: 0.8em;
  37. margin: 5px;
  38. }
Div-Footer

Was noch fehlt, ist der Fußbereich. Hier sind nur die Farben geändert worden.

  1. #copyright {
  2. background-color: #333;
  3. color: #FFF;
  4. }
  5. #copyright a {
  6. color: #FFF;
  7. }
Div-Debug

Eine kleine Besonderheit habe ich meinen Debugging gegeben. Jedes mal wenn die allgemeine Funktioncode()“ aufrufe, erzeuge ich eine „div“-Container mit der Klasse „debug“.

  1. function code($msg, $code=HTML_CODE)
  2. {
  3. $msg = print_r($msg, true);
  4. if($code == HTML_CODE)
  5. {
  6. $msg = htmlentities($msg);
  7. }
  8. echo ‘<div class=”debug”><pre>’.$msg.‘</pre></div>’;
  9. }

Zusätzlich designe ich per CSS das dieser Container über allem anderen angezeigt werden soll. Somit sehen ich ihn immer.

  1. .debug {
  2. position:absolute;
  3. width: 300px;
  4. height: 400px;
  5. overflow: auto;
  6. text-align: left;
  7. padding: 5px;
  8. color: #FFF;
  9. background-color: #300;
  10. border: 1px solid #000;
  11. }

Print-Design

Eigentlich wollte ich eine spezielle Druckversion per CSS für die Ausgabe erstellen – doch leider fehlte mir dafür die Zeit. Da sie aber auch schon auf meiner ToDo-Liste steht, wird sie bestimmt im nächsten Release vorhanden sein.

Ich hoffe ihr habt Verständnis dafür.

Downloads

Tag 19 – Formulare

In vielen Artikeln in diesem Adventskalender habe ich schon über die verwendeten Formulare berichtet. Heute möchte ich mich diesen Formularen etwas genauer widmen.

Page-Formular

Als erstes möchte ich das „Page“-Formular beschreiben. Wie schon im Artikel über die „Page“-Klasse geschildert werden nicht viele Information, die sich in 2 Gruppen unterteilen, vom Benutzer verlangt.

Im Inhaltsbereich wird der Titel der Seite, der Name des Autors und der Einführungstext angegeben, wobei nur der Titel als Pflicht verlangt wird. Da der Einführungstext sehr umfangreich sein kann, habe ich mich hier entschlossen einen online WYSIWYG-Editor einzubinden.

In den 2. Teil des Formulars werden vom Benutzer Zusatzinformationen für die Seite abgefragt. Als erstes ist das der Dateiname des zu verwendenden Templates. Mit der Select-Box kann der Veröffentlichungszustand der Seite angegeben werden. Die letzte Angabe, das Berechtigungslevel, wird zwar zur Zeit noch nicht benötigt, weshalb der Wert Null ist, kann aber später für bestimmte Zugangsberechtigungen dienen. So können später die einzelnen Seiten über verschiedene Level vor nicht berechtigten Besuchern geschützt werden.

Menu-Formular

Ähnlich wie das „Page“-Formular braucht auch das „Menü“-Formular nicht wirklich viele Angaben. Im Gegensatz zum „Page“-Formular sind die Eingaben aber in 3 Bereiche untergliedert.

Im ersten werden Angaben über den Namen des Menüpunktes und seinen Titel, er ist optional, verlangt.

Im zweite Teil des Formulars werden die Verbindungsangaben benötigt. Da der Benutzer beim Anlegen einer neuen Seite nicht direkt mitangeben muss wie sie im System verlinkt ist, kann er dies nun nachholen. Auch ist es so möglich mehrere Menüpunkte auf eine Seite zu verlinken oder er kann Seiten anlegen, die gar nicht verlinkt sind, wie z.B. Fehlerseiten.

Der letzte Bereich ist, ähnlich wie bei dem „Page“-Formular, wieder mit den Meta-Angaben über den Menüpunkt bestückt.

Box-Formular

Das letzte Formular in diesem Artikel ist das „Box“-Formular. Es ist wohl das umfangreichste von den Drein. Auch hier sind die Angaben in 3 Bereiche unterteilt.

Der Inhaltsbereich verlangt wieder nach einem Titel und nach einem Einführungstext, wie beim „Page“-Formular. Zusätzlich kann aber optional auch noch ein weiterführender Text mit angegeben werden. So ist es später möglich Übersichtsseiten mit nur den Einführungstexten der Boxen zu erstellen und über einen Link zu den weiterführenden Informationen zu gelangen.

Da jede Box zu einer Seite zugewiesen werden muss, wird im zweiten Teil des Formulars nach der Seite für die Box gefragt.

Wie bei den beiden vorhergehenden Formularen werden auch hier, im dritten Teil des Formulars werden vom Benutzer Angaben über das zu verwendende Template, über den Veröffentlichungsstatus und dem Zugriffslevel verlangt.

Donwloads

Tag 18 – HTML-Vorlagen

Heute möchte ich etwas über die verwendeten Templates schreiben. Wie schon im Artikel über die Template“-Klasse geschrieben habe, setzt sich die Website aus verschiedenen Code-Schnipsel zusammen. Sie werden ineinander verschachtelt.

Index-Seite

In der Index-Seite steht das gesamte Grundgerüst. Neben dem allgemeinen Aufbau der HTML-Seite werden hier auch alle CSS-Dateien und JavaScript-Dateien geladen.

  1. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  2. <html xmlns=“http://www.w3.org/1999/xhtml” xml:lang=“de” lang=“de”>
  3. <head>
  4. <meta http-equiv=“Content-Type” content=“text/html; charset=utf-8″ />
  5. <title>##TITLEBAR##</title>
  6. <link rel=“stylesheet” href=“##BASEURL##/templates/styles/reset.css” />
  7. <link rel=“stylesheet” href=“##BASEURL##/templates/styles/layout.css” />
  8. <link rel=“stylesheet” href=“##BASEURL##/templates/styles/design.css” />
  9. <script type=“text/javascript” src=“##BASEURL##/templates/scripts/script.js”></script>
  10. <style type=“text/css”></style>
  11. </head>
  12. <body lang=“de” dir=“ltr”>
  13. <div id=“page”>
  14. <div id=“branding”>
  15. <h1>##WEBSITETITLE##</h1>
  16. <h2>##TAGLINE##</h2>
  17. </div>
  18. <div id=“main”>
  19. <div id=“content”>
  20. ##CONTENT##
  21. </div>
  22. <div id=“sidebar”>
  23. ##SIDEBAR##
  24. </div>
  25. </div>
  26. <div id=“copyright”>
  27. <p>&copy; 2008 &ndash; <a href=“http://www.re-design.de”>RE-Design</a></p>
  28. <ul class=“valid”>
  29. <li><a href=“http://validator.w3.org/check?uri=referer”><img src=“http://www.w3.org/Icons/valid-xhtml10″ alt=“Valid XHTML 1.0 Transitional” height=“31″ width=“88″ /></a></li>
  30. <li><a href=“http://jigsaw.w3.org/css-validator/”><img style=“border:0;width:88px;height:31px” src=“http://jigsaw.w3.org/css-validator/images/vcss” alt=“CSS ist valide!” /></a></li>
  31. </ul>
  32. </div>
  33. </div>
  34. </body>
  35. </html>

In dieser Datei gibt es eigentlich nur zwei Schlüsselworte die durch neue Schnipsel ersetzt werden: ##CONTENT## und ##SIDEBAR##. Die restlichen Schlüsselworte werden direkt in der Application“-Klasse mit Inhalt gefüllt.

Content-Bereich

Da der Content-Bereich sehr viele verschiedene Aufgaben erfüllen muss, gibt es auch sehr viele verschiedene Code-Schnipsel die an diesem Platz eingesetzt werden:

  • page.tpl.html
  • page.form.tpl.html
  • menu.form.tpl.html
  • box.form.tpl.html

Der wohl wichtigste Bereich in diesem System ist die „page.tpl.html“-Datei, weswegen ich sie hier auch näher mal beschreibe.

Page-Bereich

Der „Page“-Vorlage wird von der „Page“-Klasse benutzt und mit Inhalt gefüllt. Aber zusätzlich wird in der „Page“-Klasse auch die Inhalte für die einzelnen Boxen gesammelt. Deshalb wird das „##BOXES##“-Schlüsselwort nicht direkt von der „Page“-Klasse gefüllt.

  1. <div class=“page” id=“page_##ID##”>

  2. <h2>##TITLE## ##ADMIN##</h2>
  3. <ul class=“meta”>
  4. <li>##AUTHOR##</li>
  5. <li>##MODIFIED##</li>
  6. </ul>
  7. <div class=“teaser”>
  8. ##TEASER##
  9. </div>
  10. <div class=“boxes”>
  11. ##BOXES##
  12. </div>
  13. </div>

Box-Bereich

Wie gerade beschrieben, füllt die „Box“-Klasse die „Box“-Vorlage und gibt sie dann an die „Page“-Klasse weiter, die diese dann an den richtigen Platz innerhalb der „Page“-Vorlage einsetzt.

  1. <div class=“teaserbox” id=“box_##ID##”>
  2. <h3>##TITLE## ##ADMIN##</h3>
  3. <ul class=“meta”>
  4. <li>##MODIFIED##</li>
  5. </ul>
  6. <div class=“teaser”>##TEASER##</div>
  7. <div class=“body”>##BODY##</div>
  8. </div>

Sidebar-Bereich

Auch die „Sidebar“-Vorlage wird von eine Klasse benutzt. Allerdings gibt es hier keine eigene Klasse sondern es ist die gleiche wie schon bei der „Index“-Vorlage. Es ist die „Application“-Klasse.

  1. <h3>Sidebar</h3>
  2. <div class=“box” id=“navigation”>
  3. ##NAVIGATION##
  4. </div>
  5. <div class=“box” id=“login”>
  6. ##LOGIN##
  7. </div>
  8. <div class=“box” id=“about_us”>
  9. <h4>Über das Projekt</h4>
  10. <p>Die ist nur ein kleines CMS-Beispiel. Ich hoffe ihr habt Spaß dieses zu benutzen. Falls ihr Fehler findet dann schreibt eine Nachricht an: <a href=“mailto:enrico@re-design.de” class=“nowrap”>enrico@re-design.de</a></p>
  11. </div>

Die „Application“-Klasse füllt dabei 2 Schlüsselworte mit Inhalt. Auf der einen Seite (##NAVIGATION##) ist es die Menüstruktur und auf der anderen Seite (##LOGIN##) der Administrationskasten. Zusätzlich ist hier auch noch ein fester Kasten eingetragen. Er kann später entweder mit mehr, bzw. anderen Inhalt gefüllt oder gelöscht werden.

Downloads

Tag 17 – WYSIWYG-Editor

Ein „WYSIWYG“-Editor ist ein Bearbeitungswerkzeug für Texte. Da der sichtbare Text im Browser nicht unbedingt mit dem im Quellcode übereinstimmt, müsste der Redakteur im einfachsten Fall den Quellcode von Hand schreiben. Dies ist aber fast immer sehr umständlich und zeitaufwändig.

Deshalb haben Software-Programmierer Werkzeuge entwickelt in denen man relativ einfach seinen Text schreiben kann und über spezielle Buttons dann nach seinen Wünschen formatieren. Die Software übernimmt dann die Formatierung. Das macht das Arbeiten mit HTML-Quellcode recht simple. Trotzdem sollte man immer wissen was man tut. Schließlich herrschen im Internet ein paar andere Regeln als im alt geliebten Druck.

FCKeditor

Ich habe mich bei REDcms für den FCKeditor entschieden. Er ist sehr einfach an die speziellen Bedürfnisse anzupassen, bietet aber trotzdem einen sehr großen Funktionsumfang.

Der Editor wurde mit JavaScript umgesetzt und ersetzt ein Eingabefeld durch den im iframe befindlichen Editor. Das Einbinden kann über verschiedene Sprachen geschehen. In meinem Fall ist das PHP 5. Die Syntax zum Einbinden des Editors bzw. die Verwendung der „Editor“-Klasse sieht dann wie folgt aus:

  1. $teaser = new FCKeditor(‘teaser’);
  2. $teaser->Value = ‘<p>Anzuzeigender Text</p>’;
  3. $teaser->Create();

Der übergebene Parameter beim Instanziieren der „Editor“-Klasse ist die ID des „textarea“-Tags der ersetzt werden soll. Um den Editor an den Browser zu senden kann man benutzen. In meinem Fall benutze ich die „CreateHTML()“-Methode der „Editor“-Klasse, um sie individuell in mein System einzusetzen.

Konfiguration

Die Konfiguration des Editors ist recht simple, da fast alle wichtigen Einstellungen schon vorgegeben sind. Da ich aber in meinem Fall ein paar Änderungen bzw. Anpassung vornehmen wollte, habe ich die „FCKeditor“-Klasse mit meiner „Editor“-Klasse erweitert.

Der Editor geht als erstes davon aus im Stammverzeichnis der Domain abgespeichert zu sein. Da ich mein System aber flexibel halten wollte, habe ich die „BasePath“-Eigenschaft angepasst. Auch habe ich die „ToolbarSet“-Eigenschaft auf „REDcms“ geändert. So kann ich in der Konfigurationsdatei des Editors meine eigenen Menüleisten erstellen. Auch empfand ich die Höhe des Eingabebereiches als zu klein, weswegen ich die „Height“-Eigenschaft auf 400 Pixel gesetzt habe. Zum Schluss passte ich die Konfiguration selbst mit 3 Einstellungen noch ein wenig an. Als erstes habe ich den Pfad zur Konfigurationsdatei geändert. Dann die Spracheinstellung auf deutsch geändert und zum Schluss die Verwendung des „LinkBrowsers“ aktiviert.

  1. class Editor extends FCKeditor
  2. {
  3. function __construct( $instanceName )
  4. {
  5. parent::__construct( $instanceName );
  6. $this->BasePath = BASEURL.‘/fckeditor/’;
  7. $this->ToolbarSet = ‘REDcms’;
  8. $this->Config["CustomConfigurationsPath"] = BASEURL.“/templates/scripts/myEditorConfig.js”;
  9. $this->Config['DefaultLanguage'] = ‘de’;
  10. $this->Height = 400;
  11. $this->Config['LinkBrowser'] = true;
  12. }
  13. function __destruct(){}
  14. }

myEditorConfing.js

Alle weiteren Einstellungen für die Inbetriebnahme des Editors habe ich dann in die „myEditorConfig.js“-Datei ausgelagert. So kann auch später noch relativ schnell Anpassungen vorgenommen werden.

Als erstes habe ich, wie oben schon beschrieben, meine neuen Menüleisten konfiguriert.

  1. FCKConfig.ToolbarSets["REDcms"] = [

  2. ['Source','-','Templates'],
  3. ['Cut','Copy','Paste','PasteText','PasteWord','-','SpellCheck'],
  4. ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
  5. ‘/’,
  6. ['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
  7. ['OrderedList','UnorderedList','-','Outdent','Indent','Blockquote'],
  8. ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
  9. ['Link','Unlink','Anchor'],
  10. ['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak'],
  11. ‘/’,
  12. ['Style','FontFormat'],
  13. ['FitWindow','ShowBlocks','-','About'] // No comma for the last row.
  14. ] ;

Als nächstes habe ich die URLs des „LinkBrowser“ angepasst. Damit habe ich die Möglichkeit Links auf Dateien, wie z.B. Bilder, Flash-Dateien oder ähnliches, schnell und komfortabel zu regeln.

  1. FCKConfig.LinkBrowserURL = ‘/REDcms/ckfinder/ckfinder.html’;

  2. FCKConfig.ImageBrowserURL = ‘/REDcms/ckfinder/ckfinder.html?type=Images’;
  3. FCKConfig.FlashBrowserURL = ‘/REDcms/ckfinder/ckfinder.html?type=Flash’;
  4. FCKConfig.LinkUploadURL = ‘/REDcms/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files’;
  5. FCKConfig.ImageUploadURL = ‘/REDcms/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images’;
  6. FCKConfig.FlashUploadURL = ‘/REDcms/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash’;

CKfinder

Um aber auch den „LinkBrowser“ benutzen zu können, habe ich die Erweiterung „CKfinder“ des FCKeditor mit in mein System installiert. Sie erweitert den Editor um die Möglichkeit komfortabel Dateien die verlinkt werden sollen, zu managen. Die Erweiterung ist so eingestellt dass sie automatisch im Unterordner „userfiles“ des REDcms-System nach Dateien sucht. Auch hier gibt es eine Konfigurationsdatei „config.php“, aber die Anpassungen sind hier mit einer kleinen Änderung schnell erledigt. Geändert werden muss nämlich nur wieder einmal die „$baseUrl“.

  1. $baseUrl = ‘/REDcms/userfiles/’;

Leider konnte ich hier nicht mit meiner Konstanen „BASEURL“ arbeiten, da diese Datei separat aufgerufen wird und nicht direkt ins System eingebunden ist. Vielleicht werde ich später noch eine Routine dafür schreiben.

Downloads

Tag 16 – Zusatzklassen

So bald habe wir es geschafft alle Klassen zu beschreiben. Es fehlen jetzt nur noch 2 Hilfsklassen. Auf der einen Seite ist das die „Date“-Klasse und auf der anderen die „Editor“-Klasse.

Date Class

Als erstes nun die „Date“-Klasse. Sie hat im gesamten System die wohl kleinste Rolle, denn sie managt die Konvertierung von einer internationalen Schreibweise der Zeit (YYYY-MM-DD HH:MM:SS +00:00) in eine deutsche Schreibweise. Dabei unterscheide ich 2 verschiedene Ausgaben. Einmal ist das die Kurzschreibweise des Datums (DD. MM. YYYY) und dann noch die umfangreichere Schreibweise (Tag. Monatsname Jahr).

  1. class Date
  2. {
  3. static $formatShort;
  4. static $formatLong;
  5. static function setShortFormat($format)
  6. {
  7. self::$formatShort = $format;
  8. }
  9. static function setLongFormat($format)
  10. {
  11. self::$formatLong = $format;
  12. }
  13. static function getShortFormat($date)
  14. {
  15. $ts = strtotime($date);
  16. return strftime(self::$formatShort, $ts);
  17. }
  18. static function getLongFormat($date)
  19. {
  20. $ts = strtotime($date);
  21. return strftime(self::$formatLong, $ts);
  22. }
  23. }

Um die Darstellung des Formates schnell ändern zu können wird diese in der Konfiguration abgespeichert und kann dadurch jeder Zeit geändert werden.

  1. [Application]
  2. dateformatlong = “%d. %B %Y”
  3. dateformatshort = “%d. %m. %Y”

Ich habe mich bewusst hier für statische Methoden entschieden, um schneller auf die Konvertierungen zuzugreifen. So bekomme ich mit dem Befehl „Date::getLongFormat()“ und dem übergebenen Zeitstempel direkt die deutsche Schreibweise.

Editor Class

Um die Texte online besser editieren zu können habe ich mich für FCKeditor als WYSIWYG-Editor, also als Online-Editor entschieden. Dadurch wird den Redakteuren die Arbeit mit REDcms erleichtert. Wobei man nicht vergessen darf dass es nur ein Hilfsmittel ist. Die Kenntnisse über HTML wird trotzdem vorausgesetzt.

In der „Editor“-Klasse, die die „FCKeditor“-Klasse des Online-Editors erweitert, wird nur während der Instanziierung verschiedene Einstellungen schon mal mit geladen. Wie z.B. wo der Editor gespeichert ist, wo die Konfiguration zu finden ist, bzw. welche Sprache der Editor benutzen soll.

  1. class Editor extends FCKeditor
  2. {
  3. function __construct( $instanceName )
  4. {
  5. parent::__construct( $instanceName );
  6. $this->BasePath = BASEURL.‘/fckeditor/’;
  7. $this->ToolbarSet = ‘REDcms’;
  8. $this->Config["CustomConfigurationsPath"] = BASEURL.“/templates/scripts/myEditorConfig.js”;
  9. $this->Config['DefaultLanguage'] = ‘de’;
  10. $this->Height = 400;
  11. $this->Config['LinkBrowser'] = true;
  12. }
  13. function __destruct(){}
  14. }

Downloads

Tag 15 – Login Class

Nachdem ich gestern wiedermal eine sehr umfangreiche Klasse beschrieben habe, heute nun wieder etwas einfacheres – die „Login“-Klasse.

Sie regelt das An- und Abmelden am System. Um die angemeldeten User verwalten zu können, nutze ich Sessions. Deshalb wird im Konstruktor mit der „session_start()“-Funktion eine Verbindung zur Session aufgebaut.

  1. function __construct()
  2. {
  3. session_start();
  4. }

Nach einer erfolgreichen Anmeldung z.B. werden in einer Session-Variablen „$_SESSION['REDcms']“ die Werte des Benutzers abgespeichert. Das geschieht in der „checkLogin()“-Methode. Sie prüft ob innerhalb der globalen Variablen „$_POST“ die korrekten Angaben sich befinden, die in der Klasse selbst abgespeichert sind.

  1. public function checkLogin()
  2. {
  3. if($_POST['user'] == self::$user && $_POST['password'] == self::$password)
  4. {
  5. $_SESSION['REDcms'] = array();
  6. $_SESSION['REDcms']['user'] = $_POST['user'];
  7. $_SESSION['REDcms']['access'] = 0;
  8. }
  9. header(‘Location: ‘.$_POST['request']);
  10. exit();
  11. }

Natürlich gibt es auch die „logout()“-Methode, die die gespeicherten Werte aus der Session wieder löscht.

  1. public function logout()
  2. {
  3. $_SESSION['REDcms'] = array();
  4. unset($_SESSION['REDcms']);
  5. header(‘Location: ‘.$_POST['request']);
  6. exit();
  7. }

So kann über die „isLogged()“-Methode relativ einfach überprüft werden ob der Benutzer angemeldet ist oder nicht. Das ist besonders bei den Verarbeitungsmethoden der „Page“-, „Box“- und „Menu“-Klasse wichtig.

  1. public function isLogged()
  2. {
  3. if(isset($_SESSION['REDcms']) && $_SESSION['REDcms']['user'] == self::$user)
  4. {
  5. return true;
  6. }
  7. return false;
  8. }

Als letztes gibt es noch die „getAdminBox()“-Methode. Sie hat die Aufgabe bei nicht angemeldeten Benutzern das Anmelde-Formular, bzw. bei angemeldeten Benutzern eine zusätzliches Menü anzuzeigen.

  1. public function getAdminBox()
  2. {
  3. $content = ‘<h4>Administration</h4>’;
  4. $tpl = new Template(TEMPLATEPATH);
  5. if(empty($_SESSION['REDcms']))
  6. {
  7. $tpl->load(‘login.tpl.html’);
  8. $tpl->set(‘##URL##’, BASEURL.‘/login.php’);
  9. }
  10. else
  11. {
  12. $tpl->load(‘logout.tpl.html’);
  13. $tpl->set(‘##URL##’, BASEURL.‘/logout.php’);
  14. $tpl->set(‘##URLPAGE##’, BASEURL.‘/page/0/add’);
  15. $tpl->set(‘##URLBOX##’, BASEURL.‘/box/0/add’);
  16. $tpl->set(‘##URLMENU##’, BASEURL.‘/menu/0/add’);
  17. $tpl->set(‘##USERNAME##’, $_SESSION['REDcms']['user']);
  18. }
  19. if(isset($_SERVER['REDIRECT_URI']))
  20. {
  21. $tpl->set(‘##REQUEST##’, $_SERVER['REDIRECT_URL']);
  22. }
  23. else
  24. {
  25. $tpl->set(‘##REQUEST##’, BASEURL);
  26. }
  27. $content .= $tpl->get();
  28. return $content;
  29. }

Um die An- und Abmeldung relativ einfach zu machen, habe ich für jeden Prozess eine eigene PHP-Seite erstellt. Der Inhalt dieser Dateien ist sehr überschaubar.

  1. <?php
  2. error_reporting(E_ALL | E_WARNING);
  3. require_once ‘includes.php’;
  4. $login = new Login();
  5. $login->checkLogin();
  6. ?>
  1. <?php
  2. error_reporting(E_ALL | E_WARNING);
  3. require_once ‘includes.php’;
  4. $login = new Login();
  5. $login->logout();
  6. ?>

Zu einem späteren Zeitpunkt werde ich wahrscheinlich diese separaten Dateien mit in die „index.php“-Datei integrieren.

Downloads