[latte] Renderování pouze části šablony

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

Ahoj všem,

potřeboval bych něco jako vyrenderování pouze určité části šablony – bloku, nebo jinak označené části. Snažil jsem se hledat a i trochu šmejdit v kódu nette, ale nepodařilo se mi najít nic funkčního.

Proč to vlastně hledam? Chci posílat maily generované z šablony a rád bych je odesílal cca takto:

$mail = new \Nette\Mail\Message();

$mail->addTo($recipient);

$template = $this->createTemplate(); // voláno z presenteru, abych mohl generovat odkazy
$template->setFile("email.latte");

$mail->setSubject($template->renderPart("subject"));
$mail->setBody($template->renderPart("textBody"));
$mail->setHtmlBody($template->renderPart("htmlBody"));

$mail->send();

Jediné zatím reálně a funkčně vyhlížející řešení, které mě nepadlo je vytvořit layout pro e-maily, který bude obsahovat nějaké oddělovací značky a já nechám vyrenderovat celou šablonu a pak jí rozsekam na kousky:

<-- -- -- separator -- subject -->
{include #subject}
<-- -- -- separator -- text -->
{include #text}
<-- -- -- separator -- html -->
{include #html}
<-- -- -- separator -- end -->

Tohle řešení mi ale přijde škrábání se levou rukou na pravym uchu … nemáte někdo nápad jak to udělat jinak? Nebo jenom přehlížím nějaké funkce?

P.S. Používam Nette Framework 2.0.10 (revision c0332ac released on 2013–03–08)

Semik
Backer | 135
+
0
-

Nevím proč by to mělo být škrábání levou rukou za pravým uchem.
Podívej se do dokumentace jak se pracuje s emaily ve spolupráci se šablonami a myslím, že najdeš co hledáš.

Dragonn
Člen | 12
+
0
-

Vím jak použít šablonu v mailu, ale nevím jak mít v jedné šabloně definovaný předmět, textovou a html verzi mailu zároveň. Předmět asi chápu, že se dá nastavit pomocí {var $mail->subject = "..." }, což by asi mohlo stačit, ale nevim jak bych do toho zakomponoval nějaký latte filtr (např. formát datumu, nebo něco podobného, co by bylo potřeba).

Předpokládám, že dokumentací máš na mysli https://doc.nette.org/cs/mail

David Matějka
Moderator | 6445
+
0
-

mozna ti bude stacit makro capture

Majkl578
Moderator | 1364
+
0
-

Defaultně se předmět automaticky vyextrahuje z <title> tagu. Textová verze se vygeneruje tak, že se ostripují HTML tagy.
Pokud potřebuješ tyto věci definovat specificky, brání ti něco využít samostatnou šablonu pro každou z nich (ačkoliv nechápu, proč by titulek měl být Latte šablonou)?

Dragonn
Člen | 12
+
0
-

@matej21: tohle makro jsem nějak přehlídnul, nezkoušel jsem, ale pokud je možné vyrenderovat šablonu (= zavolat $template->__toString()), výstup zahodit a přečíst jenom proměnné, tak by to bylo dobré řešení

EDIT: Bohužel, se mi nepodařilo zjistit jak to udělat, mam pocit, že instance šablony netuší, zda byla někdy renderovaná, nebo ne

@Majkl578: Využití samostatných šablon mi nic nebrání, jenom se mi do toho nechce. Chtěl jsem mít pro každou jazykovou verzi a typ mailu jeden soubor, aby se mi to lépe spravovalo.

Předmět šablona být nutně nemusí, není to uplně podmínkou, ale ještě nevim přesně, jaké budou požadavky na konkrétní obsahy mailů, tak jsem si nechtěl házet předem klacky pod nohy. Helpery jsou velice užitečná věc, ačkoliv je pravda že většinou bývá předmět ± statický.

Že se textová verze generuje automaticky jsem netušil, děkuji za informaci. Buď toho využiju, nebo tedy zůstanu u toho, co mám aktuálně teď.

Současný stav:

/**
 * Get part of given template identified by part ID
 *
 * @param string $template
 * @param array|string $block
 * @return array|string
 */
private function getBlockFromTemplate($template, $block){
    if(!($was_array = is_array($block))){
        $block = array($block);
    }

    $ret = array();
    foreach(explode(self::TEMPLATE_SEPARATOR, $template) as $template_part){
        $lines = explode("\n", $template_part);

        if(in_array($name = $lines[0], $block)){
            array_shift($lines);
            $ret[$name] = implode("\n", $lines);
        }
    }

    if($was_array){
        return $ret;
    }
    else{
        return array_pop($ret);
    }
}

public function sendMail($to, \Nette\Templating\IFileTemplate $template){
    $template->setFile($this->templateDir."/".$template->template_name.".latte");

    // create mail
    $mail = new \Nette\Mail\Message();;

    $mail->addTo($to);

    $templateContent = $this->getBlockFromTemplate(
        $template,
        array(
            "subject",
            "text",
            "html"
        )
    );

    $mail->setSubject($templateContent["subject"]);
    $mail->setBody($templateContent["text"]);
    $mail->setHtmlBody($templateContent["html"]);

    // send mail
    $mail->send();
}

a layout šablon:

subject
{include #subject}
<-- $!$ template separator $!$ -->
text
{include #text}
<-- $!$ template separator $!$ -->
html
{include #html}

Ještě jenom otázečku … je možné nějak generovat ze šablony odkazy bez závislosti na aktuálním presenteru? Rád bych se zbavil nutnosti vždy předávat výstup metody Presenter::createTemplate()

Editoval Dragonn (7. 7. 2013 3:11)

bazo
Člen | 620
+
0
-

odkazy generovat bez prezenteru sa daju. potrebujes router a vyskladat si rucne Nette\Application\Request, ktory potom prezenies cez Router::constructUrl($request)