CMS routy – best practice

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

Potřeboval bych pomoct sestavit routy pro CMS. Databáze vypadá následnovně:

Tabulka route:

section_id   presenter  action  path
1	     default	default	/
2	     default	sitemap	/mapa-stranek.html
3	     Package	default	/wellness-pobyty/
4	     Package	default	/romanticke-pobyty/
30	     Package	detail	/wellness-pobyty/beauty-lifestyle.html

Do prohlížeče se zadávají vždy cesty v path. Podle path v tabulce route určím presenter, action a section_id. Jakmile mám tyto údaje, potřebuju zobrazit příslušnou akci v odpovídajícím presenteru a neměnit url adresu, kterou zadal uživatel.

Součástí path může být i jazyk, pak potřebuji, aby adresa /en/romanticke-pobyty/ vrátila řádek číslo 4 a předala presenteru jazyk.

Dále potřebuji, aby mi fungovaly všechny vlastnosti nette (hlavně formuláře – ideálně přes továrničku createComponent…).

Také potřebuji poradi best practice na tvorbu odkazů v rámci projektu.

Děkuji.

Filip Procházka
Moderator | 4668
+
0
-

jak na to jsem popsal v tomto tématu

https://forum.nette.org/…dnot-pri-mvc?…

ty si pak jenom upravíš asi tu routu

'/stranka/[!<slug>]'
'/stranka/[!<slug>].html'

A co se týče formulářů … napíšu o tom článek, ale prozatím by ti měla stačit informace, že potřebuješ použít Nette\Forms\Form a všechnu obsluhu udělat v action

public function actionDefault()
{
	$form = $this['MyForm'];
	if ($form->isSubmitted() && $form->isValid()) {
		$this->MyFormSubmitted($form);
	}

	// ... cokoliv dalšího
}

protected function createComponentMyForm($name)
{
	$form = new Nette\Forms\Form;
	$form->setAction($this->lazyLink('default'))

	$form->addText(...

	return $form;
}

protected function MyFormSubmitted(Nette\Forms\Form $form)
{
	$values = $form->getValues();
}
Bejn
Člen | 17
+
0
-

Děkuji za pomoc, nakonec jsem to vyřešil vlastním routerem, který vypadá nísledovně:

<?php
class CMSRoute extends Object implements IRouter
{
        /** @var     string      Jméno parametru předeného presenteru */
        protected $identifierName = 'sectionId';

        /**
        * Prida na konec url /, pokud nekonci na .html, nebo uz tam neni
        *
        * @param mixed $path
        */
        function slashUrl($path)
        {
            if ($path === '/') return $path;

            if (($ext = substr($path,-4) !== 'html') && (substr($path,-1) !== '/'))
                return $path.'/';

            return $path;
        }


        /**
         * Maps HTTP request to a PresenterRequest object.
         * @param  Nette\Web\IHttpRequest
         * @return PresenterRequest|NULL
         */
        public function match(IHttpRequest $context)
        {

                $path = $context->getUri()->path;
                $path = $this->slashUrl($path);

                $params = array();
                $params += $context->getQuery();
                if ($row = dibi::fetch("SELECT [section_id], [category], [template] FROM [page] WHERE [path]=%s", $path)) {
                    $presenter = $row['category'];
                    $params['action'] = $row['template'];
                    $params[$this->identifierName] = (int)$row['section_id'];
                } else {
                    return NULL;
                }

                return new PresenterRequest(
                        $presenter,
                        $context->getMethod(),
                        $params,
                        $context->getPost(),
                        $context->getFiles(),
                        array('secured' => $context->isSecured())
                );
        }



        /**
         * Constructs URL path from PresenterRequest object.
         * @param  Nette\Web\IHttpRequest
         * @param  PresenterRequest
         * @return string|NULL
         * PresenterRequest $request, IHttpRequest $context
         */
        public function constructUrl(PresenterRequest $request, IHttpRequest $context)
        {
                $params = $request->getParams();

                if (!isset($params[$this->identifierName])) {
                        return NULL;
                }
                $path = $this->getPath($params[$this->identifierName]);

                if ($path === NULL) {
                        return NULL;
                }

                unset($params['action']);
                unset($params[$this->identifierName]);

                $uri = new UriScript($context->getUri()->scheme . '://' . $context->getUri()->authority . $context->getUri()->basePath);
                $uri->path = $path;
                $uri->query = http_build_query($params, '', '&');

                return $uri->getAbsoluteUri();
        }

        protected function getPath($id)
        {
                $query = dibi::query('
                        SELECT [route].[path]
                        FROM [route]
                        WHERE [route].[section_id] = %i', $id
                );

                if ($query->rowCount() === 0) {
                        return NULL;
                }

                return $query->fetchSingle();
        }


}

Použití:

$router = $application->getRouter();

$router[] = new CMSRoute();

$router[] = new Route('index.php', array(
    'presenter' => 'Homepage',
    'action' => 'default',
), Route::ONE_WAY);

$router[] = new Route('<presenter>/<action>/<id>', array(
    'presenter' => 'Homepage',
    'action' => 'default',
    'id' => NULL,
));

Editoval Bejn (14. 1. 2011 12:58)