Nefunguje {snippet} ve vnořené šabloně

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

Zkoušel jsem zajaxovatět svou aplikaci podle článku Kávovar na zdrojáku. Nakonec se mi to podařilo, ale když jsem vložil snippet do vnořené šablony takto:

{snippet}
<table id="mojeWeby" class="tablesorter">
    <thead>
        <tr>
            <th>#</th>
            <th>Screenshot</th>
            <th>Název</th>
		...
        </tr>
    </thead>
    <tbody>
        {foreach $weby as $web}
        <tr>
            ...
            <td class="icon akt"><a href="{link aktualizuj! $web['id']}" class="ajax"><img src="{$baseUri}img/icons/refresh.png" alt="aktualizovat" title="aktualizovat" /></a></td>
            <td class="icon delete"><a href="{link delete! $web['id']}" class="ajax" ><img src="{$baseUri}img/icons/error.png" alt="smazat" title="smazat" /></a></td>
        </tr>
        {/foreach}
    </tbody>
</table>
{/snippet}

Tak to hodí error Parse error: syntax error, unexpected '}' in ... default.phtml on line 7

Funguje to jen, když dám ten {snipper} do @layout.phtml:

	{snippet}
            {include $content}
        {/snippet}

Moc do toho zatím nevidím, ale podle článku na zdrojáku je to dost nejednoznačné a mělo by to fungovat i tak jak jsem to napsal já. Chová se to takto normálně? Nebo kde by mohla být chyba?

jasir
Člen | 746
+
0
-

Nevím, co je špatně, ale když chceš použít include na šablonu, kde jsou snippety,
musíš použít zavináčovou magii: @{include $content}

Martin Mates
Člen | 179
+
0
-

Já tím {snippet} musím obalit vždy celou šablonu? Nehází mi to parse error jedině když mám snippet na začátku a na konci šablony. Když tím obalím jen kousek kódu tak Parse Error.

<script>

{snippet}
{if $weby}

<table id="mojeWeby" class="tablesorter">
    <thead>
        <tr>
            <th>#</th>
            <th>Screenshot</th>
            <th>Název</th>
            <th>URL</th>
            <th>Kategorie</th>
            <th>UIP</th>
            <th title="PageRank">PR</th>
            <th title="Srank">SR</th>
            <th title="AlexaRank">AR</th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        {foreach $weby as $web}
        <tr>
            <td class="center">{$iterator->getIndex() + 1}.</td>
            {if file_exists($www . '/img/screenshots/100x75/' . $web['id'] .'.jpg')}
            <td><img class="screenshot" src="{$baseUri}img/screenshots/100x75/{$web['id']}.jpg" alt="{$web['url']|truncate:30}" title="{$web['url']|truncate:30}" /></td>
            {else}
            <td><img class="screenshot" src="{$baseUri}img/no_screen_small.png" alt="Není k dispozici" title="Screenshot není k dispozici. Zkuste tlačítko aktualizovat screenshot." /></td>
            {/if}
            <td>{$web['nazev']}</td>
            <td><a href="{$web['url']}">{$web['url']|truncate:30}</a></td>
            <td>{$web['kategorie']}</td>
            <td>{$web['uip']}</td>
            <td class="google">{$web['pagerank']}</td>
            <td class="seznam">{$web['srank']}</td>
            <td class="alexa">{$web['alexarank']}</td>
            <td class="icon"><a href="{link Mojeweby:editovat $web['id']}"><img src="{$baseUri}img/icons/pencil.png" alt="editovat" title="editovat" /></a></td>
            <td class="icon akt"><a href="{link aktualizuj! $web['id']}" class="ajax"><img src="{$baseUri}img/icons/refresh.png" alt="aktualizovat" title="aktualizovat" /></a></td>
            <td class="icon delete"><a href="{link delete! $web['id']}" class="ajax" ><img src="{$baseUri}img/icons/error.png" alt="smazat" title="smazat" /></a></td>
        </tr>
        {/foreach}
    </tbody>
</table>




<script type="text/javascript">
    $(function() {
        $("#mojeWeby").tablesorter({
            sortList: [[0,0]],
            headers: { 1: { sorter: false}, 9: { sorter: false}, 10: {sorter: false}, 11: {sorter: false} }
        });

        $('td.delete a.ajax').click(function() {
            var ret = confirm('Opravdu smazat? Pokud je tento web přiřazen nějaké aukci, bude také smazána.');
            if (ret == true) {
                $(this).parent("td").html('');
                $(this).parent("td").html('<img src="{!$baseUri}img/ajax-loader.gif" />');
                return true;
            } else {
                return false;
            }
        });

        $('td.akt').click(function() {
            $(this).parent("tr").children("td").html('');
            $(this).html('');
            $(this).append('<img src="{!$baseUri}img/ajax-loader.gif" />');
        });



    });
</script>

{else}
Nemáte žádné své weby.
{/if}

<a href=„{link Mojeweby:pridatnovy}“ class=„pridat_novy“>přidat nový web</a>
{/snippet}

</script>

Tomik
Nette Evangelist | 485
+
0
-

Jak píše jasir, zkus dát do @layout.phtml místo tohoto:

{snippet}
    {include $content}
{/snippet}

toto: @{include $content}

Jinak dlaší věc je, že nevím, zda je ideální vkládat snippet přímo do tagu <script>, nehledě na to, že v tom tagu máš pouze html. Ale to jen tak na okraj.. :)

Martin Mates
Člen | 179
+
0
-

Tomik napsal(a):

Jak píše jasir, zkus dát do @layout.phtml místo tohoto:

{snippet}
    {include $content}
{/snippet}

toto: @{include $content}

Jinak dlaší věc je, že nevím, zda je ideální vkládat snippet přímo do tagu <script>, nehledě na to, že v tom tagu máš pouze html. Ale to jen tak na okraj.. :)

Ten <script> je tam jen kvůli nette fóru, aby zvýraznil sytax (nějak tam zůstal). Tu zavináčovou magii jsem samozřejmě zkusil, žádná změna.

jasir
Člen | 746
+
0
-

Jak to chápu já:
Nette celou šablonu obalí do podmínky:

<?php
if (SnippetHelper::$outputAllowed) {
...kód šablony
}
?>

Při ajaxovém požadavku je SnippetHelper::$outputAllowed === FALSE.
Když je někde v šabloně `{snippet}…{/snippet},
z podmíky vyběhne a obsah snippetu se vygeneruje.

<?php
if (SnippetHelper::$outputAllowed) {
...
}  /* tato závorka právě ukončila podmínku, následuje kód snippetu */

   ...kód generující obsah snippetu

if (SnippetHelper::$outputAllowed) { /* a velká podmínka zase pokračuje */
...
?>

Bez použití snippetů se při ajaxu tedy celá šablona negeneruje,
protože ta podmínka vynechá celý obsah šablony.
Proto, když je v šabloně takovýto kód:

<?php
...kód...
{include my_ajax_using_template}
...kód...
?>

vygeneruje nějak takhle:

<?php
if (SnippetHelper::$outputAllowed) {
	...
	echo $template->subTemplate($content)->__toString(TRUE);
	...
}
?>

…čili se šablona neincluduje a případné snippety v ní se vůbec nezpracují.
No a k tomu slouží ta podivuhodná zavináčová magie

Pokud před {include ...} nebo jakoukoliv CurlyBrackets značku vložíme zavináč např. @{include ...},
šablona pro tuto značku vyběhne z podmínky
.

Tedy pro:

<?php
@{include my_ajax_using_template}
?>

vygeneruje něco jako:

<?php
if (SnippetHelper::$outputAllowed) {
...
} /*ukončení podmínky vynucené @*/

		echo $template->subTemplate($content)->__toString(TRUE);

if (SnippetHelper::$outputAllowed) { /* a jsme zase v podmínce :) */
	...
}
?>

Čili se include vykoná správně. No a na podobném principu se aplikuje celá zavináčová magie.
Prostě když vím, že je celá šablona v té velké podmínce, vím, na kterých místech z ní vyběhnout.

Rozhodně doporučuju nebát se toho a podívat se na kód generovaných šablon

Ještě se podívej na příklad z fóra použití zavináče a {if} – zde vidíš, že je nutné (a ono je to logické) označit zavináčem {if},{/if}
i to, co je mezi nimi :)

Editoval jasir (1. 5. 2009 18:50)

Jan Tvrdík
Nette guru | 2595
+
0
-

Něco na způsob jasirova příspěvku by mělo být v dokumentaci.