No quote available.

Tutorial: Upravy sablony entries.tpl


Tento rozvlacny navod je prelozenym vytazkem z diskuzniho vlakna http://www.s9y.org/forums/viewtopic.php?t=4013 (anglicky).

Uvodni otazka znela:

Pomaham jinemu uivateli Serendipity upravit moji upravenou sablonu "Carl blue theme". Pouzili jsme sablonu "entries.tpl" v puvodni prednastavene podobe, radsi nez moji upravenou verzi. Takze ted se samozrejme prispevky poslane v jeden den zobrazuji pohromade. To neni spatne, ale radsi bychom, kdyby bylo mozne oddelit prispevky carami. Aby bylo rozumeno, carami pouze mezi prispevky se stejnym datem, neoddelovat temito carami prispevky s ruznymi daty.

Odpoved (od Judeberta)

Zkusim to vysvetlit hezky Anglicky (hezky Cesky :-)), pokud to jen trochu pujde. Doporucuju to cist za plneho soustredeni, takze ne kdyz vas boli hlava. Mohl bych zacit vysvetlovat, co je to sablonovy system Smarty, ale budu se misto toho drzet otazky. A zkusim to vysvetlit co nejjednodusseji, protoze to mozna budou cist dalsi lide, kteri v tom nemaji zkusenosti.

Rozbor problemu

Nejdrive poradne definujme problem: Chceme oddelovace, ktere vypadaji asi takto:

DATUM 1

clanek 1


clanek 2


clanek 3

DATUM 2

clanek 4


clanek 5

... a tak dal. Kdyz se podivam na tenhle vzor, vidim oddelovace pod kazdym clankem, krome posledniho v jedno datum.

Co je sablona a jak funguje

A ted, clanky se skladaji z ruznych casti: nadpis, telo, paticka, atd. Ve strukture stranky existuje <div>, ktery obaluje tohle (skoro) vsechno dohromady. Pro jednoduchost nejdrive pridame oddelovac za kazdy clanek. HTML tag pro oddelovaci caru je <hr>, hr jako Horizontal Rule. Dokonce k tomu ani nepotrebujeme zadne CSS.

Protoze sablona je misto, kde se schovava HTML kod, staci zmenit prave tuhle sabonu. Taky vime (nebo nam to nekdo mui rict:-) ), ze entries.tpl je prave ta sablona, ve ktere se schovava HTML kod pro zobrazeni prispevku. A prave ji budeme menit.

System Smarty si vsima jenom toho, co je uzavreno ve slozenych zavorkach {}. To jsou pro nej pokyny, co ma delat. Vsechno ostatni zobrazi tak jak lezi a bezi jako obycejne HTML. Kdyz si odmyslime ze sablony vsechno, co nas nezajima, zbyde nece jako:

{foreach from=$entries item="dategroup"}
    <div class="serendipity_Entry_Date">
        {if $dategroup.is_sticky}
        <h3 class="serendipity_date">{$CONST.STICKY_POSTINGS}</h3>
        {else}
        <h3 class="serendipity_date">
{$dategroup.date|@formatTime:DATE_FORMAT_ENTRY}</h3>
        {/if}
        {foreach from=$dategroup.entries item="entry"}
        <h4 class="serendipity_title">
<a href="{$entry.link}">{$entry.title}</a></h4>
        <div class="serendipity_entry 
serendipity_entry_author_{$entry.author|@makeFilename} 
{if $entry.is_entry_owner}serendipity_entry_author_self{/if}">
        ... obsah prispevku ...
        </div>
        {/foreach}
        ... dalsi blbosti ...
    </div>
    {foreachelse}
    {if not $plugin_clean_page}
        {$CONST.NO_ENTRIES_TO_PRINT}
    {/if}
    {/foreach}

Prvni smycka {foreach} projede kazdou polozku v $entries (prispevky), coz je pole, do ktereho Serendipity predvyplnila jednotlive casti clanku. Serendipity seskupuje a radi prispevky podle data, takze pro kazde datum projede Smarty tuhle smycku pouze jednou pro jedno datum. Pro kazde datum pak vytvori blok <div> pro $dategroup (skupina prispevku v datu), pak vytiskne datum (a nebo stale prispevky, pokud je to zrovna skupina stalych prispevku).

$dategroup muze obsahovat vice clanku. Dalsi smycka {foreach} pak projde vsechny tyto jednotlive clanky, z nichz kazdy pojmenuje jako "$entry". Jednotlivy prispevek ($entry) je pak zobrazen v bloku <div>, ve kterem je zobrazen obsah prispevku. Pak se smycka dostane ke svemu konci ({/foreach}) a pokracuje dalsim prispevkem.

Reseni cislo 1

Pokud chceme cokoliv vlozit na konec prispevku, je toto prave to misto, kam to vlozime. Takze kdyz chceme vlozit caru, vepiseme <hr> na spravne misto, asi takhle:

        ... obsah prispevku ...
        </div>
        <hr>
        {/foreach}
        ... dalsi blbosti ...
    </div>
    {foreachelse}

Tohle bude fungovat, jen budeme mit oddelovaz za kazdym prispevkem. Bude to vypadat asi takto:

DATUM 1

clanek 1


clanek 2


clanek 3


DATUM 2

clanek 4


clanek 5


Reseni cislo 2 = pozadovany vysledek

Vidite ten oddlovac i za poslednimi clanky? Ten nechceme, takze se ho zbavime.

Pokud se podivate do kodu, ktery jsme prave projeli, uvidite prikaz {if} - podminku. Pomoci neho se zobrazuje text STICKY_POSTINGS (staly prispevek), pokud je clanek stalym prispevkem. Pokud podminka pro staly clanek neni splnena, zobrazi se jako obvykle datum. Podobne muzeme pouzit podminku {if} k pridani tridy (class) bloku prispevku, pokud si clovek, autor prohlizi vlastni clanek (serendipity_entry_author_self). Dost dobry, co?

Takze podobne my pridame jednu nasi vlastni podminku {if}, ktera nam rekne, jestli je clanek prvni. Z ruznych duvodu nebudeme testovat, jestli je clanek posledni, lepe nam pujde testovat, jestli clanek je prvni. A pokud clanek neni prvni ve skupine, pridame pred nej oddelovaci caru. Pokud je clanek ve skupine jediny, je automaticky i prvni, takze se u nej oddelovaci cara zobrazovat nebude.

Nastesti nam Smarty presne tuhle vec umoznuje zjistit. Nanestesti to ale neni nic z toho, co muzeme vycist z promennycg "entry" nebo "dategroup". Musime to zajistit primo z cyklu {foreach}. Musime mu priradit jedinecne jmeno, aby nebyl cyklus zamenitelny s jinym cyklem {foreach}.

Musime pro to udelat dve veci:

1) Pojmenovat nas cyklus {foreach}.

2) Polozit cyklu {foreach} dotaz, zda-li je v posledni smycce a pokud ano, nevypisovat oddelovac.

Nic sloziteho. Takhle pojemnujeme nas cyklus:

   {foreach name="dategroup" from=$dategroup.entries item="entry"}

Jednoduse pridame atribut "name". Muzeme pouzit jakekoliv, ale pro nas pripad je jmeno "dategroup" dostatecne jednoduche a logicke zaroven. Na nas cyklus se ted muzeme odkazovat jako:

   $smarty.foreach.dategroup

A ted, jak zjistime, jestli je cyklus v prvni smycce (to znamena prvni prispevek)

        {if $smarty.foreach.dategroup.first}
        <!-- Zadny oddelovac pro prvni prispevek! -->
        {else}
        <hr>
        {/if}

Takhle to bude fungovat. Ale jde to jeste jednoduseji. Chceme oddelovac pouze pokud nejsme v prvni smycce. Staci pred podminku pridat "not" (negace) a muzeme uple vypustit cast {else}:

        {if not $smarty.foreach.dategroup.first}
        <hr>
        {/if}

Kratsi kod je lepsi, protoze rychlejsi. Sice v tomhle pripade neznatelne, ale... vite, jak to myslim :-)

Samozrejme nemusime vkladat jen caru <hr>. Muzeme stejne dobre pridat cely blok <div>, <span>, obrazek <img> nebo cokoliv dalsiho. A pokud trochu rozumite CSS stylum, klidne muzete pridat dalsi tridy blokum, ktere chcete pozmenit. Tj. zmenit jim okraje, zvetsit odstup textu od okraju, zmenit barvu pozadi, cokoliv. Ale to je na dalsi clanek.

Zaverem

V diskusnim vlaknu zminenem nahore (pro jistotu pridavam i zde http://www.s9y.org/forums/viewtopic.php?t=4013 (anglicky) ) muzete najit k tematu podrobnejsi poznamky a doporuceni. Diky Judebertovi za jeho vysvetleni a za pridani sem na wiki. (A diky Vladovi, ktery tohle prelozil do cestiny:-))


Preklad - Vlada Ajgl, 2007/12/02, pro verzi Serendipity 1.2