Překlad URL z id na nazev článku

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

Dobrý den,

předem se omlouvám, že zakládám možná duplicitní téma. Ale vše co jsem našel, včetně přednášky Honzi Smitky na youtube, prostě neřeší můj problém. A ostatní vlákna, která jsem si na fóru přečetl, řeší problémy už zaběhnutých, větší projektů, kde je potřeba psát větší kódy.

Jak je z názvu jasné, chtěl bych docílit tohoto formátu odkazu. http://example.com/…prvni-clanek
Teď, se zobrazuje odkaz takto: http://example.com/post/show/1

Když jsem si pročítal dokumentaci, jediné, čeho se mi podařilo docílit podle návodu je http://example.com/…k/zobrazit/1 – tedy, upravil jsem si překlad presenteru a akce, ale nepodařilo se mi už převést ID na nazev článku.

V současné chvíly vypadá můj RouterFactory.php takto:

<?php

namespace App;

use Nette,
        Nette\Application\Routers\RouteList,
        Nette\Application\Routers\Route,
        Nette\Application\Routers\SimpleRouter;


/**
 * Router factory.
 */
class RouterFactory
{

        /**
         * @return \Nette\Application\IRouter
         */
        public function createRouter()
        {
                $router = new RouteList();
                $router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
                return $router;
        }

}
?>

Poradíte mi tedy prosím jak na to? Mám úplně základní blog, který jsem tvořil podle dokumentace na Nette, „ZAČÍNÁME“. Pokud se změny budou týkat i jiných souborů, nezapomeňte to prosím zmínit, například jestli si změna routování bude vyžadovat i jiný formát odkazů. Momentálně si zobrazování článků zobrazuji přes tento odkaz: <a href=„{link Post:show $post->id}“>{$post->title}</a>

Děkuji vám za pomoc

MartinitCZ
Člen | 580
+
0
-

Tak si do db ukládej slug (upravený název použitelný v url) a pak odkaz tvoř pomocí:

<a href="{link Post:show $post->slug}">{$post->title}</a>

Editoval MartinitCZ (26. 7. 2014 10:32)

Michael
Člen | 7
+
0
-

MartinitCZ napsal(a):

Tak si do db ukládej slug (upravený název použitelný v url) a pak odkaz tvoř pomocí:

<a href="{link Post:show $post->slug}">{$post->title}</a>

Vůbc nemám tušení, jak bych to měl nasadit. Myslel jsem že po kliknutí na slug vyběhne dokumentace, ale namísto toho spousty hodnot, dat, které mi nic neříkají :)

Pavel Macháň
Člen | 282
+
0
-

Michael napsal(a):

MartinitCZ napsal(a):

Tak si do db ukládej slug (upravený název použitelný v url) a pak odkaz tvoř pomocí:

<a href="{link Post:show $post->slug}">{$post->title}</a>

Vůbc nemám tušení, jak bych to měl nasadit. Myslel jsem že po kliknutí na slug vyběhne dokumentace, ale namísto toho spousty hodnot, dat, které mi nic neříkají :)

@Michael Do databáze si uložíš slug vytvořený třeba z názvu (respektive to co chceš do URL).
Pro slug se právě hodí ta funkce co ti sem @MartinitCZ dal.

$slug = \Nette\Utils\Strings::webalize($name);

Editoval Pavel Macháň (26. 7. 2014 10:50)

Michael
Člen | 7
+
0
-

Pavel Macháň napsal(a):

Michael napsal(a):

MartinitCZ napsal(a):

Tak si do db ukládej slug (upravený název použitelný v url) a pak odkaz tvoř pomocí:

<a href="{link Post:show $post->slug}">{$post->title}</a>

Vůbc nemám tušení, jak bych to měl nasadit. Myslel jsem že po kliknutí na slug vyběhne dokumentace, ale namísto toho spousty hodnot, dat, které mi nic neříkají :)

@Michael Do databáze si uložíš slug vytvořený třeba z názvu (respektive to co chceš do URL).
Pro slug se právě hodí ta funkce co ti sem @MartinitCZ dal.

$slug = \Nette\Utils\Strings::webalize($name);

Dobrý den,

to jsem pochopil. Ale jak jak mám tabulku pojmenovak, jaké jsou její sloupce a struktura, vlastnosti apod.? Na to jsem narážel, že bych potřeboval nějaký návod na to, jak ten slug dát do chodu :)

David Matějka
Moderator | 6445
+
+1
-

Ten slug si bud muzes ulozit do stejne tabulky jako je ten clanek do samostatneho sloupecku. Nebo samostatnou tabulku se slugy, na to se muzes kouknout treba tady (trochu pokrocilejsi reseni s custom routou)

Michael
Člen | 7
+
+3
-

Už to mám, děkuji všem mnohokrát :) jste zlatí. Čekal jsem osobně hejtování, ale zdá se, že zde jsem na velice kvalitním, diskrétním a tolerovaném foru. :)

Jan Suchánek
Člen | 404
+
0
-

Hejtování taky nemusím :) Ale ještě by si mohl použít překladatelský router, už se to tu hodněkrát probíralo a je na to i video.

Michael
Člen | 7
+
0
-

jenicek napsal(a):

Hejtování taky nemusím :) Ale ještě by si mohl použít překladatelský router, už se to tu hodněkrát probíralo a je na to i video.

@jenicek o tom jsem psal v prvním příspěvku, viz věta:

…včetně přednášky Honzi Smitky na youtube…

přišlo mi to nejen zmatečné (protože jsem nováček) a taktéž nevyužitelné pro můj začátečnický blog v nette. On tam využíval různých funkcí a modulů, které mi zatím nic neříkají. Jak říkám, učím se a udělat si slug byla fajná věc :)

MartinitCZ
Člen | 580
+
0
-

Osboně si myslim, že než použít filtry je lepší použít slug a při případné změně titulku (tedy i slugu) si jej zálohovat do extra tabulky. Díky tomu budeš mít i staré url funkční. Toto v případě filtrů v routách nedoážeš. ;)

Michael
Člen | 7
+
0
-

No, já se tu pořád s tím trápím, celý den. Popíši vám, co a jak mám a ukážu vám chybu, snad ji někdo najde :(

Struktura + data DB zde: http://jpeg.cz/…26/DvRQ7.png

RouterFactory.php

<?php
namespace App;
use Nette,
 Nette\Application\Routers\RouteList,
 Nette\Application\Routers\Route,
 Nette\Application\Routers\SimpleRouter;
class RouterFactory
{
 public function createRouter()
{
  $router = new RouteList();
  $router[] = new Route('<presenter>/<action>[/<slug>]', 'Homepage:default');
  return $router;
}
}
?>

Znění odkazu na daný článek
<a href=„{link Post:show $post->slug}“>{$post->title}</a>

PostPresenter.php

<?php

namespace App\Presenters;

use Nette,
	App\Model;


/**
 * Homepage presenter.
 */
class PostPresenter extends BasePresenter
{
  private $database;

	public function __construct(Nette\Database\Context $database)
	{
		$this->database = $database;
	}

public function renderShow($slug)
{
    $post = $this->database->table('posts')->get($slug);
    if (!$post) {
        $this->error('Stránka nebyla nalezena');
    }

    $this->template->post = $post;
    $this->template->comments = $post->related('comment')->order('created_at');
}

protected function createComponentCommentForm()
{
    $form = new Nette\Application\UI\Form;

    $form->addText('name', 'Jméno:')
        ->setRequired();

    $form->addText('email', 'Email:');

    $form->addTextArea('content', 'Komentář:')
        ->setRequired();

    $form->addSubmit('send', 'Publikovat komentář');

    $form->onSuccess[] = $this->commentFormSucceeded; // bez závorek

    return $form;
}

public function commentFormSucceeded($form)
{
    $values = $form->getValues();
    $slug = $this->getParameter('slug');

    $this->database->table('comments')->insert(array(
        'post_id' => $slug,
        'name' => $values->name,
        'email' => $values->email,
        'content' => $values->content,
    ));

    $this->flashMessage('Děkuji za komentář', 'success');
    $this->redirect('this');
}

protected function createComponentPostForm()
{
    $form = new Nette\Application\UI\Form;
    $form->addText('title', 'Titulek:')
        ->setRequired();
    $form->addTextArea('content', 'Obsah:')
        ->setRequired();

    $form->addSubmit('send', 'Uložit a publikovat');
    $form->onSuccess[] = $this->postFormSucceeded;

    return $form;
}

public function postFormSucceeded($form)
{
    $values = $form->getValues();
    $slug = $this->getParameter('slug');

    if ($slug) {
        $post = $this->database->table('posts')->get($slug);
        $post->update($values);
    } else {
        $post = $this->database->table('posts')->insert($values);
    }

    $this->flashMessage('Příspěvek byl úspěšně publikován.', 'success');
    $this->redirect('show', $post->slug);
}

public function actionEdit($slug)
    {
    $post = $this->database->table('posts')->get($slug);
    if (!$post) {
        $this->error('Příspěvek nebyl nalezen');
    }
    $this['postForm']->setDefaults($post->toArray());
}

}
?>

No a nakonec chybová hláška v debuggeru zde: http://jpeg.cz/…26/1AcIn.png přičem mě zaujalo, když jsem si najel v TRACY na Post:show, že nezná hodnotu poslanou v proměnné slug a vypisuje to null. Viz tento obrázek: http://jpeg.cz/…26/hNQsE.png

A poslední věc, co mne zaujala je tato. http://jpeg.cz/…26/8PbBX.png jakto že se v queries posílá id, když v odkazu jasně definuji, že chci posílat slug? ({link Post:show $post->slug}) to mi nejde do hlavy, kde mi co uniká?

Nutno podtkout, že cache byla promazána. Jak v mozille, tak v temp na FTP

Editoval Michael (26. 7. 2014 17:42)

MartinitCZ
Člen | 580
+
0
-

Doporučuji odkazy zapisovat takto, abys mu přesně řekl, který parametr to je (+ se to i lépe čte):

<a href="{link Post:show, slug => $post->slug}">{$post->title}</a>

Co se týká dotazu, tak je to jasné. Koukni na API get funkce.
Správně máš mít:

$post = $this->database->table('posts')->where(array('slug' => $slug))->limit(1)->fetch(); // Najdi jeden článek dle slug
Michael
Člen | 7
+
0
-

MartinitCZ napsal(a):

Doporučuji odkazy zapisovat takto, abys mu přesně řekl, který parametr to je (+ se to i lépe čte):

<a href="{link Post:show, slug => $post->slug}">{$post->title}</a>

Co se týká dotazu, tak je to jasné. Koukni na API get funkce.
Správně máš mít:

$post = $this->database->table('posts')->where(array('slug' => $slug))->limit(1)->fetch(); // Najdi jeden článek dle slug

Tooo, mi nějak uniklo. Samozřejmně vše funguje jak má a na tu api se podívám, děkuji mnohokrát :)