11. gyakorlat¶
Saját tagek (Custom tags)¶
A felhasználó saját maga hozhat létre új tagaket. Ezáltal segít abban, hogy ne kelljen scriptleteket használni, illetve segít szeparálni az üzleti logikát a megjelenítéstől. Ezek mellett talán a legnagyobb előnye, hogy ezeket a tageket újra fel tudjuk használni több helyen is. Kétféleképpen használhatjuk a saját tagjeinket:
1 2 3 4 5 6 7 |
|
A saját tagek definíciójához nagyobb szabadságot ad, ha TLD-ket (Tag Library Descriptor-okat) adunk meg, de ez túlmutat a céljainkon, mivel kicsit nehézkes és több helyen kell ezeket megadni.
Egy másik, egyszerűbb módja, hogy a tag definíciókat a WEB-INF/tags mappában helyezzük el. Készítsük el a current-datetime taget!
WEB-INF/tags/current-datetime.tag
1 2 3 4 5 6 |
|
Figyeljük meg, hogy a page
direktíva helyett azt írtjuk, hogy tag
, ezzel is jelezvén, hogy egy saját tag-et definiálunk.
A tag egyszerűen kiírja az aktuális dátumot és időt.
Használata, index.jsp
1 2 3 4 |
|
A taglib direktívában nem az uri-t kell megadnunk, hanem a tagdir attribútumban a saját tagjeink könyvtárát. Innentől már használhatjuk a tags könyvtárban lévő tageket mint például a current-datetime-ot.
Custom tagek attribútumai¶
Az előző példában csak egy tag-et csináltunk, de annak nem voltak attribútumai, ami viszont egy elég általános elvárás egy saját tag-től.
Készítsük el azt a saját tag-et amelyet a következőképpen tudunk használni:
1 |
|
Ehhez készítünk egy cube.tag állományt a WEB-INF/tags mappába, melynek tartalma:
1 2 3 4 5 6 7 |
|
<%@ attribute %>
direktívával adhatunk meg.
Ez a direktíva csak tag definícióknál használható, jsp oldalaknál nem.
Az attribútumnak meg lehet adni a nevét, hogy kötelező-e, mint azt a fenti példában is láthatjuk.
Nagyon fontos a type
attribútum.
A példában a 3. hatványra emelő tagünknek egy számot kell várnia, azonban az attribútumok alaptípusa java.util.String
.
A mi esetünkben ez egy nagy exception-t eredményezne, mivel arra nem tudja értelmezni a value * value
kifejezést, így a type-ot megadtuk, hogy Double-t várjon és így működik is a tag.
Ezen felül az attribútumnak adhatunk leírást is a description
megadásával.
Amennyiben nem attribútumban, hanem a tagek között akarjuk megadni az értéket a cube-nak, akkor a következőt kell tennünk:
1 2 3 4 5 6 7 8 |
|
A jsp:doBody segítségével a custom tagünk közötti body részt értékelhetjük ki. A kiértékelés eredményét egyből nyomhatjuk az outba, ekkor nem kell sem a scope sem a var attribútumot használnunk. Ha viszont szeretnénk felhasználni az értékét később, akkor érdemes lehet eltárolni, mint ahogyan most is ki akarjuk számolni a köbét. Ehhez kiolvassuk a tartalmat, majd string-é alakítjuk és trimmeljük, hogy tudjunk parsolni olyat is ha különböző sorban van a nyitó és záró tag, illetve közte az adat. Használni egyszerűen a következőképpen lehet:
1 |
|
Az attribute direktívának van egy további paramétere, mégpedig, hogy az attribútum az fragment-e. Ez azt jelenti, hogy a tag paraméterül jsp kódrészletet kap. Ezek nagyon jól használhatóak, ha például template-et kell készítenünk az oldalainkhoz.
A cube tag-et bővítsük, hogy benne még további jsp-t adhassunk meg! A tag definícióban az alábbiakat kell írnunk:
1 2 3 4 5 6 7 8 9 10 |
|
<jsp:invoke>
használatával illeszthetjük be.
Ezt akár több ponton is megtehetjük.
Ezután a használatát tekintve a következőket kell tennünk:
1 2 3 4 5 |
|
Most, hogy az alapokat megnéztük ideje, hogy átalakítsuk az alkalmazásunkat úgy, hogy az page template-eket használjon. Az esetleges újdonságokat menet közben még tisztázzuk.
Feladat
Alakítsuk át úgy a contacts alkalmazásunkat, hogy page template-eket használjon!
Először is különböztessük meg azt a különböző eseteket, amikre szükségünk lehet:
- Common header szükséges az oldalhoz
- Common header és menü is szükséges az oldalon
Ez alapján kétféle page template-et fogunk elkészíteni.
Vegyük az elsőt, melyben csak a common header lesz benne.
Ehhez a WEB-INF
alatt hozzuk létre a tags
könyvtárat, ahol létrehozzuk a basic-layout.tag
állományt, melynek a következő tartalma lesz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
A fájl elején megadjuk, hogy egy custom tag-ről van szó (aminek neve megegyezik a fájl nevével: basic-layout
), majd megadjuk, hogy milyen attribútumokat fogunk használni ebben a tag-ben.
Az első attribútum a title
, mely az oldal címét adja meg és annak típusú String
.
Ha megnézzük, hogy hol használjuk fel a title
attribútumot, akkor láthatjuk, hogy a <title>${title}</title>
megadásban szerepel, ami az oldal címét adja meg.
Ilyenkor a tag-et a következőképpen fogjuk használni: <basic-layout title="Login">...</basic-layout>
, melynek eredményeképpen a megadott oldal címe Login
lesz.
A <head>
részben a korábban common-header.jsp
oldalon megadott elemeket helyezzük el.
Ugyanakkor itt van még egy fontos pont, amikor meghívjuk a header
attribútumot, amely viszont már egy fragment a title
-el ellentétben, így az tartalmazhat HTML részfát is akár.
Erre azért van szükség, mert az egyes oldalak esetleg tovább szeretnék bővíteni a <head>
-ben megadott elemeket, mint például az add-contact.jsp
-ben szeretnénk használni az add-contact.js
állományt (máshol viszont nem).
Ugyanezt végezzük el a footer
-re, melyet jelenleg ugyan nem használunk, de később jól jöhet.
A használat helyén a <basic-layout title="xxx">...</basic-layout>
között megadott tartalmat a <jsp:doBody/>
hívással írhatjuk ki a template-ben.
Ezt a tartalmat egy div
-ben helyezzük el <div id="body" class="container">
.
Miután megvan a template, nézzük, hogy hogyan használhatjuk fel azt például a login.jsp
oldalon:
1 2 3 4 5 6 7 8 |
|
A fenti példában a behúzzuk a használni kívánt tagek mappáját: tagdir
és adunk neki egy prefixet, mely most a t
.
Ezután egyszerűen használjuk a saját basic-layout
tag-ünket, ahol megadjuk a title
attribútumot.
Most a megadott <form>
elem kerül a template-ben megadott <jsp:doBody/>
helyre.
A teljesség kedvéért alul látható a böngészőben elérhető HTML, ahol már a saját tag- feloldását láthatjuk:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
Ezt az alap template-et a login mellett a register.jsp
is használja, mely nagyon hasonló lesz a login-hoz:
1 2 3 4 5 6 7 8 |
|
Az eddigi form-ot átmozgattuk a basic-layout
tag body részébe, illetve más title
-t adtunk meg, de más különbség nincs.
Ezután nézzük meg azt, hogy hogyan használhatjuk fel a basic-layout
tag-et egy másik tag definíciójában, azaz hogyan bővíthetjük ezt a tag-et (a menüvel).
Nyilvánvalóan a basic-layout
-ban szereplő elemeket szeretnénk a basic-layout-menu
tag-ben is alkalmazni, viszont kódot nem szeretnénk duplikálni.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Mivel hasonlóan meg szeretnénk adni egy basic-layout-menu
tag-nek is a title
-t, az esetleges header
-t és footer
-t, így ezeket az attribútumokat itt is "kivezetjük", melyeket majd továbbadjuk a basic-layout
-nak.
Ez látszódik például a <t:basic-layout title="${title}">
sorban is.
A header
és a footer
megadása kicsit másképpen működik.
A header
beillesztéséhez a <jsp:invoke fragment="header" />
-ot kell meghívnunk, melyet "kívülről" kapunk.
Mivel ezt a <t:basic-layout>
-nak szeretnénk továbbadni, így itt meg kell adni, hogy a basic-layout
header
attribútumát szeretnénk beállítani, ezért kell a <jsp:attribute name="header">
megadás.
Hasonlóképpen a kívülről kapott basic-layout-menu
tartalmát tovább szeretnénk adni a basic-layout
body-jaként, így ezt <jsp:body>
tag-ek között kell megadnunk.
Annyi a különbség, hogy a kívülről kapott body HTML tartalom elé berakjuk a nav
-ot, azaz a menüt.
Nézzük, hogy hogyan használja fel a list-contact.jsp
oldal a template-et:
1 2 3 4 5 6 7 8 9 10 11 |
|
A tag felhasználása a megszokott módon történik, nincs semmi mágia.
A különbség annyi, hogy most már a <basic-layout-menu>
tag-et használjuk.
Viszont van egy fontos különbség, akkor amikor a header
-be vagy a footer
-be is bele szeretnénk valamit rakni.
Ez igazából hasonlóan megy, mint a basic-layout-menu
-nél.
Lássuk az add-contact.jsp
oldalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Szokásos módon behúzzuk a használni kívánt tag-ek könyvtárát: <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>
.
Ezután a <basic-layout-menu>
-on belül a header-t szeretnénk megadni, ahol a <script src="${pageContext.request.contextPath}/js/add-contact.js"></script>
bővítést szeretnénk eszközölni.
Ezután pedig a body-ban megadni a useBean
-nel a megfelelő Contact
objektumot és a form
-ot.
Amennyiben nem jeleznénk, hogy mi a header attribútum és mi a basic-layout-menu
body-ja, akkor a rendszer mindent body-nak venne, így megadjuk a header attribútum értékét a <jsp:attribute name="header">
tag használatával, illetve a <jsp:body>
-val magát basic-layout-menu
body-ját.
A profile.jsp
oldalon hasonló módosításokat kell tennünk, mint az add-contact.jsp
-n, így azt itt már nem mutatjuk be.
Ezzel elkészítettük a kontakt alkalmazásunk webes változatát is. A teljes projektet lásd a pub-on!