Konfigurace
Přehled všech konfiguračních voleb v Nette Frameworku.
Různé součásti Nette nastavujeme pomocí konfiguračních souborů. Ty se obvykle zapisují ve formátu NEON, s jehož syntaxí se seznamte. K editaci doporučujeme editory s podporou tohoto formátu.
Chcete-li zapsat řetězec začínající znakem @
nebo obsahující %
, musíte znak escapovat
zdvojením na @@
nebo %%
.
application: Application
constants: Definice PHP konstant
database: Databáze
decorator: Dekorátor
di: DI kontejner
extensions: Instalace dalších DI rozšíření
forms: Formuláře
http: HTTP hlavičky
includes: Vkládání souborů
latte: Šablony Latte
mail: Maily
parameters: Parametry
php: PHP konfigurace
routing: Routování
security: Přístupová oprávnění
services: Služby
session: Session
tracy: Tracy debugger
Application
Základní nastavení chování Nette Application.
application:
# zobrazit "Nette Application" panel v Tracy BlueScreen?
debugger: ... # (bool) výchozí je true
# bude se při chybě volat error-presenter?
catchExceptions: ... # (bool) výchozí je true v produkčním režimu
# název error-presenteru
errorPresenter: Error # (string) výchozí je 'Nette:Error'
# chybné odkazy negenerují varování?
# má efekt pouze ve vývojářském režimu
silentLinks: ... # (bool) výchozí je false
Protože ve vývojovém režimu se error-presentery standardně nevolají a chybu zobrazí až Tracy, změnou hodnoty
catchExceptions
na true
můžeme při vývoji ověřit jejich správnou funkčnost.
Volba silentLinks
určuje, jak se Nette zachová ve vývojářském režimu, když selže generování odkazu
(třeba proto, že neexistuje presenter, atd). Výchozí hodnota false
znamená, že Nette vyhodí
E_USER_WARNING
chybu. Nastavením na true
dojde k potlačení této chybové hlášky. V produkčním
prostředí se E_USER_WARNING
vyvolá vždy. Toto chování můžeme také ovlivnit nastavením proměnné presenteru
$invalidLinkMode.
Mapování
Definuje pravidla, podle kterých se z názvu presenteru (třeba Homepage
) odvodí název třídy (třeba
App\Presenters\HomepagePresenter
). Právě takového mapování lze docílit následující konfigurací:
application:
mapping:
*: App\Presenters\*Presenter
Název presenteru se nahradí za hvezdičku a výsledkem je název třídy. Snadné!
Pokud presentery členíme do modulů, můžeme pro každý modul mít vlastní mapování:
application:
mapping:
Front: App\FrontModule\*Presenter
Admin: App\AdminModule\*Presenter
Error: App\Error\*Presenter
Nyní se presenter Front:Homepage
mapuje na třídu App\FrontModule\HomepagePresenter
a presenter
Admin:Dashboard
na třídu App\AdminModule\DashboardPresenter
.
Šikovnější bude vytvořit obecné (hvězdičkové) pravidlo, které první dvě nahradí a přibude v něm hvezdička navíc právě pro modul:
application:
mapping:
*: App\*Module\*Presenter
Error: App\ModuleError\*Presenter
Opět presenter Front:Homepage
namapuje na třídu App\FrontModule\HomepagePresenter
.
Ale co když používáme vícenásobně zanořené moduly a máme třeba presenter Admin:User:Edit
? V takovém
případě se segment s hvězdičkou představující modul pro každou úroveň jednoduše zopakuje a výsledkem bude třída
App\AdminModule\UserModule\EditPresenter
.
Alternativním zápisem je místo řetězce použít pole skládající se ze tří segmentů:
application:
mapping:
*: [App, *Module, *Presenter]
I v tomto případě bude výsledkem třída App\AdminModule\UserModule\EditPresenter
.
Výchozí hodnotou je *: *Module\*Presenter
.
Automatická registrace presenterů
Nette automaticky přidává presentery jako služby do DI kontejneru, což zásadně zrychlí jejich vytváření. Jak Nette presentery dohledává lze konfigurovat:
application:
# hledat presentery v Composer class map?
scanComposer: ... # (bool) výchozí je true
# jaký řetězec musí obsahovat název třídy a souboru?
scanFilter: ... # (string) výchozí je 'Presenter'
# ve kterých adresářích hledat presentery?
scanDirs: # (string[]|false) výchozí je '%appDir%'
- %vendorDir%/mymodule
Adresáře uvedené v scanDirs
nepřepisují výchozí hodnotu %appDir%
, ale doplňují ji,
scanDirs
tedy bude obsahovat obě cesty %appDir%
a %vendorDir%/mymodule
. Pokud bychom
chtěli výchozí adresář vynechat, použijeme vykřičník,
který hodnotu přepíše:
application:
scanDirs!:
- %vendorDir%/mymodule
Skenování adresářů lze vypnout uvedením hodnoty false. Nedoporučujeme úplně potlačit automatické přidávání presenterů, protože jinak dojde ke snížení výkonu aplikace.
Konstanty
Vytváření PHP konstant.
constants:
FOOBAR: 'baz'
Po nastartování aplikace bude vytvořena konstanta FOOBAR
.
Databáze
Konfigurace jednoho či více databázových spojení pro Nette Database.
database:
# DSN, jediný povinný klíč
dsn: "sqlite2:%appDir%/Model/demo.db"
# uživatelské jméno
user: ...
# heslo
password: ...
Vytvoří služby typu Nette\Database\Connection
a také Nette\Database\Context
pro vrstvu Database Explorer. Databáze se obvykle předává autowiringem, není-li to možné,
použijte názvy služeb @database.default.connection
resp. @database.default.context
.
Další nastavení:
database:
# zobrazit database panel v Tracy Bar?
debugger: ... # (bool) výchozí je true
# zobrazit EXPLAIN dotazů v Tracy Bar?
explain: ... # (bool) výchozí je true
# povolit autowiring pro toto spojení?
autowired: ... # (bool) výchozí je true u prvního připojení
# konvence tabulek: discovered, static nebo jméno třídy
conventions: discovered # (string) výchozí je 'discovered'
options:
# připojovat se k databázi teprve když je potřeba?
lazy: ... # (bool) výchozí je false
# PHP třída ovladače databáze
driverClass: # (string)
# lze uvádět volby, které najdete v dokumentaci ovladačů PDO
PDO::MYSQL_ATTR_COMPRESS: true
V konfiguraci můžeme definovat i více databázových spojení rozdělením do pojmenovaných sekcí:
database:
main:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
another:
dsn: 'sqlite2::memory:'
Každé takto definované spojení vytváří služby zahrnující v názvu i název sekce, tj.
@database.main.connection
& @database.main.context
a dále @database.another.connection
& @database.another.context
.
Autowiring je zapnutý jen u služeb z první sekce. Lze to změnit pomocí autowired: false
nebo
autowired: true
. Neautowirované služby předáváme explicitně:
services:
- UserManager(@database.another.connection)
Decorator
Jak upravit hromadně všechny služby určitého typu? Třeba zavolat určitou metodu u všech presenterů, které dědí od konkrétního společného předka? Od toho je tu decorator.
decorator:
# u všech služeb, co jsou instancí této třídy nebo rozhraní
App\Presenters\BasePresenter:
setup:
- setProjectId(10) # zavolej tuto metodu
- $absoluteUrls = true # a nastav proměnnou
Decorator se dá používat také pro nastavení tagů nebo zapnutí režimu inject.
decorator:
InjectableInterface:
tags: [mytag: 1]
inject: true
DI
Technické nastavení DI kontejneru.
di:
# zobrazit DIC v Tracy Bar?
debugger: ... # (bool) výchozí je true
# typy parametrů, které nikdy neautowirovat
excluded: ... # (string[])
# třída, od které dědí DI kontejner
parentClass: ... # (string) výchozí je Nette\DI\Container
Rozšíření
Registrace dalších DI rozšíření. Tímto způsobem přidáme např. DI rozšíření
Dibi\Bridges\Nette\DibiExtension22
pod názvem dibi
extensions:
dibi: Dibi\Bridges\Nette\DibiExtension22
Následně ho tedy konfigurujeme v sekci dibi
:
dibi:
host: localhost
Jako rozšíření lze přidat i třídu, která má parametry:
extensions:
application: Nette\Bridges\ApplicationDI\ApplicationExtension(%debugMode%, %appDir%, %tempDir%/cache)
Formuláře
V konfiguraci lze změnit výchozí chybové hlášky formulářů.
forms:
messages:
EQUAL: 'Zadejte %s.'
NOT_EQUAL: 'Tato hodnota by neměla být %s.'
FILLED: 'Toto pole je povinné.'
BLANK: 'Toto pole by mělo být prázdné.'
MIN_LENGTH: 'Zadejte prosím alespoň %d znaků.'
MAX_LENGTH: 'Zadejte prosím maximálně %d znaků.'
LENGTH: 'Zadejte prosím hodnotu %d až %d znaků dlouho.'
EMAIL: 'Zadejte platnou e-mailovou adresu.'
URL: 'Zadejte prosím platné URL.'
INTEGER: 'Zadejte platné celé číslo.'
FLOAT: 'Zadejte platné číslo.'
MIN: 'Zadejte prosím hodnotu větší nebo rovnou %d.'
MAX: 'Zadejte prosím hodnotu menší nebo rovnou %d.'
RANGE: 'Zadejte hodnotu mezi %d a %d.'
MAX_FILE_SIZE: 'Velikost nahraného souboru může být nejvýše %d bytů.'
MAX_POST_SIZE: 'Nahraná data překračují limit %d bytů.'
MIME_TYPE: 'Nahraný soubor není v očekávaném formátu.'
IMAGE: 'Nahraný soubor musí být obraz ve formátu JPEG, GIF, PNG nebo WebP.'
Nette\Forms\Controls\SelectBox::VALID: 'Vyberte prosím platnou možnost.'
Nette\Forms\Controls\UploadControl::VALID: 'Při nahrávání souboru došlo k chybě.'
Nette\Forms\Controls\CsrfProtection::PROTECTION: 'Vaše relace vypršela. Vraťte se na domovskou stránku a zkuste to znovu.'
HTTP hlavičky
http:
# hlavičky, které se s každým požadavkem odešlou
headers:
X-Powered-By: MyCMS
X-Content-Type-Options: nosniff
X-XSS-Protection: '1; mode=block'
# ovlivňuje hlavičku X-Frame-Options
frames: ... # (string|bool) výchozí je 'SAMEORIGIN'
Framework z bezpečnostních důvodů odesílá hlavičku X-Frame-Options: SAMEORIGIN
, která říká, že
stránku lze zobrazit uvnitř jiné stránky (v elementu <iframe>
) pouze pokud se nachází na stejné
doméně. To může být v některých situacích nežádoucí (například pokud vyvíjíte aplikaci pro Facebook), chování
lze proto změnit nastavením frames: http://allowed-host.com
nebo frames: true
.
Snadno lze sestavovat hlavičky Content-Security-Policy
(dále CSP), jejich popis najdete v popisu CSP. CSP direktivy (jako např. script-src
) mohou být zapsány
buď jako řetězce dle specifikace, nebo jako pole hodnot kvůli lepší čitelnosti. Pak není potřeba kolem klíčových slov,
jako třeba 'self'
, psát uvozovky. Nette také automaticky vygeneruje hodnotu nonce
, takže
v hlavičce bude třeba 'nonce-y4PopTLM=='
.
http:
# Content Security Policy (od nette/http 2.4.10)
csp:
# řetězec ve tvaru dle specifikace CSP
default-src: "'self' https://example.com"
# pole hodnot
script-src:
- nonce
- strict-dynamic
- self
- https://example.com
# bool v případě přepínačů
upgrade-insecure-requests: true
block-all-mixed-content: false
V šablonách používejte <script n:nonce>...</script>
a hodnota nonce se doplní automaticky.
Dělat bezpečné weby v Nette je opravdu snadné.
Podobně lze sestavit i hlavičky Content-Security-Policy-Report-Only
(které lze používat souběžně s CSP)
a Feature Policy:
http:
# Content Security Policy Report-Only
cspReportOnly:
default-src: self
report-uri: 'https://my-report-uri-endpoint'
# Feature Policy
featurePolicy:
unsized-media: none
geolocation:
- self
- https://example.com
HTTP cookie
Lze změnit vychozí hodnoty parametru $secure
u metody Nette\Http\Response::setCookie().
http:
# posílat cookie pouze přes HTTPS?
cookieSecure: ... # (bool|auto) výchozí je false
Hodnota auto
znamená, že pokud web běží na HTTPS, budou se cookies odesílat s příznakem
Secure
a tedy budou dostupné pouze přes HTTPS.
HTTP proxy
Pokud web běží za HTTP proxy, zadejte její IP adresu, aby správně fungovala detekce IP adresy klienta Nette\Http\Response::getRemoteAddress() a spojení přes HTTPS isSecured().
http:
# IP adresa, rozsah (např. 127.0.0.1/8) nebo pole těchto hodnot
proxy: 127.0.0.1 # (string|string[]) výchozí je nenastaveno
Vkládání souborů
Další konfigurační soubory můžeme vložit v sekci includes
:
includes:
- parameters.php
- services.neon
- presenters.neon
Název parameters.php
není překlep, konfigurace může být zapsaná také v PHP souboru, který ji vrátí
jako pole:
<?php
return [
'database' => [
'main' => [
'dsn' => 'sqlite::memory:',
],
],
];
Pokud se v konfiguračních souborech objeví prvky se stejnými klíči, budou přepsány, nebo v případě polí sloučeny. Později
vkládaný soubor má vyšší prioritu než předchozí. Soubor, ve kterém je sekce includes
uvedena, má vyšší
prioritu než v něm vkládané soubory.
Šablony Latte
Tímto nastavením lze globálně ovlivnit chování Latte v komponentách a presenterech.
latte:
# přepne Latte do XHTML režimu
xhtml: ... # (bool) výchozí je false
# třída objektu $this->template
templateClass: App\MyTemplateClass # výchozí je Nette\Bridges\ApplicationLatte\Template
Dále lze registrovat nové tagy (makra) a to buď uvedením jména třídy, nebo referencí na službu. Jako výchozí je
zavolána metoda install()
, ale to lze změnit tím, že uvedeme jméno jiné metody:
latte:
# registrace uživatelských Latte značek
macros:
- App\MyLatteMacros::register # statická metoda, classname nebo callable
- @App\MyLatteMacrosFactory # služba s metodou install()
- @App\MyLatteMacrosFactory::register # služba s metodou register()
services:
- App\MyLatteMacrosFactory
Maily
Pro odesílání e-mailů se standardně používá mailer
Nette\Mail\SendmailMailer
, který se dále nekonfiguruje. Můžeme jej však přepnout na
Nette\Mail\SmtpMailer
:
mail:
# použije SmtpMailer
smtp: true # (bool) výchozí je false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
secure: ... # (ssl|tls|null) výchozí je null
clientHost: ... # (string) výchozí je $_SERVER['HTTP_HOST']
persistent: ... # (bool) výchozí je false
Parametry
V konfiguraci můžete definovat parametry, které lze pak použít jako součást definic služeb. Čímž můžete zpřehlednit konfiguraci nebo sjednotit a vyčlenit hodnoty, které se budou měnit.
parameters:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: secret
Na parametr dsn
se odkážeme kdekoliv v konfiguraci zápisem %dsn%
. Parametry lze používat
i uvnitř řetězců jako '%wwwDir%/images'
.
Parametry nemusí být jen řetězce nebo čísla, mohou také obsahovat pole:
parameters:
mailer:
host: smtp.example.com
secure: ssl
user: franta@gmail.com
languages: [cs, en, de]
Na konkrétní klíč se odkážeme jako %mailer.user%
.
Chcete-li zapsat řetězec začínající znakem @
nebo obsahující %
, musíte znak
escapovat zdvojením na @@
nebo %%
.
Pokud potřebujete ve vašem kódu, například třídě, zjistit hodnotu jakékoliv parametru, tak jej do této třídy předejte. Například v konstruktoru. Neexistuje žádný globální objekt představující konfiguraci, kterého by se třídy dotazovaly na hodnoty parametrů. To by bylo porušením principu dependency injection.
PHP
Nastavení direktiv PHP. Přehled všech direktiv naleznete na php.net.
php:
date.timezone: Europe/Prague
Routování
Základní nastavení:
routing:
# zobrazit routovací panel v Tracy Bar?
debugger: ... # (bool) výchozí je true
# serializuje router do DI kontejneru
cache: ... # (bool) výchozí je false
Routování obvykle definujeme ve třídě RouterFactory, omezenější alternativou je definice v konfiguraci pomocí dvojic
maska: akce
:
routing:
routes:
'detail/<id>': Admin:Home:default
'<presenter>/<action>': Front:Home:default
Přístupová oprávnění
V konfiguraci lze definovat seznam uživatelů, a tak vytvořit jednoduchý
authenticator (Nette\Security\SimpleAuthenticator
). Protože se v konfiguraci uvádějí hesla v čitelné
podobě, je tohle řešení vhodné pouze pro testovací účely.
security:
# zobrazit panel uživatele v Tracy Bar?
debugger: ... # (bool) výchozí je true
users:
# jméno: heslo
frantisek: tajneheslo
# jméno, heslo, role a další data dostupná v identitě
dobrota:
password: tajneheslo
roles: [admin]
data: ...
Dále lze definovat role a zdroje a vytvořit tak základ pro autorizátor
(Nette\Security\Permission
):
security:
roles:
guest:
registered: [guest] # registered dědí od guest
admin: [registered] # a od něj dědí admin
resources:
article:
comment: [article] # zdroj dědí od article
poll:
Session
Základní nastavení sessions:
session:
# zobrazit session panel v Tracy Bar?
debugger: ... # (bool) výchozí je false
# doba neaktivity po které session vyexpiruje
expiration: 14 days # (string) výchozí je '3 hours'
# startovat automaticky session po vytvoření kontejneru?
# 'smart' startuje session pokud je již vytvořena
autoStart: ... # (bool|smart) výchozí je 'smart'
# handler, služba implementující rozhraní SessionHandlerInterface
handler: @handlerService
Dále lze nastavovat všechny PHP session direktivy (ve formátu camelCase):
session:
# 'session.name' zapíšeme jako 'name'
name: MYID
# 'session.save_path' zapíšeme jako 'savePath'
savePath: "%tempDir%/sessions"
Session cookie
Nastavení cookieSecure
se přebírá z nastavení HTTP cookie, můžete navíc
upravit volby cookieDomain
a cookieSamesite
.
session:
# domény, které přijímají cookie
cookieDomain: 'example.com' # (string|domain) výchozí je nenastaveno
# omezení při přístupu z jiné domény
cookieSamesite: Lax # (Strict|Lax|None) výchozí je nenastaveno
Atribut cookieDomain
určuje, které domény mohou cookie přijímat. Není-li uveden, cookie přijímá stejná
(sub)doména, jako ji nastavila, ale nikoliv její subdomény. Pokud je cookieDomain
zadaný, jsou zahrnuty
i subdomény. Proto je uvedení cookieDomain
méně omezující než vynechání.
Například při cookieDomain: nette.org
jsou cookies dostupné i na všech subdoménách jako
doc.nette.org
. Téhož lze dosáhnout také pomocí speciální hodnoty domain
, tedy
cookieDomain: domain
.
Atribut cookieSamesite
ovlivňuje, zda bude cookie odeslaná při přístupu z jiné
domény, což poskytuje určitou ochranu před útoky Cross-Site Request Forgery (CSRF).
Tracy debugger
V konfiguraci lze nastavovat parametry Tracy a také přidávat nové panely do Tracy Bar. Tyto nastavení se aplikují teprve po vytvoření DI kontejneru, takže chyby vzniklé předtím je nemohou reflektovat.
Konfigurace logování chyb:
tracy:
# e-mail, na který se posílají notifikace, že došlo k chybě
email: dev@example.com # (string|string[]) výchozí je nenastaveno
# odesílatel e-mailu
fromEmail: robot@example.com # (string) výchozí je nenastaveno
# použít pro odesílání e-mailů Nette mailer? (od Tracy 2.5)
netteMailer: ... # (bool) výchozí je true
# pro jaké úrovně chyb se loguje i BlueScreen?
logSeverity: [E_WARNING, E_NOTICE] # výchozí je []
Konfigurace chování funkce dump()
:
tracy:
# maximální délka řetězce
maxLength: 150 # (int) výchozí dle verze Tracy
# maximální hloubka zanoření
maxDepth: 10 # (int) výchozí dle verze Tracy
# zobrazit místo, kde byla volána funkce dump()?
showLocation: ... # (bool) výchozí dle verze Tracy
Instalace rozšíření Tracy:
tracy:
# přidá panely do Tracy Bar
bar:
- Nette\Bridges\DITracy\ContainerPanel
- IncludePanel
- XDebugHelper('myIdeKey')
- MyPanel(@MyService)
# přidá panely do BlueScreen
blueScreen:
- DoctrinePanel::renderException
Ostatní volby:
tracy:
# ve vývojovém režimu zobrazí chyby typu notice nebo warning jako BlueScreen
strictMode: ... # (bool) výchozí je true
# zobrazit umlčené (@) chybové hlášky?
scream: ... # (bool) výchozí je false
# formát odkazu pro otevření v editoru
editor: .... # (string) výchozí je 'editor://open/?file=%file&line=%line'
# cesta k šabloně s vlastní stránkou pro chybu 500
errorTemplate: ... # (string) výchozí je nenastaveno
# zobrazit Tracy Bar?
showBar: ... # (bool) výchozí je true
editorMapping:
# originál: nová
/var/www/html: /data/web
/home/web: /srv/html
Služby a úpravy
Konfigurace je místem, kam umísťujeme definice vlastních služeb. Slouží k tomu sekce services
, podrobný
popis najdete v kapitole Služby.
Například takto může vypadat definice služby pojmenované database
, což bude instance PDO
:
services:
database: PDO('mysql:host=127.0.0.1;dbname=test', root, password)
Dále je v DI kontejneru řada služeb, které přidaly vestavěné nebo vaše rozšíření.
Definice těchto služeb lze v konfiguraci pozměnit. Třeba u služby application.application
, což je standardně
objekt Nette\Application\Application
, můžeme změnit třídu:
services:
application.application:
factory: MyApplication
alteration: true
Příznak alteration
je informativní a říká, že jen modifikujeme existující službu.
Můžeme také doplnit setup:
services:
application.application:
factory: MyApplication
alteration: true
setup:
- $onStartup = [@resource::init]
Službu přidanou rozšířením lze také z kontejneru odstranit:
services:
cache.journal: false