Webpuzzle [ Kirakni gyerekjáték ] - Moduláris webhelyépítés A-Z-ig

XHTML, CSS, PHP, MySQL, JavaScript, AJAX, jQuery, CMS rendszerek, webbiztonság. Programozás, letölthető példakódok, részletes esettanulmányok, összefogalók, segédletek, puskák lelkes amatőröknek...

Tanfolyamok:

40 órás webprogramozó II. tanfolyam Óbudán

40 órás webprogramozó II.

Első alkalom: 2011. november 27. 09:00
Helyszín:1033 Budapest, III. ker.
Óbuda Szérűskert utca 40.
Semper Studió Gimnázium (Kaszásdűlő)

Időpont: vasárnap 09.00-16.00

További részletek...

20 órás webgrafika tanfolyam Óbudán

20 órás webgrafika tanfolyam

Első alkalom: 2012. március 5. 17:30
Helyszín:1033 Budapest, III. ker.
Óbuda Szérűskert utca 40.
Semper Studió Gimnázium (Kaszásdűlő)

Időpont: hétfő 17.30-21.30

További részletek...

Könyvajánló:

Lynn Beighley, Michael Morrison
Agyhullám: PHP & MySQL

Lynn Beighley, Michael Morrison - Agyhullám: PHP & MySQL

Már ismertem a könyv eredeti angol verzióját, mégis nagy lelkesedéssel vártam a magyar változat megjelenését. Évek óta foglalkozom webfejlesztéssel és régóta tanítom is különböző iskolákban. Bátran állíthatom, hogy ez a könyv jelenleg a legérdekesebb, legszórakoztatóbb és legszínvonalasabb könyv ebben a témában, amit jelenleg Magyarországon meg lehet vásárolni. Tartalom alapú, CSS stíluslapokkal formázott, szemantikus honlapszerkesztésre támaszkodva - hasznos (működő) és jó példákat mutat be, szórakoztató stílusban. Munkafüzet jellege segít jobban elsajátítani a leckéket. További erősségének tartom még, hogy kitér a webes biztonság témakörére is. Mindenkinek nagy szeretettel ajánlom, aki PHP-t és MySQL-t szeretne tanulni. Már alig várom a sorozat további köteteit, főként egy jó Objektum Orientált Programozásról szóló könyvet.

További részletek...

Virginia Debolt: HTML & CSS
Webszerkesztés stílusosan

Virginia Debolt: XHTML & CSS - Webszerkesztés stílusosan

Ajánljuk mindenkinek, aki szeretne eleve szabványos webtervezési módszereket megtanulni, aki a hatékonyság érdekében nem riad vissza némi programozástól, aki már ismeri a HTML-t és talán kicsit a CSS-t is, de szeretné elmélyíteni, illetve rendszerezni a tudását, de annak is, aki soha, egyetlen weblapot sem készített még, de könnyen, és gyorsan szeretné a szükséges tudást elsajátítani.

További részletek...

Esettanulmányok

Statikus tartalomkezelő rendszer készítése

Egy megrendelő olyan weblapot szeretne készíttetni velünk, ahol pár menüpontban be tudná mutatni cégét. Szokásos tartalmakra gondolt, mint: bemutatkozás, termékek, szolgáltatások, referenciák, kapcsolat. Konkrét elképzelése nincs a megjelenésről, ránk bízta. Csak statikus információkat szeretne szerepeltetni az oldalon, viszont szeretne hozzá olyan felületet, amin keresztül saját maga, különösebb informatikai tudás nélkül is egyszerűen tudja szerkeszteni majd az oldalát, esetleg később bővítené pár új menüponttal.

Esetfelvetés

Gyakran keresnek meg ilyen jellegű kérésekkel kis vállalkozások, magánszemélyek, barátok... Sok esetben elegendő mindez kis weboldalaknál, ahol csak információkat kell megjelenítenünk és nincs szükség extra dinamikus elemekre. A nehézség csupán az, hogy a megbízó adminisztrációs felületet is szeretne magának, amivel a kezdők - akik csak most ismerkednek a webprogramozással - nem rendelkeznek elég rutinnal, vagy tapasztalattal. Nos, ez a cikk leginkább nekik szól.

Hogyan is fogjunk hozzá?

A legegyszerűbb lenne, ha letöltenénk egy ingyenes (CMS) tartalomkezelő rendszert, telepítenénk, testre szabnánk és kész. Lehetőségek vannak, könnyű rájönni a használatukra is (lásd: WordPress, Drupal, Joomla, Frog, Pluck stb.)... Mi viszont szeretnénk egy saját rendszert megírni, és ezen keresztül megtanulni, hogy mi is rejtőzik egy ilyen rendszer mögött? Csapjunk bele!

A statikus oldal elkészítése

Oldalszerkezet

Készítsünk papíron vázlatokat, hogy pontosan mit is szeretnénk. Rajzoljunk magunknak látványterveket. Ha úgy érezzük, hogy megvan az elképzelés, akkor lássunk neki a megvalósításnak. Az első dolog a statikus XHTML oldal kialakítása. Megtervezzük az oldalstruktúrát, ami tisztán tartalmi elemeket tartalmaz csak (itt a későbbi megjelenéssel még nem foglalkozunk). Általában fejléc, menüsor, tartalom és lábléc a leggyakoribb szerkezeti egységek. Ez alapján elkészítjük az oldal gerincét:

<div id="befoglalo">
<div id="fejlec"></div>
<div id="menu"></div>
<div id="tartalom"></div>
<div id="lablec"></div>
</div>

Az XHTML tartalom

Kiegészítjük a szabványos weboldalnál alkalmazott kötelező elemekkel, mint a <!DOCTYPE>, <html>, <head>, <body> és <title> címkék, valamint a böngészőknek és keresőknek szóló <meta> tagokkal. Használjunk most iso-8859-2 kódolást. A <title> az egyik legfontosabb kereső szó, ezért érdemes megfelelően kitölteni. A leírás szintén fontos lehet a keresőknél, bár a kulcsszavak megadása egyre kevesebb hangsúlyt kap. Több <meta> elemet is használok később a kódban, működés szempontjából ezek nem fontosak, ezekre most nem térek ki. A tartalom és megjelenés teljes mértékű szétválasztására természetesen külső stíluslapot illesztek a fejrészbe.

Az oldal 0. megjelenés

A dokumentum törzsének megírása következik most. A fejlécbe bekerül a legfontosabb <h1> címsor. Ez szintén nagyon fontos keresőszó! Ha háttérképet használunk a későbbiekben, akkor is fontos, hogy szerepeljen ez a címsor, legfeljebb eltüntetjük majd a megjelenésnél. A menüpontokat listadobozba tesszük, és próba linkekkel látjuk el (<a href="#">). A tartalom rész következik ezután. Ezt szemantikusan (azzal jelöljük az elemeket, amire valók) formázzuk. Használjunk bátran címsorokat, mert ezeket szintén szeretik a keresők és a "régi iskola" képviselői amúgy is gyakran méltatlanul mellőzték ezeket. Ha nem kapunk forrásszöveget a megrendelőtől vagy csak egy sablon rendszert szeretnénk készíteni, akkor használjunk a klasszikus kamu latin szöveget a Lorem ipsum...-ot (www.lipsum.com). A struktúra könnyű átláthatósága kedvében használjunk a kód begépelésénél tabulátorokat. Mentsük el az elkészült fájlt mycms.html néven. Ezzel készen is vagyunk a statikus tartalom megírásával, jöhet a megjelenés.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="hu" xml:lang="hu">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<title>MyCMS - Tartalomkezelő rendszer</title>
<meta name="Description" content="Ide kerül majd a weboldal pármondatos bemutatkozó szövege" />
<meta name="Keywords" content="kulcszó 1, kulcsszó 2, kulcsó 3, ... kulcszó 25" />
<meta name="Author" content="Készítő neve" />
<meta name="Publisher" content="Szerkesztő neve" />
<meta name="Copyright" content="Védjegy" />
<meta name="Distributor" content="Global" />
<meta name="Rating" content="General" />
<meta name="Robots" content="Index, follow" />
<meta name="Revisit-After" content="30 days" />
<link href="mycms.css" rel="stylesheet" type="text/css" />
<link type="image/x-icon" href="index/favicon.png" rel="icon"/>
<link type="image/x-icon" href="index/favicon.png" rel="shortcut icon"/>
</head>

<body>
<div id="befoglalo">
<div id="fejlec">
<h1>MyCMS - Tartalomkezelő rendszer</h1>
</div>

<div id="menu">
<ul>
<li><a href="#">Bemutatkozás</a></li>
<li><a href="#">Termékek</a></li>
<li><a href="#">Szolgáltatások</a></li>
<li><a href="#">Referenciák</a></li>
<li><a href="#">Kapcsolat</a></li>
</ul>
</div>

<div id="tartalom">
<h2>Bemutatkozás</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a sagittis turpis. Praesent sit amet nibh a justo placerat varius et ut orci. Sed vulputate nisl quis eros cursus a consequat nisl volutpat. Etiam nulla turpis, accumsan et tincidunt id, lobortis a nunc. Quisque dictum hendrerit feugiat. Fusce lobortis lectus vitae augue blandit viverra at at mauris. Nulla lobortis orci eros, in pulvinar erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi tempor sodales venenatis. Nunc pulvinar placerat urna, vitae pellentesque orci mattis a. Donec felis orci, lacinia eu fermentum ut, dapibus ut ante. Pellentesque egestas, mi vitae aliquet varius, metus sapien commodo nunc, vel adipiscing augue nunc et felis.</p>
<p>Utolsó frissítés: 2010-07-27 10:00:00</p>
</div>

<div id="lablec">
<p>&copy; 2010 MyCMS - Minden jog fenntartva!</p>
</div>
</div>
</body>
</html>

Kattints ide a letölthető xhtml kódért

A CSS stíluslap

A CSS stíluslapot célszerű úgy írni, hogy először felveszem az elem, majd azonosító és végül a csoportkijelölőket, pont abban a sorrendben, ahogy az XHTML lapon megadtam, mintha egy A/4-es oldalt felülről lefelé olvasnék (ez a természetes szövegfolyam). Mivel a megjelenés nem a legfontosabb szempont a megrendelő esetében, ezért erre most nem fektetek itt komoly hangsúlyt.

body {}
#befoglalo {}
#fejlec {}
#menu {}
#tartalom {}
#lablec {}
.tiszta {}

Az elkészült statikus oldal

Pár szempont: Fix oldalszélesség, középre rendezett megjelenéssel. Szöveges fejléc, mely később könnyen kicserélhető grafikusra. Függőleges menüsor, így tetszőlegesen bővíthető majd, és nem nyomja szét a dizájnt, ha túl sok lesz a menüpont. Néhány szín használata, ami bármikor saját színekre cserélhető. Röviden ennyi. Mentsük el az elkészült fájlt mycms.css néven. Kísérletezz szabadon, készíts magadnak másfajta megjelenést is. Ne feledd a tartalom alapú webfejlesztés esetén egy tartalomhoz bármennyi megjelenés készíthető (Lásd: www.csszengarden.com).

body {
margin:0;
text-align:center;
font-family:Tahoma;
background-color:#999;
/* background-repeat:repeat;
background-image:url(tapeta.jpg); */
}
#befoglalo {
width:770px;
text-align:left;
margin:20px auto;
background-color:#EEE;
border:solid 10px #FFF;
}
#fejlec {
height:100px;
background-color:#F00;
/* background-repeat:no-repeat;
background-image:url(fejlec.jpg); */
border-bottom:solid 10px #FFF;
}
#fejlec h1 {
margin:0;
font-size:24px;
padding-top:35px;
text-align:center;
}
#menu {
float:left;
width:160px;
font-size:14px;
}
#menu h2 {
font-size:18px;
margin-top:20px;
margin-left:20px;
padding-left:20px;
border-bottom:solid 1px #F00;
}
#menu a {
color:#000;
text-decoration:none;
}
#menu a:hover {
color:#F00;
}
#tartalom {
margin:20px 20px 20px 180px;
}
#tartalom h2 {
font-size:18px;
border-bottom:solid 1px #F00;
}
#tartalom h3 {
font-size:16px;
}
#tartalom h4 {
font-size:14px;
}
#tartalom p {
font-size:13px;
text-align:justify;
}
#tartalom a {
color:#F00;
text-decoration:none;
}
#tartalom a:hover {
color:#000;
}
#lablec {
clear:both;
text-align:center;
background-color:#666;
border-top:solid 10px #FFF;
}
#lablec p {
margin:0;
padding:10px;
font-size:14px;
color:#FFF;
}
.tiszta {
clear:left;
}

Kattints ide a letölthető css kódért

Lehetőségek

Így elkészült egy tökéletes, érvényes kódú tartalmi oldalunk és a hozzá tartozó stíluslap. Ha megelégednénk a statikus verzióval, akkor most az következne, hogy a menüben található próba linkeket (#) valódira (bemutatkozas.html, termekeink.html, szolgaltatasink.html, referenciak.html, kapcsolat.html) cserélnénk a tartalmi oldalban. A lábléc alá beszúrnánk egy Google Analytics (ingyenes oldalstatisztika: www.google.hu/analytics) mérőkódot, hogy láthassuk mennyien látogatják az oldalunk. A weboldalt elmentenénk annyi fájlnéven, amennyi aloldalt szeretnénk a honlapunknál, ezekben kicserélnénk csak a tartalmi részeket. Ha szeretnénk színesebbé tenni, akkor a tartalomba képeket is szúrhatunk. A stíluslapon esetleg átírnánk a fejléc mostani megjelenését, a színeket, hátteret készíthetnénk (www.bgpatterns.com), faviconnal (www.favicon.hu) látnánk el és kész. Mehet a feltöltés.

A dinamikus átalakítás

Szép-szép az eddig elkészült holmi, mi viszont ezzel még nem elégszünk itt meg. Átalakítjuk az oldalunk dinamikussá, hogy ne csak magunkfajta informatika iránt érdeklődők tudjuk az oldalt szerkeszteni, hanem azok is, akiknek közük se volt eddig hozzá. Készítsünk egy olyan egyszerű szerkesztő felületetet az oldalhoz, amit 10 perc alatt bárkinek meg tudunk tanítani. A megoldáshoz PHP programnyelvet fogunk használni és MySQL adatbázisban fogjuk az oldal tartalmát eltárolni.

Adatbázis tervezés

A következő lépés az adatbázis megtervezése. Itt pontosan ki kell találnunk, hogy mennyi és milyen típusú adatot fogunk tárolni. Ez az a rész mikor alaposan el kell gondolkodnunk arról, hogy mekkora mennyiségű adattal találkozunk a weblap pályafutása során. Nem érdemes se túl, se alábecsülni sem, mert lehet, hogy később meg lesz ennek a böjtje. Kényelmetlen lesz ennek későbbi megváltoztatása, vagy nem kívánt adatvesztés léphet fel. Szerencsére mivel ez csupán egy táblát használó alkalmazás, annyira egyszerű, hogy nem okozhat túl nagy fejfájást. Beszéljük először az adatbázis-struktúráról!

Localhost - Helyi fejlesztőkörnyezet

Mire is van szükségünk?

id: TINYINT NOT NULL UNSIGNED PRIMARY KEY
Hogy egyértelműen ki tudjunk választani egy aloldalt szükség van egy egyedi azonosítóra, vagyis elsődleges kulcsra is. Ezt tradicionálisan nevezzük "id"-nak, ami egy kis egész szám (viszonylag kisszámú aloldal miatt), előjel nélkül (negatív aloldal azonosítónak nincs értelme) és magától növeli a sorszámát (hogy ne kelljen fejbe tartani, hogy mi volt az előző).

Egyébként azért érdemes egész számot használni egyedi azonosítóként, mert nem léphetnek fel szám esetében karakterkódolási hibák, a megadási mód inkognitót biztosít az őket reprezentáló adatoknak és a legrövidebb lejegyzési forma.

sorrend: TINYINT NOT NULL UNSIGNED
Nem biztos, hogy a menüpontokat abban a sorrendben kell szerepeltetni, ahogy felvittük, vagy nem használhatunk abc sorrendet, tehát szükségünk van egy sorrendre is. Ez hasonló, mint az id esetében használtuk, tehát kis egész előjel nélküli szám

menunev: VARCHAR (32) NOT NULL
Egy viszonylag rövid szöveg, maximum 32 karakter.

tartalom: TEXT NULL
Erről nincsenek előre információink, mert lehet ez akár egy mondat is, de lehet egy egész regény is, ezért dinamikus viszonylag nagy szöveges típust választunk, ebbe maximum 65 536 karakter fér bele. Itt megengedhető a NULL érték is, mert lehet hogy első körben nem kerül bele tartalom, csak üres menüpontot veszünk fel.

datum: DATETIME NOT NULL [ÉÉÉÉ-HH-NN ÓÓ:PP:MM]
Ha szükség van az oldalon, kiírhatjuk a legutolsó módosítás dátumát is (ez opcionális). A leggyakrabban pontos dátumot és időpontot szokták megadni.

statusz: VARCHAR (16) NOT NULL
Ha szükséges ki tudjuk kapcsolni az oldal megjelenését, láthatóságát - ha nincs teljesen kész, vagy éppen karbantartás alatt van vagy jelen pillanatban nem aktuális. Később akár beállíthatjuk itt pl.: a regisztrált felhasználóknak szóló oldalakat is.

Ezzel megterveztük az adatbázis struktúráját. Lépjünk a tettek mezejére és készítsük el az adatbázist és a táblákat. Lépjünk be localhost-on keresztül a phpMyAdmin grafikus adatbázis-kezelőbe és adjuk meg az adatbázis nevét. Hívjuk az adatbázist mycms-nek. Majd hozzunk létre ebben egy új táblát statikus_tartalom-nak. Adjuk meg a mező neveket és típusokat, majd hagyjuk jóvá. Aki a szöveges SQL-t jobban kedveli annak itt mellékelem az SQL kérést is.

Adatbázistábla elkészítése

CREATE DATABASE mycms
CREATE TABLE statikus_tartalom (
id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
sorrend TINYINT UNSIGNED NOT NULL,
menunev VARCHAR(32) NOT NULL,
tartalom TEXT NULL,
datum DATETIME NOT NULL,
statusz VARCHAR(16) NOT NULL
) ENGINE = MYISAM;

Mintaadatok feltöltése

Ha ezzel sikeresen végeztünk, vigyük fel legalább 2 aloldal tartalmát. Fontos itt megjegyezni, hogy az id-t hagyjuk üresen, mert automatikusan sorszámozódik. A sorszámot úgy adjuk meg, ahogy a menüpontok sorrendjét szeretnénk látni. A tartalom XHTML-ben legyen feltöltve, ezt a későbbiekben megoldjuk, hogy az oldal szerkesztője egyszerű word-szerű szövegnek lássa. Azért szükséges az XHTML szöveg, hogy bármilyen elemet el tudjunk helyezni a tartalomban, pl.: címsorok, listák, képek, linkek, táblázatok, stb. A státusz legyen mindenhol "aktív". A mintaoldalak beszúrásához itt is adok egy kis segítséget. Ha phpMyAdmin-t használsz, csak másold be az SQL fül alatti dobozba. Ha nem grafikus felületet használsz, akkor tudod, hogy mi a dolgod!

Adatbázistábla feltöltve minta adatokkal

Kattints ide a letölthető sql kódért

FrontEnd oldal kialakítása

A folytatásban elkészítjük azt az oldalt, amivel a látogató találkozik, vagyis a BackEnd-et. Ez az oldal adatbázisból táplálkozik már, teljesen profin működik, viszont még nem rendelkezik a BackEnd-el, tehát az adminisztrátori felülettel. Olyan, mint egy hollywoodi díszlet, ahol a papírfal mögött nincs semmi, de a weboldal már így is tökéletes, de még nem nélkülözi az oldal karbantartójának szakértelmét. A tartalomfrissítést is még csak az adatbázison keresztül tudja elvégezni. De elég legyen a szócséplésből, folytassuk!

Adatbázis kiolvasása

Nyissuk meg a már elkészített mycms.html nevű fájlunkat, ezt fogjuk kissé átalakítani. Nevezzük át index.php-nek, hogy automatikusan induljon a fájl, ha megnyitjuk az oldalt. A most készülő kódot az oldal legtetejére fogjuk elkészíteni, hogy teljesen különválasszuk az oldal PHP kódját, a már megírt statikus tartalomtól. Itt összegyűjtjük változókban a későbbiekben kiírandó tartalmakat (pufferelés) és majd beillesztjük a megfelelő helyekre.

Többek között elejét vehetjük azoknak a gyakori hibáknak, amit kezdő programozók oly gyakran elkövetnek, a "kétszer elküldött fejrész" problémájának. Abban az esetben, ha egyetlen karaktert kiírsz a böngészőbe, majd ezután átirányítod az oldalt valahova header("location:...") függvénnyel, akkor hibát kapsz. Az ob_start(), ob_end_flush()-t nem ajánlom, mert kifagyaszthatja az Apache szervert!

Adatbázis-kapcsolat létrehozása

Elsőként létre kell hozni az adatbázis kapcsolatot. Megadjuk a szükséges paramétereket: kiszolgáló, felhasználónév, jelszó, adatbázisnév. A jelszó az esetetek majdnem 100%-ában localhost, az a felhasználónév és jelszó, amit a MySQL telepítésénél megadtál vagy amit a szolgáltatótól kaptál. Ez helyi fejlesztőkörnyezetben root: admin páros szokott lenni. Valós környezetben viszont biztos, hogy más, mert ez lenne a legelső próbálkozás, amivel egy hacker azonnal feltörné az adatbázisod. Az adatbázisnévnek a mycms-t választottuk előbb. A mysql_connect() csatlakozik az adatbázishoz, a mysql_select_db() kiválasztja az aktuális adatbázist, amivel dolgozunk. A die() függvény opcionális, hiba esetén kiírja a benne szereplő üzenetet.

Ha egy függvény elé "@" jelet írunk, akkor a hibaüzeneteket tilthatjuk le vele!

A mysql_query() lefuttatja az összeállított adatbázis lekérdezéseket. A SET NAMES latin2 beállítja a magyar ékezeteket, amire leginkább a "ő" és "ű" hungarikum betűink a legérzékenyebbek. Tesztelhetünk az "árvíztűrő tükörfúrógéppel" is (ebben a szóban szerepel az összes magyar ékezetes karakter). Szabványos esetben az adatbázisból műveletek az adatbázis lezárásával fejeződnek be: mysql_close() a végén, ha ez nem történik meg a kapcsolat meghatározott idő elteltével magától is megszakad. Biztonsági szempontból előnyősebb, ha az adatbázis kapcsolat csak a lekérdezés idejére (pár ezredmásodperc) van felépítve.

<?php
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "admin";
$dbName = "mycms";
$dbConn = mysql_connect($dbHost, $dbUser, $dbPass) or die("Sikertelen csatlakozás az adatbázishoz!");
mysql_select_db($dbName, $dbConn) or die("Sikertelen adatbázis megnyitás!");
mysql_query("SET NAMES latin2");

Menü elkészítése

Olvassuk ki sorba rendezve az adatbázisból azoknak az egyedi azonosítót és azoknak az almenüpontoknak a neveit, amik láthatók, tehát a státuszuk "aktív". Futtassuk le az összeállított SQL kérést a mysql_query() paranccsal és az eredményt tegyük az $eredmeny nevű változóba. Ezt követően az eredményből készítsünk sorokat, vagyis asszociatív (címkével ellátott) tömböket: mysql_fetch_assoc() segítségével. Mivel több almenünk van ezért szükségünk lesz a while() ciklusra, amíg addig olvassa az adatbázis sorait, amíg az összeset fel nem dolgozza A cikluson belül összeállítjuk a menü lista elemeit és ezeket $menu elnevezésű gyűjtőváltozóba teszem. Fontos itt a hozzáfűzés operátor (.), hogy ne csak az utolsó menüpont látsszon! :) Ha alaposabban megfigyeljük a listaelemekben hivatkozások is szerepelnek. Ha egy adott menüpontra kattintunk, akkor az URL paraméterként átadja a saját id értékét (vagyis pontosan azonosítja majd, hogy melyik adatbázis sor tartalmát kell beilleszteni majd az oldal tartalmi részébe).

$sql = "SELECT id, menunev FROM statikus_tartalom WHERE statusz = 'aktiv' ORDER BY sorszam ASC";
$eredmeny = mysql_query($sql);
while ($sor = mysql_fetch_assoc($eredmeny)) {
$menu .= "<li><a href=\"?id=".$sor['id']."\">".$sor['menunev']."</a></li>\n";
}

A hivatkozásoknál találunk \" (védőkarakterrel ellátott idézőjel), ami elsőre nagyon zavaró lehet, de arra szolgál, hogy egy adott php kódban szereplő szövegnél a program ne keverje össze a sztring kezdete-vége jelet egy szövegben kiírandó idézőjellel, tehát ezeket a szövegben szereplő idézőjeleket mindig védő (\) karakterekkel kell ellátni. Ez elsőre borzalmas, de hamar hozzászokik a szemünk.

Lehetséges az aposztrófok és időző jelek kevert használata a kezdeti sikeresebb kódírás miatt, de hosszútávon nem ajánlom, mert kevésbé lesz stílusos és átlátható a kódunk.

A sorok végén szereplő "\n" vezérlő karakter a generált forráskódokban új sorokat készít, hogy igényes és szép kódunk legyen! Nem lesz hosszú összefüggő, egybeömlesztett kód, amit sok forráskódban láthatunk. Használata nem kötelező. A tabulátorok szintén a struktúra nyomon követésére, átláthatóságra szolgálnak.

Azért nem * (minden oszlopot) kérdezek le az SQL parancsban, mert ha nagyobb oldal tartalom is belekerül a lekért adatokba, akkor lassabb lesz a lekérdezés, igaz ez csak ezredmásodpercben mérhető :), de legyünk már rendesek.

A tartalom összeállítása

Az URL-ben átadott id alapján meghatározzuk, hogy milyen tartalmat kell lekérdezni. Ezt $_GET-es paraméterátadásnak hívják. Ez működés közben valahogy így néz ki: index.php?id=1. Ez a címsorban és a státuszsorban tetten érhető. Amennyiben először töltődik be az oldal még nincs átadott paraméter, mert ezt csak a menüpontra való kattintáskor adódhat át, így gondoskodnunk kell egy kezdeti default értékről pl. id=1, ami az adatbázis első sora. Ezt egy ternáris operátorral oldottam meg: (feltétel) ? ha igaz : ha hamis, ami nagy kedvencem és kódjaimban gyakran alkalmazom. Ez egy nagyon tömör if-else leírási mód. Így vagy alapból az első oldal, vagy a kívánt azonosítóval rendelkező oldal fog lehívódni az adatbázisból. Ha ez megvan, akkor jöhet az SQL kérés összeállítása, ahol lekérem az elkapott id azonosítóval rendelkező sort. Ezt ugyanúgy, ahogy az imént egy $eredmeny változóba begyűjtöm és $sor-t, vagyis egy asszociatív tömböt készítek belőle. Mivel csak egy sor az eredmény, ezért nincs szükség while() ciklusra. A tartalmi kimenetet itt is puffer változóba gyűjtöm. Ezzel kész is a programozási részünk, csak az eredményt kell a megfelelő helyre kitennünk, kiíratnunk. Keressük ki az XHTML részben a menüpontok listaelemeit és szúrjuk be ezek helyére az összeállított menü puffer változót a print() függvény segítségével. A tartalmi részt a kiürített tartalom <div> elembe helyezzük el! Ezzel el is készültünk. Próbáljuk ki a működő FrontEndet és örüljünk munkánk gyümölcsének!

$id = (isset($_GET['id'])) ? $_GET['id'] : 1;
$sql = "SELECT menunev, tartalom, datum FROM statikus_tartalom WHERE id = ".$id;
$eredmeny = mysql_query($sql);
$sor = mysql_fetch_assoc($eredmeny);

$tartalom = "<h2>".$sor['menunev']."</h2>\n";
$tartalom .= $sor['tartalom']."\n";
$tartalom .= "<p>Utolsó frissítés: ".$sor['datum']."</p>\n\n";

XHTML kód kicserélése PHP pufferelt változók tartalmára

<div id="menu">
<ul>
<?php print $menu; ?>
</ul>
</div>
...
<div id="tartalom">
<?php print $tartalom; ?>
</div>

A <title> elem korszerűsítése

Jobb weboldalak a <title> címkéiben nem csak az oldal nevét tüntetik fel, hanem az éppen aktuálisan látogatott aloldal nevét is. Ez célszerűbb a gyorsabb áttekinthetőség, jobb könyvjelzőzhetőség és kereshetőség miatt is. A keresők egyébként is jobban kedvelik, ha minden aloldalnak saját címe, saját leírása és saját kulcsszavai vannak a <meta> tagok között! Pl. Weboldal neve - Aloldal címe

Megvalósítási lehetőség: XHTML kódban módosítást a weboldal fejrészében a <title> elemet így:

<title>MyCMS - Tartalomkezelő rendszer - <?php print $sor['menunev']; ?></title>

Biztonsági problémák

Ha az oldalt rendeltetésszerűen használják, akkor nincs gond, stabilan működik. De két probléma is adódhat.

Az adatbázis felvitele szempontjából van egy nagyon veszélyes jel: az aposztróf('), ezzel egy pillanat alatt meg lehet ölni az egész oldalt, és nem biztos hogy rájövünk, hogy mi okozta az össszeomlást. Egyszer csak pár év múltán - mikor már elfelejtettük, hogy valaha is közünk volt ehhez a weboldalhoz - az oldal szerkesztője leírja, hogy a kedvenc száma az It's a kind of magic a Queentől... Puff, na és azonnal elájul az oldal. Erre használható az addslashes()-stripcslashes() páros, amik feltöltésnél védőkarakterekkel látják el a tartalmat, lekérdezéskor pedig eltávolítják azokat, ezzel kiküszöbölik ezt a végzetes hibát.

stripcslashes($sor['menunev']); stripcslashes($sor['tartalom']);

Valaki úgy gondolja, hogy a címsorba beírja, hogy index.php?id=666, mert annyira gonosz, vagy az index.php?id=-23 as oldalra kíváncsi, netán az index.php?id=első a szerinte érdekes lap, ebben az esetben az oldal kiakad. Erre azt mondanám, hogy valószínűleg szándékos támadást hajt végre az oldalunkkal szemben (URL injekciózás), vagy a haverjaival szórakozik. Itt gondoskodni kell, hogy az oldal ne szálljon el, tehát tiltsuk le akár egy "@" karakterrel az érzékeny kódrészt. Abban az esetben pedig, ha az adott id azonosítóval az nincs az adatbázisban egyetlen találat sem, akkor írjunk ki valamilyen hibaüzenetet. Egy lehetséges megvalósítási lehetőség:

if (mysql_num_rows($eredmeny) == 1) {
$tartalom = "<h2>".$sor['menunev']."</h2>\n";
$tartalom .= $sor['tartalom']."\n\n";
$tartalom .= "<p>Utolsó frissítés: ".$sor['datum']."</p>\n\n";
}
else {
$tartalom = "<h2>Hiba!</h2>\n";
$tartalom .= "<p>A keresett oldal nem található!</p>\n";
}

A teljes PHP kód

<?php
// Adatbáziskapcsolat kialakítása
$dbHost = "localhost";
$dbUser = "root";
$dbPass = "admin";
$dbName = "mycms";
$dbConn = mysql_connect($dbHost, $dbUser, $dbPass) or die("Sikertelen csatlakozás az adatbázishoz!");
mysql_select_db($dbName, $dbConn) or die("Sikertelen adatbázis megnyitás!");
mysql_query("SET NAMES latin2");

// Menü elkészítése
$sql = "SELECT id, menunev FROM statikus_tartalom WHERE statusz = 'aktiv' ORDER BY sorszam ASC";
$eredmeny = mysql_query($sql);
while ($sor = mysql_fetch_assoc($eredmeny)) {
$menu .= "<li><a href=\"?id=".$sor['id']."\">".stripcslashes($sor['menunev'])."</a></li>\n";
}

// Tartalom összeállítása
if (mysql_num_rows($eredmeny) == 1) {
$tartalom = "<h2>".stripcslashes($sor['menunev'])."</h2>\n";
$tartalom .= stripcslashes($sor['tartalom'])."\n\n";
$tartalom .= "<p>Utolsó frissítés: ".$sor['datum']."</p>\n\n";
}
else {
$tartalom = "<h2>Hiba!</h2>\n";
$tartalom .= "<p>A keresett oldal nem található!</p>\n";
}

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="hu" xml:lang="hu">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
<title>MyCMS - Tartalomkezelő rendszer - <?php stripcslashes($sor['menunev']); ?></title>
<meta name="Description" content="Ide kerül majd a weboldal pármondatos bemutatkozó szövege" />
<meta name="Keywords" content="kulcszó 1, kulcsszó 2, kulcsó 3, ... kulcszó 25" />
<meta name="Author" content="Készítő neve" />
<meta name="Publisher" content="Szerkesztő neve" />
<meta name="Copyright" content="Védjegy" />
<meta name="Distributor" content="Global" />
<meta name="Rating" content="General" />
<meta name="Robots" content="Index, follow" />
<meta name="Revisit-After" content="30 days" />
<link href="mycms.css" rel="stylesheet" type="text/css" />
<link type="image/x-icon" href="index/favicon.png" rel="icon"/>
<link type="image/x-icon" href="index/favicon.png" rel="shortcut icon"/>
</head>

<body>
<div id="befoglalo">
<div id="fejlec">
<h1>MyCMS - Tartalomkezelő rendszer</h1>
</div>

<div id="menu">
<h2>Menü</h2>
<ul>
<?php print $menu; ?>
</ul>
</div>

<div id="tartalom">
<?php print $tartalom; ?>
</div>

<div id="lablec">
<p>&copy; 2010 MyCMS Tartalomkezelő rendszer - Minden jog fenntartva!</p>
</div>
</div>

<div id="statisztika">
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxxxxx-x");
pageTracker._initData();
pageTracker._trackPageview();
</script>
</div>
</body>
</html>

Kattints ide a letölthető php kódért

Fejlesztési lehetőségek

  1. Bug: ha az adatbázis id=1 sorát törlik, akkor hiba van az oldal első betöltésénél, mert ezt adtuk meg a ternáris (?) operátornál default értékként. De ennek megoldását már rád bízom! :)
  2. Készítsünk robots.txt-t, amiben a keresőrobotokat tájékoztatjuk arról, hogy mihez férhetnek hozzá és mi az, amiket nem indexelhetnek le.
  3. Minden aloldalhoz saját leírás és saját kulcsszavak hozzáadásával javul a reláváns tartalom / meta tartalom arány, így az oldalunk jobb lesz a keresőkben. Ezt az átalakítást célszerű a statikus_tartalom tábla új mezőkkel történő kiegészítésével kezdeni, majd ezeket az adatokat lekérdezésnél a description és keywords metákba kell ágyaznunk.
  4. Keresőbarát URL alkalmazása jobb helyezést hozhatna a keresőkben. Ehhez érdemes lenne megadni valami rövidnevet - "Alias"-t is, ami egy újabb mező lenne az adattáblában és a menüpontra való kattintáskor ez is átadódna pl.: index.php?id=1&oldal=bemutatkozas, melyet némi Apache hangolással át kellene alakítani ilyen formátumra, hogy www.sajatoldal.hu/bemutatkozas. Jelszó: Apache mod_rewrite
  5. Ha a statikus tartalmak között szükséged van egy dinamikus modulra, akkor azt hogyan oldanád meg? Például kell az egyik aloldalamra egy kapcsolat felvételi űrlap, hírportál, eseménynaptár, szavazó vagy bármilyen kis apróság... Jó fejtörést!

Hamarosan folytatom az adminisztrációs oldal megírásával...

Vissza a tetejére...

© 2010 WebPuzzle [ Kirakni gyerekjáték ] - Moduláris webhelyépítés A-Z-ig: Programozás, példakódok, esettanulmányok, összefoglalók lelkes amatőröknek