Obsah / Jet\MVC_Page_Content

Už víte jak v Jet funguje MVC, co je to báze, co je to stránka. A teď přišel čas podívat se na obsah stránky. Tedy na možná trochu nenápadnou (nebo spíše zastrčená), ale přes to velice důležitou třídu Jet\MVC_Page_Content a její interface Jet\MVC_Page_Content_Interface. I tato třída je vyměnitelná díky systému továren, stejně jako všechny ostatní třídy v rámci ekosystému MVC.

Pro přehlednost si opět třídu rozdělíme alespoň na tématický okruhy. I když její implementace není zas tak velká a není tedy rozdělena na traity.

Základní metody

Metoda Význam
public setPage(
MVC_Page_Interface $page
): void
Nastavení ke které stránce obsah náleží. To si entita stránka řeší sama (např. při __wakeup). Metody tedy není nutné běžně používat.
public getPage(
): MVC_Page_Interface
Vrátí instanci stránky ke které obsah náleží.
public toArray(
): array
Metoda pro převedení objektu do surových dat určených k uložení.

Pozice obsahu v rámci layoutu

Metoda Význam
public getOutputPosition(
): string
Metoda vrací název pozice v rámci layoutu na kterou obsah patří.
public setOutputPosition(
string $output_position
): void
Nastaví pozici (název pozice) v rámci layoutu.
public getOutputPositionOrder(
): int
Definice názvu pozice nestačí. Na jedné pozici může být libovolné množství obsahu. Pozice není vyhrazena jen pro jeden výstup / obsah. Tedy je nutné určit pořadí (prioritu) v jakém se má obsah na dané pozici zobrazit.
public setOutputPositionOrder(
int $output_position_order
): void
Viz metoda getOutputPositionOrder

Statický obsah, nebo callback

U stránky máte možnost definovat celý její statický obsah, nebo callback pomocí kterého je obsah generovaná.

A úplně to samé platí pro jednotlivý obsah. S tím rozdílem, že se to samozřejmě netýká celé stránky, ale pouze jednotlivého obsahu na určité pozici.

Dejme tomu, že na určité pozici chcete mít pouze nějaký informační text. Daný text nebude často měněn, nebude třeba jej editovat z administrace. Zase na druhou stranu nechcete jej dávat přímo do layoutu, protože se tento text (nebo libovolný jiný typ obsahu) může na různých stránkách lišit. 

Pro takovou věc nemusí mít smysl dělat celý modul, kontroler, view ... Obsah může mít zcela statickou podobu (a upravovat to můžete v Jet Studiu, když budete chtít), nebo je tu možnost použít callback. Ostatně demonstrace použití callback pro takovou situaci je v ukázkové aplikaci.

Pochopitelně pokud použijete tento přístup, pak nepoužíváte návaznost na moduly a kontrolery.

Metoda Význam
public getOutput(
): string|callable
Vrací nastavený statický obsah, nebo callback.
public setOutput(
string|callable $output
): void
Nastavuje statický výstup, nebo callback.

Obsah s použitím aplikačních modulů

Pokud obsah není statický, nebo generovaný callbackem, pak může být navázán na aplikační moduly. Je to sice jedna z možností, ale pro mne je to nejčastější způsob jak k věci přistupovat a tento způsob používám nejčastěji.

Například tento článek zobrazil modul "Web.Doc.Browser", ale v ukázkové aplikaci máte spoustu dalších modulů na prozkoumání, např. "Content.Articles", "Test.MVC" a celou řadu dalších.

Metoda Význam
public getModuleName(
): string
Metoda getModuleName vrátí název aplikačního modulu, který bude mít obsah na starosti.
public setModuleName(
string $module_name
): void
Nastaví název aplikačního modulu, který se postará o obsah.
public getModuleInstance(
): Application_Module|bool
Vrátí instanci aplikačního modulu, který se postará o obsah.

Pozor! Může vrátit i hodnotu false. A je to naprosto v pořádku.

Systém počítá s tím, že modul nemusí být nainstalován, nebo není aktivní. A takový obsah prostě přeskočí. 

Pokud tedy budete (správně) používat aplikační moduly, tak máte možnost aktivovat a deaktivovat různé prvky a funkce vaší aplikace.

Kontroler - s použitím aplikačních modulů

Pokud se o obsah bude starat nějaký aplikační modul, pak je nutné určit jaký kontroler aplikačního modulu bude mít obsah na starosti. Ovšem nespecifikuje celý / plný název třídy kontroleru, ale pouze název kontroleru, který se automaticky převede na název třídy patřící do aplikačního modulu.

Raději to vysvětlím rovnou na příkladu. V ukázkové aplikaci máte například stránku "Test lokalizace", která demonstruje co umí Locale.

Toto je definice obsahu zmíněné stránky:

  return [ 
      
// ... ... ...
      
'content' => [
               [
            
'module_name'           => 'Test.Locale',
            
'controller_name'      => 'Main',
            
'controller_action'     => 'test_locale',
            
'output_position_order' => 1
        
]
    ]
];

Jak vidíte, tak obsah směřuje na aplikační modul Test.Locale a název kontroleru je Main (Což je mimochodem výchozí hodnota a je tedy použita i když kontroler není přímo specifikován - proto v definicích tento údaj nemusíte vždy nalézt.).

Ale název kontroleru "Main" se ve finále změní na název třídy:
JetApplicationModule\Test\Locale\Controller_Main

A tato třída se postará o zabezpečení konkrétního obsahu. O sestavení názvu třídy kontroleru se Jet postará sám. 

Obsah již ví na jakou třídu kontroleru aplikačního modulu bude směrovat - tedy jaká konkrétní třída obsah zabezpečí. To už je téměř vše, ale zůstává jedna otázka: Jaká metoda té třídy má být zavolána? 

Když se blíže seznámíte s kontrolerem, tak budete vědět, že kontroler zavádí pojem akce. Akce jsou de facto metody v jejichž názvu je přípona _Action

Samozřejmě že jeden kontroler může mít akcí víc - tolik kolik je třeba. Neplatí že kontroler má jednu akci a proto je nutné určit na jakou konkrétní akci (fakticky metody) má být zabezpečení obsahu směrováno.

Tedy úplně jednoduše řečeno: Název akce specifikuje, která z metod (které mají v názvy příponu _Action) třídy kontroleru se má zavolat aby se postarala o obsah.

Metoda Význam
public setControllerName(
string $controller_name
): void
Nastaví název kontroleru aplikačního modulu, který se má postarat o obsah.
public getControllerName(
): string
Vrátí název kontroleru aplikačního modulu, který se má postarat o obsah.
public getControllerInstance(
): MVC_Controller|bool
Vrátí již instanci kontroleru aplikačního modulu.

Pozor! Platí zde to samé jako pro metodu getModuleInstance. Tedy to, že metoda může vrátit false. Pokud je obsah navázán na nenainstalovaný a/nebo neaktivní aplikační modul, tak logicky není možné ani instancovat kontroler. Ovšem jak jsem již psal, tak systém s tím plně počítá a obsah se jednoduše "přeskočí".
public getControllerAction(
): string|bool
Vrátí název akce kontroleru.

Pokud název akce není specifikován v definici, tak je použita hodnota konstanty MVC_Page_Content::DEFAULT_CONTROLLER_ACTION, což znamená akce "default".
public setControllerAction(
string $controller_action
): void
Nastaví akci kontroleru.

Kontroler - bez aplikačních modulů

Je ještě jedna možnost jak se postarat o obsah. A není to ani statický obsah, ani callback a ani aplikační moduly. 

Obsah je možné přímo navázat na nějakou třídu (třídu, která bude ve vašem aplikačním prostoru), která nemusí být součástí žádného modulu a tato třída představuje kontroler, tedy dědí od abstraktní třídy Jet\MVC_Controller.

Ano, je technicky z Jet MVC ponechat prakticky vše, ale nepoužívat aplikační moduly. Osobně jsem tuto možnost nikdy nepoužil, ale možná to někdy pro něco bude vhodnější řešení.

Metoda Význam
public setControllerClass(
string $controller_class
): void
Nastaví plný název třídy kontroleru majícího na starosti obsah, který není součástí žádného aplikačního modulu.
public getControllerClass(
): string
Vrátí název plný třídy kontroleru majícího na starosti obsah, který není součástí žádného aplikačního modulu.

Parametry

Stejně jako u stránky, tak i u jednotlivého obsahu je možnost používat parametry. Parametry jsou součástí definice, ale je možné s nimi libovolně pracovat v rámci aplikačního prostoru.

Metoda Význam
public getParameters(
): array
Tato metoda vrátí seznam všech parametrů v podobě asociovaného pole, kde klíčem pole je název parametru.
public setParameters(
array $parameters
): void
Nastaví interní parametry obsahu. Viz metoda getParameters.
public getParameter(
string $key,
mixed $default_value = null
): mixed
Vrátí hodnotu konkrétního parametru, nebo výchozí hodnotu, pokud parametr není definován.
public setParameter(
string $key,
mixed $value
): void
Nastaví jeden konrétní parametr.
public parameterExists(
string $key
): bool
Zjistí zda daný parametr existuje.

Keš

Keš MVC je téma samo o sobě. Ale je nutné si něco říct o kešování v kontextu s obsahem stránky.

V první řadě obsah musí definovat zda je / není kešovatelný.

Tedy například pokud jde např. o výpis článku, tedy obsah který se nemění, nebo se mění zcela minimálně, pak určitě kešovatelný je. 

Pokud jde ale o výpis dat v reálném čase, prostě něco co se často mění a keš by se stejně neustále promazávala, tak takovou věc kešovat nemá smysl (nebo je to dokonce kontraproduktivní).

Zde malá vsuvka. V průběhu let jsem zkoušel různé strategie jak na to. Určit zda kešovat nebo nekešovat je velice důležité. Hledal jsem a zkoušel různé cesty, různou automatiku a semiautomatiku v rámci Jet. Ale došel jsem k závěru že jak se to bude a má chovat ví nejlépe vývojář aplikace (tedy vy) a že nejlepší je kešovatelnost prostě definovat a nechat na vývojáři jak s tím naloží.

Metoda Význam
public setIsCacheable(
bool $state
): void
Nastaví zda je obsah kešovatelný.
public isCacheable(
): bool
Indikuje zda je obsah kešovatelný.
public saveOutputCache(
string $output
): void
Ukládá výstup do keše.

Je to záležitost systému, v aplikačním prostoru to nemusíte řešit.
public loadOutputCache(
): bool
Přednahrává obsah z keše.

Opět vnitřní záležitost systému o kterou se v praxi nemusíte starat.

Dispatch a output

Metoda Význam
public dispatch(
): void
A zde se vše děje ... 

Zde je zavolán kontroler, případně callback, nebo je statický obsah rovnou zařazen do layoutu.

Metoda ale také řeší vše okolo. Nastavuje správně překladač. Rovněž automaticky vytváří bloky profileru

Z tohoto důležitého místa se tedy již bude volat váš kód, vaše moduly a vaše třídy. 
public output(
string $output
): void
Pomocí této metody vrací kontroler zpět obsahu vygenerovaný výstup.

Pokud budete používat běžnou cestu a pracovat s moduly, tak se s touto metodou v praxi nesetkáte.

Pokud ale potřebujete přece jen jiný přístup, tak je důležité mít tuto metodu na paměti. Metoda se postará o uložení výstupu do keše a také o umístění výstupu na správnou pozici v layoutu.
Předchozí kapitola
Jet\MVC_Page
Další kapitola
Jet\MVC_Page_MetaTag