2. díl - CMS v Nette a Doctrine 2 - Kostra aplikace

PHP Nette Framework Doctrine CMS v Nette a Doctrine 2 - Kostra aplikace

V minulém tutoriálu o programování CMS v Nette a Doctrine 2 jsme si představili potřebné technologie. V tomto článku si pomocí Composeru stáhneme všechny důležité knihovny a vytvoříme základní kostru naší aplikace.

Založení projektu

Získání potřebných knihoven

K získání knihoven použijeme Composer. Veškeré důležité informace naleznete na oficiálním webu https://getcomposer.org.

Composer využívá souboru composer.json, ve kterém je uvedeno jaké všechny knihovny mají v aplikaci být. Můžeme pak pomocí příkazového řádku všechny knihovny stáhnout.

Poté, co Composer nainstalujete, v příkazovém řádku zadejte cestu ke složce, kde chcete mít náš projekt, např.:

cd xampp/htdocs/nette_doctrine

a napište:

composer create-project nette/sandbox nazev_projektu
composer.json

Předchozím příkazem se nám stáhne sandbox Nette s adresářovou strukturou. Automaticky se také vytvořil soubor composer.json. Ten otevřete a do parametru require přidejte:

...
"doctrine/orm": "*",
"kdyby/annotations": "^2.2",
"kdyby/console": "^2.4",
"kdyby/events": "^2.4",
"kdyby/doctrine-cache": "^2.4",
"kdyby/doctrine": "~2.3.1",
"symfony/config": "~2.7",
"symfony/translation": "~2.7",
"kdyby/translation": "~2.2"
...

Tímto určíme, aby se nám stáhly všechny potřebné knihovny pro náš projekt. Nakonec v příkazovém řádku zadejte cestu ke složce, kde je soubor composer.json, a napište:

composer update

Tímto Composer projede soubor, zjistí, které knihovny jsou nové nebo upravené, a provede aktualizaci. Všechny knihovny stahuje do složky vendor/.

Pokud budeme chtít v průběhu stahovat další knihovny, nemusíme ručně upravovat soubor, stačí v příkazovém řádku napsat příkaz

composer require nazev/knihovny

např.:

composer require kdyby/translation

Jelikož jsme stáhli sandbox nette, máme adresářovou strukturu vytvořenou automaticky.

Poznámka: Zkoušel jsem to pouze na Windows, na Linuxu bude zřejmě trochu jiný postup. Vše je ale na oficiálních stránkách Composeru vysvětleno.

Konfigurace

app/config/con­fig.local.neon

V našem lokálním konfiguračním souboru config.local.neon změníme informace o naší databázi pro Doctrine:

parameters:


doctrine:
    user: root
    password: ****
    dbname: doctrine
    metadata:
        App: %appDir%

Přihlašovací jméno a heslo si samozřejmě nastavte podle sebe.

Metadata (informace o entitách atp.) bude Doctrine hledat v naší složce app/.

app/config/con­fig.neon

Do hlavního konfiguračního souboru config.neon poté zaregistrujeme všechna naše rozšíření:

...
extensions:
        console: Kdyby\Console\DI\ConsoleExtension
        events: Kdyby\Events\DI\EventsExtension
        annotations: Kdyby\Annotations\DI\AnnotationsExtension
        doctrine: Kdyby\Doctrine\DI\OrmExtension
        translation: Kdyby\Translation\DI\TranslationExtension

A na závěr si připravíme možnost překladů a povolíme češtinu a angličtinu (defaultně bude použita čeština).

...
translation:
        default: cs
        fallback: [cs, en]
        whitelist: [cs, en]

Úprava routeru

app/router/Rou­terFactory.php

Abychom mohli rozpoznat, v jakém jazyce chce uživatel stránky zobrazit, přidáme do masky routeru nepovinný parametr locale.

<?php

namespace App;

use Nette;
use Nette\Application\IRouter;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;

/**
 * Routovací továrnička.
 * Řídí routování v celé aplikaci.
 * @package App
 */
class RouterFactory
{

        /**
         * Vytváří router pro aplikaci.
         * @return IRouter výsledný router pro aplikaci
         */
        public static function createRouter()
        {
                $router = new RouteList();
                $router[] = new Route("[<locale=cs cs|en>/]<presenter>/<action>[/<id>]", "Homepage:default");
                return $router;
        }
}

Pomocí hranatých závorek jsme určili, že parametr locale není povinný a pokud nebude v URL vyplněn, použije se defaultně čeština.

Naše URL poté mohou vypadat např. en/article-category/list.

Způsob překladu

Všechny texty, které se budou překládat, budou uloženy pod klíčem v NEON souboru (stejný používá i konfigurační soubor). Jak to funguje, si můžete zkusit zde: http://ne-on.org.

Překlady budeme psát do jednotlivých souborů podle toho, kam dané texty spadají (texty ohledně článků budou v souborech article, pro formuláře v souborech form, pro výjimky exception, obecné texty common apod.). Kdyby\Translation se poté automaticky postará o načtení všech důležitých souborů. Způsob rozdělení je tedy na nás, jak se nám to zdá přehledné (přiznávám, že nakonec stejně budou texty různě poházeny).

Výhodou tohoto nástroje také je, že můžeme překládat i texty s proměnlivým obsahem - jednoduše napíšeme zástupný identifikátor, který se poté přepíše hodnotou, např.:

textKey: "Celkem je zde %articlesCount% článků a %usersCount% aktivních uživatelů"

V šabloně poté hodnoty dosadíme pomocí pole.

{_textKey, ["articlesCount" => 500, "usersCount" => 30]}

// vypíše  Celkem je zde 500 článků a 30 aktivních uživatelů

Překlad již na úrovni vrstvy Presenteru obstarává třída Kdyby\Translation\Translator. Tu si automaticky injectujeme do třídy BasePresenter a také se bude předávat konstruktorem do form factory tříd.

app/presenter­s/BasePresenter­.php

Konečně se dostáváme k troše akce. Jako první si upravíme náš BasePresenter a vytvoříme mu atribut locale a Translator, který se automaticky injectuje. Nezapomínejte, že všechny atributy, které se injectují automaticky, musí mít viditelnost public.

<?php

namespace App\Presenters;

use App\Model;
use Nette;
use Nette\Application\UI\Presenter;

/**
 * Základní presenter pro všechny ostatní presentery aplikace.
 * @package App\Presenters
 */
abstract class BasePresenter extends Presenter
{
        /** @persistent null|string Určuje jazykovou verzi webu. */
        public $locale;

        /**
         * @var \Kdyby\Translation\Translator Obstarává jazykový překlad na úrovni presenteru.
         * @inject
         */
        public $translator;
}

Atribut $locale obsahuje informaci o jazyku. Díky anotaci @persistent je hodnota automaticky předávána při každém požadavku - nemusíme ji proto uvádět v odkazech.

Makro na překlad

Dále si ještě do třídy BasePresenter zaregistrujeme makro na překlad:

...
/**
 * Registrace makra na překlad.
 * @inheritdoc
 */
protected function createTemplate()
{
        /** @var Template $template Latte šablona pro aktuální presenter. */
        $template = parent::createTemplate();
        $this->translator->createTemplateHelpers()
                ->register($template->getLatte());
        return $template;
}

Tímto zaregistrujeme makro {_}, díky kterému lze v šabloně jednoduše přeložit text, a nemusíme tak překlady ukládat do proměnných a předávat šablonám.

Databázová struktura

Abychom nemuseli v každém dalším článku něco přidávat nebo upravovat, přiložím rovnou soubor db.sql s SQL příkazem, který celou databázi vytvoří.

Databáze obsahuje pět tabulek:

  • article
  • article_category
  • article_comment
  • user
  • user_settings

Do databáze budou automaticky přidání dva uživatelé:

Jméno Heslo Popis
admin admin administrátor
user user uživatel

Poznámka: Doctrine umí z entit vygenerovat strukturu databáze a opačně. Více se dozvíte zde.

Přebytečné soubory v Nette sandboxu

  • model/UserManager.php - tento soubor z projektu úplně odstraňte - nejen, že nám k ničemu nebude, ale naopak by nám překážel (kvůli implementaci rozhraní Nette\Security\IAuthenticator). Také ho odstraňte ze souboru config.neon.
  • forms/SignFormFactory.php - můžete odstranit, my si budeme vytvářet náš vlastní, trochu odlišný.
  • presenters/SignPresenter.php - také si budeme vytvářet vlastní.

Tímto druhý tutoriál zakončíme - příště začneme pomalu stavět naši modelovou vrstvu.


 

Stáhnout

Staženo 77x (3.43 MB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

  Aktivity (1)

Článek pro vás napsal Martin Konečný (pavelco1998)
Avatar
Autor se o IT moc nezajímá, raději by se věnoval speciálním jednotkám jako jsou SEALs nebo SAS. Když už to ale musí být něco z IT, tak tvorba web. aplikací v PHP.

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
CMS v Nette a Doctrine 2

 

 

Komentáře

Avatar
Milan Gallas
Redaktor
Avatar
Milan Gallas:

Ahoj je možné, že mi composer nebere znak ^. Všechny znaky ^ , jsem musel vyměnit za ~ aby se začalo neco aktualizovat. Dále je problém že komposer stahuje i další knihovny, které mají znak ^a kde to nemůžu ovlivnit.
Mám verzi 1.0.0-alpha9. Může to být tím?

 
Odpovědět 26.10.2015 19:07
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Milan Gallas
Jindřich Máca:

Verzí to samozřejmě být může, ale spíš by bylo dobré vložit sem obsah Tvého composer.json nebo alespoň chybu, co to hází. :-)

Editováno 26.10.2015 19:16
 
Odpovědět 26.10.2015 19:15
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Jindřich Máca
Milan Gallas:

Použil jsem příkazy:

composer create-project nette/sandbox myApp 2.3.4

composer require kdyby/doctrine

a pak Všechny znaky ^ , jsem musel vyměnit za ~

Hází mi to chybové hlášky

Could not parse varsion constraint ^2.3.5: Invalid version string "^2.3.5"

Could not load package nette/component-model in http://packagist.org: Could not parse version constraint ^2.3.5: Invalid version String "^2.3.5"

Obsah soubrou composer.json:

"require": {
                "php": ">= 5.3.7",
                "nette/application": "~2.3.0",
                "nette/bootstrap": "~2.3.0",
                "nette/caching": "~2.3.0",
                "nette/database": "~2.3.0",
                "nette/di": "~2.3.0",
                "nette/finder": "~2.3.0",
                "nette/forms": "~2.3.0",
                "nette/http": "~2.3.0",
                "nette/mail": "~2.3.0",
                "nette/robot-loader": "~2.3.0",
                "nette/safe-stream": "~2.3.0",
                "nette/security": "~2.3.0",
                "nette/utils": "~2.3.0",
                "latte/latte": "~2.3.0",
                "tracy/tracy": "~2.3.0",
        "kdyby/doctrine": "~2.3"
        }
 
Odpovědět 27.10.2015 10:52
Avatar
Jindřich Máca
Tým ITnetwork
Avatar
Odpovídá na Milan Gallas
Jindřich Máca:

Tak to bude s největší pravděpodobností tou verzí composeru. Jednoduché řešení je příkaz

composer self-update

, který automaticky aktualizuje composer. Pak zkus znovu použít ty příkazy na tvorbu projektu a už by měli fungovat. ;-)

 
Odpovědět  +1 27.10.2015 11:45
Avatar
ONIO s.r.o.
Člen
Avatar
ONIO s.r.o.:

Ahoj, jak by se řešilo více databázových spojení?

 
Odpovědět 16. července 13:07
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.