Menu

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><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><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><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
Products/en/products.aspx About/en/about.aspx Our values/en/about/our-values.aspx Our values/en/about/our-values.aspx Our history/en/about/our-history.aspx Homeen/default.aspx

Menu by mohlo vypadat třeba takto:

Home Products About Product 1 Product 2 Product 3 Products

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:

Products About Our values/en/about/our-values.aspx Our values/en/about/our-values.aspx Our history/en/about/our-history.aspx Homeen/default.aspx

A menu bychom chtěli třeba takovéto:

Home Products About Product 1 Product 2 Product 3 Some page

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.

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 pageGroupvirtualGroup. 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.

Připomínky a postřehy

Máte-li nějakou připomínku, dobrý nápad nebo jste našli v dokumentaci chybu, rádi od vás uslyšíme.