Základy nejzákladnější – layout/šablony a jak je použít
- icanjan
- Člen | 30
Zdravím, už několik dní bojuju s Nette. Začínám s ním, stejně jako s PHP, takže se možná ptám na úplné blbosti, co jsou všem jasné, ale…
Trocha zoufalství na začátek
Jsou někde popsané nějaké úplné základy? Např co je/jaký je rozdíl
mezi šablonou a layoutem a snippetem?
Kam patří které soubory, na co jsou…? I když tak nějak intuitivně
chápu, co je .latte, je to někde popsané? V příkladech jsou soubory .phtml
a v dokumentaci .latte… mám v tom naprostý bordel.
Snažil jsem se rozjet examply CD-collections, Fifteen atd. Proč musím ručně
dokopírovat do složky vendor složku others kde je jen prázdný .gitignore?
Co to je? K čemu to je? Proč to není nikde napsané? Proč je v jednom
příkladu $container = require __DIR__ . ‚neconeco‘; jednou v index.php a
podruhé v bootstrap.php? No, asi je to jedno, ale je to strašně matoucí pro
nováčky.
Chybí mi návod, kde bude napsané „Lamo, abys mohl používat latte, musíš
udělat to a to, a dát to můžeš jen tam a tam, protože to a to to tam
hledá… :-(“ Nějaký diagrámek vztahů, já nevím… Furt v dokumentaci
čtu jak to bude s nette jednodušší, jak si ho zamiluju… tak já už chci,
to mít jednodušší, ale když mě to nejedéééé :-(
Tak a teď něco konkrétního
Upravuji vzorový příklad sandbox – možná nette-blog – já nevím,
chvíli se to v dokumentaci jmenuje nějak, pak zase nějak. Jako kdyby se
měnila verze, ale nebylo to pořádně označené, části zůstaly
zastaralé atd…
v @layout.latte mám hlavní kostru stránek, tady něco jako
<div> {include leftColumn} </div>
<div> {include content} </div>
v Homepage/default.latte něco takovéhoto
{block leftColumn}
<ul class="mainmenu">
<li><a n:href="prvni">Prvni</a></li>
<li><a n:href="druha">Druha</a></li>
</ul>
{/block}
{block content}
Prvni stranka
{/block}
no a teď chci vytvořit tu druhou stránku, takže jsem si udělal soubor
v Homepage druha.latte, kde bych chtěl mít jen ten
{block content}, abych tam podruhé už nemusel znovu psát to
menu. No, ale aby mě to fungovalo, tak tam musím mít oba bloky. Tak to je
přece blbost, proto se snažím použít nette, abych tohle nemusel dělat.
Když jsem si cvičně zkopírova všechny bloky, aby se mě po kliknutí na
odkaz zobrazila ta druhá stránka, tak se sice zobrazila, ale očividně něco
je špatně. Nejsou vidět obrázky a některé styly, jako by se najednou
stránka načítala z jiného umístění a cesty byly špatně.
V URL se místo http://localhost/…andcrew/www/ zobrazilo http://localhost/…mepage/druha.
Dokumentaci o routován, šablony a vše podobné jsem si přečetl, ale prostě mě to nic nedalo, mám v tom akorát zmatek. Nejsou někde popsané úplné základy?
Předem díky za rady, jak to má fungovat a co dělám špatně. Popřípadě krátkou lekcí základů nepohrdnu naopak přivítám.
- Jan Tvrdík
- Nette guru | 2595
co je/jaký je rozdíl mezi šablonou a layoutem a snippetem?
Layout je obvykle ta část šablony, kterou mají jednotlivé stránky společné. Snippet je v nette terminologii kus šablony, který lze snadno aktualizovat AJAXem. Jako začátečník se snippetům radši úplně vyhni.
V příkladech jsou soubory .phtml a v dokumentaci .latte
.phtml
je přípona, který se používala před mnoha lety,
najdeš ji tedy ve starých příkladech. Není mezi nimi žádný rozdíl, ale
přípona .latte
je modernější. Něco jako .jpg
a
.jpeg
.
Proč musím ručně dokopírovat do složky vendor složku others kde je jen prázdný .gitignore?
Prázdnou složku others
určitě nikam kopírovat nemusíš.
Soubor .gitignore
říká, které soubory má verzovací nástoj
Git ignorovat. Pokud Git nepoužívat, tak můžeš s klidným svědomím
všechny .gitignore
soubory smazat.
Proč je v jednom příkladu $container = require __DIR__ . ‚neconeco‘; jednou v index.php a podruhé v bootstrap.php?
Jestli myslíš to, co si myslím, že si myslíš, tak je to jedno. Příklady (na planette) se můžou lišit, protože jsou často zastaralé.
chci vytvořit tu druhou stránku, kde bych chtěl mít jen ten {block content}
Pokud je to menu společné pro všechny stránky, tak patří to layoutu, ne do šablony konkrétní stránky.
Nejsou vidět obrázky a některé styly, jako by se najednou stránka načítala z jiného umístění a cesty byly špatně.
Tohle jsou základy HTML, ach jo. Máš špatně cesty. V nette se to
obvykle řeší tak, že do všech cest necháš vypsat proměnnou
{$basePath}
, viz např. https://github.com/…layout.latte#…
Nejsou někde popsané úplné základy?
Obecně dokumentace PHP + dokumentace Nette + logické uvažování by mělo stačit. V případě, kdy nestačí je tu fórum nebo se můžeš naučit číst zdrojové kódy Nette.
- Panda
- Člen | 569
Psaním základní aplikace by tě měl provést quickstart, ale dlouho jsem ho nekontroloval, takže nevím, jak moc je aktuální a kolik toho doopravdy vysvětluje.
K celému povzdechu: prosím o konkrétní informace. Sice píšeš, že v jednom example je něco a ve druhém něco jiného, ale když ani neřekneš, které příklady to jsou, tak se s tím opravdu těžce něco dělá. Totéž k tomu příkladu, který upravuješ – když nevím, jaký to je, nedokážu poradit. Dokumentace/fórum/pla.nette se na něj možná může odkazovat pod různými jmény, ale URL nebo složku v balíčku bude mít pořád stejnou.
Ještě k *.latte
vs *.phtml
– jedná se
o historickou záležitost z doby, kdy Latte nebylo Latte, ale jen drobná
vrstva, která generovala PHP. V oficiálních examples by mělo být už
dávno použité pouze *.latte
, tady na fóru a v některých
starších návodech na pla.nette může být ještě *.phtml
.
V zásadě jde o jednu a tu samou šablonu. Pokud je někde v něčem
oficiálním (dokumentace, example z distribuce apod.) použito
*.phtml
, tak prosím o konkrétní informace, kde to najít.
K blokům: vtip je v tom, že makro {include}
vkládá blok na
dané místo. No, a aby mohlo blok vložit, musí ten blok někde existovat,
stejně jako při volání include
v čistém PHP musí existovat
uvedený soubor. Při vykreslování té druhé stránky Latte nic neví
o blocích definované v té první, vykonává se jen
@layout.latte
a pak stránka příslušného view.
Řešení: přesunout menu do layoutu, kde by mělo logicky být:
<div>
{block leftColumn}
<ul class="mainmenu">
<li><a n:href="prvni">Prvni</a></li>
<li><a n:href="druha">Druha</a></li>
</ul>
{/block}
</div>
<div> {include content} </div>
Blok pak můžeš přepisovat v jednotlivých dílčích stránkách stejně, jako u toho include.
Obrázky a styly máš rozbité nejspíš kvůli tomu, že uvádíš pouze relativní odkazy:
<img src="img/obrazek.png" />
Ty jsou relativní k aktuálnímu souboru, tj. po přechodu na
homepage/druha
se všechno vyhledává relativně ke složce
homepage
, která nejspíš ani neexistuje.
Řešení: použít absolutní URL s proměnnou {$basePath}
,
která obsahuje cestu ke kořenovému adresáři veřejné části projektu (tj.
ten, kde je index.php
):
<img src="{$basePath}/img/obrazek.png" />
Co se týče dokumentace, tak doporučuji začít již zmíněným quickstartem, pak Slovníček pojmů a MVC aplikace & presentery. Pokud nemáš předchozí zkušenosti s vývojem pro web z jiných jazyků (C#, Java, Python, Ruby…), tak si nemyslím, že začínat současně s PHP a s Nette je dobrý nápad. Nette vychází logicky z principů a architektury PHP aplikací, proto spousta věcí v dokumentaci řečena není, protože se předpokládá znalost PHP.
- Šaman
- Člen | 2666
icanjan napsal(a):
Snažil jsem se rozjet examply CD-collections, Fifteen atd. Proč musím ručně dokopírovat do složky vendor složku others kde je jen prázdný .gitignore? Co to je? K čemu to je?
Do aresáře /vendor/others
patří externí knihovny, které
nejsou pod správou composeru. Ale dříve byl ten adresář úplně prázdný
(nebyl tam ani ten .gitignore) a některé programy (a mám podezření, že
i git) tento prázdný dresář ignorovaly. Problém je, že když chybí,
vyběhne ti chyba. Proto se do projektů starších, než dva měsíce musí
často nakopírovat ručně.
Proč je v jednom příkladu $container = require __DIR__ . ‚neconeco‘; jednou v index.php a podruhé v bootstrap.php?
Na tohle narazíš častěji. Sandbox není Nette a tak se čas od času změní nějaká věc, která se dá napsat více způsoby. Dříve se bootstrap používal na všelijaká nastavení (třeba definici rout), teď jen připraví a vrátí aplikační kontejner. Všechno ostatní se postupem času přesunulo do configu.
Furt v dokumentaci čtu jak to bude s nette jednodušší, jak si ho zamiluju… tak já už chci, to mít jednodušší, ale když mě to nejedéééé :-(
Žádná dokumentace pro úplné začátečníky není. I proto, že
programátoři neradi píší dokumentace a protože se Nette stále mění. Ale
hlavní problém je v tom, že teprve začínáš s PHP. Zkus si napsat blog
v čistém PHP a pak to samé v Nette. Teprve pak pochopíš, v čem to je
jednodušší. Bohužel vstupní bariéra je poměrně velká.
Jestli máš takové problémy, tak ti ještě doporučím nevyužívat zatím
„objektový“ přístup k databázi pomocí ->table()
, ale
pro začátek si psát čisté query a Nette\Database použít jen jako
chytřejší dotazovač (řeší escapování, snadné připojení a změnu
databáze apod).
- icanjan
- Člen | 30
Díky všem za reakce. Je mi jasné, že mám s Nette problémy, protože neumím to PHP. Jsem si právě myslel, že když se naučím Nette, tak nemusím moc do toho PHP. Něco jako, že když umím Qt, nemusím se učit OpenGL… Ale v tomto případě mě ty základy opravdu chybí. Nevzdávám se a bojuju dál.
Teď konkrétně:
Rada s {$basePath} opravdu pomohla. Díky
<img src="{$basePath}/img/obrazek.png" />
Ale potom když v souboru Homepage/defaul.latte mám tu první stránku (viz příklad v prvním postu) a překliknu se v tom menu na tu druhou – tedy Homepage/druha.latte, tak podle mého chápání jsem pořád ve stejné složce, tedy by měly fungovat i relativní odkazy. Ale nefungovaly, jak to?
Dále bych poprosil o podrobnější vysvětlení tohoto:
Jan Tvrdík:
Pokud je to menu společné pro všechny stránky, tak patří to layoutu, ne do šablony konkrétní stránky.
Jaký je rozdíl mezi layoutem a šablonou konkrétní stránky? Poznám to nějak podle jména/umístění souboru? Jak to poznám v kódu?
Chápu to tak, že layout je něco, co se moc nemění. Takže je to třeba struktura stránky, kde se pak mění jen třeba obsah podle toho kde jsem v menu. No a to, co se mění, to je pak ta šablona stránky? To mě pak mate, proč se to jmenuje šablona, když už je to jiné pro každou stránku. Šablona stránky se do layoutu vkládají tím {include sablona}?
A ještě ke strukturování webu (rozšíření mé otázky
z prvního postu):
dejme tomu, že mám základní strukturu stránky, která obsahuje 4 bloky. To
mám tedy udělané v @layout.latte. A pomocí {include
blok1},{include blok2}… si tam vložím obsah.
Stránka pak vypadá třeba takto: A | B | C | D
A pak mám další stránky, třeba s tímto obsahem: A | B | E |
F další A | G | H | D
No a jak to teď tedy vyřešit s těma includama? Blok A si
můžu dát přímo do layoutu, ale co to ostatní? Doposud si myslím, že bych
pro každou stránku (každý ze třech příkladů), měl mít jednu šablonu
stránky – tedy jeden .latte soubor – a tam musím mít všechny tři
zbývající bloky těch includů… no ale to se pak B a D
bude opakovat a určitě to není správné použití. Takže předpokládám,
že tady mě něco hodně uniká. Jak tady na tuto problematiku správně?
- Šaman
- Člen | 2666
Začni základama. Tam se include makro ani nevyužívá, ty si v layoutu nadefinuješ blok a ten v šabloně naplníš. Základní idea layoutu je mít na jednom místě kostru html dokumentu a jednotlivé pohledy pak přepisují jen obsah stránky. Dá se s tím samozřejmě dělat sousta kouzel, ale základ na první aplikaci je jeden layout a spousta šablon pohledů, které ten layout extendují (to se děje automaticky).
K tomu $basePath
: Nikdy nevíš, kde šablona bude. Když se
časem rozhodneš všechnu svoji práci přesunout do modulu (třeba Frontend),
tak se ti najednou relativní umístění aresáře /www
změní.
A ta proměnná $basePath
to jistí. Používej ji všude, je
přístupná i v komponentách (které se také mohou celé přesouvat vcelku
libovolně).
To tvoje A|B|C|D|F nejpíš budou řešit komponenty, případně (jde-li jen o html bez obslužného php kódu) tam použiješ to makro include. V každé šabloně pak vypišeš co chceš za komponenty/includy. Do layoutu patří jen skutečně společné věci, jako třeba nabídka, horní banner a další. Můžeš mít více layoutů (třeba jeden normální a jeden pro nepřihlášeného uživatele bez nabídky), ale ani tak by tam nemělo být nic, co se týká obsahu stránky.
Editoval Šaman (15. 6. 2014 22:36)
- mpis
- Člen | 65
to icanjan
Podívej se sem:
http://www.itnetwork.cz/…-a-tutorialy
To je přesně to, co potřebuješ.
Sám jsem se těmito začátečnickými problémy prokousával velmi obtížně.
A jenom proto, že dokumentace k Nette je zoufale špatná, zejména pro
začátečníky. Tím je pak jinak vynikající Nette degradováno. Tvůrci
Nette jsou mimo jakoukoliv pochybnost dobří programátoři, ale to je asi tak
všechno. Vytvořit dobrou dokumentaci se jim nepodařilo a jak se zdá, tak se
o to ani nijak moc nesnaží. A mám dojem, že nejen dokumentace, ale
i propagace značně pokulhává.
Ale i přes tyto obtíže je dobré vytrvat a Nette se naučit.
- buffus
- Člen | 101
@icanjan Doporučil bych zhlédnout pěkné video NETTE framework – static pages, menu. Je sice staršího data (únor 2011, Nette v2.0 Alpha 2), ale prezentovaný postup na vytvoření statického webu předpokládám bude fungovat i pro současnou v2.2.1.
- Mesiah
- Člen | 240
A ještě ke strukturování webu (rozšíření mé otázky z prvního postu):
dejme tomu, že mám základní strukturu stránky, která obsahuje 4 bloky. To mám tedy udělané v @layout.latte. A pomocí {include blok1},{include blok2}… si tam vložím obsah.Stránka pak vypadá třeba takto: A | B | C | D
A pak mám další stránky, třeba s tímto obsahem: A | B | E | F další A | G | H | D
No a jak to teď tedy vyřešit s těma includama? Blok A si můžu dát přímo do layoutu, ale co to ostatní? Doposud si myslím, že bych pro každou stránku (každý ze třech příkladů), měl mít jednu šablonu stránky – tedy jeden .latte soubor – a tam musím mít všechny tři zbývající bloky těch includů… no ale to se pak B a D bude opakovat a určitě to není správné použití. Takže předpokládám, že tady mě něco hodně uniká. Jak tady na tuto problematiku správně?
Ahoj, hele píšu z hlavy, tak to nemusí 100% sedět… ale myslím, že tyhle snippety by ti mohly pomoci
Layout:
<div>{block blok1}A - v podstatě failblock (zobrazí se pokud budu inludovat parenta, jinak se přepíše){/block}</div>
<div>{block blok2}B{/block}</div>
<div>{block blok3}C{/block}</div>
<div>{block blok4}D{/block}</div>
Homepage/default
<div>{block blok1}{include parent}{/block}</div>
<div>{block blok2}{include parent}{/block}</div>
<div>{block blok3}E{/block}</div>
<div>{block blok4}F{/block}</div>
Homepage/foo
<div>{block blok1}{include parent}{/block}</div>
<div>{block blok2}G{/block}</div>
<div>{block blok3}H{/block}</div>
<div>{block blok4}{include parent}{/block}</div>
A máš pravdu, A může být napevno v layoutu, pokud jej nebudeš měnit. A je ještě fajn si uvědomit, že můžeš includovat taky view dané cestou, takže se můžeš vyhnout tomu, že máš více stejných view a jedna změna by musela být provedena na více místech…
Editoval Mesiah (16. 6. 2014 9:51)