Witryna NotH.gajdaw.pl stanowi wizytówkę programu NotH – bezpłatnego edytora plików HTML, XHTML i CSS. Na stronie znajdują się podstawowe informacje o programie, podręcznik, zestaw skrótów klawiszowych oraz pliki do pobrania. Całość jest wykonana w PHP przy użyciu szablonów Smarty oraz plików tekstowych.
Struktura funkcjonalna witryny
Witryna zawiera menu poziome, które odgrywa
rolę menu głównego. Ma ono cztery opcje:
O programie, Copyright, Autorzy
oraz Pobierz.
Menu pionowe, które znajduje się z lewej
strony, pełni rolę menu kontekstowego.
Zawarte w nim opcje są zależne od tego na
której stronie aktualnie się znajdujemy. Dwie
główne opcje menu pionowego pozwalają na
dotarcie do podręcznika użytkownika oraz zestawu skrótów klawiszowych.
Menu kontekstowe dostępne na stronach
podręcznika różni się od menu kontekstowego
stron prezentujących skróty. Na rysunku obok widać
menu kontekstowe, które jest wyświetlane na
podstronach wybieranych z menu głównego.
Po wybraniu opcji Podręcznik, opcja ta zostaje
rozwinięta. W menu kontekstowym pojawiają
się podopcje – poszczególne podstrony
podręcznika.
Poszczególne strony podręcznika użytkownika
są dostępne w menu kontekstowym, w spisie treści zawartym na stronie
głównej podręcznika oraz za pośrednictwem
hiperłączy do następnej, poprzedniej,
pierwszej lub ostatniej strony. Hiperłącza
do przewijania stron podręcznika są umieszczone
powyżej oraz poniżej treści podręcznika.
Strony ze skrótami klawiszowymi są dostępne
w menu kontekstowym, w spisie
treści oraz za pośrednictwem hiperłączy:
następna strona, poprzednia strona, pierwsza
strona i ostatnia strona. Hiperłącza te są umiejscowione
powyżej oraz poniżej tabeli skrótów.
Przyjazne adresy URL
Witryna stosuje przyjazne URL-e wykonane
przy użyciu modułu {stala}mod_rewrite{/stala}. Przestrzeń adresowa witryny, widoczna na zewnątrz,
składa się z:
- adresów .html,
- obrazów,
- plików do pobrania.
Obrazy oraz pliki do pobrania są udostępniane
jako statyczne pliki z folderów {stala}img/{/stala} oraz
download/.
Pliki .html są przekierowywane na skrypt
index.php z odpowiednimi parametrami. Dostępnymi
adresami są:
- menu główne (4 podstrony):
- o programie: index.html
- copyright: copyright.html
- autorzy: autorzy.html
- pobierz: pobierz.html
- podręcznik użytkownika (1+15 podstron):
- spis treści: pu-spis-tresci.html
- pierwsza strona: pu-01-wstawianie-kodu.html
- druga strona: pu-02-zdublowane-skroty.html
- …
- skróty klawiszowe (1+14 podstron):
- spis treści: skr-spis-tresci.html
- pierwsza strona: skr-01-struktura.html
- druga strona: skr-02-naglowki.html
- …
Łącznie witryna ma więc 35 podstron.
Adresy URL
Przyjazne adresy URL są mapowane na odwołania
do skryptu {stala}index.php{/stala}. Skrypt {stala}index.php{/stala}
stosuje dwie zmienne: id oraz id2. Zmienna
id adresuje podstrony menu głównego oraz
spis treści podręcznika użytkownika i spis treści
skrótów klawiszowych.
index.html ==> index.php?id=3
copyright.html ==> index.php?id=4
autorzy.html ==> index.php?id=5
pobierz.html ==> index.php?id=6
pu-spis-tresci.html ==> index.php?id=8
skr-spis-tresci.html ==> index.php?id=10
Podstrony podręcznika użytkownika stosują
zmienne id oraz id2. Pierwsza z nich przyjmuje
wartość 9, a druga – numer strony podręcznika,
np.:
pu-01-wstawianie-kodu.html ==> index.php?id=9&id2=1
pu-02-zdublowane-skroty.html ==> index.php?id=9&id2=2
pu-03-dostepnosc-skrotow.html ==> index.php?id=9&id2=3
...
Strony ze skrótami klawiszowymi również
stosują zmienne id oraz id2. Tym razem id
przyjmuje wartość 7, a id2 – numer wybranej
strony ze skrótami klawiszowymi:
skr-01-struktura.html ==> index.php?id=7&id2=1
skr-02-naglowki.html ==> index.php?id=7&id2=2
skr-03-tekst.html ==> index.php?id=7&id2=3
...
Dane
Wszystkie dane zawarte na podstronach serwisu
pochodzą z plików tekstowych.
Podstrony adresowane przy użyciu wyłącznie
zmiennej id (czyli podstrony menu
głównego oraz dwa spisy treści) są zapisane
w plikach:
- 2.txt (błąd 404)
- 3.txt (o programie)
- 4.txt (copyright)
- 5.txt (autorzy)
- 6.txt (pobierz)
- 8.txt (spis treści podręcznika użytkownika)
- 10.txt (spis treści skrótów klawiszowych)
Nazwa pliku odpowiada wartości zmiennej id.
Strony podręcznika użytkownika są zapisane
w plikach: u1.txt, u2.txt, u3.txt, …,u15.txt.
Zaś dane na temat skrótów klawiszowych
pochodzą z folderu skroty/:
- 1-struktura.txt
- 2-naglowki.txt
- 3-tekst.txt
- …
- 14-ogonki.txt
Tytuły podstron zawarte pomiędzy znacznikami
{html}
trzech plików: tytuly-a.txt, tytuly-u.txt
oraz tytuly-s.txt.
Plik tytuly-a.txt zawiera tytuły podstron
z menu głównego. W pliku tytuly-u.txt są zawarte
tytuły podstron podręcznika użytkownika.
Zaś plik tytuly-s.txt zawiera tytuły podstron
ze skrótami klawiszowymi.
Implementacja
Szablon XHTML/CSS
Pracę nad witryną rozpoczynamy od przygotowania
szablonu XHTML/CSS. Wykorzystany
szablon jest zmiennej szerokości (tj.
płynnie dostosowuje się do szerokości okna
przeglądarki). W szablonie wykorzystane są
sztuczki:
- udawane kolumny (ang. faux columns),
- ujemne marginesy (ang. negative margins),
- czyszczenie elementów pływających (ang. clearing floats),
- wysuwane tła (ang. sliding door).
Skrypt PHP
Skrypt PHP rozpoczynamy od ustalenia strony
domyślnej. Jest nią strona o numerze 2
(obsługa błędu 404). Potem sprawdzamy, czy
nie została odwiedzona strona {stala}index.php{/stala} bez
żadnej zmiennej (tj. czy {stala}empty($_GET{/stala}) zwraca
true). Jeśli tak, to ustalamy numer strony na
3 (strona główna – o programie):
$numer = 2;
if (empty($_GET)) {
$_GET[\'id\'] = \'3\';
}
Przechodzimy do walidacji zmiennej id.
Sprawdzamy, czy zmienna ta występuje oraz
czy jest poprawną liczbą całkowitą z zakresu
od 2 do 10:
if (isset($_GET[\'id\']) && str_ievpifr($_GET[\'id\'], 2, 10)) {
$numer = $_GET[\'id\'];
}
Następnie na stronach podręcznika użytkownika
(tj. wówczas, gdy id == 9) oraz na
stronach ze skrótami (tj. gdy id == 7) sprawdzamy
poprawność zmiennej id2. W przypadku
strony ze skrótami test przyjmuje postać:
if ($numer == 7) {
if (isset($_GET[\'id2\']) && str_ievpifr($_GET[\'id\'], 1, 14)) {
$numer2 = $_GET[\'id2\'];
$tytuly_url = string2VArray(file_get_contents(\'dane/tytuly-s.txt\'));
$s->assign(\'tytuly_url\', $tytuly_url);
}
} elseif ...
Głównym zadaniem wykonywanym podczas
walidacji zmiennej id2 jest ustalenie wartości zmiennej $numer2. Dodatkowo na podstawie
plików {stala}dane/tytuly-s.txt{/stala}, {stala}dane/tytuly-p{/stala}.
txt i dane/tytuly-a.txt ustalamy tytuły podstron.
Są one przekazane do szablonu Smarty
jako zmienna {stala}$tytuly_url{/stala}.
Po przeprowadzeniu walidacji na podstawie
zmiennej {stala}$numer{/stala} ustalamy zawartość strony.
Odczytujemy odpowiedni plik tekstowy do
zmiennej {stala}$dane{/stala}:
switch ($numer) {
case 2:
$dane = file_get_contents(\'dane/\'. $numer . \'.txt\');
break;
case 3:
$dane = file_get_contents(\'dane/\'. $numer . \'.txt\');
break;
...
}
Bardziej skomplikowanymi przypadkami są
strony podręcznika użytkownika oraz skrótów
klawiszowych. Tym razem należy odczytać odpowiedni
plik, przekazać go do szablonu oraz
ustalić numer następnej strony ({stala}numer2_p1{/stala}
przekazywane do szablonu) oraz numer poprzedniej
strony ({stala}numer2_m1{/stala}):
case 9:
$dane = file_get_contents(\'dane/u\' . $numer2 . \'.txt\');
$s->assign(\'numer2\', $numer2);
$s->assign(\'numer2_m1\', $numer2 - 1);
$s->assign(\'numer2_p1\', $numer2 + 1);
break;
Tabela skrótów klawiszowych jest wykonywana
funkcją {stala}NotHopis(){/stala}:
case 7:
$dane = NotHopis($numer2, \'\');
$s->assign(\'numer2\' $numer2);
$s->assign(\'numer2_m1\', $numer2 - 1);
$s->assign(\'numer2_p1\', $numer2 + 1);
break;
Na zakończenie przekazujemy do szablonu
zawartość strony (zmienna {stala}$dane{/stala}) oraz numer
wybranej podstrony:
$s->assign(\'strona\', $dane);
$s->assign(\'akcja\', $numer);
po czym przetwarzamy szablon wykonując
translacje adresów URL z postaci {stala}index.php{/stala}?… na .html:
$page = $s->fetch(\'index.tpl\');
$tmpOutputTranslations = file_get_contents(\'dane/output-translations.txt\');
list($w, $c, $translations) = string2VArray ($tmpOutputTranslations, \"\t\");
$page = str_replace($translations[0], $translations[1], $page);
Kod XHTML możemy poddać (w przeglądarce Firefox) walidacji wbudowanym parserem
XML:
/* walidacja XHTML */
header(\'Content-Type: application/xhtml+xml; charset=iso-8859-2\');
W przypadku strony błędu 404 należy wysłać odpowiedni nagłówek HTTP:
if ($numer == 2) {
header(\'HTTP/1.x 404 Not Found\');
}
Ostatnia instrukcja skryptu wyświetla wygenerowaną
stronę WWW:
echo $page;
Przyjazne URL-e
Obsługę przyjaznych URL-i wykonujemy przygotowując
plik {stala}.htaccess{/stala}. W pliku należy włączyć
moduł {stala}mod_rewrite{/stala}:
RewriteEngine on
oraz podać reguły mapowania adresów:
RewriteRule ^index\.html$ index.php?id=3 [L]
RewriteRule ^copyright\.html$ index.php?id=4 [L]
RewriteRule ^autorzy\.html$ index.php?id=5 [L]
...
Odczyt i krojenie plików tekstowych
Trzy pliki {stala}tytuly-a.txt, tytuly-u.txt{/stala} i {stala}tytuly-s.txt{/stala},
wykorzystane do generowania tytułów podstron,
plik {stala}output-translations.txt{/stala} użyty do translacji
adresów URL oraz pliki, na podstawie których
powstają tabele skrótów wymagają przetworzenia.
Każdy z tych plików stosuje jeden znak do
ustalenia podziału na kolumny. Na przykład
w pliku {stala}1-struktura.txt{/stala} zawarte są linijki:
B1|pusta strona utf-8 bez stylów|
B2|pusta strona utf-8 style wew.|
B3|pusta strona utf-8 style zew.|
...
Plik ten trzeba \”pokroić\” na dwuwymiarową
tablicę. Zadanie takie realizują dwie funkcje: {stala}string2VArray(){/stala} oraz {stala}string2HArray(){/stala}.
Pierwsza z nich zwraca liczbę wierszy, liczbę
kolumn oraz dwuwymiarową pokrojoną tablicę
\”pionową\” (tj. taką, w której pierwszy
indeks jest indeksem kolumny, a drugi – indeksem
wiersza). Po wywołaniu:
$p = file_get_contents(\'dane.txt\');
$pokrojony = string2VArray($p, \'@\');
zmienna $pokrojony zawiera:
$pokrojony[0] - liczba wierszy
$pokrojony[1] - liczba kolumn
$pokrojony[2] - dane
Na przykład {stala}$pokrojony[2][3][7]{/stala} jest elementem
z czwartej kolumny (indeks 3) oraz ósmego wiersza (indeks 7). Plik dane.txt został
pokrojony znakiem @.
Funkcja {stala}string2HArray(){/stala} zwraca liczbę wierszy
oraz dane. Po wywołaniu:
$p = file_get_contents(\'dane.txt\');
$pokrojony = string2HArray($p, \'#\'
zmienna {stala}$pokrojony{/stala} przyjmie wartości:
$pokrojony[0] - liczba wierszy
$pokrojony[1] - dane
Element {stala}$pokrojony[1][3][7]{/stala} znajduje się
w czwartym wierszu (indeks 3) i ósmej kolumnie
(indeks 7). Plik {stala}dane.txt{/stala} został pokrojony
znakiem #.
W przypadku braku drugiego argumentu
dane są krojone znakiem |.
Ochrona plików z danymi
Pliki z danymi (a więc wszystkie pliki tekstowe
oraz szablony) należy zabezpieczyć przed
dostępem z zewnątrz. Jeśli to możliwe, pliki
umieszczamy poza drzewem katalogów widocznym
w ramach usługi WWW. W przypadku
gdy folderem dostępnym poprzez WWW
jest {stala}public_html/{/stala}:
/home/gajdaw/public_html/
możemy witrynę umieścić w folderze:
/home/gajdaw/public_html/noth/
zaś pliki z danymi w folderze {stala}noth-dane/{/stala} (powyżej folderu public_html/):
/home/gajdaw/noth-dane/
Jeśli dostawca hostingu nie umożliwia
wyjścia powyżej folderu widocznego poprzez
WWW, do ochrony plików możemy wykorzystać
pliki {stala}.htaccess{/stala}. W folderze zawierającym
dane tekstowe należy umieścić plik {stala}.htaccess{/stala}
o zawartości:
Order allow,deny Deny from all