Jak na AJAXové odkazy v menu

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

Ahoj,
potřebuji, abych nějakým způsobem navázal AJAX na odkazy v menu. Tzn. Když kliknu třeba na odkaz Hlavní stránka, tak aby se reloadnul jenom obsah a ne třeba menu a další prvky webu.

@layout.latte

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="description" content="">
    <meta name="robots" content="{$robots}" n:ifset="$robots">


    <script src="../js/netteForms.js"></script>
    <link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/admin.css">
    <link rel="stylesheet" media="print" href="{$basePath}/css/print.css">
    {block head}{/block}
</head>

<body>

	<script> document.documentElement.className+=' js' </script>
	<br />
	<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
	{if $user->loggedIn}
	<div class="logout">
	    <a n:href="logout!">Odhlásit se ... </a>
	</div>
	<div class="menu" >

	 <ul class="level-1">
        <li class="level-1"><a n:href="Homepage:">Hlavní stránka</a>
        </li>
        <li class="level-1"><a href="odkaz">Správa článků</a>
            <ul class="level-2">
                <li class="level-2"><a n:href="Articles:">Přidat článek</a></li>
                <li class="level-2"><a href="odkaz">Přidat kategorii</a></li>
                <li class="level-2"><a href="odkaz">Zobrazit článek</a></li>

            </ul>
        </li>
        <li class="level-1"><a href="odkaz">Nastavení</a>
        </li>
    </ul>
	</div>
	{/if}
	<div class="content">
	{include content}
	</div>

	{block scripts}
	<script src="{$basePath}/js/jquery.js"></script>
	<script src="{$basePath}/js/netteForms.js"></script>
	<script src="{$basePath}/js/nette.ajax.js"></script>
	<script src="{$basePath}/js/main.js"></script>
	{/block}
</body>
</html>

Kupříkladu bych rád, aby když kliknu na "Přidat článek, tak se reloadnul jen určitý <div>

Můžete sem prosím někdo hodit příklad použití snippetu v jednoduchém menu? Nic moc jsem nenašel. Díky.

Editoval Freestyler (23. 6. 2014 20:17)

Томас
Člen | 85
+
+1
-

Buď zdráv,
v první řadě: Proč to tak chceš? Dejme tomu, že to takhle má nějaký web, kam chodíš. Adresa je „www.neco.cz“. Klikneš si do menu na „kontaktujte nás“, a jsou tam nějaký super informace a chceš to někomu přeposlat. Jak? link je stále „www.neco.cz“ i když je obsah jinej… vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím obeznámen :P)

Každopádně pokud k tomu máš nějaký rozumný důvod tak to jde úplně jednoduše:

1. stáhní https://componette.org/search/?… a naincluduj si ho do layoutu

<script src="{$basePath}/js/nette-ajax-js.js"></script>
// až po jquery! -> potom už jen zavoláš metodu init
$(function () {
    $.nette.init();
});

teď si to co chceš přes ajax refreshovat obalíš do nějakýho snippetu např:

<div class="menu">
   <a n:href="Page:show 1" class="moje_class_na_sexy_linky ajax">kontaktujte nás</a>
   <a n:href="Page:show 2" class="moje_class_na_sexy_linky ajax">něco zajímavýho</a>
   // v class musí být ajax!
</div>
<div class="page">
   {snippet page}
   	{include content}
   {/snippet}
</div>

no, a máme skoro vyhráno, teď už jenom v přesenteru dát vědět, že se bude jednat o ajax.
Dejme tomu že máš metodu nějak takto?

// PagePresenter.php
public function renderShow($pageId)
{
    $this->template->page = $this->database->table('moje_sexy_clanky')->get($pageId);
    if($this->isAjax()){
      // jestli se jedná o ajax překresli snippet page
      $this->redrawControl('page');
    }else{
      // pokud to ajax z nějakýho důvodu není tak není
      // tak sem můžeš dát přesměrování (tady asi nic leda by to byla handle)
      // $this->redirect('this');
    }
}

Teď po kliknutí na link v menu se ti pomocí ajaxu překreslí ten snippet page a máme hotovo. Snad jsem na nic nezapoměl přeci jen jsem ještě nespal! :'(

Mimochodem : netteForms.js includuješ 2× → používej $basePath

Editoval Томас (24. 6. 2014 9:15)

mirimCZ
Člen | 24
+
0
-

Pusť si ještě Vojtu Dobeše, určitě ti to taky pomůže :)

https://www.youtube.com/watch?…

iNviNho
Člen | 352
+
0
-

zle, zle, zle nerobil by som to už len kvoli SEO

jiri.pudil
Nette Blogger | 1032
+
0
-

link je stále „www.neco.cz“ i když je obsah jinej… vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím obeznámen

Jde to obejít pomocí History API, podpora je ve všech moderních prohlížečích a IE 10+. Vojta Dobeš na to má i rozšíření pro nette.ajax.js

mirimCZ
Člen | 24
+
0
-

Problém se SEO už je dávno vyřešený, ale vyžaduje to „trochu“ jinej level přístupu k aplikaci. Nemluvě o tom, že nette způsob tvorby SPA prvků by seo nijak narušovat neměl (v praxi jsem to nepoužil nikdy, SPA dělám jen backend a ještě k tomu na angularu), vzhledem k tomu, že ta aplikace by měla poslat celou stránku, když isAjax() spadne do false – nebo aspoň tak bych to teda programoval.

https://developers.google.com/…tml-snapshot

http://stackoverflow.com/…applications

Editoval mirimCZ (24. 6. 2014 14:54)

Freestyler
Člen | 50
+
0
-

Díky, díky. Hlavní myšlenka byla v tom, že nechci reloadovat celou stránku, když třeba menu, grafika a další prvky jsou pořád stejný a mění se prakticky jen jeden <div> a to ten se contentem a vypsanýma datama z db (momentálně řeším backend aplikace, na frontend dojde taky brzy).

A pro to je Ajax jako stvořenej ne? Nebo jak to řešíte vy? Reloadujete všechno? Budu rád za jakoukoliv radu, přece jen s nette teprve začínám a třeba mi něco uteklo.

P.S. Ještě trochu konkrétnosti:

Administrace se skládá z menu, kde se položky nemění, odkazu na odhlášení, ten se taky nemění a je pořád stejnej, grafika je naprosto stejná a uprostřed je <div> do kterýho se všechno vypisuje, ten jedinej chci při kliknutí na určitou položku v menu měnit. Jdu na to správně?

Díky.

EDIT: teď mi došlo, že to fakt není SEO, je to hodně proti proudu … (musel jsem si dát kafe aby mi to začal myslet :))

Editoval Freestyler (24. 6. 2014 19:58)

Томас
Člen | 85
+
0
-

Pokud řešíš administraci, tak si to klidně přes ajax udělej takhle. Do přední části aplikace bych to ale necpal.

BTW: Nejde mi na mozek proč ti vadí reloadovat o 20 řádků navíc, které jsou natvrdo napsané v kódu? Opravdu si myslíš, že bude nějaký rozdíl v rychlosti načítání, kor když menu atd mají dohromady 10 řádků? (neřeknu kdyby to menu mělo 150 odkazů a tahal si to z DB nebo něco trošičku časově náročnějšího, co není třeba pořád reloadovat) :-D

Томас
Člen | 85
+
0
-

jiri.pudil napsal(a):

link je stále „www.neco.cz“ i když je obsah jinej… vidíš ten problém? (Třeba to jde nějak obejít, ale nejsem s tím obeznámen

Jde to obejít pomocí History API, podpora je ve všech moderních prohlížečích a IE 10+. Vojta Dobeš na to má i rozšíření pro nette.ajax.js

dík, mrknu na to, mohlo by se hodit :)

mirimCZ
Člen | 24
+
-1
-

Томас napsal(a):

Pokud řešíš administraci, tak si to klidně přes ajax udělej takhle. Do přední části aplikace bych to ale necpal.

BTW: Nejde mi na mozek proč ti vadí reloadovat o 20 řádků navíc, které jsou natvrdo napsané v kódu? Opravdu si myslíš, že bude nějaký rozdíl v rychlosti načítání, kor když menu atd mají dohromady 10 řádků? (neřeknu kdyby to menu mělo 150 odkazů a tahal si to z DB nebo něco trošičku časově náročnějšího, co není třeba pořád reloadovat) :-D

Nejde o deset řádků navíc, jde o to, že když klikneš na odkaz a reloaduje se ti celá stránka, posílají se znova veškeré requesty na css, javascript, obrázky a jak všichni určitě víme, právě přehršel HTTP požadavků obvykle brzdí stránky nejvíc. Pokud použiješ ajax, pošle se request jeden – ostatní už tam je a není nutné to tedy načítat znova.

Těžká datová logika z databáze by stejně měla být nacachovana – v příadě menu by bylo ideální, kdyby se nacachovalo rovnou i vyrenderované HTML menu, takže o to ani tak nejde…

Freestyler napsal(a):

A pro to je Ajax jako stvořenej ne? Nebo jak to řešíte vy? Reloadujete všechno? Budu rád za jakoukoliv radu, přece jen s nette teprve začínám a třeba mi něco uteklo.

Osobně používám AngularJS. Celej „content block“ zatím neposílám – ikdyž se na to chystám v blízké době. Momentálně používám jen asynchronní komponenty – mám asynchronní grid a formuláře. Grid normálně leží ve stránce jako by ležel ikdyž ho renderuje phpko, formuláře se otevírají do modálního okna. Do gridu ze strany php putuje čistý JSON, akce s formulářemi posílají normálně html.

Tohle řešení furt nevyužívá plného SPA potenciálu Angularu – ten umí i routování, templatování, atd

https://docs.angularjs.org/…ctive/ngView

Jinak dobře udělané SPA by phpko mělo vracet víceméně jen čistě JSON data. Templatování by pak řešil frontendovej js framework (třeba již zmíněný angular, nebo ember a podobné).

Editoval mirimCZ (25. 6. 2014 11:43)

Freestyler
Člen | 50
+
0
-

Přesně to jsem myslel, nechci reloadovat všechno, když už jsem to jednou udělal a není potřeba to dělat znova.

Tvoje řešení se mi líbí, ale bohužel zatím přesahuje moje programátorské dovednosti. Holt si zatím vystačím s tím co umím :).

Každopádně díky za rady a nápady.

Čamo
Člen | 798
+
0
-

mirimCZ:
SPA,Angula,JSON,Asynchronný javascript, Nette cache… ale to, že prehliadače si obrázky, a javascripty cachujú, takže žiadne přehršle http requestou sa neposielajú to nevieš. Nehovoriac o tom aký je ten kód potom prehľadný, keď do neho narveš všetko možné aj nemožné. Toto ja nepochopím…

Editoval Čamo (28. 6. 2014 13:54)