První projekt s nette – pár dotazů

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

Ahoj, jen bych se potřeboval ujistit, že to mám správně:

Když chci, aby mi to na locallhostu ukazovalo laděnku s chybama a zorazoval se debugbar a na hostingu se ukazovali „pěkné“ chybové hlášky a zapisovalo se do logu, tak jsem v boot strap nastavil toto:

$configurator->enableDebugger(Nette\Diagnostics\Debugger::DETECT,__DIR__ . '/../log');

Nic jiného ohledně debugg. jsem tam nedával… Mám to dobře, nebo něco ještě chybí? Nemůžu to vyzkoušet ještě prakticky, protože hosting ještě není zařízený, proto se ptám… Díky…

jiri.pudil
Nette Blogger | 1032
+
0
-

Není to správně. Když se podíváš do API dokumentace, zjistíš, že do enableDebugger předáváš špatné argumenty. Prostředí se dá nastavit pomocí setDebugMode, ale dělat to nemusíš, automatická detekce je výchozí.

n.u.r.v.
Člen | 485
+
0
-

Ahá, díky…, takže pokud chápu dobře, tak stačí mít ohledně debug. jen toto:

$configurator->setDebugMode();
$configurator->enableDebugger(__DIR__ . '/../log');

A pak je to tedy automatická detekce…

jiri.pudil
Nette Blogger | 1032
+
0
-

Voláním

$configurator->setDebugMode();

natvrdo zapneš debug režim (protože ta metoda má výchozí hodnotu parametru TRUE). Stačí toto:

$configurator->enableDebugger(__DIR__ . '/../log');
n.u.r.v.
Člen | 485
+
0
-

Ok, já si to myslel, ale pak jsem to tam dopsal $configurator->setDebugMode(); ok, díky

n.u.r.v.
Člen | 485
+
0
-

Ahoj, tak mám další dva problémy:

  1. v latte mám jquery funkci tablesorter, který má některé parametry v {závorkách} – jak to mám oddělit od nette-latte? Protože dostávám od latte hlášku, že proměnná v {} neexistuje
  2. a druhý problém je, že z db dostanu seznam a ten vypisuji v latte do tabulky a já bych potřeboval aby byly všechny položky v řádku jako odkazy (stejný cíl)… Jde to udělat lepším způsobem než ke každé buňce dávat zvlášť ten stejný odkaz?

Takhle mám vykreslení tabulky:

<tr n:foreach="$seznam as $list">

<td><a href="{link odkaz:?parametr=$list->polozka1}">{$list->polozka1}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka2}">{$list->polozka2}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka3}">{$list->polozka3}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka4}">{$list->polozka4}</a></td>

</tr>
JHadamcik
Člen | 47
+
0
-

n.u.r.v. napsal(a):

Ahoj, tak mám další dva problémy:

  1. v latte mám jquery funkci tablesorter, který má některé parametry v {závorkách} – jak to mám oddělit od nette-latte? Protože dostávám od latte hlášku, že proměnná v {} neexistuje
  2. a druhý problém je, že z db dostanu seznam a ten vypisuji v latte do tabulky a já bych potřeboval aby byly všechny položky v řádku jako odkazy (stejný cíl)… Jde to udělat lepším způsobem než ke každé buňce dávat zvlášť ten stejný odkaz?

Takhle mám vykreslení tabulky:

<tr n:foreach="$seznam as $list">

<td><a href="{link odkaz:?parametr=$list->polozka1}">{$list->polozka1}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka2}">{$list->polozka2}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka3}">{$list->polozka3}</a></td>
<td><a href="{link odkaz:?parametr=$list->polozka4}">{$list->polozka4}</a></td>

</tr>

Odkazy tuším napsat musíš, ale používej je

{link Presenter:action, 'parameter' => $list->polozka1}

A latte se escapuje mezerou (nebo alespoň mě to fungovalo)

{ obyčejný text}
Aurielle
Člen | 1281
+
0
-

Nebo můžeš použít makra {l} a {r}, které vykreslí levou, resp. pravou složenou závorku.

n.u.r.v.
Člen | 485
+
0
-

Jo, ještě poznámka k těm odkazům v tabulce – bylo by možné udělat celý klikací řádek?

Něco jako

<tr n:foreach="$seznam_akci as $list" n:href="odkaz">

Toto ale nefunguje…díky

petr.pavel
Člen | 535
+
0
-

Poslyš, asi by sis měl zopáknout základy HTML :-) Pro odkaz je tag A, ne TR.

Jestli se ti nechce opakovat A v každé buňce a roztahovat ho na celou šířku buňky, tak budeš muset použít JavaScript. Ale to už jsme utekli od Nette.

frosty22
Člen | 373
+
0
-

n.u.r.v. napsal(a):

Jo, ještě poznámka k těm odkazům v tabulce – bylo by možné udělat celý klikací řádek?

Něco jako

<tr n:foreach="$seznam_akci as $list" n:href="odkaz">

Toto ale nefunguje…díky

Předpokládám, že v tabulce chceš mít jenom jeden link, u více odkazů by bylo klikání na celý řádek relativně zavádějící takže v tomto případě, pokud používáš jQuery, pak to jde relativně snadno, například:

$("tr").click(function() {
  window.location.href = $(this).find("a").attr("href");
});

A tabulka například:

<table>
	<tr n:foreach="$seznam_akci as $list">
		<td>Foo</td>
		<td>Bar</td>
		<td><a n:href="odkaz">Link</a></td>
	</tr>
</table>

BTW: Řešení implementace JS je samozřejmě mnoho, tohle má pak ještě výhodu, když nebude zaplý javascript a nebo prostě tu funkcionalitu dáš pryč, stále tam zůstane ten klikatelný Link :)

n.u.r.v.
Člen | 485
+
0
-

petr.pavel:

Poslyš, asi by sis měl zopáknout základy HTML :-) Pro odkaz je tag A, ne TR.

Jestli se ti nechce opakovat A v každé buňce a roztahovat ho na celou šířku buňky, tak budeš muset > > > použít JavaScript. Ale to už jsme utekli od Nette.

Hmm, to jsme si nerozuměli – chtěl jsem celej klikací řádek – aby se uživatel nemusel strefovat na odkaz v buňce, ale aby kdykoliv mohl kliknout na řádek tabulky – tak jsem si myslel, že by mohlo vyjít dát do tr href…

Ale už vyřešeno jinak…

frosty22
Člen | 373
+
0
-

Náhodou ti rozumněl správně, stejně jako já, ale chtěl ti říci, že v HTML nemá řádek tabulky tj. TR atribut HREF. Ke „klikání“ slouží odkazu a to je tag A. Proto ti nabízel buď možnost dát do každé buňky odkaz „A“ a přes styly ho roztáhnout přes celou buňku, tím pádem by všechny linky v řádku vedli na to samé a splnilo by to účel. A nebo druhá možnost využít JavaScript, kde se dá podchytit událost kliku na řádek buňky.

A v podstatě to řešení, co jsem ti tam napsal, tak to je takový průnik – je tam odkaz, aby když nefunguje JavaScript, tak šlo přesměrovat i bez něj tj. tím odkazem ale zároveň jsem ti tam napsal fci pro jQuery, která udělá to, že při události kliknutí na řádek najde odkaz uvnitř toho řádku, vezme si z něj HREF a přesměruje na něj.

n.u.r.v.
Člen | 485
+
0
-

frosty22: aha, díky…já už jsem to právě taky vyřešil přes js…takže ok…

a ještě by mě zajímala tato věc:

Jde nějak do config.neon zapsat konstanty které v aplikaci používám?

Např. odesílací emailová adresa, počet nějakých pokusů apod?

Když jsem ještě nepoužíval nette, tak jsem si udělal soubor config.php a tam jsem dal potřebná konfigurační data (pole apod) a ten soubor includoval do aplikace.

Vím že to stejné by třeba šlo udělat v basepresenteru, ale myslím, že hezčí by to bylo oddělené někde v nějakém configu…

  • potřebuji se k těm hodnotám dostat jak z presenteru, tak z repositářů…

Jak to co nejlíp řešit? Díky…

Editoval n.u.r.v. (18. 7. 2013 16:49)

JHadamcik
Člen | 47
+
0
-

n.u.r.v. napsal(a):

frosty22: aha, díky…já už jsem to právě taky vyřešil přes js…takže ok…

a ještě by mě zajímala tato věc:

Jde nějak do config.neon zapsat konstanty které v aplikaci používám?

Např. odesílací emailová adresa, počet nějakých pokusů apod?

Když jsem ještě nepoužíval nette, tak jsem si udělal soubor config.php a tam jsem dal potřebná konfigurační data (pole apod) a ten soubor includoval do aplikace.

Vím že to stejné by třeba šlo udělat v basepresenteru, ale myslím, že hezčí by to bylo oddělené někde v nějakém configu…

  • potřebuji se k těm hodnotám dostat jak z presenteru, tak z repositářů…

Jak to co nejlíp řešit? Díky…

Hledej šmudlo. Milionkrát a jednou zodpovězený dotaz.

frosty22
Člen | 373
+
0
-

Například zde https://forum.nette.org/…lou-aplikaci

Akorát tedy brát parametry z konfigu v presenteru není zrovna best practice .. viz problém service locater ala $this->context …

Správným řešením by bylo mít danou službu a té ty parametry předat, čili například jsi uvedl odesílací adresa, čili tím pádem bych si udělal nějaký objekt EmailDispatcher, který bych zaregistroval jako službu v neonu, a tomu předal parametr odesílací emailové adresy + by zařizovala odesílání emailů a poté již bych předával presenteru tuto službu:

Takže ve finále bys měl v presenteru něco jako:

<?php
class FooPresenter extends Presenter {

   /** @var EmailDispatcher */
   protected $emailDispatcher;

   /** Tuto metodu volá nette samo a předává službu z kontextu */
   public function injectEmailDispatcher(EmailDispatcher $emailDispatcher)
   {
       $this->emailDispatcher = $emailDispatcher;
   }

   public function actionDefault()
   {
        // Tady příklad volání tvé služby na odesílání emailů
   	$this->emailDispatcher->send("mojesablona.latte", "uzivatel@novak.cz");
   }

}
?>

V neonu již jen:

common:
   parameters:
      sender: "odesilatel@example.com"

   services:
      EmailDispatcher: EmailDispatcher(%email.sender%)

A ještě tedy ta implementace tvého objektu na odesílání emailů, třeba:

<?php
class EmailDispatcher extends \Nette\Object {

   private $sender;

   public function __construct($sender)
   {
      $this->sender = $sender;
   }

   public function send($filename, $receiver)
   {
	$template = new FileTemplate($filename);
        $email = new Message();
        $email->setFrom($this->sender);
        $email->addTo($receiver);
        $email->setHtmlBody($filename);
        // .. apod. tohle je nefunkční příklad, jen schéma
   }

}
?>

BTW: Nejedná se o funkční příklad jen schéma, jak by to mohlo být

n.u.r.v.
Člen | 485
+
0
-

Hmm, asi něco dělám blbě… Na odesílání e-mailů mám v app/model soubor EmailRepository, ve kterém je metoda pro odeslání e-mailu: public function send_meil(příjemce, předmět, text, soubor=null).

A teď jsem chtěl dát do config.neon ten parametr „odesilatel“:

common:
	parameters:
		email_odesilatel: 'muj@email.cz'
...
...

services:
		authenticator: Authenticator
		routerFactory: RouterFactory
		router: @routerFactory::createRouter

		...
		emailRepository: Todo\EmailRepository(@parameters.email_odesilatel)

Jenže pak nevím co dál – jak v emailRepository přijmout ten předaný parametr? Když jsem udělal:

private $sender;

   public function __construct($sender)
   {
      $this->sender = $sender;
   }

Tak to nejde a laděnka hlásí chybu: „Service ‚emailRepository‘: Parameter $sender in Method Todo\EmailRepository::__construct() has no type hint, so its value must be specified“

Nevíte co s tím? Asi vadí, že není v u parametru v konstruktoru uveden typ, ale nevím jaký dát… Díky…

jiri.pudil
Nette Blogger | 1032
+
0
-
emailRepository: Todo\EmailRepository(%email_odesilatel%)
n.u.r.v.
Člen | 485
+
0
-

jiri.pudil: To jsem zkoušel a žádná změna---

edit: já jsem píp… na localhostu používám druhej soubor neon a cpu to do prvního…

Editoval n.u.r.v. (22. 7. 2013 10:36)

n.u.r.v.
Člen | 485
+
0
-

Ahoj, tak jsem dal můj projekt na testování na hosting a po řadě problémů s chybějícíma funkcema v php to docela běží… ještě je ale jeden problém, někdy vyskočí chyba 500 a v logu je:

Fatal error: Call to undefined function Nette\Utils\utf8_decode() in …/libs/Nette/Utils/Strings.php

Co s tím?

enumag
Člen | 2118
+
0
-

@n.u.r.v. Na hostingu zřejmě chybí XML Parser, tedy přesněji libxml extension. Nechápu ale proč by ho někdo vypínal, je zabudované přímo v PHP a ve výchozím stavu zapnuté.

Editoval enumag (24. 7. 2013 15:14)

n.u.r.v.
Člen | 485
+
0
-

Enumag: No náš hosting je postaven takto: vše deaktivované a co potřebuješ o to si napiš, takže když jsem dal na hosting nette ,tak checker byl rudej, pak nešla DB – chybělo pdo, pak nešel hash(‚sha512‘,něco), pak utf8_encode a teď jsme konečně rozchodili meily…

edit: koukám do manuálu php a tam je ut8_decode uvedena pod XML Parserem, ne libxml…nebo se pletu? Musím na hostingu říct přesně co doinstalovat…

ještě něco, platí toto: "":https://forum.nette.org/…-vstupu-form i když nepoužívám dibi, ale klasiky DB nette? Tedy nemusím používat mysql_real_escape_string když např mám formulář pro výběr uživatele z DB (select kde value jsou např. ID z DB uživatelů) a po odeslání formu se provede :

zpracování formu v presenteru:

zpracování formu:
$values = $form->getValues();
get_user($values->id)

metoda get_user(id) v modelu:

return $this->connection->table(tbl_uzivatele)->where(array("id"=>id));

díky

Editoval n.u.r.v. (26. 7. 2013 10:45)

enumag
Člen | 2118
+
0
-

Jestli jsem to správně pochopil tak ten XML parser je součást libxml. Díval jsem se na své PHP info a tam žádný XML parser neni, aale ta fce normálně funguje.

NDB si to escapuje sama.

frosty22
Člen | 373
+
0
-

Ano nemusíš a neměl bys používat mysql_real_escape_string při správném použití NDB.

n.u.r.v.
Člen | 485
+
0
-

Ahoj, ještě dotaz – teď můj projekt funguje, ale mám nastaveno, když se dá http://muj_projekt/, tak to přesměruje na http://muj_projekt/www/… Protože index je tam… je nějak možné udělat, aby tam nemuselo být v adrese to www/? díky

mkoubik
Člen | 728
+
0
-

Nastav si DocumentRoot do adresáře www.

n.u.r.v.
Člen | 485
+
0
-

Aha, to asi musí hosting…

s4muel
Člen | 92
+
0
-

mozno by pomohol este .htaccess v root adresari

RewriteEngine On
RewriteCond %{HTTP_HOST} ^muj_projekt$ [NC,OR] #NC - case insensitive; OR - alebo sa pouzije nasledujuce pravidlo nizsie
RewriteCond %{HTTP_HOST} ^www.muj_projekt$
RewriteCond %{REQUEST_URI} !www/
RewriteRule (.*) /www/$1

len si pozri, aby sa ti tie pravidla s niecim nebili. ved skusis a uvidis

n.u.r.v.
Člen | 485
+
0
-

s4muel:

Ahoj, díky – pomohlo… Jen jsem musel upravit cesty k obrázků, a k js:

místo původního:
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css">

jsem musel udělat:
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/www/css/screen.css">

A ještě zajímavost:

Na stránkách mám zobrazení logu co se na portálu dělo. Pro to mám LogPresenter a templates/Log/default.latte

A pak je tedy odkaz: muj_projekt.cz/log/

A na hostingu to funguje, ale na localhostu mi to hodí access denied

frosty22
Člen | 373
+
0
-

Chm s těmi cestami je to zvláštní, stejný htaccess občas používám též, jelikož některé projekty jsou hostované na hostingu, který nepodporuje změni document_root a nikdy jsem určitě nemusel cesty měnit. Ten .htaccess by měl podstrčit všechny cesty čili i k CSS, JS, obrázkům, atd.

n.u.r.v.
Člen | 485
+
0
-

frosty22 napsal(a):

Chm s těmi cestami je to zvláštní, stejný htaccess občas používám též, jelikož některé projekty jsou hostované na hostingu, který nepodporuje změni document_root a nikdy jsem určitě nemusel cesty měnit. Ten .htaccess by měl podstrčit všechny cesty čili i k CSS, JS, obrázkům, atd.

No hlavně že to funguje stejně na hostingu i na localhostu – jen je zajímavé, že nalocalhostu nejde můj logpresenter – jako by si apache myslel, že chci jít do složky log která je zakázaná…

frosty22
Člen | 373
+
0
-

No to si myslí určitě. Akorát řešení neznám viz http://stackoverflow.com/…-real-folder

n.u.r.v.
Člen | 485
+
0
-

Ahoj, ještě dotaz: v budoucnu budeme potřebovat náš web v nette mít zabezpečený → https…Hledal jsem zde na foru a jestli jsem z vyhledaných informací pochopil správně, tak stačí v RouterFactory napsat „Route::SECURED“

tedy takto:

aktuální stav:

class RouterFactory
{
	public function createRouter()
	{
		$router = new RouteList();
		$router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY);
		$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
		return $router;
	}

}

s https:

class RouterFactory
{
	public function createRouter()
	{
		$router = new RouteList();
		$router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY, Route::SECURED);
		$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default', Route::SECURED);
		return $router;
	}

}

Je to tak-nic víc nemusím v nette/php upravovat? Díky…

frosty22
Člen | 373
+
0
-

Ano slouží k tomu Route::SECURED, čímž jsou pak vytvářeny URL adresy s https a nikoliv http. PHP se to tedy tolik ani netýká, to data již přijímá ze serveru v nešifrované podobě, ale musíš to mít samozřejmě vše zařízené a nastavené na serveru, v Apache.

A z hlediska Nette již by mělo stačit toto. Pouze tedy v tvém příkladu, jak máš tu jednosměrku, tak tam předáváš Route::SECURED jako 4 parametr, ale objekt Route nemá 4 parametry, všechny flagy se předávají ve 3. parametru čili:

<?php
$router[] = new Route('index.php', 'Homepage:default', Route::ONE_WAY | Route::SECURED);
?>
n.u.r.v.
Člen | 485
+
0
-

ok, díky…

n.u.r.v.
Člen | 485
+
0
-

Ahoj, tak tu mám další menší zádrhel:

v latte šabloně vypisuji tabulku v cyklu. Z DB mimo jiné dostávám jednu informaci (např. „A“, „B“, „C“), ale uživateli potřebuji na zákledě těchto písmen vypsat celou informaci, ne jen zkratku…jelikož to jsou jen 3 možnosti, tak jsem si udělal v latte pole a to vypisuji, jenže jsem chtěl ošetřit případ, kdyby náhodou index byl malé písmeno…zkusil jsem helper upper, ale nějak to nefunguje – viz následující kod:

{default $statusy = array("A"=>"Něco1", "B"=>"Něco2", "C"=>"Něco3")}
...
...
výpis tabulky v cyklu:
<tr n:foreach="$seznam as $list">
<td>....
...
<td id="edit" href="...$list->id}">{$statusy[($list->STATUS|upper)]}</td>

Když tomu předhodím malé písmeno, tak dostávám chybu „Undefined index: a“ – proč, když by to mělo přehodit na velké písmeno?Díky

Editoval n.u.r.v. (22. 8. 2013 10:12)

rixi
Člen | 109
+
0
-

nespravne si pouzil helper, malo by to byt nieco v duchu „hodnota|helper“, cize:

{$statusy[$list->STATUS]|upper}

niekedy su pripady, ked to takto nejde, vtedy sa da pouzit aj PHP zapis

{$template->upper($statusy[$list->STATUS])}

inak nebolo by vhodnejsie pouzit neasociativne pole (0, 1, 2,..)?

Editoval rixi (22. 8. 2013 10:28)

n.u.r.v.
Člen | 485
+
0
-

rixi napsal(a):

nespravne si pouzil helper, malo by to byt nieco v duchu „hodnota|helper“, cize:

{$statusy[$list->STATUS]|upper}

niekedy su pripady, ked to takto nejde, vtedy sa da pouzit aj PHP zapis

{$template->upper($statusy[$list->STATUS])}

NN, já nepotřebuji zvětšit výsledek – tedy to co mi vrátí pole, ale hodnotu $list->STATUS, který pak předám jako index pole.
Tedy:

{default $statusy = array("A"=>"Něco1", "B"=>"Něco2", "C"=>"Něco3")}
Když je $list->STATUS = "A";
Tak {$statusy[$list->STATUS]} vypíše "Něco1"
Když ale bude $list->STATUS = "a";
Tak to hodí chybu, protože v poli statusy není index malé "a"
Takže jsem chtěl to ošetřit že budu měnit $list->STATUS vždy na velká písmena
rixi
Člen | 109
+
0
-

aha, nevsimol som si to. tak v tom pripade by malo zabrat:

{$statusy[$template->upper($list->STATUS)]}
n.u.r.v.
Člen | 485
+
0
-

rixi napsal(a):

aha, nevsimol som si to. tak v tom pripade by malo zabrat:

{$statusy[$template->upper($list->STATUS)]}

Jo, funguje…díky…

n.u.r.v.
Člen | 485
+
0
-

Ahoj, nemůžu to na foru nikde najít, tak se raději zeptám:

Když potřebuji z DB najít záznam, který má například DATUM is not null, tak to mohu zapsat takto?

$user = $this->database_data->table("user")->select("user.ID")->where(array("DATE =?" => "IS NOT NULL"))->fetch();

Díky…

EDIT: Našel jsem na webu tento zápis, sice funguje, ale nevím, zda je to čisté řešení…:

...where(array("NOT DATE_VALID"=>null)...

Editoval n.u.r.v. (13. 11. 2013 11:51)