JellyPot implicitně nepředpokládá žádnou konkrétní strukturu webu. Nepředpokládá tedy ani žádnou podobu menu a další navigace. Struktura dat v administraci může být – a obvykle je – odlišná od struktury webu samotného. Pro vytvoření menu je tedy nutné specifikovat:
- strukturu stránek v souboru v pagemap.config,
- chování položek menu a jejich označování CSS třídami podle aktuální URL.
Popisu struktury stránek se věnuje pagemap.config, tento článek se zabývá popisem chování odkazů menu. K tomu slouží atribut mark
u controlů pro tvorbu odkazů <je:a>
a <je:aVar>
(příp. <je:elem>
). S jeho pomocí lze označit jimi generované HTML tagy zvolenou třídou.
<je:a runat="server" href="/en/some-page.aspx" mark="active by page">Some page</je:a>
Poznámka 1: Vše zde uvedené předpokládá, že menu je umístěno ve společném masteru nebo uživatelském controlu nebo obsahuje odkazy generované controlem <je:aVar>
. Pokud by totiž bylo zopakováno v každém .aspx a obsahovalo jen statické odkazy, nebylo by nutné se zabývat jejich označováním. Bylo by možné je snadno označit ručně.
Poznámka 2: Pokud nemáte v Pagemap.config definovanou strukturu webu nebo ji máte definovanou chybně (tj. v rozporu se strukturou menu), bude se přiřazování tříd chovat divně a nepředvídatelně.
Syntaxe
Hodnotou atributu mark
je řetězec, který definuje, v jakém případě a jakou třídou má být HTML tag vygenerovaný controlem označen. Syntaxe je následující:
mark="class-name by case, class-name by another-case"
kde class-name
je jméno třídy, která bude elementu přiřazena, pokud nastane případ case
(resp. another-case
). Čárkou se oddělují jednotlivé bloky, které jsou vyhodnocovány nezávisle na ostatních. class-name
může být i více tříd, pak se zapíše prostě jako
mark="class-name-1 class-name-2 by case"
Případy case
JellyPot rozeznává následující:
- page – vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL uvedenou v jeho atributu
href
bez ohledu na případnou proměnnou v URL obsaženou - var – vygenerovaný HTML element bude označen danou třídou, pokud se proměnná obsažená v aktuální URL shoduje s proměnnou obsaženou v URL uvedené v jeho atributu
href
- pageGroup – vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL v jeho atributu href nebo pokud se aktuální URL shoduje s URL libovolné podstránky podle definice v Pagemap.config
- virtualGroup – vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL libovolné podstránky daného elementu virtual podle definice v Pagemap.config
Controly podporující atribut mark
Atribut mark
lze použít s controly <je:a>
, <je:aVar>
a <je:elem>
. Každý má trochu jiný užitek a hodí se k něčemu jinému. Pokud je potřeba označit třídou přímo odkaz (tj. HTML element <a>
), pak se mark
použije s controly <je:a>
nebo <je:aVar>
:
<je:a runat="server" href="/en/some-page.aspx" mark="active by page">Some page</je:a>
Nebo pro <je:aVar>
uvnitř <je:repeater>
:
... <je:aVar runat="server" href="/en/some-item-page.aspx" mark="active by page">...</je:a> ...
Pokud je potřeba třídou označit jiný element než přímo odkaz – například <li>
, který odkaz obaluje – pak se použije <je:elem>
:
<je:elem runat="server" tag="li" mark="active by page"> <je:a runat="server" href="/en/some-page.aspx">Some page</je:a> </je:elem>
V takovém případě se vyhledá první control <je:a>
(resp. <je:avar>
) v <je:elem>
obsažený a výraz mark
se vyhodnotí jako by byl uveden přímo na <je:a>
(resp. <je:avar>
). Controly <je:a>
nebo <je:avar>
přitom musí být bezprostředními potomky <je:elem>
, dále do hloubky se kód neprohledává. (To je sice obecně omezující, ale vzhledem k použití to stačí a renderování stránky je výrazně rychlejší.)
Případy pro přiřazení tříd
by page
Vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL uvedenou v jeho atributu href
. Má smysl u: <je:a>
(příp. <je:elem>
který obsahuje <je:a>
)
<je:a runat="server" href="/en/some-page.aspx" mark="my-class by page">Some page</je:a>
V uvedeném příkladu bude odkaz označený třídou my-class
, pokud URL aktuální stránky je /en/some-page.aspx
.
page
se používá typicky pro statické odkazy. Pokud by v URL aktuální stránky byla obsažena proměnná, by page
ji prostě ignoruje. Tedy např. URL:
/en/other-page/my-hovercraft-123xyz.aspx /en/other-page/is-full-of-eels-567abc.aspx /en/other-page.aspx
jsou považovány za shodné. Jinými slovy by page
porovnává URL stránky bez proměnné.
Lze použít zkrácenou verzi mark="my-class"
. Tento zápis je ekvivalentní s mark="my-class by page"
.
by var
Vygenerovaný HTML element bude označen danou třídou, pokud se proměnná obsažená v aktuální URL shoduje s proměnnou obsaženou v URL uvedené v jeho atributu href
. Má smysl u: <je:aVar>
(příp. <je:elem>
který obsahuje <je:aVar>
).
... <je:aVar runat="server" href="/en/some-page.aspx" mark="my-class by var"> ... </je:aVar> ...
Protože var
porovnává URL včetně obsažené proměnné, jsou např. URL:
/en/other-page/my-hovercraft-123xyz.aspx /en/other-page/is-full-of-eels-567abc.aspx /en/other-page.aspx
považovány za rozdílné.
Odkaz bude danou třídou označen i v případě, pokud jeho URL obsahuje proměnnou, která je podle deklarace v Site.config libovolně hierarchicky nadřazená proměnné obsažené v aktuální URL.
by pageGroup
Vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL v jeho atributu href
nebo pokud se aktuální URL shoduje s URL libovolné podstránky podle definice v Pagemap.config. Má smysl především u: <je:a>
a <je:elem>
.
<je:a runat="server" href="/en/my-group.aspx" mark="my-class by pageGroup">My Group</je:a>
V uvedeném příkladu bude odkaz označen třídou my-class
, pokud je aktuální URL /en/my-group.aspx
nebo pokud je aktuální URL podstránkou /en/my-group.aspx
podle definice v Pagemap.config.
by virtualGroup
Vygenerovaný HTML element bude označen danou třídou, pokud se aktuální URL shoduje s URL libovolné podstránky daného elementu virtual podle definice v Pagemap.config. Má smysl především u: <je:elem>
.
<je:elem runat="server" mark="my-class by virtualGroup myGroup">My Group <je:a runat="server" href="/en/some-page-in-my-group.aspx">Some Page</je:a> <je:a runat="server" href="/en/another-page-in-my-group.aspx">Another Page</je:a> </je:elem>
V uvedeném příkladu bude obalující element označen třídou my-class
, pokud aktuální URL je /en/some-page-in-my-group.aspx
nebo /en/another-page-in-my-group.aspx
a tyto jsou podle definice v Pagemap.config podstránkami elementu virtual
pojmenovaného myGroup
.
Příklad
Máme web, který obsahuje:
- homepage
- stránku s produkty a jejich detaily
- stránku o nás, která má dvě další podstránky
Menu by mohlo vypadat třeba takto:
Při kliknutí na libovolnou položku je uživatel okamžitě odkázán na odpovídající stránku. Menu má pouze jednu úroveň. Zároveň ale chceme, aby se zvýraznila příslušná položka menu v případě, kdy je uživatel na podstránkách (například detailu produktu nebo historii společnosti).
Struktura v Pagemap.config je definovaná takto:
<JellyPotDef xmlns="urn:Bet:ns:JellyPot:PagemapConfig"> <SiteMap> <Page href="/en/default.aspx" /> <Page href="/en/products.aspx"> <Page href="/en/products/product.aspx" /> </Page> <Page href="/en/about.aspx"> <Page href="/en/about/our-values.aspx" /> <Page href="/en/about/our-history.aspx" /> </Page> </SiteMap> </JellyPotDef>
Menu v master stránce by vypadalo takto:
<je:a runat="server" href="/en/default.aspx" mark="active by page">Home</je:a> <je:a runat="server" href="/en/products.aspx" mark="active by pageGroup">Products</je:a> <je:a runat="server" href="/en/about.aspx" mark="active by pageGroup">About us</a>
Kdybychom chtěli, aby menu by bylo roletkové, tj. položky Products a About by nevedly na samostatné stránky, na kliknutí by pouze rozbalovaly podmenu. Stránky Products a About by tedy neexistovaly, byly by jen logické ( = virtuální), strukturu webu bychom si mohli představit takto:
A menu bychom chtěli třeba takovéto:
Při kliknutí na Products nebo About se vybalí menu druhé úrovně, stránky Products nebo About fakticky vůbec neexistují – jsou jenom logickým seskupením nějakých jiných stránek.
V Pagemap.config by definice struktury vypadalo takto:
<JellyPotDef xmlns="urn:Bet:ns:JellyPot:PagemapConfig"> <SiteMap> <Page href="/en/default.aspx" /> <Virtual name="products"> <Page href="/en/products/product.aspx" /> </Virtual> <Virtual name="about"> <Page href="/en/about/our-values.aspx" /> <Page href="/en/about/our-history.aspx" /> </Virtual> </SiteMap> </JellyPotDef>
Menu v master stránce by bylo následující:
<je:a runat="server" href="/en/default.aspx" mark="active by page">Home</je:a> <je:elem runat="server" tag="div" mark="active by virtualGroup products"> Products <div> <je:repeater runat="server"> <item> <je:aVar runat="server" href="/en/" mark="active by var"> <je:item runat="server" field=".title" /> </je:aVar> </item> </je:repeater> </div> </je:elem> <je:elem runat="server" tag="div" mark="active by virtualGroup about"> About us <div> <je:a runat="server" href="/en/about/our-values.aspx" mark="active by page"> <je:item runat="server" field=".title" /> </je:a> <je:a runat="server" href="/en/about/our-history.aspx" mark="active by page"> <je:item runat="server" field=".title" /> </je:a> </div> </je:elem>
Pochopitelně je možné na jednom webu kombinovat pageGroup
a virtualGroup
. Jen v našem jednoduchém případě by to vedlo k podivně se chovajícímu menu (některé položky by rozbalovaly podmenu, jiné by rovnou vedly na stránky) a to by asi nikdo nechtěl (odkaz na homepage je běžná výjimka ;). Typická situace, kdy by se kombinovaly, je, pokud je menu víceúrovňové. Pak první uroveň je třeba pageGroup
, druhá virtualGroup
.