Problém s jazykovámi mutacemi při kešování odkazů

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Bejn
Člen | 17
+
0
-

Nette 2(version 2.0-dev 9f535f9 released on 2011–01–10) a PHP 5.2.

Mám problém s kešováním odkazů v šablonách. Vytvořil jsem si makro clink, které mi vytváří odkazy na stránky z CMS.

class Macros extends LatteMacros implements IRoute
{
    public static function clink($request)
    {
        list($id, $lang) = explode(':',$request);
        return Environment::getApplication()->getPresenter()->clink($id, $lang);
    }

}

Makro registruji v BasePresenteru, kde má i kód, který zjišťuje cestu.

abstract class BasePresenter extends Presenter implements IRoute
{
    protected $model = NULL;
    protected $routes;

    function startup()
    {
        if ($this->model === NULL) $this->model = new BaseModel;
        parent::startup();
        LatteMacros::$defaultMacros['clink'] = '%Macros::clink%';
    }

    /**
    * Vraci cestu
    *
    * @param mixed $sectionId
    * @param mixed $langId
    */
    function clink($sectionId, $langId = NULL)
    {
        $this->initRoutes();
        $sectionId = (int)$sectionId;
        if ($langId === NULL) $langId = $this->langId;
        $x = $this->routes[$sectionId][$langId];
        return $this->routes[$sectionId][$langId] === NULL
                ? 'error: Pozadovana stranka v cms neexistuje'
                : htmlSpecialChars($this->template->basePath.'/'.$this->routes[$sectionId][$langId][self::R_PATH],ENT_QUOTES);
    }

    /**
    * Inicializace odkazů - pole vsech odakzu pra kazdy jazyk
    *
    */
    function initRoutes()
    {
        if ($this->routes === NULL)
            $this->routes = $this->model->getRoutes();
    }

}

V šabloně pak používám například (pro odkaz na stránku v aktuálním jazyce):

<a href="{clink 4}" class="more">Více</a>

Mohl bych volat i například (pro odkaz na stránku v anglickém jazyce):

<a href="{clink 4:2}" class="more">Více</a>

Odkazy se sami o sobě generují správně pro všechny kombinace jazyka a identifikatoru. Problém je v tom, že když načtu českou mutaci, tak se mi nakešují všechny odkazy na stránce a při zadání url anglické mutace se zobrazují české odkazy z cache.

Kešování odkazů se mi líbí, protože ve většině případů pak nemusím přistupovat do databáze, abych získal celou tabulku odkazů. Potřeboval bych nějak donutit keš, aby stránky kešovala podle URL, protože url je jedinečná pro každou jazykovou mutaci.

Napadá prosím někoho elegantní řešení jak docílit změny způsobu kešování odkazů ve stránkách? Vypnout ho nechci (ikdyž nevím jak).

Ještě mě napadlo dodávat do makra clink vždy id i jazyk, ale nepodařilo se mi ho tam dostat. Pokud totiž zavolám:

<a href="{clink 4:$langId}" class="more">Více</a>

Tak se mi jako parametr funkce Macros::clink předá 4:\$langId místo 4:2. Zkoušel jsem volat i

<a href="{clink 4:!$langId}" class="more">Více</a>

ovšem výsledek byl stejný. Tímto způsobem to dělat nechci, ale zajímalo by mě jak dostat do makra proměnnou. Víte prosím někdo jak na to?

Děkuji

Aurielle
Člen | 1281
+
0
-

Naprosto mi uniká, proč třída extendující LatteMacros implemetuje rozhraní IRoute (které ani neexistuje)…

Bejn
Člen | 17
+
0
-

gmvasek napsal(a):

Naprosto mi uniká, proč třída extendující LatteMacros implemetuje rozhraní IRoute (které ani neexistuje)…

Kvůli konstantě self::R_PATH. Pro úplnost:

interface IRoute
{
    const T_ROUTE = 'route';
    const R_PATH = 'path';
    const R_ID = 'section_id';
    const R_LANG = 'lang_id';
    const R_DELETED = 'deleted';

}

Věděl by prosím někdo jak vyřešit můj problém s keší?

norbe
Backer | 405
+
0
-
  1. Kvůli konstantě jedné třídy/rozhraní ji hned nemusíš rozšiřovat/implementovat, ale můžeš použít IRoute::R_PATH
  2. Řekl bych, že jsi nepochopil jak se chovají makra. Makro slouží k překompilování šablony. Tj. např. {clink foo:$neco} vidí pouze jako nějaký řetězec, který může nahradit za řetězec jiný. Doporučuji se podívat na jiná makra v LatteFilter, pak by jsi měl pochopit jak to funguje.
Bejn
Člen | 17
+
0
-

norbe napsal(a):

  1. Kvůli konstantě jedné třídy/rozhraní ji hned nemusíš rozšiřovat/implementovat, ale můžeš použít IRoute::R_PATH
  2. Řekl bych, že jsi nepochopil jak se chovají makra. Makro slouží k překompilování šablony. Tj. např. {clink foo:$neco} vidí pouze jako nějaký řetězec, který může nahradit za řetězec jiný. Doporučuji se podívat na jiná makra v LatteFilter, pak by jsi měl pochopit jak to funguje.

Ad 1) Asi ano. Používám to tak v šablonách. Zamyslím se ještě nad tím.

Ad 2) Byl to jen nápad jak obejít kešování. Nicméně od začátku to tak nechci dělat, jen mě zajímalo jestli to jde. Neměl jsem to sem vůbec psát.

Věděl by prosím někdo jak vyřešit podstatu mé otázky? Tj. kešování odkazů.

Příklad:
Stránky http://darkstar/matystav/www/ a http://darkstar/matystav/www/en/ jsou dvě stejné stránky (Homepage:default).

V šabloně použiji {clink 4}, což by mělo vygenerovat pro každou mutaci jiný odkaz:

na stránce http://darkstar/matystav/www/ by to měl být odkaz: http://darkstar/matystav/www/kontakty/

a

na stránce http://darkstar/matystav/www/en/ by to měl být odkaz: http://darkstar/matystav/www/en/contacts/

Všechny adresy se tahají z db a obecně nelze určit žádný vztah mezi dvěmi stejnými stránkami ve dvou mutacích.

Mutace, kterou načtu jako první určuje odkazy i ve všech ostatních, což právě nechci. Vždycky když smažu cache mezi přepnutím mutace, tak vše funguje správně.

Jak je to s kešováním odkazů? Podle jakého klíče se stránky kešují? Podle chování odhaduji, že podle klíče Presenter:action. Pokud je tomu tak, lze nějak změnit tento klíč na url adresu?