diff --git a/application/bg/@left-menu.texy b/application/bg/@left-menu.texy
index e19ec32175..24596b3137 100644
--- a/application/bg/@left-menu.texy
+++ b/application/bg/@left-menu.texy
@@ -15,5 +15,8 @@
Допълнително четене
*******************
+- [Защо да използвате Nette? |www:10-reasons-why-nette]
+- [Инсталация |nette:installation]
+- [Създайте първото си приложение! |quickstart:]
- [Най-добри практики |best-practices:]
- [Отстраняване на неизправности |nette:troubleshooting]
diff --git a/application/bg/ajax.texy b/application/bg/ajax.texy
index 5ac48a22b8..1bcf75bc98 100644
--- a/application/bg/ajax.texy
+++ b/application/bg/ajax.texy
@@ -10,9 +10,13 @@ AJAX и фрагменти
-Заявката AJAX може да бъде открита чрез метода на услугата, който [капсулира HTTP заявката |http:request] `$httpRequest->isAjax()` (определя се въз основа на HTTP заглавието `X-Requested-With`). Съществува и съкратен метод в програмата за представяне: `$this->isAjax()`.
-Заявката AJAX не се различава от обикновената заявка - водещият се извиква с определено представяне и параметри. От водещия зависи и как ще реагира: той може да използва процедурите си, за да върне фрагмент от HTML код, XML документ, JSON обект или част от Javascript код.
+Заявка AJAX .[#toc-ajax-request]
+================================
+
+Заявката AJAX не се различава от класическата заявка - водещият се извиква с определен изглед и параметри. От водещия също зависи как да отговори на нея: той може да използва своя собствена процедура, която връща фрагмент от HTML код (HTML snippet), XML документ, JSON обект или JavaScript код.
+
+От страна на сървъра AJAX заявката може да бъде открита с помощта на метода на услугата, [капсулиращ HTTP заявката |http:request] `$httpRequest->isAjax()` (открива се въз основа на HTTP заглавието `X-Requested-With`). Вътре в презентатора е наличен пряк път под формата на метода `$this->isAjax()`.
Съществува предварително обработен обект `payload`, предназначен за изпращане на данни към браузъра във формат JSON.
@@ -60,6 +64,21 @@ npm install naja
```
+За да създадете AJAX заявка от обикновена връзка (сигнал) или подаване на формуляр, просто маркирайте съответната връзка, формуляр или бутон с класа `ajax`:
+
+```html
+Go
+
+
+
+or
+
+```
+
Извадки .[#toc-snippety]
========================
@@ -149,7 +168,7 @@ $this->isControlInvalid('footer'); // -> true
В горния пример трябва да се уверите, че само един елемент ще бъде добавен към масива `$list`, когато бъде направена заявката AJAX, така че цикълът `foreach` ще изведе само един динамичен фрагмент.
```php
-class HomepagePresenter extends Nette\Application\UI\Presenter
+class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* Этот метод возвращает данные для списка.
diff --git a/application/bg/bootstrap.texy b/application/bg/bootstrap.texy
index 17833a42e7..8d0b3dc5c4 100644
--- a/application/bg/bootstrap.texy
+++ b/application/bg/bootstrap.texy
@@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```
-Конфигурационните файлове могат да използват нормалния запис `%projectId%` за достъп до параметъра с име `projectId`. По подразбиране конфигураторът попълва следните параметри: `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` и `consoleMode`.
+В конфигурационните файлове можем да запишем обичайната нотация `%projectId%`, за да получим достъп до параметъра с име `projectId`.
Динамични параметри .[#toc-dynamic-parameters]
@@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```
+Параметри по подразбиране .[#toc-default-parameters]
+----------------------------------------------------
+
+Можете да използвате следните статични параметри в конфигурационните файлове:
+
+- `%appDir%` е абсолютният път до директорията на файла `Bootstrap.php`
+- `%wwwDir%` е абсолютният път до директорията, съдържаща входния файл `index.php`
+- `%tempDir%` е абсолютният път до директорията за временни файлове
+- `%vendorDir%` е абсолютният път до директорията, в която Composer инсталира библиотеки
+- `%debugMode%` показва дали приложението е в режим на отстраняване на грешки
+- `%consoleMode%` показва дали заявката е постъпила от командния ред
+
+
Внесени услуги .[#toc-imported-services]
----------------------------------------
diff --git a/application/bg/components.texy b/application/bg/components.texy
index e2ed9dfed6..27b0129100 100644
--- a/application/bg/components.texy
+++ b/application/bg/components.texy
@@ -233,31 +233,34 @@ $this->redirect(/* ... */); // пренасочване
Постоянни параметри .[#toc-persistent-parameters]
=================================================
-Често е необходимо да се запази даден параметър в компонент за целия период на експлоатация на компонента. Това може да бъде например номер на страница в странирането. Този параметър трябва да бъде отбелязан като постоянен с помощта на анотацията `@persistent`.
+Постоянните параметри се използват за поддържане на състоянието на компонентите между различните заявки. Тяхната стойност остава същата дори след щракване върху връзката. За разлика от данните за сесията, те се прехвърлят в URL адреса. И се прехвърлят автоматично, включително връзките, създадени в други компоненти на същата страница.
+
+Например, имате компонент за страниране на съдържание. На една страница може да има няколко такива компонента. И искате всички компоненти да останат на текущата си страница, когато щракнете върху връзката. Затова правим номера на страницата (`page`) постоянен параметър.
+
+Създаването на постоянен параметър е изключително лесно в Nette. Просто създайте публично свойство и го маркирайте с атрибута: (преди се използваше `/** @persistent */` )
```php
-class PollControl extends Control
+use Nette\Application\Attributes\Persistent; // този ред е важен
+
+class PaginatingControl extends Control
{
- /** @persistent */
- public int $page = 1;
+ #[Persistent]
+ public int $page = 1; // трябва да бъдат публични
}
```
-Този параметър ще се предава автоматично във всяка връзка като параметър `GET`, докато потребителят напусне страницата с този компонент.
+Препоръчваме ви да включите типа данни (например `int`) към свойството, като можете да включите и стойност по подразбиране. Стойностите на параметрите могат да бъдат [валидирани |#Validation of Persistent Parameters].
-.[caution]
-Никога не се доверявайте сляпо на постоянни параметри, тъй като те могат лесно да бъдат подправени (чрез презаписване на URL адреса). Проверете например дали номерът на страницата е в правилния интервал.
+Можете да променяте стойността на постоянен параметър, когато създавате връзка:
-В PHP 8 можете също така да използвате атрибути, за да маркирате постоянни параметри:
+```latte
+next
+```
-```php
-use Nette\Application\Attributes\Persistent;
+Или може да бъде *ресетнат*, т.е. да бъде премахнат от URL адреса. След това той ще приеме стойността си по подразбиране:
-class PollControl extends Control
-{
- #[Persistent]
- public int $page = 1;
-}
+```latte
+reset
```
@@ -378,7 +381,7 @@ interface PollControlFactory
1) може да се показва в шаблон
2) той знае каква част от себе си да покаже по време на [заявката AJAX |ajax#invalidation] (фрагменти)
-3) може да съхранява състоянието си в URL (параметри за устойчивост).
+3) има възможност да съхранява състоянието си в URL (постоянни параметри).
4) има възможност да реагира на действията (сигналите) на потребителя.
5) създава йерархична структура (където коренът е главният).
@@ -403,6 +406,33 @@ Nette\ComponentModel\Component { IComponent }
[* lifecycle-component.svg *] *** * Жизнен цикъл на компонента* .<>
+Утвърждаване на постоянни параметри .[#toc-validation-of-persistent-parameters]
+-------------------------------------------------------------------------------
+
+Стойностите на [постоянните параметри, |#persistent parameters] получени от URL адреси, се записват в свойствата чрез метода `loadState()`. Той също така проверява дали типът данни, зададен за свойството, съвпада, в противен случай ще отговори с грешка 404 и страницата няма да бъде показана.
+
+Никога не се доверявайте сляпо на постоянните параметри, защото те лесно могат да бъдат пренаписани от потребителя в URL адреса. Например, така проверяваме дали номерът на страницата `$this->page` е по-голям от 0. Добър начин да направите това е да презапишете метода `loadState()`, споменат по-горе:
+
+```php
+class PaginatingControl extends Control
+{
+ #[Persistent]
+ public int $page = 1;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // тук се задава $this->page
+ // следва проверката на потребителската стойност:
+ if ($this->page < 1) {
+ $this->error();
+ }
+ }
+}
+```
+
+Противоположният процес, т.е. събирането на стойности от постоянни пропъртита, се обработва от метода `saveState()`.
+
+
Сигнали в дълбочина .[#toc-signals-in-depth]
--------------------------------------------
diff --git a/application/bg/creating-links.texy b/application/bg/creating-links.texy
index 6097a3719c..659326e6fe 100644
--- a/application/bg/creating-links.texy
+++ b/application/bg/creating-links.texy
@@ -52,7 +52,7 @@
Атрибутът `n:href` е много полезен за HTML тагове. ``. Ако искаме да покажем връзката на друго място, например в текста, използваме `{link}`:
```latte
-URL: {link Homepage:default}
+URL: {link Home:default}
```
@@ -88,7 +88,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Следователно основната форма е `Presenter:action`:
```latte
-главная страница
+главная страница
```
Ако се позоваваме на действието на текущия водещ, можем да пропуснем името му:
@@ -100,7 +100,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Ако действието е `default`, можем да го пропуснем, но двоеточието трябва да остане:
```latte
-главная страница
+главная страница
```
Връзките могат да сочат и към други [модули |modules]. Тук връзките се разграничават на относителни към подмодули или абсолютни. Принципът е подобен на дисковите пътища, само че с двоеточия вместо с наклонени черти. Да предположим, че водещият е част от модул `Front`, тогава записваме:
@@ -119,7 +119,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Можем да направим връзка към определена част от HTML страницата чрез така наречения фрагмент след символа хеш `#`:
```latte
-ссылка на Homepage:default и фрагмент #main
+ссылка на Home:default и фрагмент #main
```
@@ -128,7 +128,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Връзките, генерирани от `link()` или `n:href`, винаги са абсолютни пътища (т.е. започват с `/`), но не и абсолютни URL адреси с протокол и домейн, като `https://domain`.
-За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например `n:href="//Homepage:"`). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете `$this->absoluteUrls = true`.
+За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например `n:href="//Home:"`). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете `$this->absoluteUrls = true`.
Връзка към текущата страница .[#toc-link-to-current-page]
@@ -213,13 +213,13 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Ако искаме да направим препратка към презентаторите в шаблона на компонента, използваме тага `{plink}`:
```latte
-главная страница
+главная страница
```
или в кода
```php
-$this->getPresenter()->link('Homepage:default')
+$this->getPresenter()->link('Home:default')
```
diff --git a/application/bg/how-it-works.texy b/application/bg/how-it-works.texy
index b329738fcc..6f267f3b26 100644
--- a/application/bg/how-it-works.texy
+++ b/application/bg/how-it-works.texy
@@ -23,10 +23,10 @@
web-project/
├── app/ ← каталог с приложением
│ ├── Presenters/ ← классы презентеров
-│ │ ├── HomepagePresenter.php ← Класс презентера главной страницы
+│ │ ├── HomePresenter.php ← Класс презентера главной страницы
│ │ └── templates/ ← директория шаблонов
│ │ ├── @layout.latte ← шаблон общего макета
-│ │ └── Homepage/ ← шаблоны презентера главной страницы
+│ │ └── Home/ ← шаблоны презентера главной страницы
│ │ └── default.latte ← шаблон действия `default`
│ ├── Router/ ← конфигурация URL-адресов
│ └── Bootstrap.php ← загрузочный класс Bootstrap
@@ -134,10 +134,10 @@ class ProductPresenter extends Nette\Application\UI\Presenter
1) URL адресът ще `https://example.com`
2) изтегляме приложението, създаваме контейнер и стартираме `Application::run()`
-3) маршрутизаторът декодира URL адреса като двойка `Homepage:default`
-4) обектът е създаден `HomepagePresenter`
+3) маршрутизаторът декодира URL адреса като двойка `Home:default`
+4) обектът е създаден `HomePresenter`
5) извиква се методът `renderDefault()` (ако съществува)
-6) шаблонът `templates/Homepage/default.latte` с оформлението `templates/@layout.latte` се визуализира
+6) шаблонът `templates/Home/default.latte` с оформлението `templates/@layout.latte` се визуализира
Може би сега ще се сблъскате с много нови концепции, но ние смятаме, че те имат смисъл. Създаването на приложения в Nette е лесно.
diff --git a/application/bg/modules.texy b/application/bg/modules.texy
index d62f08c7d5..622fd48b2e 100644
--- a/application/bg/modules.texy
+++ b/application/bg/modules.texy
@@ -104,7 +104,7 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
Определя правилата, по които името на класа се извежда от главното име. Записваме ги в [конфигурацията |configuration] под ключа `application › mapping`.
-Нека започнем с пример, при който не се използват модули. Искаме само главните класове да имат пространството от имена `App\Presenters`. Това означава, че искаме главното име, например `Homepage`, да се съпостави с класа `App\Presenters\HomepagePresenter`. Това може да се постигне със следната конфигурация:
+Нека започнем с пример, при който не се използват модули. Искаме само главните класове да имат пространството от имена `App\Presenters`. Това означава, че искаме главното име, например `Home`, да се съпостави с класа `App\Presenters\HomePresenter`. Това може да се постигне със следната конфигурация:
```neon
application:
@@ -124,7 +124,7 @@ application:
Api: App\Api\*Presenter
```
-Сега водещият `Front:Homepage` е определен от класа `App\Modules\Front\HomepagePresenter`, а презентер `Admin:Dashboard` - `App\AdminModule\DashboardPresenter`.
+Сега водещият `Front:Home` е определен от класа `App\Modules\Front\HomePresenter`, а презентер `Admin:Dashboard` - `App\AdminModule\DashboardPresenter`.
Би било по-удобно да се създаде общо правило (звездичка), което да замени първите две правила, и да се добави допълнителна звездичка само за модула:
diff --git a/application/bg/presenters.texy b/application/bg/presenters.texy
index 6eddfd227a..9c09769cda 100644
--- a/application/bg/presenters.texy
+++ b/application/bg/presenters.texy
@@ -158,7 +158,7 @@ $url = $this->link('Product:show', [$id, 'lang' => 'en']);
$this->forward('Product:show');
```
-Пример за временно пренасочване с HTTP код 302 или 303:
+Пример за т.нар. временно пренасочване с HTTP код 302 (или 303, ако текущият метод на заявка е POST):
```php
$this->redirect('Product:show', $id);
@@ -170,7 +170,7 @@ $this->redirect('Product:show', $id);
$this->redirectPermanent('Product:show', $id);
```
-Можете да пренасочите към друг URL адрес извън приложението, като използвате метода `redirectUrl()`:
+Можете да пренасочите към друг URL адрес извън приложението, като използвате метода `redirectUrl()`. Като втори параметър може да се посочи HTTP кодът, като по подразбиране той е 302 (или 303, ако текущият метод на заявка е POST):
```php
$this->redirectUrl('https://nette.org');
@@ -239,46 +239,54 @@ public function actionData(): void
Постоянни параметри .[#toc-persistent-parameters]
=================================================
-Постоянните параметри се **предават автоматично** във връзките. Това означава, че не е необходимо да ги посочваме изрично във всеки `link()` или `n:href` в шаблона, но те все пак ще бъдат предадени.
+Постоянните параметри се използват за поддържане на състоянието между различните заявки. Стойността им остава същата дори след щракване върху връзката. За разлика от данните за сесията, те се предават в URL адреса. Това става напълно автоматично, така че не е необходимо да ги посочвате изрично в `link()` или `n:href`.
-Ако приложението ви има няколко езикови версии, текущият език е параметър, който винаги трябва да бъде част от URL адреса. И би било изключително досадно да го споменаваме във всяка връзка. При Nette това не е необходимо. Затова просто отбелязваме параметъра `lang` като постоянен:
+Пример за използване? Имате многоезично приложение. Действителният език е параметър, който трябва да бъде част от URL адреса по всяко време. Но би било изключително досадно да го включвате във всяка връзка. Затова го правите постоянен параметър с име `lang` и той ще се пренася сам. Страхотно!
+
+Създаването на постоянен параметър е изключително лесно в Nette. Просто създайте публично свойство и го маркирайте с атрибута: (преди се използваше `/** @persistent */` )
```php
+use Nette\Application\Attributes\Persistent; // този ред е важен
+
class ProductPresenter extends Nette\Application\UI\Presenter
{
- /** @persistent */
- public string $lang;
+ #[Persistent]
+ public string $lang; // трябва да бъдат публични
}
```
-Ако текущата стойност на параметъра `lang` е `'en'`, тогава URL адресът, създаден с `link()` или `n:href` в шаблона, ще съдържа `lang=en`. Перфектно!
-
-Можем обаче да добавим и параметъра `lang` и по този начин да променим стойността му:
+Ако `$this->lang` има стойност като `'en'`, то връзките, създадени с помощта на `link()` или `n:href`, ще съдържат и параметъра `lang=en`. И когато върху връзката се щракне, тя отново ще бъде `$this->lang = 'en'`.
-```latte
-подробности на английском
-```
-
-Или пък можем да го изтрием, като му зададем стойност null:
-
-```latte
-нажмите здесь
-```
+За свойствата препоръчваме да включите типа данни (например `string`), а също така можете да включите стойност по подразбиране. Стойностите на параметрите могат да бъдат [валидирани |#Validation of Persistent Parameters].
-Една постоянна променлива трябва да бъде декларирана като публична. Можем да зададем и стойност по подразбиране. Ако параметърът има същата стойност като тази по подразбиране, той няма да бъде включен в URL адреса.
+Постоянните параметри се предават между всички действия на даден презентатор по подразбиране. За да ги предадете между няколко водещи, трябва да ги дефинирате или:
-Постоянството отразява йерархията на класовете на презентаторите, така че параметър, дефиниран в конкретен презентатор или черта, се предава автоматично на всеки презентатор, който наследява от него или използва същата черта.
-
-В PHP 8 можете също така да използвате атрибути, за да маркирате постоянни параметри:
+- в общ предшественик, от който презентаторите наследяват
+- в чертата, която презентаторите използват:
```php
-use Nette\Application\Attributes\Persistent;
-
-class ProductPresenter extends Nette\Application\UI\Presenter
+trait LangAware
{
#[Persistent]
public string $lang;
}
+
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ use LangAware;
+}
+```
+
+Можете да променяте стойността на постоянен параметър, когато създавате връзка:
+
+```latte
+detail in Czech
+```
+
+Или може да бъде *ресетнат*, т.е. да бъде премахнат от URL адреса. След това той ще приеме стойността си по подразбиране:
+
+```latte
+click
```
@@ -302,7 +310,32 @@ class ProductPresenter extends Nette\Application\UI\Presenter
Изисквания и параметри .[#toc-requirement-and-parameters]
---------------------------------------------------------
-Заявката, която се обработва от водещия, е обект [api:Nette\Application\Request] и се връща от метода на водещия `getRequest()`. Той включва масив от параметри, всеки от които принадлежи или на някой компонент, или директно на водещия (който всъщност също е компонент, макар и специален). По този начин Nette преразпределя параметрите и ги прехвърля между отделните компоненти (и водещия) чрез извикване на метода `loadState(array $params)`, който е описан по-подробно в главата [Компоненти |components]. Параметрите могат да се извличат чрез метода `getParameters(): array`, а поотделно - чрез `getParameter($name)`. Стойностите на параметрите са низове или масиви от низове, предимно необработени данни, получени директно от URL.
+Заявката, която се обработва от водещия, е обектът [api:Nette\Application\Request] и се връща от метода на водещия `getRequest()`. Тя включва масив от параметри и всеки от тях принадлежи или на някой от компонентите, или директно на водещия (който всъщност също е компонент, макар и специален). Затова Nette преразпределя параметрите и преминава между отделните компоненти (и водещия), като извиква метода `loadState(array $params)`. Параметрите могат да бъдат получени чрез метода `getParameters(): array`, а поотделно чрез `getParameter($name)`. Стойностите на параметрите са низове или масиви от низове, те по същество са необработени данни, получени директно от URL адреса.
+
+
+Утвърждаване на постоянни параметри .[#toc-validation-of-persistent-parameters]
+-------------------------------------------------------------------------------
+
+Стойностите на [постоянните параметри, |#persistent parameters] получени от URL адреси, се записват в свойствата чрез метода `loadState()`. Той също така проверява дали типът данни, посочен в свойството, съвпада, в противен случай ще отговори с грешка 404 и страницата няма да бъде показана.
+
+Никога не се доверявайте сляпо на постоянните параметри, тъй като те лесно могат да бъдат пренаписани от потребителя в URL адреса. Например, така проверяваме дали `$this->lang` е сред поддържаните езици. Добър начин да направите това е да пренастроите метода `loadState()`, споменат по-горе:
+
+```php
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ #[Persistent]
+ public string $lang;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // тук се задава $this->lang
+ // следва проверката на потребителската стойност:
+ if (!in_array($this->lang, ['en', 'cs'])) {
+ $this->error();
+ }
+ }
+}
+```
Запазване и възстановяване на заявка .[#toc-save-and-restore-the-request]
diff --git a/application/bg/routing.texy b/application/bg/routing.texy
index 183446edbb..96e134bc79 100644
--- a/application/bg/routing.texy
+++ b/application/bg/routing.texy
@@ -93,12 +93,12 @@ $router->addRoute('chronicle/', 'History:show');
Разбира се, името на водещия и действието също могат да бъдат параметри. Например:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
Този маршрут приема например URL адреси под формата съответно на `/article/edit` и `/catalog/list` и ги превръща в презентатори и действия съответно `Article:edit` и `Catalog:list`.
-Той също така дава на `presenter` и `action` стойности по подразбиране за `Homepage` и `default` и следователно те не са задължителни. Затова маршрутът също така взема URL адреса `/article` и го превежда като `Article:default`. Или обратното, връзка към `Product:default` генерира пътя `/product`, а връзка към стандартния `Homepage:default` генерира пътя `/`.
+Той също така дава на `presenter` и `action` стойности по подразбиране за `Home` и `default` и следователно те не са задължителни. Затова маршрутът също така взема URL адреса `/article` и го превежда като `Article:default`. Или обратното, връзка към `Product:default` генерира пътя `/product`, а връзка към стандартния `Home:default` генерира пътя `/`.
Маската може да описва не само относителен път, базиран на корена на сайта, но и абсолютен път, ако започва с наклонена черта, или дори цял абсолютен URL адрес, ако започва с две наклонени черти:
@@ -160,7 +160,7 @@ $router->addRoute('//[.]example.com//', /* ... */);
```php
$router->addRoute(
'[[-]/][page-]',
- 'Homepage:default',
+ 'Home:default',
);
//получени URL адреси:
@@ -183,16 +183,16 @@ $router->addRoute('[!.html]', /* ... */);
Незадължителни параметри (т.е. параметри, които имат стойност по подразбиране) без квадратни скоби се държат така, сякаш са обвити по този начин:
```php
-$router->addRoute('//', /* ... */);
+$router->addRoute('//', /* ... */);
// е равно на:
-$router->addRoute('[/[/[]]]', /* ... */);
+$router->addRoute('[/[/[]]]', /* ... */);
```
-За да промените начина, по който се генерира най-дясната наклонена черта, т.е. вместо `/homepage/` да получите `/homepage`, конфигурирайте маршрута по този начин:
+За да промените начина, по който се генерира най-дясната наклонена черта, т.е. вместо `/home/` да получите `/home`, конфигурирайте маршрута по този начин:
```php
-$router->addRoute('[[/[/]]]', /* ... */);
+$router->addRoute('[[/[/]]]', /* ... */);
```
@@ -220,7 +220,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
]);
```
@@ -232,7 +232,7 @@ use Nette\Routing\Route;
$router->addRoute('/[/]', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
@@ -252,7 +252,7 @@ $router->addRoute('/[/]', [
Добра практика е изходният код да бъде написан на английски език, но какво да правите, ако URL адресът на уебсайта ви трябва да бъде преведен на друг език?
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
ще генерира английски URL адреси като `/product/123` или `/cart`. Ако искаме презентаторите и действията в URL адреса да бъдат преведени на немски език (напр. `/produkt/123` или `/einkaufswagen`), можем да използваме речник за превод. За да го добавим, вече се нуждаем от "по-ясна" версия на втория параметър:
@@ -262,7 +262,7 @@ use Nette\Routing\Route;
$router->addRoute('/', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterTable => [
// строка в URL => ведущий
'produkt' => 'Product',
@@ -290,7 +290,7 @@ use Nette\Routing\Route;
$router->addRoute('//', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
@@ -313,7 +313,7 @@ $router->addRoute('//', [
use Nette\Routing\Route;
$router->addRoute('/', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
@@ -503,15 +503,15 @@ http://example.com/?presenter=Product&action=detail&id=123
Параметърът на конструктора `SimpleRouter` е презентаторът и действието по подразбиране, т.е. действието, което ще се изпълни, ако отворим например `http://example.com/` без никакви допълнителни параметри.
```php
-// използвайте презентатора 'Homepage' и действието 'default'
-$router = new Nette\Application\Routers\SimpleRouter('Homepage:default');
+// използвайте презентатора 'Home' и действието 'default'
+$router = new Nette\Application\Routers\SimpleRouter('Home:default');
```
Препоръчваме да дефинирате SimpleRouter директно в [конфигурацията |dependency-injection:services]:
```neon
services:
- - Nette\Application\Routers\SimpleRouter('Homepage:default')
+ - Nette\Application\Routers\SimpleRouter('Home:default')
```
@@ -611,7 +611,7 @@ class MyRouter implements Nette\Routing\Router
```php
[
- 'presenter' => 'Front:Homepage',
+ 'presenter' => 'Front:Home',
'action' => 'default',
]
```
diff --git a/application/bg/templates.texy b/application/bg/templates.texy
index d32c30c5ba..850d3e2ecd 100644
--- a/application/bg/templates.texy
+++ b/application/bg/templates.texy
@@ -42,7 +42,9 @@ Nette използва системата за шаблони [Latte |latte:]. L
- `templates//.latte`
- `templates/..latte`
-Ако шаблонът не е намерен, отговорът ще бъде [грешка 404 |presenters#error-404-etc].
+Ако шаблонът не бъде намерен, ще се опита да търси в директорията `templates` едно ниво по-нагоре, т.е. на същото ниво като директорията с класа на водещия.
+
+Ако шаблонът не бъде намерен и там, отговорът ще бъде [грешка 404 |presenters#Error 404 etc.].
Можете също така да промените изгледа с помощта на `$this->setView('jineView')`. Или вместо да търсите директно, посочете името на файла с шаблона, като използвате `$this->template->setFile('/path/to/template.latte')`.
@@ -148,7 +150,7 @@ public function renderDefault(): void
Атрибутът `n:href` е много удобен за HTML таговете. ``. Ако искаме да посочим връзка на друго място, например в текста, използваме `{link}`:
```latte
-Adresa je: {link Homepage:default}
+Adresa je: {link Home:default}
```
Вижте [Създаване на URL връзки |creating-links] за повече информация.
diff --git a/application/cs/@left-menu.texy b/application/cs/@left-menu.texy
index 9c512de998..f7378fff34 100644
--- a/application/cs/@left-menu.texy
+++ b/application/cs/@left-menu.texy
@@ -15,5 +15,8 @@ Aplikace v Nette
Další četba
***********
+- [Proč používat Nette? |www:10-reasons-why-nette]
+- [Instalace |nette:installation]
+- [Píšeme první aplikaci! |quickstart:]
- [Návody a postupy |best-practices:]
- [Řešení problémů |nette:troubleshooting]
diff --git a/application/cs/ajax.texy b/application/cs/ajax.texy
index 90b0c2d742..e4d30f762a 100644
--- a/application/cs/ajax.texy
+++ b/application/cs/ajax.texy
@@ -10,10 +10,14 @@ Moderní webové aplikace dnes běží napůl na serveru, napůl v prohlížeči
-AJAXový požadavek lze detekovat metodou služby [zapouzdřující HTTP požadavek |http:request] `$httpRequest->isAjax()` (detekuje podle HTTP hlavičky `X-Requested-With`). Uvnitř presenteru je k dispozici "zkratka" v podobě metody `$this->isAjax()`.
+
+AJAXový požadavek
+=================
AJAXový požadavek se nijak neliší od klasického požadavku - je zavolán presenter s určitým view a parametry. Je také věcí presenteru, jak bude na něj reagovat: může použít vlastní rutinu, která vrátí nějaký fragment HTML kódu (HTML snippet), XML dokument, JSON objekt nebo kód v JavaScriptu.
+Na straně serveru lze AJAXový požadavek detekovat metodou služby [zapouzdřující HTTP požadavek |http:request] `$httpRequest->isAjax()` (detekuje podle HTTP hlavičky `X-Requested-With`). Uvnitř presenteru je k dispozici "zkratka" v podobě metody `$this->isAjax()`.
+
Pro odesílání dat prohlížeči ve formátu JSON lze využít předpřipravený objekt `payload`:
```php
@@ -60,6 +64,21 @@ npm install naja
```
+Aby se z obyčejného odkazu (signálu) nebo odeslání formuláře vytvořil AJAXový požadavek, stačí označit příslušný odkaz, formulář nebo tlačítko třídou `ajax`:
+
+```html
+Go
+
+
+
+nebo
+
+```
+
Snippety
========
@@ -149,7 +168,7 @@ Dynamické snippety nelze invalidovat přímo (invalidace `item-1` neudělá vů
V příkladu výše zkrátka musíte zajistit, aby při ajaxovém požadavku byla v proměnné `$list` pouze jedna položka a tedy aby ten cyklus `foreach` naplnil pouze jeden dynamický snippet:
```php
-class HomepagePresenter extends Nette\Application\UI\Presenter
+class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* Tato metoda vrací data pro seznam.
diff --git a/application/cs/bootstrap.texy b/application/cs/bootstrap.texy
index fdb5decb4d..55fbbfc0f5 100644
--- a/application/cs/bootstrap.texy
+++ b/application/cs/bootstrap.texy
@@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```
-Na parametr `projectId` se lze v konfiguraci odkázat obvyklým zápisem `%projectId%`. Třída Configurator automaticky přidává parametry `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` a `consoleMode`.
+Na parametr `projectId` se lze v konfiguraci odkázat obvyklým zápisem `%projectId%`.
Dynamické parametry
@@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```
+Výchozí parametry
+-----------------
+
+V konfiguračních souborech můžete využít tyto statické parametry:
+
+- `%appDir%` je absolutní cesta k adresáři se souborem `Bootstrap.php`
+- `%wwwDir%` je absolutní cesta k adresáři se vstupním souborem `index.php`
+- `%tempDir%` je absolutní cesta k adresáři pro dočasné soubory
+- `%vendorDir%` je absolutní cesta k adresáři, kam Composer instaluje knihovny
+- `%debugMode%` udává, zda je aplikace v debugovacím režimu
+- `%consoleMode%` udává, zda request přišel přes příkazovou řádku
+
+
Importované služby
------------------
diff --git a/application/cs/components.texy b/application/cs/components.texy
index 977f44f950..d73de7ae83 100644
--- a/application/cs/components.texy
+++ b/application/cs/components.texy
@@ -198,7 +198,7 @@ Odkaz, který zavolá signál, vytvoříme obvyklým způsobem, tedy v šabloně
click here
```
-Signál se vždy volá na aktuálním presenteru a view, tudíž není možné jej vyvolat na jiném presenteru nebo view.
+Signál se vždy volá na aktuálním presenteru a action, není možné jej vyvolat na jiném presenteru nebo jiné action.
Signál tedy způsobí znovunačtení stránky úplně stejně jako při původním požadavku, jen navíc zavolá obslužnou metodu signálu s příslušnými parametry. Pokud metoda neexistuje, vyhodí se výjimka [api:Nette\Application\UI\BadSignalException], která se uživateli zobrazí jako chybová stránka 403 Forbidden.
@@ -233,31 +233,34 @@ $this->redirect(/* ... */); // a přesměrujeme
Persistentní parametry
======================
-Často se stává, že je v komponentách potřeba držet nějaký parametr pro uživatele po celou dobu, kdy se s komponentou pracuje. Může to být například číslo stránky ve stránkování. Takový parametr označíme jako persistentní pomocí anotace `@persistent`.
+Persistentní parametry slouží k udržování stavu v komponentách mezi různými požadavky. Jejich hodnota zůstává stejná i po kliknutí na odkaz. Na rozdíl od dat v session se přenášejí v URL. A to zcela automaticky, včetně odkazů vytvořených v jiných komponentách na téže stránce.
+
+Máte např. komponentu pro stránkování obsahu. Takových komponent může být na stránce několik. A přejeme si, aby po kliknutí na odkaz zůstaly všechny komponenty na své aktuální stránce. Proto z čísla stránky (`page`) uděláme persistentní parametr.
+
+Vytvoření persistentního parametru je v Nette nesmírně jednoduché. Stačí vytvořit veřejnou property a označit ji atributem: (dříve se používalo `/** @persistent */`)
```php
-class PollControl extends Control
+use Nette\Application\Attributes\Persistent; // tento řádek je důležitý
+
+class PaginatingControl extends Control
{
- /** @persistent */
- public int $page = 1;
+ #[Persistent]
+ public int $page = 1; // musí být public
}
```
-Tento parametr bude automaticky přenášen v každém odkazu jako GET parametr, a to až do chvíle, kdy uživatel stránku s touto komponentou opustí.
+U property doporučujeme uvádět i datový typ (např. `int`) a můžete uvést i výchozí hodnotu. Hodnoty parametrů lze [validovat |#Validace persistentních parametrů].
-.[caution]
-Nikdy slepě nevěřte persistentním parametrům, protože mohou být snadno podvrženy (přepsáním v URL adrese stránky). Ověřte si například, zda je číslo stránky v platném rozsahu.
+Při vytváření odkazu lze persistentnímu parametru změnit hodnotu:
-V PHP 8 můžete pro označení persistentních parametrů použít také atributy:
+```latte
+next
+```
-```php
-use Nette\Application\Attributes\Persistent;
+Nebo jej lze *vyresetovat*, tj. odstranit z URL. Pak bude nabývat svou výchozí hodnotu:
-class PollControl extends Control
-{
- #[Persistent]
- public int $page = 1;
-}
+```latte
+reset
```
@@ -378,7 +381,7 @@ Komponenty v Nette Application představují znovupoužitelné součásti webov
1) je vykreslitelná v šabloně
2) ví, kterou svou část má vykreslit při [AJAXovém požadavku |ajax#invalidace] (snippety)
-3) má schopnost ukládat svůj stav do URL (persistetní parametry)
+3) má schopnost ukládat svůj stav do URL (persistentní parametry)
4) má schopnost reagovat na uživatelské akce (signály)
5) vytváří hierarchickou strukturu (kde kořenem je presenter)
@@ -403,6 +406,33 @@ Nette\ComponentModel\Component { IComponent }
[* lifecycle-component.svg *] *** *Životní cyklus componenty* .<>
+Validace persistentních parametrů
+---------------------------------
+
+Hodnoty [persistentních parametrů |#Persistentní parametry] přijatých z URL zapisuje do properties metoda `loadState()`. Ta také kontroluje, zda odpovídá datový typ uvedený u property, jinak odpoví chybou 404 a stránka se nezobrazí.
+
+Nikdy slepě nevěřte persistentním parametrům, protože mohou být snadno uživatelem přepsány v URL. Takto například ověříme, zda je číslo stránky `$this->page` větší než 0. Vhodnou cestou je přepsat zmíněnou metodu `loadState()`:
+
+```php
+class PaginatingControl extends Control
+{
+ #[Persistent]
+ public int $page = 1;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // zde se nastaví $this->page
+ // následuje vlastní kontrola hodnoty:
+ if ($this->page < 1) {
+ $this->error();
+ }
+ }
+}
+```
+
+Opačný proces, tedy sesbírání hodnot z persistentních properites, má na starosti metoda `saveState()`.
+
+
Signály do hloubky
------------------
@@ -414,7 +444,7 @@ Signál může přijímat jakákoliv komponenta, presenter nebo objekt, který i
Mezi hlavní příjemce signálů budou patřit `Presentery` a vizuální komponenty dědící od `Control`. Signál má sloužit jako znamení pro objekt, že má něco udělat – anketa si má započítat hlas od uživatele, blok s novinkami se má rozbalit a zobrazit dvakrát tolik novinek, formulář byl odeslán a má zpracovat data a podobně.
-URL pro signál vytváříme pomocí metody [Component::link() |api:Nette\Application\UI\Component::link()]. Jako parametr `$destination` předáme řetězec `{signal}!` a jako `$args` pole argumentů, které chceme signálu předat. Signál se vždy volá na aktuální view s aktuálními parametry, parametry signálu se jen přidají. Navíc se přidává hned na začátku **parametr `?do`, který určuje signál**.
+URL pro signál vytváříme pomocí metody [Component::link() |api:Nette\Application\UI\Component::link()]. Jako parametr `$destination` předáme řetězec `{signal}!` a jako `$args` pole argumentů, které chceme signálu předat. Signál se vždy volá na aktuálním presenteru a action s aktuálními parametry, parametry signálu se jen přidají. Navíc se přidává hned na začátku **parametr `?do`, který určuje signál**.
Jeho formát je buď `{signal}`, nebo `{signalReceiver}-{signal}`. `{signalReceiver}` je název komponenty v presenteru. Proto nemůže být v názvu komponenty pomlčka – používá se k oddělení názvu komponenty a signálu, je ovšem možné takto zanořit několik komponent.
@@ -437,17 +467,6 @@ Tím je signál provedený předčasně a už se nebude znovu volat.
/** @var callable[]&(callable(Component $sender): void)[]; Occurs when component is attached to presenter */
public $onAnchor;
- /**
- * Loads state informations.
- */
- public function loadState(array $params): void
-
- /**
- * Saves state informations for next request.
- */
- public function saveState(array &$params): void
-
-
/**
* Returns destination as Link object.
* @param string $destination in format "[homepage] [[[module:]presenter:]action | signal! | this] [#fragment]"
diff --git a/application/cs/creating-links.texy b/application/cs/creating-links.texy
index b2f3fcf88d..a21c986098 100644
--- a/application/cs/creating-links.texy
+++ b/application/cs/creating-links.texy
@@ -52,7 +52,7 @@ V odkazech se také automaticky předávají tzv. [persistentní parametry|prese
Atribut `n:href` je velmi šikovný pro HTML značky ``. Chceme-li odkaz vypsat jinde, například v textu, použijeme `{link}`:
```latte
-Adresa je: {link Homepage:default}
+Adresa je: {link Home:default}
```
@@ -88,7 +88,7 @@ Formát podporují všechny značky Latte a všechny metody presenteru, které s
Základním tvarem je tedy `Presenter:action`:
```latte
-úvodní stránka
+úvodní stránka
```
Pokud odkazujeme na akci aktuálního presenteru, můžeme jeho název vynechat:
@@ -100,7 +100,7 @@ Pokud odkazujeme na akci aktuálního presenteru, můžeme jeho název vynechat:
Pokud je cílem akce `default`, můžeme ji vynechat, ale dvojtečka musí zůstat:
```latte
-úvodní stránka
+úvodní stránka
```
Odkazy mohou také směřovat do jiných [modulů |modules]. Zde se odkazy rozlišují na relativní do zanořeného submodulu, nebo absolutní. Princip je analogický k cestám na disku, jen místo lomítek jsou dvojtečky. Předpokládejme, že aktuální presenter je součástí modulu `Front`, potom zapíšeme:
@@ -119,7 +119,7 @@ Speciálním případem je odkaz [na sebe sama|#Odkaz na aktuální stránku], k
Odkazovat můžeme na určitou část stránky přes tzv. fragment za znakem mřížky `#`:
```latte
-odkaz na Homepage:default a fragment #main
+odkaz na Home:default a fragment #main
```
@@ -128,7 +128,7 @@ Absolutní cesty
Odkazy generované pomocí `link()` nebo `n:href` jsou vždy absolutní cesty (tj. začínají znakem `/`), ale nikoliv absolutní URL s protokolem a doménou jako `https://domain`.
-Pro vygenerování absolutní URL přidejte na začátek dvě lomítka (např. `n:href="//Homepage:"`). Nebo lze přepnout presenter, aby generoval jen absolutní odkazy nastavením `$this->absoluteUrls = true`.
+Pro vygenerování absolutní URL přidejte na začátek dvě lomítka (např. `n:href="//Home:"`). Nebo lze přepnout presenter, aby generoval jen absolutní odkazy nastavením `$this->absoluteUrls = true`.
Odkaz na aktuální stránku
@@ -165,7 +165,7 @@ Parametry jsou stejné jako u metody `link()`, navíc je však možné místo ko
V kombinaci s `n:href` v jednom elementu se dá použít zkrácená podoba:
```latte
-...
+...
```
Zástupný znak `*` lze použít pouze místo akce, nikoliv presenteru.
@@ -213,13 +213,13 @@ Protože [komponenty|components] jsou samostatné znovupoužitelné celky, kter
Pokud bychom chtěli v šabloně komponenty odkazovat na presentery, použijeme k tomu značku `{plink}`:
```latte
-úvod
+úvod
```
nebo v kódu
```php
-$this->getPresenter()->link('Homepage:default')
+$this->getPresenter()->link('Home:default')
```
diff --git a/application/cs/how-it-works.texy b/application/cs/how-it-works.texy
index e696819c47..b0025a12a0 100644
--- a/application/cs/how-it-works.texy
+++ b/application/cs/how-it-works.texy
@@ -23,10 +23,10 @@ Adresářová struktura vypadá nějak takto:
web-project/
├── app/ ← adresář s aplikací
│ ├── Presenters/ ← presentery a šablony
-│ │ ├── HomepagePresenter.php ← třída presenteru Homepage
+│ │ ├── HomePresenter.php ← třída presenteru Home
│ │ └── templates/ ← adresář se šablonami
│ │ ├── @layout.latte ← šablona layoutu
-│ │ └── Homepage/ ← šablony presenteru Homepage
+│ │ └── Home/ ← šablony presenteru Home
│ │ └── default.latte ← šablona akce 'default'
│ ├── Router/ ← konfigurace URL adres
│ └── Bootstrap.php ← zaváděcí třída Bootstrap
@@ -134,10 +134,10 @@ Pro jistotu, zkusme si zrekapitulovat celý proces s trošku jinou URL:
1) URL bude `https://example.com`
2) bootujeme aplikaci, vytvoří se kontejner a spustí `Application::run()`
-3) router URL dekóduje jako dvojici `Homepage:default`
-4) vytvoří se objekt třídy `HomepagePresenter`
+3) router URL dekóduje jako dvojici `Home:default`
+4) vytvoří se objekt třídy `HomePresenter`
5) zavolá se metoda `renderDefault()` (pokud existuje)
-6) vykreslí se šablona např. `templates/Homepage/default.latte` s layoutem např. `templates/@layout.latte`
+6) vykreslí se šablona např. `templates/Home/default.latte` s layoutem např. `templates/@layout.latte`
Možná jste se teď setkali s velkou spoustou nových pojmů, ale věříme, že dávají smysl. Tvorba aplikací v Nette je ohromná pohodička.
diff --git a/application/cs/modules.texy b/application/cs/modules.texy
index d1158b7d2a..2cb3e42719 100644
--- a/application/cs/modules.texy
+++ b/application/cs/modules.texy
@@ -104,7 +104,7 @@ Mapování
Definuje pravidla, podle kterých se z názvu presenteru odvodí název třídy. Zapisujeme je v [konfiguraci|configuration] pod klíčem `application › mapping`.
-Začněme ukázkou, která moduly nepoužívá. Budeme jen chtít, aby třídy presenterů měly jmenný prostor `App\Presenters`. Tedy aby se presenter například `Homepage` mapoval na třídu `App\Presenters\HomepagePresenter`. Toho lze docílit následující konfigurací:
+Začněme ukázkou, která moduly nepoužívá. Budeme jen chtít, aby třídy presenterů měly jmenný prostor `App\Presenters`. Tedy aby se presenter například `Home` mapoval na třídu `App\Presenters\HomePresenter`. Toho lze docílit následující konfigurací:
```neon
application:
@@ -124,7 +124,7 @@ application:
Api: App\Api\*Presenter
```
-Nyní se presenter `Front:Homepage` mapuje na třídu `App\Modules\Front\Presenters\HomepagePresenter` a presenter `Admin:Dashboard` na třídu `App\Modules\Admin\Presenters\DashboardPresenter`.
+Nyní se presenter `Front:Home` mapuje na třídu `App\Modules\Front\Presenters\HomePresenter` a presenter `Admin:Dashboard` na třídu `App\Modules\Admin\Presenters\DashboardPresenter`.
Praktičtější bude vytvořit obecné (hvězdičkové) pravidlo, které první dvě nahradí. V masce třídy přibude hvezdička navíc právě pro modul:
diff --git a/application/cs/presenters.texy b/application/cs/presenters.texy
index 4ee86fce4e..c6621449e7 100644
--- a/application/cs/presenters.texy
+++ b/application/cs/presenters.texy
@@ -158,7 +158,7 @@ Metoda `forward()` přejde na nový presenter okamžitě bez HTTP přesměrován
$this->forward('Product:show');
```
-Příklad tzv. dočasného přesměrování s HTTP kódem 302 nebo 303:
+Příklad tzv. dočasného přesměrování s HTTP kódem 302 (nebo 303, je-li metoda aktuálního požadavku POST):
```php
$this->redirect('Product:show', $id);
@@ -170,7 +170,7 @@ Permanentní přesměrování s HTTP kódem 301 docílíte takto:
$this->redirectPermanent('Product:show', $id);
```
-Na jinou URL mimo aplikaci lze přesměrovat metodou `redirectUrl()`:
+Na jinou URL mimo aplikaci lze přesměrovat metodou `redirectUrl()`. Jako druhý parametr lze uvést HTTP kód, výchozí je 302 (nebo 303, je-li metoda aktuálního požadavku POST):
```php
$this->redirectUrl('https://nette.org');
@@ -239,46 +239,54 @@ public function actionData(): void
Persistentní parametry
======================
-Persistentní parametry se v odkazech **přenášejí automaticky**. To znamená, že je nemusíme explicitně uvádět v každém volání `link()` nebo `n:href` v šabloně, ale přesto se přenesou.
+Persistentní parametry slouží k udržování stavu mezi různými požadavky. Jejich hodnota zůstává stejná i po kliknutí na odkaz. Na rozdíl od dat v session se přenášejí v URL. A to zcela automaticky, není tedy potřeba je explicitně uvádět v `link()` nebo `n:href`.
-Pokud má vaše aplikace více jazykových mutací, tak aktuální jazyk je parameter, který musí být neustále součástí URL. A bylo by neskutečně únavné ho v každém odkazu uvádět. To není s Nette potřeba. Prostě si parametr `lang` označíme jako persistentní tímto způsobem:
+Příklad použití? Máte multijazyčnou aplikaci. Aktuální jazyk je parameter, který musí být neustále součástí URL. Ale bylo by neskutečně únavné ho v každém odkazu uvádět. Tak z něj uděláte persistentní parametr `lang` a bude se přenášet sám. Paráda!
+
+Vytvoření persistentního parametru je v Nette nesmírně jednoduché. Stačí vytvořit veřejnou property a označit ji atributem: (dříve se používalo `/** @persistent */`)
```php
+use Nette\Application\Attributes\Persistent; // tento řádek je důležitý
+
class ProductPresenter extends Nette\Application\UI\Presenter
{
- /** @persistent */
- public string $lang;
+ #[Persistent]
+ public string $lang; // musí být public
}
```
-Pokud aktuální hodnota parametru `lang` bude `'en'`, tak URL vytvořené pomocí `link()` nebo `n:href` v šabloně bude obsahovat `lang=en`. Paráda!
-
-Při vytváření odkazu nicméně lze persistentní parametr uvést a tím změnit jeho hodnotu:
-
-```latte
-detail v češtině
-```
+Pokud bude `$this->lang` mít hodnotu například `'en'`, tak i odkazy vytvořené pomocí `link()` nebo `n:href` budou obsahovat parameter `lang=en`. A po kliknutí na odkaz bude opět `$this->lang = 'en'`.
-Nebo jej lze naopak odstranit tím, že ho vynulujeme:
+U property doporučujeme uvádět i datový typ (např. `string`) a můžete uvést i výchozí hodnotu. Hodnoty parametrů lze [validovat |#Validace persistentních parametrů].
-```latte
-klikni
-```
+Persistentní parametry se standardně přenášejí mezi všemi akcemi daného presenteru. Aby se přenášely i mezi více presentery, je potřeba je definovat buď:
-Persistentní proměnná musí být deklarovaná jako public. Můžeme uvést i výchozí hodnotu. Bude-li mít parametr hodnotu stejnou jako výchozí, nebude v URL obsažen.
-
-Persistence zohledňuje hierarchii tříd presenterů, tedy parametr definovaný v určitém presenteru nebo traitě je poté automaticky přenášen do každého presenteru z něj dědícího nebo užívajícího stejnou traitu.
-
-V PHP 8 můžete pro označení persistentních parametrů použít také atributy:
+- ve společném předkovi, od kterého presentery dědí
+- v traitě, kterou presentery použijí:
```php
-use Nette\Application\Attributes\Persistent;
-
-class ProductPresenter extends Nette\Application\UI\Presenter
+trait LangAware
{
#[Persistent]
public string $lang;
}
+
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ use LangAware;
+}
+```
+
+Při vytváření odkazu lze persistentnímu parametru změnit hodnotu:
+
+```latte
+detail v češtině
+```
+
+Nebo jej lze *vyresetovat*, tj. odstranit z URL. Pak bude nabývat svou výchozí hodnotu:
+
+```latte
+klikni
```
@@ -302,7 +310,32 @@ S tím, co jsme si dosud v této kapitole ukázali, si nejspíš úplně vystač
Požadavek a parametry
---------------------
-Požadavek, který vyřizuje presenter, je objekt [api:Nette\Application\Request] a vrací ho metoda presenteru `getRequest()`. Jeho součástí je pole parametrů a každý z nich patří buď některé z komponent, nebo přímo presenteru (což je vlastně také komponenta, byť speciální). Nette tedy parametry přerozdělí a předá mezi jednotlivé komponenty (a presenter) zavoláním metody `loadState(array $params)`, což dále popisujeme v kapitole [Komponenty|components]. Získat parametry lze metodu `getParameters(): array`, jednotlivě pomocí `getParameter($name)`. Hodnoty parametrů jsou řetězce či pole řetězců, jde v podstatě o surové data získané přímo z URL.
+Požadavek, který vyřizuje presenter, je objekt [api:Nette\Application\Request] a vrací ho metoda presenteru `getRequest()`. Jeho součástí je pole parametrů a každý z nich patří buď některé z komponent, nebo přímo presenteru (což je vlastně také komponenta, byť speciální). Nette tedy parametry přerozdělí a předá mezi jednotlivé komponenty (a presenter) zavoláním metody `loadState(array $params)`. Získat parametry lze metodu `getParameters(): array`, jednotlivě pomocí `getParameter($name)`. Hodnoty parametrů jsou řetězce či pole řetězců, jde v podstatě o surové data získané přímo z URL.
+
+
+Validace persistentních parametrů
+---------------------------------
+
+Hodnoty [persistentních parametrů |#Persistentní parametry] přijatých z URL zapisuje do properties metoda `loadState()`. Ta také kontroluje, zda odpovídá datový typ uvedený u property, jinak odpoví chybou 404 a stránka se nezobrazí.
+
+Nikdy slepě nevěřte persistentním parametrům, protože mohou být snadno uživatelem přepsány v URL. Takto například ověříme, zda je jazyk `$this->lang` mezi podporovanými. Vhodnou cestou je přepsat zmíněnou metodu `loadState()`:
+
+```php
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ #[Persistent]
+ public string $lang;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // zde se nastaví $this->lang
+ // následuje vlastní kontrola hodnoty:
+ if (!in_array($this->lang, ['en', 'cs'])) {
+ $this->error();
+ }
+ }
+}
+```
Uložení a obnovení požadavku
diff --git a/application/cs/routing.texy b/application/cs/routing.texy
index aee02d66fe..816436fac4 100644
--- a/application/cs/routing.texy
+++ b/application/cs/routing.texy
@@ -93,12 +93,12 @@ Routa bude nyní akceptovat i URL `https://example.com/chronicle/`, které opět
Parametrem může být samozřejmě i jméno presenteru a akce. Třeba takto:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
Uvedená routa akceptuje např. URL ve tvaru `/article/edit` nebo také `/catalog/list` a chápe je jako presentery a akce `Article:edit` a `Catalog:list`.
-Zaroveň dává parametrům `presenter` a `action` výchozí hodnoty `Homepage` a `default` a jsou tedy také volitelné. Takže routa akceptuje i URL ve tvaru `/article` a chápe ji jako `Article:default`. Nebo obráceně, odkaz na `Product:default` vygeneruje cestu `/product`, odkaz na výchozí `Homepage:default` cestu `/`.
+Zaroveň dává parametrům `presenter` a `action` výchozí hodnoty `Home` a `default` a jsou tedy také volitelné. Takže routa akceptuje i URL ve tvaru `/article` a chápe ji jako `Article:default`. Nebo obráceně, odkaz na `Product:default` vygeneruje cestu `/product`, odkaz na výchozí `Home:default` cestu `/`.
Maska může popisovat nejen relativní cestu od kořenového adresáře webu, ale také absolutní cestu, pokud začíná lomítkem, nebo dokonce celé absolutní URL, začíná-li dvěma lomítky:
@@ -160,7 +160,7 @@ Sekvence je možné libovolně zanořovat a kombinovat:
```php
$router->addRoute(
'[[-]/][/page-]',
- 'Homepage:default',
+ 'Home:default',
);
// Akceptuje cesty:
@@ -183,16 +183,16 @@ $router->addRoute('[!.html]', /* ... */);
Volitelné parametry (tj. parametry mající výchozí hodnotu) bez hranatých závorek se chovají v podstatě tak, jako by byly uzávorkovány následujícím způsobem:
```php
-$router->addRoute('//', /* ... */);
+$router->addRoute('//', /* ... */);
// odpovídá tomuto:
-$router->addRoute('[/[/[]]]', /* ... */);
+$router->addRoute('[/[/[]]]', /* ... */);
```
-Pokud bychom chtěli ovlivnit chování koncového lomítka, aby se např. místo `/homepage/` generovalo jen `/homepage`, lze toho docílit takto:
+Pokud bychom chtěli ovlivnit chování koncového lomítka, aby se např. místo `/home/` generovalo jen `/home`, lze toho docílit takto:
```php
-$router->addRoute('[[/[/]]]', /* ... */);
+$router->addRoute('[[/[/]]]', /* ... */);
```
@@ -220,7 +220,7 @@ Druhý parametr routy, který často zapisujeme ve formátu `Presenter:action`,
```php
$router->addRoute('/[/]', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
]);
```
@@ -232,7 +232,7 @@ use Nette\Routing\Route;
$router->addRoute('/[/]', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
@@ -252,7 +252,7 @@ Filtry a překlady
Zdrojové kódy aplikace píšeme v angličtině, ale pokud má mít web české URL, pak jednoduché routování typu:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
bude generovat anglické URL, jako třeba `/product/123` nebo `/cart`. Pokud chceme mít presentery a akce v URL reprezentované českými slovy (např. `/produkt/123` nebo `/kosik`), můžeme využít překladového slovníku. Pro jeho zápis už potřebujeme "upovídanější" variantu druhého parametru:
@@ -262,7 +262,7 @@ use Nette\Routing\Route;
$router->addRoute('/', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterTable => [
// řetězec v URL => presenter
'produkt' => 'Product',
@@ -290,7 +290,7 @@ use Nette\Routing\Route;
$router->addRoute('//', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
@@ -313,7 +313,7 @@ Vedle filtrů určených pro konkrétní parametry můžeme definovat též obec
use Nette\Routing\Route;
$router->addRoute('/', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
@@ -503,15 +503,15 @@ http://example.com/?presenter=Product&action=detail&id=123
Parametrem konstruktoru SimpleRouteru je výchozí presenter & akce, na který se má směřovat, pokud otevřeme stránku bez parametrů, např. `http://example.com/`.
```php
-// výchozím presenterem bude 'Homepage' a akce 'default'
-$router = new Nette\Application\Routers\SimpleRouter('Homepage:default');
+// výchozím presenterem bude 'Home' a akce 'default'
+$router = new Nette\Application\Routers\SimpleRouter('Home:default');
```
Doporučujeme SimpleRouter přímo definovat v [konfiguraci |dependency-injection:services]:
```neon
services:
- - Nette\Application\Routers\SimpleRouter('Homepage:default')
+ - Nette\Application\Routers\SimpleRouter('Home:default')
```
@@ -611,7 +611,7 @@ Při zpracování požadavku musíme vrátit minimálně presenter a akci. Náze
```php
[
- 'presenter' => 'Front:Homepage',
+ 'presenter' => 'Front:Home',
'action' => 'default',
]
```
diff --git a/application/cs/templates.texy b/application/cs/templates.texy
index 075572e94e..5d0de8dc1a 100644
--- a/application/cs/templates.texy
+++ b/application/cs/templates.texy
@@ -42,7 +42,9 @@ Cestu k šablonám odvodí presenter podle jednoduché logiky. Zkusí, zda exist
- `templates//.latte`
- `templates/..latte`
-Pokud šablonu nenajde, je odpovědí [chyba 404|presenters#Chyba 404 a spol.].
+Pokud šablonu nenajde, zkusí hledat ještě v adresáři `templates` o úroveň výš, tj. na stejné úrovni, jako je adresář s třídou presenteru.
+
+Pokud ani tam šablonu nenajde, je odpovědí [chyba 404|presenters#Chyba 404 a spol.].
Můžete také změnit view pomocí `$this->setView('jineView')`. Nebo místo dohledávání přímo určit jméno souboru se šablonou pomocí `$this->template->setFile('/path/to/template.latte')`.
@@ -148,7 +150,7 @@ V šabloně se vytvářejí odkazy na další presentery & akce tímto způsobem
Atribut `n:href` je velmi šikovný pro HTML značky ``. Chceme-li odkaz vypsat jinde, například v textu, použijeme `{link}`:
```latte
-Adresa je: {link Homepage:default}
+Adresa je: {link Home:default}
```
Více informací najdete v kapitole [Vytváření odkazů URL|creating-links].
diff --git a/application/de/@left-menu.texy b/application/de/@left-menu.texy
index 8fac50f03b..e3d59146db 100644
--- a/application/de/@left-menu.texy
+++ b/application/de/@left-menu.texy
@@ -15,5 +15,8 @@ Nette Bewerbung
Weitere Lektüre
***************
+- [Warum Nette verwenden? |www:10-reasons-why-nette]
+- [Die Installation |nette:installation]
+- [Erstellen Sie Ihre erste Anwendung! |quickstart:]
- [Bewährte Praktiken |best-practices:]
- [Fehlersuche |nette:troubleshooting]
diff --git a/application/de/ajax.texy b/application/de/ajax.texy
index a51e2b4011..63922c5732 100644
--- a/application/de/ajax.texy
+++ b/application/de/ajax.texy
@@ -10,9 +10,13 @@ Moderne Webanwendungen laufen heute zur Hälfte auf einem Server und zur Hälfte
-Eine AJAX-Anfrage kann mit einer Methode eines Dienstes, [der eine HTTP-Anfrage kapselt |http:request], erkannt werden `$httpRequest->isAjax()` (erkennt anhand des `X-Requested-With` HTTP-Headers). Es gibt auch eine Kurzform der Methode in Presenter: `$this->isAjax()`.
-Eine AJAX-Anfrage unterscheidet sich nicht von einer normalen Anfrage - ein Presenter wird mit einer bestimmten Ansicht und Parametern aufgerufen. Auch hier ist es dem Präsentator überlassen, wie er reagiert: Er kann seine Routinen nutzen, um entweder ein Fragment von HTML-Code (ein Snippet), ein XML-Dokument, ein JSON-Objekt oder ein Stück Javascript-Code zurückzugeben.
+AJAX-Anfrage .[#toc-ajax-request]
+=================================
+
+Eine AJAX-Anfrage unterscheidet sich nicht von einer klassischen Anfrage - der Presenter wird mit einer bestimmten Ansicht und Parametern aufgerufen. Es liegt auch am Präsentator, wie er darauf reagiert: Er kann seine eigene Routine verwenden, die ein HTML-Codefragment (HTML-Snippet), ein XML-Dokument, ein JSON-Objekt oder JavaScript-Code zurückgibt.
+
+Auf der Serverseite kann eine AJAX-Anfrage mit Hilfe der Servicemethode erkannt werden [, die die HTTP-Anfrage kapselt |http:request] `$httpRequest->isAjax()` (erkennt auf der Grundlage des HTTP-Headers `X-Requested-With`). Innerhalb des Presenters ist eine Abkürzung in Form der Methode `$this->isAjax()` verfügbar.
Es gibt ein vorverarbeitetes Objekt namens `payload`, das für das Senden von Daten in JSON an den Browser bestimmt ist.
@@ -60,6 +64,21 @@ npm install naja
```
+Um eine AJAX-Anfrage aus einem regulären Link (Signal) oder einer Formularübermittlung zu erzeugen, markieren Sie einfach den entsprechenden Link, das Formular oder die Schaltfläche mit der Klasse `ajax`:
+
+```html
+Go
+
+
+
+or
+
+```
+
Schnipsel .[#toc-snippets]
==========================
@@ -149,7 +168,7 @@ Ein dynamisches Snippet kann nicht direkt neu gezeichnet werden (das erneute Zei
Im obigen Beispiel müssen Sie sicherstellen, dass bei einer AJAX-Anfrage nur ein Element zum Array `$list` hinzugefügt wird, so dass die Schleife `foreach` nur ein dynamisches Snippet ausgibt.
```php
-class HomepagePresenter extends Nette\Application\UI\Presenter
+class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* This method returns data for the list.
diff --git a/application/de/bootstrap.texy b/application/de/bootstrap.texy
index 217e1b2407..590e4e76ef 100644
--- a/application/de/bootstrap.texy
+++ b/application/de/bootstrap.texy
@@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```
-In Konfigurationsdateien können wir die übliche Notation `%projectId%` verwenden, um auf den Parameter mit dem Namen `projectId` zuzugreifen. Standardmäßig füllt der Configurator die folgenden Parameter aus: `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` und `consoleMode`.
+In Konfigurationsdateien können wir die übliche Notation `%projectId%` verwenden, um auf den Parameter `projectId` zuzugreifen.
Dynamische Parameter .[#toc-dynamic-parameters]
@@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```
+Standard-Parameter .[#toc-default-parameters]
+---------------------------------------------
+
+Sie können die folgenden statischen Parameter in den Konfigurationsdateien verwenden:
+
+- `%appDir%` ist der absolute Pfad zu dem Verzeichnis, in dem sich die Datei `Bootstrap.php` befindet
+- `%wwwDir%` ist der absolute Pfad zu dem Verzeichnis, das die `index.php` Eintragsdatei enthält
+- `%tempDir%` ist der absolute Pfad zu dem Verzeichnis für temporäre Dateien
+- `%vendorDir%` ist der absolute Pfad zu dem Verzeichnis, in dem Composer die Bibliotheken installiert
+- `%debugMode%` gibt an, ob sich die Anwendung im Debug-Modus befindet
+- `%consoleMode%` zeigt an, ob die Anfrage über die Befehlszeile kam
+
+
Importierte Dienste .[#toc-imported-services]
---------------------------------------------
diff --git a/application/de/components.texy b/application/de/components.texy
index a9da3e2047..4429cd3cd7 100644
--- a/application/de/components.texy
+++ b/application/de/components.texy
@@ -233,31 +233,34 @@ In der Vorlage stehen diese Meldungen in der Variablen `$flashes` als Objekte `s
Dauerhafte Parameter .[#toc-persistent-parameters]
==================================================
-Oft ist es erforderlich, einige Parameter in einer Komponente für die gesamte Zeit der Arbeit mit der Komponente zu behalten. Dies kann z.B. die Seitennummer bei der Paginierung sein. Dieser Parameter sollte mit dem Vermerk `@persistent` als persistent gekennzeichnet werden.
+Persistente Parameter werden verwendet, um den Zustand von Komponenten zwischen verschiedenen Anfragen zu erhalten. Ihr Wert bleibt gleich, auch wenn ein Link angeklickt wird. Im Gegensatz zu Sitzungsdaten werden sie in der URL übertragen. Und sie werden automatisch übertragen, einschließlich Links, die in anderen Komponenten auf derselben Seite erstellt wurden.
+
+Sie haben zum Beispiel eine Komponente zum Paging von Inhalten. Es kann mehrere solcher Komponenten auf einer Seite geben. Und Sie möchten, dass alle Komponenten auf ihrer aktuellen Seite bleiben, wenn Sie auf den Link klicken. Deshalb machen wir die Seitennummer (`page`) zu einem dauerhaften Parameter.
+
+Das Erstellen eines dauerhaften Parameters ist in Nette extrem einfach. Erstellen Sie einfach eine öffentliche Eigenschaft und versehen Sie sie mit dem Attribut: (früher wurde `/** @persistent */` verwendet)
```php
-class PollControl extends Control
+use Nette\Application\Attributes\Persistent; // diese Zeile ist wichtig
+
+class PaginatingControl extends Control
{
- /** @persistent */
- public int $page = 1;
+ #[Persistent]
+ public int $page = 1; // muss öffentlich sein
}
```
-Dieser Parameter wird automatisch in jedem Link als `GET` Parameter übergeben, bis der Benutzer die Seite mit dieser Komponente verlässt.
+Es wird empfohlen, den Datentyp (z. B. `int`) mit der Eigenschaft zu verknüpfen, und Sie können auch einen Standardwert angeben. Parameterwerte können [validiert |#Validation of Persistent Parameters] werden.
-.[caution]
-Vertrauen Sie persistenten Parametern niemals blind, da sie leicht gefälscht werden können (durch Überschreiben der URL). Überprüfen Sie zum Beispiel, ob die Seitenzahl innerhalb des richtigen Intervalls liegt.
+Sie können den Wert eines persistenten Parameters beim Erstellen eines Links ändern:
-In PHP 8 können Sie auch Attribute verwenden, um persistente Parameter zu kennzeichnen:
+```latte
+next
+```
-```php
-use Nette\Application\Attributes\Persistent;
+Oder er kann *zurückgesetzt* werden, d.h. aus der URL entfernt werden. Er nimmt dann seinen Standardwert an:
-class PollControl extends Control
-{
- #[Persistent]
- public int $page = 1;
-}
+```latte
+reset
```
@@ -378,7 +381,7 @@ Komponenten in einer Nette-Anwendung sind die wiederverwendbaren Teile einer Web
1) sie ist in einer Vorlage renderbar
2) sie weiß, welcher Teil von ihr bei einer [AJAX-Anfrage |ajax#invalidation] gerendert werden soll (Snippets)
-3) sie hat die Möglichkeit, ihren Zustand in einer URL zu speichern (Persistenzparameter)
+3) er kann seinen Zustand in einer URL speichern (persistente Parameter)
4) es hat die Fähigkeit, auf Benutzeraktionen zu reagieren (Signale)
5) er erstellt eine hierarchische Struktur (wobei die Wurzel der Präsentator ist)
@@ -403,6 +406,33 @@ Lebenszyklus der Komponente .[#toc-life-cycle-of-component]
[* lifecycle-component.svg *] *** *Lebenszyklus einer Komponente* .<>
+Validierung von persistenten Parametern .[#toc-validation-of-persistent-parameters]
+-----------------------------------------------------------------------------------
+
+Die Werte von [persistenten Parametern |#persistent parameters], die von URLs empfangen werden, werden von der Methode `loadState()` in Eigenschaften geschrieben. Sie prüft auch, ob der für die Eigenschaft angegebene Datentyp übereinstimmt, andernfalls antwortet sie mit einem 404-Fehler und die Seite wird nicht angezeigt.
+
+Verlassen Sie sich niemals blind auf persistente Parameter, da sie leicht vom Benutzer in der URL überschrieben werden können. So prüfen wir zum Beispiel, ob die Seitenzahl `$this->page` größer als 0 ist. Eine gute Möglichkeit, dies zu tun, ist, die oben erwähnte Methode `loadState()` zu überschreiben:
+
+```php
+class PaginatingControl extends Control
+{
+ #[Persistent]
+ public int $page = 1;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // hier wird die $this->page gesetzt
+ // auf die Prüfung der Benutzerwerte:
+ if ($this->page < 1) {
+ $this->error();
+ }
+ }
+}
+```
+
+Der umgekehrte Prozess, d. h. das Sammeln von Werten aus dauerhaften Propertys, wird von der Methode `saveState()` übernommen.
+
+
Signale in der Tiefe .[#toc-signals-in-depth]
---------------------------------------------
diff --git a/application/de/creating-links.texy b/application/de/creating-links.texy
index ae9a95e4d6..1ec3fbd1e9 100644
--- a/application/de/creating-links.texy
+++ b/application/de/creating-links.texy
@@ -52,7 +52,7 @@ Die so genannten [persistenten Parameter |presenters#persistent parameters] werd
Das Attribut `n:href` ist sehr praktisch für HTML-Tags ``. Wenn wir den Link an anderer Stelle, zum Beispiel im Text, ausgeben wollen, verwenden wir `{link}`:
```latte
-URL is: {link Homepage:default}
+URL is: {link Home:default}
```
@@ -88,19 +88,19 @@ Das Format wird von allen Latte-Tags und allen Presenter-Methoden unterstützt,
Die Grundform ist also `Presenter:action`:
```latte
-homepage
+home
```
Wenn wir auf die Aktion des aktuellen Moderators verweisen, können wir seinen Namen weglassen:
```latte
-homepage
+home
```
Wenn die Aktion `default` lautet, können wir sie weglassen, aber der Doppelpunkt muss bleiben:
```latte
-homepage
+home
```
Links können auch auf andere [Module |modules] verweisen. Hier unterscheidet man zwischen relativen und absoluten Links zu den Untermodulen. Das Prinzip ist analog zu Plattenpfaden, nur dass anstelle von Schrägstrichen Doppelpunkte stehen. Nehmen wir an, dass der eigentliche Präsentator Teil des Moduls `Front` ist, dann schreiben wir:
@@ -119,7 +119,7 @@ Ein Sonderfall ist die [Verknüpfung mit sich selbst |#Links to Current Page]. H
Wir können auf einen bestimmten Teil der HTML-Seite über ein so genanntes Fragment nach dem Rautezeichen `#` verlinken:
```latte
-link to Homepage:default and fragment #main
+link to Home:default and fragment #main
```
@@ -128,7 +128,7 @@ Absolute Pfade .[#toc-absolute-paths]
Die von `link()` oder `n:href` erzeugten Links sind immer absolute Pfade (d. h. sie beginnen mit `/`), nicht aber absolute URLs mit Protokoll und Domäne wie `https://domain`.
-Um eine absolute URL zu erzeugen, fügen Sie zwei Schrägstriche am Anfang hinzu (z. B. `n:href="//Homepage:"`). Sie können den Präsentator auch so einstellen, dass er nur absolute Links erzeugt, indem Sie `$this->absoluteUrls = true` einstellen.
+Um eine absolute URL zu erzeugen, fügen Sie zwei Schrägstriche am Anfang hinzu (z. B. `n:href="//Home:"`). Sie können den Präsentator auch so einstellen, dass er nur absolute Links erzeugt, indem Sie `$this->absoluteUrls = true` einstellen.
Link zur aktuellen Seite .[#toc-link-to-current-page]
@@ -213,13 +213,13 @@ Da [Komponenten |components] separate, wiederverwendbare Einheiten sind, die kei
Wenn wir auf Präsentatoren in der Komponentenvorlage verlinken wollen, verwenden wir das Tag `{plink}`:
```latte
-homepage
+home
```
oder im Code
```php
-$this->getPresenter()->link('Homepage:default')
+$this->getPresenter()->link('Home:default')
```
diff --git a/application/de/how-it-works.texy b/application/de/how-it-works.texy
index c99da75b2b..ae27a40ede 100644
--- a/application/de/how-it-works.texy
+++ b/application/de/how-it-works.texy
@@ -23,10 +23,10 @@ Die Verzeichnisstruktur sieht in etwa so aus:
web-project/
├── app/ ← Verzeichnis mit Anwendung
│ ├── Presenters/ ← Presenter-Klassen
-│ │ ├── HomepagePresenter.php ← Homepage presenterklasse
+│ │ ├── HomePresenter.php ← Home presenterklasse
│ │ └── templates/ ← Vorlagenverzeichnis
│ │ ├── @layout.latte ← Vorlage für gemeinsames Layout
-│ │ └── Homepage/ ← Vorlagen für Homepage-presenter
+│ │ └── Home/ ← Vorlagen für Home-presenter
│ │ └── default.latte ← Vorlage für Aktion `default`
│ ├── Router/ ← Konfiguration von URL-Adressen
│ └── Bootstrap.php ← bootende Klasse Bootstrap
@@ -134,10 +134,10 @@ Um sicherzugehen, versuchen wir, den gesamten Prozess mit einer etwas anderen UR
1) Die URL lautet dann `https://example.com`
2) wir booten die Anwendung, erstellen einen Container und starten `Application::run()`
-3) der Router dekodiert die URL als ein Paar `Homepage:default`
-4) ein `HomepagePresenter` Objekt wird erstellt
+3) der Router dekodiert die URL als ein Paar `Home:default`
+4) ein `HomePresenter` Objekt wird erstellt
5) die Methode `renderDefault()` wird aufgerufen (falls vorhanden)
-6) eine Vorlage `templates/Homepage/default.latte` mit einem Layout `templates/@layout.latte` wird gerendert
+6) eine Vorlage `templates/Home/default.latte` mit einem Layout `templates/@layout.latte` wird gerendert
Vielleicht sind Sie jetzt auf eine Menge neuer Konzepte gestoßen, aber wir glauben, dass sie sinnvoll sind. Das Erstellen von Anwendungen in Nette ist ein Kinderspiel.
diff --git a/application/de/modules.texy b/application/de/modules.texy
index 6481f57995..fcdf4331c4 100644
--- a/application/de/modules.texy
+++ b/application/de/modules.texy
@@ -104,7 +104,7 @@ Abbildung .[#toc-mapping]
Legt die Regeln fest, nach denen der Klassenname aus dem Namen des Präsentators abgeleitet wird. Wir schreiben sie in die [Konfiguration |configuration] unter dem Schlüssel `application › mapping`.
-Beginnen wir mit einem Beispiel, das keine Module verwendet. Wir wollen nur, dass die Presenter-Klassen den Namespace `App\Presenters` haben. Das bedeutet, dass ein Presenter wie `Homepage` auf die Klasse `App\Presenters\HomepagePresenter` abgebildet werden soll. Dies kann durch die folgende Konfiguration erreicht werden:
+Beginnen wir mit einem Beispiel, das keine Module verwendet. Wir wollen nur, dass die Presenter-Klassen den Namespace `App\Presenters` haben. Das bedeutet, dass ein Presenter wie `Home` auf die Klasse `App\Presenters\HomePresenter` abgebildet werden soll. Dies kann durch die folgende Konfiguration erreicht werden:
```neon
application:
@@ -124,7 +124,7 @@ application:
Api: App\Api\*Presenter
```
-Der Referent `Front:Homepage` wird der Klasse `App\Modules\Front\Presenters\HomepagePresenter` zugeordnet und der Referent `Admin:Dashboard` der Klasse `App\Modules\Admin\Presenters\DashboardPresenter`.
+Der Referent `Front:Home` wird der Klasse `App\Modules\Front\Presenters\HomePresenter` zugeordnet und der Referent `Admin:Dashboard` der Klasse `App\Modules\Admin\Presenters\DashboardPresenter`.
Es ist praktischer, eine allgemeine (Stern-)Regel zu erstellen, um die ersten beiden zu ersetzen. Das zusätzliche Sternchen wird der Klassenmaske nur für dieses Modul hinzugefügt:
diff --git a/application/de/presenters.texy b/application/de/presenters.texy
index 10ea87fbee..3e5c98a43d 100644
--- a/application/de/presenters.texy
+++ b/application/de/presenters.texy
@@ -158,7 +158,7 @@ Die `forward()` schaltet ohne HTTP-Umleitung sofort auf den neuen Präsentator u
$this->forward('Product:show');
```
-Beispiel einer temporären Umleitung mit HTTP-Code 302 oder 303:
+Beispiel für eine so genannte temporäre Umleitung mit HTTP-Code 302 (oder 303, wenn die aktuelle Anfragemethode POST ist):
```php
$this->redirect('Product:show', $id);
@@ -170,7 +170,7 @@ Um eine dauerhafte Umleitung mit HTTP-Code 301 zu erreichen, verwenden Sie:
$this->redirectPermanent('Product:show', $id);
```
-Sie können mit der Methode `redirectUrl()` zu einer anderen URL außerhalb der Anwendung umleiten:
+Sie können mit der Methode `redirectUrl()` zu einer anderen URL außerhalb der Anwendung umleiten. Der HTTP-Code kann als zweiter Parameter angegeben werden, wobei der Standardwert 302 ist (oder 303, wenn die aktuelle Anforderungsmethode POST ist):
```php
$this->redirectUrl('https://nette.org');
@@ -239,46 +239,54 @@ public function actionData(): void
Dauerhafte Parameter .[#toc-persistent-parameters]
==================================================
-Persistente Parameter werden in Links **automatisch** übertragen. Das bedeutet, dass wir sie nicht explizit in jedem `link()` oder `n:href` in der Vorlage angeben müssen, aber sie werden trotzdem übertragen.
+Persistente Parameter werden verwendet, um den Zustand zwischen verschiedenen Anfragen zu erhalten. Ihr Wert bleibt gleich, auch wenn ein Link angeklickt wird. Im Gegensatz zu Sitzungsdaten werden sie in der URL übergeben. Dies geschieht völlig automatisch, so dass es nicht notwendig ist, sie in `link()` oder `n:href` explizit anzugeben.
-Wenn Ihre Anwendung mehrere Sprachversionen hat, dann ist die aktuelle Sprache ein Parameter, der immer Teil der URL sein muss. Und es wäre unglaublich mühsam, ihn in jedem Link zu erwähnen. Mit Nette ist das nicht nötig. Wir kennzeichnen den Parameter `lang` auf diese Weise einfach als persistent:
+Beispiel für die Verwendung? Sie haben eine mehrsprachige Anwendung. Die aktuelle Sprache ist ein Parameter, der immer Teil der URL sein muss. Es wäre aber unglaublich mühsam, ihn in jeden Link aufzunehmen. Also machen Sie ihn zu einem dauerhaften Parameter mit dem Namen `lang` und er wird sich selbst tragen. Toll!
+
+Das Erstellen eines dauerhaften Parameters ist in Nette extrem einfach. Erstellen Sie einfach eine öffentliche Eigenschaft und kennzeichnen Sie sie mit dem Attribut: (früher wurde `/** @persistent */` verwendet)
```php
+use Nette\Application\Attributes\Persistent; // diese Zeile ist wichtig
+
class ProductPresenter extends Nette\Application\UI\Presenter
{
- /** @persistent */
- public string $lang;
+ #[Persistent]
+ public string $lang; // muss öffentlich sein
}
```
-Wenn der aktuelle Wert des Parameters `lang` ist `'en'`, dann wird die URL, die mit `link()` oder `n:href` in der Vorlage erstellt wird, `lang=en` enthalten. Prima!
-
-Wir können jedoch auch den Parameter `lang` hinzufügen und damit seinen Wert ändern:
+Wenn `$this->lang` einen Wert wie `'en'` hat, dann werden Links, die mit `link()` oder `n:href` erstellt werden, auch den Parameter `lang=en` enthalten. Und wenn der Link angeklickt wird, wird er wieder `$this->lang = 'en'` sein.
-```latte
-detail in English
-```
-
-Umgekehrt kann er entfernt werden, indem er auf null gesetzt wird:
-
-```latte
-click here
-```
+Für Eigenschaften wird empfohlen, den Datentyp anzugeben (z. B. `string`), und Sie können auch einen Standardwert angeben. Parameterwerte können [validiert |#Validation of Persistent Parameters] werden.
-Die persistente Variable muss als öffentlich deklariert werden. Wir können auch einen Standardwert angeben. Wenn der Parameter den gleichen Wert wie der Standardwert hat, wird er nicht in die URL aufgenommen.
+Persistente Parameter werden standardmäßig zwischen allen Aktionen eines bestimmten Präsentators weitergegeben. Um sie zwischen mehreren Präsentatoren zu übergeben, müssen Sie sie entweder definieren:
-Die Persistenz spiegelt die Hierarchie der Presenter-Klassen wider, d. h. ein in einem bestimmten Presenter oder Trait definierter Parameter wird automatisch auf jeden Presenter übertragen, der von diesem erbt oder denselben Trait verwendet.
-
-In PHP 8 können Sie auch Attribute verwenden, um persistente Parameter zu kennzeichnen:
+- in einem gemeinsamen Vorfahren, von dem die Präsentatoren erben
+- in der Eigenschaft, die die Präsentatoren verwenden:
```php
-use Nette\Application\Attributes\Persistent;
-
-class ProductPresenter extends Nette\Application\UI\Presenter
+trait LangAware
{
#[Persistent]
public string $lang;
}
+
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ use LangAware;
+}
+```
+
+Sie können den Wert eines dauerhaften Parameters ändern, wenn Sie einen Link erstellen:
+
+```latte
+detail in Czech
+```
+
+Oder er kann *zurückgesetzt* werden, d.h. aus der URL entfernt werden. Er nimmt dann seinen Standardwert an:
+
+```latte
+click
```
@@ -302,7 +310,32 @@ Was wir bisher in diesem Kapitel gezeigt haben, wird wahrscheinlich ausreichen.
Anforderung und Parameter .[#toc-requirement-and-parameters]
------------------------------------------------------------
-Die vom Präsentator bearbeitete Anforderung ist das Objekt [api:Nette\Application\Request] und wird von der Methode `getRequest()` des Präsentators zurückgegeben. Es enthält ein Array von Parametern, und jeder von ihnen gehört entweder zu einer der Komponenten oder direkt zum Präsentator (der eigentlich auch eine Komponente ist, wenn auch eine spezielle). Nette verteilt also die Parameter um und übergibt sie zwischen den einzelnen Komponenten (und dem Presenter), indem es die Methode `loadState(array $params)` aufruft, die im Kapitel [Komponenten |Components] näher beschrieben wird. Die Parameter können über die Methode `getParameters(): array`, individuell über `getParameter($name)` bezogen werden. Bei den Parameterwerten handelt es sich um Strings oder Arrays von Strings, d. h. um Rohdaten, die direkt aus einer URL bezogen werden.
+Die vom Präsentator bearbeitete Anfrage ist das Objekt [api:Nette\Application\Request] und wird von der Methode `getRequest()` des Präsentators zurückgegeben. Sie enthält ein Array von Parametern, und jeder von ihnen gehört entweder zu einer der Komponenten oder direkt zum Präsentator (der eigentlich auch eine Komponente ist, wenn auch eine spezielle). Nette verteilt also die Parameter um und übergibt sie zwischen den einzelnen Komponenten (und dem Präsentator) durch Aufruf der Methode `loadState(array $params)`. Die Parameter können mit der Methode `getParameters(): array`, einzeln mit `getParameter($name)` abgerufen werden. Bei den Parameterwerten handelt es sich um Strings oder Arrays von Strings, also im Grunde um Rohdaten, die direkt aus einer URL bezogen werden.
+
+
+Validierung von persistenten Parametern .[#toc-validation-of-persistent-parameters]
+-----------------------------------------------------------------------------------
+
+Die Werte von [persistenten Parametern |#persistent parameters], die von URLs empfangen werden, werden von der Methode `loadState()` in Eigenschaften geschrieben. Sie prüft auch, ob der in der Eigenschaft angegebene Datentyp übereinstimmt, andernfalls antwortet sie mit einem 404-Fehler und die Seite wird nicht angezeigt.
+
+Verlassen Sie sich niemals blind auf persistente Parameter, da sie leicht vom Benutzer in der URL überschrieben werden können. So überprüfen wir zum Beispiel, ob `$this->lang` zu den unterstützten Sprachen gehört. Eine gute Möglichkeit, dies zu tun, besteht darin, die oben erwähnte Methode `loadState()` zu überschreiben:
+
+```php
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ #[Persistent]
+ public string $lang;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // hier wird die $this->lang gesetzt
+ // nach der Prüfung der Benutzerwerte:
+ if (!in_array($this->lang, ['en', 'cs'])) {
+ $this->error();
+ }
+ }
+}
+```
Speichern und Wiederherstellen der Anfrage .[#toc-save-and-restore-the-request]
diff --git a/application/de/routing.texy b/application/de/routing.texy
index 438c8ff3c0..1cd5fcc40d 100644
--- a/application/de/routing.texy
+++ b/application/de/routing.texy
@@ -93,12 +93,12 @@ Die Route wird nun die URL `https://any-domain.com/chronicle/` mit dem Parameter
Natürlich kann auch der Name des Präsentators und der Aktion ein Parameter sein. Zum Beispiel:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
Diese Route nimmt z.B. eine URL in der Form `/article/edit` bzw. `/catalog/list` entgegen und übersetzt sie in Präsentatoren und Aktionen `Article:edit` bzw. `Catalog:list`.
-Außerdem werden den Parametern `presenter` und `action` die Standardwerte`Homepage` und `default` zugewiesen, so dass sie optional sind. So akzeptiert die Route auch eine URL `/article` und übersetzt sie als `Article:default`. Oder umgekehrt, ein Link auf `Product:default` erzeugt einen Pfad `/product`, ein Link auf den Standardwert `Homepage:default` erzeugt einen Pfad `/`.
+Außerdem werden den Parametern `presenter` und `action` die Standardwerte`Home` und `default` zugewiesen, so dass sie optional sind. So akzeptiert die Route auch eine URL `/article` und übersetzt sie als `Article:default`. Oder umgekehrt, ein Link auf `Product:default` erzeugt einen Pfad `/product`, ein Link auf den Standardwert `Home:default` erzeugt einen Pfad `/`.
Die Maske kann nicht nur den relativen Pfad auf der Grundlage des Stammverzeichnisses der Website beschreiben, sondern auch den absoluten Pfad, wenn er mit einem Schrägstrich beginnt, oder sogar die gesamte absolute URL, wenn sie mit zwei Schrägstrichen beginnt:
@@ -160,7 +160,7 @@ Sequenzen können frei verschachtelt und kombiniert werden:
```php
$router->addRoute(
'[[-]/][/page-]',
- 'Homepage:default',
+ 'Home:default',
);
// Akzeptierte URLs:
@@ -183,16 +183,16 @@ $router->addRoute('[!.html]', /* ... */);
Optionale Parameter (d.h. Parameter mit Standardwerten) ohne eckige Klammern verhalten sich so, als wären sie so umbrochen:
```php
-$router->addRoute('//', /* ... */);
+$router->addRoute('//', /* ... */);
// gleichbedeutend mit:
-$router->addRoute('[/[/[]]]', /* ... */);
+$router->addRoute('[/[/[]]]', /* ... */);
```
-Um zu ändern, wie der Schrägstrich ganz rechts erzeugt wird, d. h. statt `/homepage/` ein `/homepage` zu erhalten, passen Sie die Route folgendermaßen an:
+Um zu ändern, wie der Schrägstrich ganz rechts erzeugt wird, d. h. statt `/home/` ein `/home` zu erhalten, passen Sie die Route folgendermaßen an:
```php
-$router->addRoute('[[/[/]]]', /* ... */);
+$router->addRoute('[[/[/]]]', /* ... */);
```
@@ -220,7 +220,7 @@ Der zweite Parameter der Route, den wir oft im Format `Presenter:action` schreib
```php
$router->addRoute('/[/]', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
]);
```
@@ -232,7 +232,7 @@ use Nette\Routing\Route;
$router->addRoute('/[/]', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
@@ -252,7 +252,7 @@ Filter und Übersetzungen .[#toc-filters-and-translations]
Es ist eine gute Praxis, den Quellcode auf Englisch zu schreiben, aber was ist, wenn die URL Ihrer Website in eine andere Sprache übersetzt werden soll? Einfache Routen wie z.B.:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
erzeugen englische URLs, wie `/product/123` oder `/cart`. Wenn wir Präsentatoren und Aktionen in der URL ins Deutsche übersetzt haben wollen (z. B. `/produkt/123` oder `/einkaufswagen`), können wir ein Übersetzungswörterbuch verwenden. Um es hinzuzufügen, benötigen wir bereits eine "gesprächigere" Variante des zweiten Parameters:
@@ -262,7 +262,7 @@ use Nette\Routing\Route;
$router->addRoute('/', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterTable => [
// String in URL => Präsentator
'produkt' => 'Product',
@@ -290,7 +290,7 @@ use Nette\Routing\Route;
$router->addRoute('//', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
@@ -313,7 +313,7 @@ Neben Filtern für bestimmte Parameter können Sie auch allgemeine Filter defini
use Nette\Routing\Route;
$router->addRoute('/', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
@@ -503,15 +503,15 @@ http://example.com/?presenter=Product&action=detail&id=123
Der Parameter des `SimpleRouter` -Konstruktors ist ein Standard-Präsentator und eine Aktion, d.h. eine Aktion, die ausgeführt wird, wenn wir z.B. `http://example.com/` ohne zusätzliche Parameter öffnen.
```php
-// Standardmäßig wird der Präsentator 'Homepage' und die Aktion 'default' verwendet
-$router = new Nette\Application\Routers\SimpleRouter('Homepage:default');
+// Standardmäßig wird der Präsentator 'Home' und die Aktion 'default' verwendet
+$router = new Nette\Application\Routers\SimpleRouter('Home:default');
```
Wir empfehlen, SimpleRouter direkt in der [Konfiguration |dependency-injection:services] zu definieren:
```neon
services:
- - Nette\Application\Routers\SimpleRouter('Homepage:default')
+ - Nette\Application\Routers\SimpleRouter('Home:default')
```
@@ -611,7 +611,7 @@ Bei der Verarbeitung der Anfrage müssen wir zumindest den Präsentator und die
```php
[
- 'presenter' => 'Front:Homepage',
+ 'presenter' => 'Front:Home',
'action' => 'default',
]
```
diff --git a/application/de/templates.texy b/application/de/templates.texy
index 65639b369c..a21bd7266f 100644
--- a/application/de/templates.texy
+++ b/application/de/templates.texy
@@ -42,7 +42,9 @@ Der Pfad zu den Vorlagen wird nach einer einfachen Logik hergeleitet. Es wird ve
- `templates//.latte`
- `templates/..latte`
-Wenn die Vorlage nicht gefunden wird, wird der [Fehler 404 |presenters#Error 404 etc.] ausgegeben.
+Wird die Vorlage nicht gefunden, wird versucht, im Verzeichnis `templates` eine Ebene höher zu suchen, d. h. auf der gleichen Ebene wie das Verzeichnis mit der Presenter-Klasse.
+
+Wenn die Vorlage auch dort nicht gefunden wird, ist die Antwort ein [404-Fehler |presenters#Error 404 etc.].
Sie können die Ansicht auch mit `$this->setView('otherView')` ändern. Oder geben Sie statt der Suche direkt den Namen der Vorlagendatei mit `$this->template->setFile('/path/to/template.latte')` an.
@@ -148,7 +150,7 @@ In der Vorlage erstellen wir Links zu anderen Präsentatoren und Aktionen wie fo
Das Attribut `n:href` ist sehr praktisch für HTML-Tags ``. Wenn wir den Link an anderer Stelle, zum Beispiel im Text, ausgeben wollen, verwenden wir `{link}`:
```latte
-URL is: {link Homepage:default}
+URL is: {link Home:default}
```
Weitere Informationen finden Sie unter [Links erstellen |Creating Links].
diff --git a/application/el/@left-menu.texy b/application/el/@left-menu.texy
index 79024816ce..b704f8e06d 100644
--- a/application/el/@left-menu.texy
+++ b/application/el/@left-menu.texy
@@ -15,5 +15,8 @@
Περαιτέρω ανάγνωση
******************
+- [Γιατί να χρησιμοποιήσετε τη Nette; |www:10-reasons-why-nette]
+- [Εγκατάσταση |nette:installation]
+- [Δημιουργήστε την πρώτη σας εφαρμογή! |quickstart:]
- [Βέλτιστες πρακτικές |best-practices:]
- [Αντιμετώπιση προβλημάτων |nette:troubleshooting]
diff --git a/application/el/ajax.texy b/application/el/ajax.texy
index aa08c15d07..8ca0741a48 100644
--- a/application/el/ajax.texy
+++ b/application/el/ajax.texy
@@ -10,9 +10,13 @@ AJAX & Snippets
-Μια αίτηση AJAX μπορεί να ανιχνευθεί με τη χρήση μιας μεθόδου μιας υπηρεσίας που [ενθυλακώνει μια αίτηση HTTP |http:request] `$httpRequest->isAjax()` (ανιχνεύει με βάση την επικεφαλίδα `X-Requested-With` HTTP). Υπάρχει επίσης μια σύντομη μέθοδος στο presenter: `$this->isAjax()`.
-Μια αίτηση AJAX δεν διαφέρει από μια κανονική αίτηση - καλείται ένας παρουσιαστής με μια συγκεκριμένη προβολή και παραμέτρους. Εξαρτάται, επίσης, από τον παρουσιαστή πώς θα αντιδράσει: μπορεί να χρησιμοποιήσει τις ρουτίνες του για να επιστρέψει είτε ένα τμήμα κώδικα HTML (ένα απόσπασμα), ένα έγγραφο XML, ένα αντικείμενο JSON ή ένα κομμάτι κώδικα Javascript.
+Αίτηση AJAX .[#toc-ajax-request]
+================================
+
+Ένα αίτημα AJAX δεν διαφέρει από ένα κλασικό αίτημα - ο παρουσιαστής καλείται με μια συγκεκριμένη προβολή και παραμέτρους. Εξαρτάται επίσης από τον παρουσιαστή πώς θα απαντήσει σε αυτό: μπορεί να χρησιμοποιήσει τη δική του ρουτίνα, η οποία επιστρέφει ένα τμήμα κώδικα HTML (απόσπασμα HTML), ένα έγγραφο XML, ένα αντικείμενο JSON ή κώδικα JavaScript.
+
+Από την πλευρά του διακομιστή, ένα αίτημα AJAX μπορεί να ανιχνευθεί χρησιμοποιώντας τη μέθοδο service που [ενθυλακώνει το αίτημα HTTP |http:request] `$httpRequest->isAjax()` (ανιχνεύει με βάση την επικεφαλίδα HTTP `X-Requested-With`). Στο εσωτερικό του παρουσιαστή, είναι διαθέσιμη μια συντόμευση με τη μορφή της μεθόδου `$this->isAjax()`.
Υπάρχει ένα προεπεξεργασμένο αντικείμενο που ονομάζεται `payload` και είναι αφιερωμένο στην αποστολή δεδομένων στο πρόγραμμα περιήγησης σε JSON.
@@ -60,6 +64,21 @@ npm install naja
```
+Για να δημιουργήσετε μια αίτηση AJAX από έναν κανονικό σύνδεσμο (σήμα) ή μια υποβολή φόρμας, απλά επισημάνετε τον σχετικό σύνδεσμο, τη φόρμα ή το κουμπί με την κλάση `ajax`:
+
+```html
+Go
+
+
+
+or
+
+```
+
Snippets .[#toc-snippets]
=========================
@@ -149,7 +168,7 @@ $this->isControlInvalid('footer'); // -> true
Στο παραπάνω παράδειγμα πρέπει να βεβαιωθείτε ότι για μια αίτηση AJAX θα προστεθεί μόνο ένα στοιχείο στον πίνακα `$list`, επομένως ο βρόχος `foreach` θα εκτυπώσει μόνο ένα δυναμικό απόσπασμα.
```php
-class HomepagePresenter extends Nette\Application\UI\Presenter
+class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* This method returns data for the list.
diff --git a/application/el/bootstrap.texy b/application/el/bootstrap.texy
index 830a951dd6..71f6028048 100644
--- a/application/el/bootstrap.texy
+++ b/application/el/bootstrap.texy
@@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```
-Στα αρχεία ρυθμίσεων, μπορούμε να γράψουμε τον συνήθη συμβολισμό `%projectId%` για να αποκτήσουμε πρόσβαση στην παράμετρο με το όνομα `projectId`. Από προεπιλογή, ο διαμορφωτής συμπληρώνει τις ακόλουθες παραμέτρους: `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` και `consoleMode`.
+Στα αρχεία ρυθμίσεων, μπορούμε να γράψουμε τον συνήθη συμβολισμό `%projectId%` για να αποκτήσουμε πρόσβαση στην παράμετρο με το όνομα `projectId`.
Δυναμικές παράμετροι .[#toc-dynamic-parameters]
@@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```
+Προεπιλεγμένες παράμετροι .[#toc-default-parameters]
+----------------------------------------------------
+
+Μπορείτε να χρησιμοποιήσετε τις ακόλουθες στατικές παραμέτρους στα αρχεία διαμόρφωσης:
+
+- `%appDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο του αρχείου `Bootstrap.php`
+- `%wwwDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο που περιέχει το αρχείο καταχώρησης `index.php`
+- `%tempDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο για τα προσωρινά αρχεία
+- `%vendorDir%` είναι η απόλυτη διαδρομή προς τον κατάλογο όπου ο Composer εγκαθιστά τις βιβλιοθήκες
+- Το `%debugMode%` δηλώνει αν η εφαρμογή βρίσκεται σε κατάσταση αποσφαλμάτωσης.
+- Το `%consoleMode%` δηλώνει αν η αίτηση υποβλήθηκε μέσω της γραμμής εντολών.
+
+
Εισαγόμενες υπηρεσίες .[#toc-imported-services]
-----------------------------------------------
diff --git a/application/el/components.texy b/application/el/components.texy
index e9658ada5f..7f4088b591 100644
--- a/application/el/components.texy
+++ b/application/el/components.texy
@@ -233,31 +233,34 @@ $this->redirect(/* ... */); // και ανακατεύθυνση
Μόνιμες παράμετροι .[#toc-persistent-parameters]
================================================
-Συχνά χρειάζεται να διατηρείται κάποια παράμετρος σε ένα στοιχείο για όλη τη διάρκεια της εργασίας με το στοιχείο. Μπορεί να είναι για παράδειγμα ο αριθμός της σελίδας στην σελιδοποίηση. Αυτή η παράμετρος θα πρέπει να χαρακτηρίζεται ως μόνιμη χρησιμοποιώντας το σχόλιο `@persistent`.
+Οι μόνιμες παράμετροι χρησιμοποιούνται για τη διατήρηση της κατάστασης των στοιχείων μεταξύ διαφορετικών αιτήσεων. Η τιμή τους παραμένει η ίδια ακόμη και μετά το κλικ σε έναν σύνδεσμο. Σε αντίθεση με τα δεδομένα συνόδου, μεταφέρονται στη διεύθυνση URL. Και μεταφέρονται αυτόματα, συμπεριλαμβανομένων των συνδέσμων που δημιουργούνται σε άλλα στοιχεία στην ίδια σελίδα.
+
+Για παράδειγμα, έχετε ένα στοιχείο σελιδοποίησης περιεχομένου. Μπορεί να υπάρχουν πολλά τέτοια στοιχεία σε μια σελίδα. Και θέλετε όλα τα συστατικά να παραμένουν στην τρέχουσα σελίδα τους όταν κάνετε κλικ στο σύνδεσμο. Επομένως, κάνουμε τον αριθμό σελίδας (`page`) μια μόνιμη παράμετρο.
+
+Η δημιουργία μιας μόνιμης παραμέτρου είναι εξαιρετικά εύκολη στη Nette. Απλά δημιουργήστε μια δημόσια ιδιότητα και επισημάνετέ την με το χαρακτηριστικό: (προηγουμένως χρησιμοποιούνταν το `/** @persistent */` )
```php
-class PollControl extends Control
+use Nette\Application\Attributes\Persistent; // αυτή η γραμμή είναι σημαντική
+
+class PaginatingControl extends Control
{
- /** @persistent */
- public int $page = 1;
+ #[Persistent]
+ public int $page = 1; // πρέπει να είναι δημόσια
}
```
-Αυτή η παράμετρος θα περνάει αυτόματα σε κάθε σύνδεσμο ως παράμετρος `GET` έως ότου ο χρήστης εγκαταλείψει τη σελίδα με αυτό το στοιχείο.
+Συνιστούμε να συμπεριλάβετε τον τύπο δεδομένων (π.χ. `int`) μαζί με την ιδιότητα και μπορείτε επίσης να συμπεριλάβετε μια προεπιλεγμένη τιμή. Οι τιμές των παραμέτρων μπορούν να [επικυρωθούν |#Validation of Persistent Parameters].
-.[caution]
-Ποτέ μην εμπιστεύεστε τυφλά τις μόνιμες παραμέτρους, επειδή μπορούν να παραποιηθούν εύκολα (με αντικατάσταση της διεύθυνσης URL). Επαληθεύστε, για παράδειγμα, αν ο αριθμός της σελίδας είναι εντός του σωστού διαστήματος.
+Μπορείτε να αλλάξετε την τιμή μιας μόνιμης παραμέτρου κατά τη δημιουργία ενός συνδέσμου:
-Στην PHP 8, μπορείτε επίσης να χρησιμοποιήσετε χαρακτηριστικά για να επισημάνετε μόνιμες παραμέτρους:
+```latte
+next
+```
-```php
-use Nette\Application\Attributes\Persistent;
+Ή μπορεί να *επαναρυθμιστεί*, δηλαδή να αφαιρεθεί από τη διεύθυνση URL. Τότε θα πάρει την προεπιλεγμένη τιμή της:
-class PollControl extends Control
-{
- #[Persistent]
- public int $page = 1;
-}
+```latte
+reset
```
@@ -378,7 +381,7 @@ interface PollControlFactory
1) είναι δυνατό να αποδοθεί σε ένα πρότυπο
2) γνωρίζει ποιο μέρος του εαυτού του να αποδώσει κατά τη διάρκεια μιας [αίτησης AJAX |ajax#invalidation] (αποσπάσματα)
-3) έχει τη δυνατότητα να αποθηκεύει την κατάστασή του σε μια διεύθυνση URL (παράμετροι επιμονής)
+3) έχει τη δυνατότητα να αποθηκεύει την κατάστασή του σε μια διεύθυνση URL (μόνιμες παράμετροι)
4) έχει τη δυνατότητα να ανταποκρίνεται σε ενέργειες του χρήστη (σήματα)
5) δημιουργεί μια ιεραρχική δομή (όπου η ρίζα είναι ο παρουσιαστής)
@@ -403,6 +406,33 @@ Nette\ComponentModel\Component { IComponent }
[* lifecycle-component.svg *] *** *Κύκλος ζωής του συστατικού* .<>
+Επικύρωση μόνιμων παραμέτρων .[#toc-validation-of-persistent-parameters]
+------------------------------------------------------------------------
+
+Οι τιμές των [μόνιμων παραμέτρων |#persistent parameters] που λαμβάνονται από τις διευθύνσεις URL εγγράφονται στις ιδιότητες με τη μέθοδο `loadState()`. Ελέγχει επίσης αν ο τύπος δεδομένων που έχει καθοριστεί για την ιδιότητα ταιριάζει, διαφορετικά θα απαντήσει με σφάλμα 404 και η σελίδα δεν θα εμφανιστεί.
+
+Ποτέ μην εμπιστεύεστε τυφλά τις μόνιμες παραμέτρους, επειδή μπορούν εύκολα να αντικατασταθούν από τον χρήστη στη διεύθυνση URL. Για παράδειγμα, με αυτόν τον τρόπο ελέγχουμε αν ο αριθμός σελίδας `$this->page` είναι μεγαλύτερος από 0. Ένας καλός τρόπος για να το κάνετε αυτό είναι να παρακάμψετε τη μέθοδο `loadState()` που αναφέρθηκε παραπάνω:
+
+```php
+class PaginatingControl extends Control
+{
+ #[Persistent]
+ public int $page = 1;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // εδώ ορίζεται η σελίδα $this->page
+ // ακολουθεί τον έλεγχο της τιμής του χρήστη:
+ if ($this->page < 1) {
+ $this->error();
+ }
+ }
+}
+```
+
+Η αντίθετη διαδικασία, δηλαδή η συλλογή τιμών από persistent properites, αντιμετωπίζεται από τη μέθοδο `saveState()`.
+
+
Σήματα σε βάθος .[#toc-signals-in-depth]
----------------------------------------
diff --git a/application/el/creating-links.texy b/application/el/creating-links.texy
index 5e914b2863..e36d982225 100644
--- a/application/el/creating-links.texy
+++ b/application/el/creating-links.texy
@@ -52,7 +52,7 @@
Το χαρακτηριστικό `n:href` είναι πολύ χρήσιμο για τις ετικέτες HTML ``. Αν θέλουμε να εκτυπώσουμε τον σύνδεσμο αλλού, για παράδειγμα στο κείμενο, χρησιμοποιούμε το `{link}`:
```latte
-URL is: {link Homepage:default}
+URL is: {link Home:default}
```
@@ -88,19 +88,19 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Η βασική μορφή είναι επομένως `Presenter:action`:
```latte
-homepage
+home
```
Αν συνδεθούμε με τη δράση του τρέχοντος παρουσιαστή, μπορούμε να παραλείψουμε το όνομά του:
```latte
-homepage
+home
```
Αν η ενέργεια είναι `default`, μπορούμε να την παραλείψουμε, αλλά η άνω και κάτω τελεία πρέπει να παραμείνει:
```latte
-homepage
+home
```
Οι σύνδεσμοι μπορούν επίσης να παραπέμπουν σε άλλες [ενότητες |modules]. Εδώ, οι σύνδεσμοι διακρίνονται σε σχετικούς με τις υποενότητες ή απόλυτους. Η αρχή είναι ανάλογη με τις διαδρομές δίσκου, μόνο που αντί για κάθετους υπάρχουν άνω και κάτω τελεία. Ας υποθέσουμε ότι ο πραγματικός παρουσιαστής είναι μέρος της ενότητας `Front`, τότε θα γράψουμε:
@@ -119,7 +119,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Μπορούμε να συνδεθούμε σε ένα συγκεκριμένο τμήμα της σελίδας HTML μέσω ενός λεγόμενου αποσπάσματος μετά το σύμβολο κατακερματισμού `#`:
```latte
-link to Homepage:default and fragment #main
+link to Home:default and fragment #main
```
@@ -128,7 +128,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Οι σύνδεσμοι που δημιουργούνται από το `link()` ή το `n:href` είναι πάντα απόλυτες διαδρομές (δηλ. ξεκινούν με `/`), αλλά όχι απόλυτες διευθύνσεις URL με πρωτόκολλο και τομέα όπως `https://domain`.
-Για να δημιουργήσετε μια απόλυτη διεύθυνση URL, προσθέστε δύο κάθετους στην αρχή (π.χ. `n:href="//Homepage:"`). Ή μπορείτε να αλλάξετε τον παρουσιαστή ώστε να παράγει μόνο απόλυτους συνδέσμους, ρυθμίζοντας το `$this->absoluteUrls = true`.
+Για να δημιουργήσετε μια απόλυτη διεύθυνση URL, προσθέστε δύο κάθετους στην αρχή (π.χ. `n:href="//Home:"`). Ή μπορείτε να αλλάξετε τον παρουσιαστή ώστε να παράγει μόνο απόλυτους συνδέσμους, ρυθμίζοντας το `$this->absoluteUrls = true`.
Σύνδεσμος προς την τρέχουσα σελίδα .[#toc-link-to-current-page]
@@ -213,13 +213,13 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Αν θέλουμε να συνδέσουμε με παρουσιαστές στο πρότυπο συστατικού, χρησιμοποιούμε την ετικέτα `{plink}`:
```latte
-homepage
+home
```
ή στον κώδικα
```php
-$this->getPresenter()->link('Homepage:default')
+$this->getPresenter()->link('Home:default')
```
diff --git a/application/el/how-it-works.texy b/application/el/how-it-works.texy
index 138f0006ee..b5b1f766dd 100644
--- a/application/el/how-it-works.texy
+++ b/application/el/how-it-works.texy
@@ -23,10 +23,10 @@
web-project/
├── app/ ← directory with application
│ ├── Presenters/ ← presenter classes
-│ │ ├── HomepagePresenter.php ← Homepage presenter class
+│ │ ├── HomePresenter.php ← Home presenter class
│ │ └── templates/ ← templates directory
│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Homepage/ ← templates for Homepage presenter
+│ │ └── Home/ ← templates for Home presenter
│ │ └── default.latte ← template for action `default`
│ ├── Router/ ← configuration of URL addresses
│ └── Bootstrap.php ← booting class Bootstrap
@@ -134,10 +134,10 @@ class ProductPresenter extends Nette\Application\UI\Presenter
1) η διεύθυνση URL θα είναι `https://example.com`
2) εκκινούμε την εφαρμογή, δημιουργούμε έναν περιέκτη και εκτελούμε `Application::run()`
-3) ο δρομολογητής αποκωδικοποιεί τη διεύθυνση URL ως ζεύγος `Homepage:default`
-4) δημιουργείται ένα αντικείμενο `HomepagePresenter`
+3) ο δρομολογητής αποκωδικοποιεί τη διεύθυνση URL ως ζεύγος `Home:default`
+4) δημιουργείται ένα αντικείμενο `HomePresenter`
5) καλείται η μέθοδος `renderDefault()` (αν υπάρχει)
-6) αποδίδεται ένα πρότυπο `templates/Homepage/default.latte` με διάταξη `templates/@layout.latte`
+6) αποδίδεται ένα πρότυπο `templates/Home/default.latte` με διάταξη `templates/@layout.latte`
Μπορεί να έχετε συναντήσει πολλές νέες έννοιες τώρα, αλλά πιστεύουμε ότι βγάζουν νόημα. Η δημιουργία εφαρμογών στη Nette είναι πανεύκολη.
diff --git a/application/el/modules.texy b/application/el/modules.texy
index 56dc5ee920..b2bb1dffd0 100644
--- a/application/el/modules.texy
+++ b/application/el/modules.texy
@@ -104,7 +104,7 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
Καθορίζει τους κανόνες με τους οποίους το όνομα της κλάσης προκύπτει από το όνομα του παρουσιαστή. Τους γράφουμε στη [διαμόρφωση |configuration] κάτω από το κλειδί `application › mapping`.
-Ας ξεκινήσουμε με ένα δείγμα που δεν χρησιμοποιεί ενότητες. Θα θέλουμε απλώς οι κλάσεις presenter να έχουν το namespace `App\Presenters`. Αυτό σημαίνει ότι ένας παρουσιαστής όπως το `Homepage` θα πρέπει να αντιστοιχίζεται στην κλάση `App\Presenters\HomepagePresenter`. Αυτό μπορεί να επιτευχθεί με την ακόλουθη διαμόρφωση:
+Ας ξεκινήσουμε με ένα δείγμα που δεν χρησιμοποιεί ενότητες. Θα θέλουμε απλώς οι κλάσεις presenter να έχουν το namespace `App\Presenters`. Αυτό σημαίνει ότι ένας παρουσιαστής όπως το `Home` θα πρέπει να αντιστοιχίζεται στην κλάση `App\Presenters\HomePresenter`. Αυτό μπορεί να επιτευχθεί με την ακόλουθη διαμόρφωση:
```neon
application:
@@ -124,7 +124,7 @@ application:
Api: App\Api\*Presenter
```
-Τώρα ο παρουσιαστής `Front:Homepage` αντιστοιχίζεται στην κλάση `App\Modules\Front\Presenters\HomepagePresenter` και ο παρουσιαστής `Admin:Dashboard` στην κλάση `App\Modules\Admin\Presenters\DashboardPresenter`.
+Τώρα ο παρουσιαστής `Front:Home` αντιστοιχίζεται στην κλάση `App\Modules\Front\Presenters\HomePresenter` και ο παρουσιαστής `Admin:Dashboard` στην κλάση `App\Modules\Admin\Presenters\DashboardPresenter`.
Είναι πιο πρακτικό να δημιουργήσετε έναν γενικό κανόνα (αστέρι) για να αντικαταστήσετε τους δύο πρώτους. Ο επιπλέον αστερίσκος θα προστεθεί στη μάσκα κλάσης μόνο για την ενότητα:
diff --git a/application/el/presenters.texy b/application/el/presenters.texy
index 2406abbc74..98c5b4ea42 100644
--- a/application/el/presenters.texy
+++ b/application/el/presenters.texy
@@ -158,7 +158,7 @@ $url = $this->link('Product:show', [$id, 'lang' => 'en']);
$this->forward('Product:show');
```
-με κωδικό HTTP 302 ή 303:
+Παράδειγμα μιας λεγόμενης προσωρινής ανακατεύθυνσης με κωδικό HTTP 302 (ή 303, εάν η τρέχουσα μέθοδος αίτησης είναι POST):
```php
$this->redirect('Product:show', $id);
@@ -170,7 +170,7 @@ $this->redirect('Product:show', $id);
$this->redirectPermanent('Product:show', $id);
```
-Μπορείτε να ανακατευθύνετε σε μια άλλη διεύθυνση URL εκτός της εφαρμογής με τη μέθοδο `redirectUrl()`:
+Μπορείτε να ανακατευθύνετε σε μια άλλη διεύθυνση URL εκτός της εφαρμογής χρησιμοποιώντας τη μέθοδο `redirectUrl()`. Ο κωδικός HTTP μπορεί να καθοριστεί ως δεύτερη παράμετρος, με προεπιλεγμένη τιμή 302 (ή 303, αν η τρέχουσα μέθοδος αίτησης είναι POST):
```php
$this->redirectUrl('https://nette.org');
@@ -239,46 +239,54 @@ public function actionData(): void
Εμμένουσες παράμετροι .[#toc-persistent-parameters]
===================================================
-Οι μόνιμες παράμετροι **μεταφέρονται αυτόματα** στους συνδέσμους. Αυτό σημαίνει ότι δεν χρειάζεται να τις προσδιορίσουμε ρητά σε κάθε `link()` ή `n:href` του προτύπου, αλλά και πάλι θα μεταφερθούν.
+Οι μόνιμες παράμετροι χρησιμοποιούνται για τη διατήρηση της κατάστασης μεταξύ διαφορετικών αιτήσεων. Η τιμή τους παραμένει η ίδια ακόμη και μετά το κλικ σε έναν σύνδεσμο. Σε αντίθεση με τα δεδομένα συνόδου, μεταβιβάζονται στη διεύθυνση URL. Αυτό γίνεται εντελώς αυτόματα, οπότε δεν χρειάζεται να τις δηλώσετε ρητά στο `link()` ή στο `n:href`.
-Εάν η εφαρμογή σας έχει πολλαπλές γλωσσικές εκδόσεις, τότε η τρέχουσα γλώσσα είναι μια παράμετρος που πρέπει πάντα να αποτελεί μέρος της διεύθυνσης URL. Και θα ήταν απίστευτα κουραστικό να την αναφέρετε σε κάθε σύνδεσμο. Αυτό δεν είναι απαραίτητο με τη Nette. Με αυτόν τον τρόπο απλά χαρακτηρίζουμε την παράμετρο `lang` ως μόνιμη:
+Παράδειγμα χρήσης; Έχετε μια πολύγλωσση εφαρμογή. Η πραγματική γλώσσα είναι μια παράμετρος που πρέπει να αποτελεί μέρος του URL ανά πάσα στιγμή. Αλλά θα ήταν απίστευτα κουραστικό να τη συμπεριλάβετε σε κάθε σύνδεσμο. Οπότε την κάνετε μια μόνιμη παράμετρο με το όνομα `lang` και θα μεταφέρεται μόνη της. Ωραία!
+
+Η δημιουργία μιας μόνιμης παραμέτρου είναι εξαιρετικά εύκολη στη Nette. Απλά δημιουργήστε μια δημόσια ιδιότητα και επισημάνετέ την με το χαρακτηριστικό: (προηγουμένως χρησιμοποιούνταν το `/** @persistent */` )
```php
+use Nette\Application\Attributes\Persistent; // αυτή η γραμμή είναι σημαντική
+
class ProductPresenter extends Nette\Application\UI\Presenter
{
- /** @persistent */
- public string $lang;
+ #[Persistent]
+ public string $lang; // πρέπει να είναι δημόσια
}
```
-Εάν η τρέχουσα τιμή της παραμέτρου `lang` είναι `'en'`, τότε η διεύθυνση URL που δημιουργείται με `link()` ή `n:href` στο πρότυπο θα περιέχει `lang=en`. Υπέροχα!
-
-Ωστόσο, μπορούμε επίσης να προσθέσουμε την παράμετρο `lang` και μέσω αυτής να αλλάξουμε την τιμή της:
+Εάν το `$this->lang` έχει μια τιμή όπως `'en'`, τότε οι σύνδεσμοι που δημιουργούνται με χρήση των `link()` ή `n:href` θα περιέχουν επίσης την παράμετρο `lang=en`. Και όταν ο σύνδεσμος πατηθεί, θα είναι και πάλι `$this->lang = 'en'`.
-```latte
-detail in English
-```
-
-Ή, αντίστροφα, μπορεί να αφαιρεθεί θέτοντας την τιμή null:
-
-```latte
-click here
-```
+Για τις ιδιότητες, συνιστούμε να περιλαμβάνετε τον τύπο δεδομένων (π.χ. `string`) και μπορείτε επίσης να συμπεριλάβετε μια προεπιλεγμένη τιμή. Οι τιμές των παραμέτρων μπορούν να [επικυρωθούν |#Validation of Persistent Parameters].
-Η μόνιμη μεταβλητή πρέπει να δηλωθεί ως δημόσια. Μπορούμε επίσης να καθορίσουμε μια προεπιλεγμένη τιμή. Εάν η παράμετρος έχει την ίδια τιμή με την προεπιλεγμένη, δεν θα συμπεριληφθεί στη διεύθυνση URL.
+Οι μόνιμες παράμετροι μεταβιβάζονται μεταξύ όλων των ενεργειών ενός συγκεκριμένου παρουσιαστή από προεπιλογή. Για να τις περάσετε μεταξύ πολλαπλών παρουσιαστών, πρέπει να τις ορίσετε είτε:
-Η εμμονή αντικατοπτρίζει την ιεραρχία των κλάσεων παρουσιαστή, έτσι η παράμετρος που ορίζεται σε έναν συγκεκριμένο παρουσιαστή ή χαρακτηριστικό μεταφέρεται στη συνέχεια αυτόματα σε κάθε παρουσιαστή που κληρονομεί από αυτόν ή χρησιμοποιεί το ίδιο χαρακτηριστικό.
-
-Στην PHP 8, μπορείτε επίσης να χρησιμοποιήσετε χαρακτηριστικά για να επισημάνετε μόνιμες παραμέτρους:
+- σε έναν κοινό πρόγονο από τον οποίο κληρονομούν οι παρουσιαστές
+- στην ιδιότητα που χρησιμοποιούν οι παρουσιαστές:
```php
-use Nette\Application\Attributes\Persistent;
-
-class ProductPresenter extends Nette\Application\UI\Presenter
+trait LangAware
{
#[Persistent]
public string $lang;
}
+
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ use LangAware;
+}
+```
+
+Μπορείτε να αλλάξετε την τιμή μιας μόνιμης παραμέτρου κατά τη δημιουργία ενός συνδέσμου:
+
+```latte
+detail in Czech
+```
+
+Ή μπορεί να *επαναρυθμιστεί*, δηλαδή να αφαιρεθεί από τη διεύθυνση URL. Τότε θα πάρει την προεπιλεγμένη τιμή της:
+
+```latte
+click
```
@@ -302,7 +310,32 @@ class ProductPresenter extends Nette\Application\UI\Presenter
Απαίτηση και παράμετροι .[#toc-requirement-and-parameters]
----------------------------------------------------------
-Το αίτημα που χειρίζεται ο παρουσιαστής είναι το αντικείμενο [api:Nette\Application\Request] και επιστρέφεται από τη μέθοδο του παρουσιαστή `getRequest()`. Περιλαμβάνει έναν πίνακα παραμέτρων και κάθε μία από αυτές ανήκει είτε σε κάποιο από τα συστατικά είτε απευθείας στον παρουσιαστή (ο οποίος στην πραγματικότητα είναι επίσης ένα συστατικό, αν και ειδικό). Έτσι, η Nette ανακατανέμει τις παραμέτρους και περνάει μεταξύ των επιμέρους συστατικών (και του παρουσιαστή) καλώντας τη μέθοδο `loadState(array $params)`, η οποία περιγράφεται περαιτέρω στο κεφάλαιο [Components |Components]. Οι παράμετροι μπορούν να ληφθούν με τη μέθοδο `getParameters(): array`, μεμονωμένα με τη χρήση του `getParameter($name)`. Οι τιμές των παραμέτρων είναι συμβολοσειρές ή πίνακες συμβολοσειρών, είναι ουσιαστικά ακατέργαστα δεδομένα που λαμβάνονται απευθείας από μια διεύθυνση URL.
+Το αίτημα που χειρίζεται ο παρουσιαστής είναι το αντικείμενο [api:Nette\Application\Request] και επιστρέφεται από τη μέθοδο του παρουσιαστή `getRequest()`. Περιλαμβάνει έναν πίνακα παραμέτρων και κάθε μία από αυτές ανήκει είτε σε κάποιο από τα συστατικά είτε απευθείας στον παρουσιαστή (ο οποίος στην πραγματικότητα είναι επίσης ένα συστατικό, αν και ειδικό). Έτσι, η Nette ανακατανέμει τις παραμέτρους και περνάει μεταξύ των επιμέρους συστατικών (και του παρουσιαστή) καλώντας τη μέθοδο `loadState(array $params)`. Οι παράμετροι μπορούν να ληφθούν με τη μέθοδο `getParameters(): array`, μεμονωμένα με τη χρήση του `getParameter($name)`. Οι τιμές των παραμέτρων είναι συμβολοσειρές ή πίνακες συμβολοσειρών, είναι ουσιαστικά ακατέργαστα δεδομένα που λαμβάνονται απευθείας από μια διεύθυνση URL.
+
+
+Επικύρωση μόνιμων παραμέτρων .[#toc-validation-of-persistent-parameters]
+------------------------------------------------------------------------
+
+Οι τιμές των [μόνιμων παραμέτρων |#persistent parameters] που λαμβάνονται από τις διευθύνσεις URL εγγράφονται στις ιδιότητες με τη μέθοδο `loadState()`. Ελέγχει επίσης αν ο τύπος δεδομένων που καθορίζεται στην ιδιότητα ταιριάζει, διαφορετικά θα απαντήσει με σφάλμα 404 και η σελίδα δεν θα εμφανιστεί.
+
+Ποτέ μην εμπιστεύεστε τυφλά τις μόνιμες παραμέτρους, καθώς μπορούν εύκολα να αντικατασταθούν από τον χρήστη στη διεύθυνση URL. Για παράδειγμα, με αυτόν τον τρόπο ελέγχουμε αν το `$this->lang` είναι μεταξύ των υποστηριζόμενων γλωσσών. Ένας καλός τρόπος για να το κάνετε αυτό είναι να παρακάμψετε τη μέθοδο `loadState()` που αναφέρθηκε παραπάνω:
+
+```php
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ #[Persistent]
+ public string $lang;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // εδώ ορίζεται το $this->lang
+ // ακολουθεί τον έλεγχο της τιμής του χρήστη:
+ if (!in_array($this->lang, ['en', 'cs'])) {
+ $this->error();
+ }
+ }
+}
+```
Αποθήκευση και επαναφορά της αίτησης .[#toc-save-and-restore-the-request]
diff --git a/application/el/routing.texy b/application/el/routing.texy
index 55da217819..19b2ceb7bf 100644
--- a/application/el/routing.texy
+++ b/application/el/routing.texy
@@ -93,12 +93,12 @@ $router->addRoute('chronicle/', 'History:show');
Φυσικά, το όνομα του παρουσιαστή και της ενέργειας μπορεί επίσης να είναι παράμετρος. Για παράδειγμα:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
Αυτή η διαδρομή δέχεται, για παράδειγμα, μια διεύθυνση URL της μορφής `/article/edit` ή `/catalog/list` και τις μεταφράζει σε παρουσιαστές και ενέργειες `Article:edit` ή `Catalog:list`.
-Δίνει επίσης στις παραμέτρους `presenter` και `action` προεπιλεγμένες τιμές`Homepage` και `default` και επομένως είναι προαιρετικές. Έτσι, η διαδρομή δέχεται επίσης ένα URL `/article` και το μεταφράζει ως `Article:default`. Ή αντίστροφα, ένας σύνδεσμος προς το `Product:default` δημιουργεί μια διαδρομή `/product`, ένας σύνδεσμος προς την προεπιλεγμένη `Homepage:default` δημιουργεί μια διαδρομή `/`.
+Δίνει επίσης στις παραμέτρους `presenter` και `action` προεπιλεγμένες τιμές`Home` και `default` και επομένως είναι προαιρετικές. Έτσι, η διαδρομή δέχεται επίσης ένα URL `/article` και το μεταφράζει ως `Article:default`. Ή αντίστροφα, ένας σύνδεσμος προς το `Product:default` δημιουργεί μια διαδρομή `/product`, ένας σύνδεσμος προς την προεπιλεγμένη `Home:default` δημιουργεί μια διαδρομή `/`.
Η μάσκα μπορεί να περιγράφει όχι μόνο τη σχετική διαδρομή με βάση τη ρίζα του ιστότοπου, αλλά και την απόλυτη διαδρομή όταν αρχίζει με μια κάθετο, ή ακόμη και ολόκληρη την απόλυτη διεύθυνση URL όταν αρχίζει με δύο κάθετους:
@@ -160,7 +160,7 @@ $router->addRoute('//[.]example.com//', /* ... */);
```php
$router->addRoute(
'[[-]/][/page-]',
- 'Homepage:default',
+ 'Home:default',
);
// Αποδεκτές διευθύνσεις URL:
@@ -183,16 +183,16 @@ $router->addRoute('[!.html]', /* ... */);
Οι προαιρετικές παράμετροι (δηλαδή οι παράμετροι που έχουν προεπιλεγμένη τιμή) χωρίς τετράγωνες αγκύλες συμπεριφέρονται σαν να είναι τυλιγμένες έτσι:
```php
-$router->addRoute('//', /* ... */);
+$router->addRoute('//', /* ... */);
// ισούται με:
-$router->addRoute('[/[/[]]]', /* ... */);
+$router->addRoute('[/[/[]]]', /* ... */);
```
-Για να αλλάξετε τον τρόπο με τον οποίο παράγεται η δεξιότερη κάθετος, δηλαδή αντί για `/homepage/` να πάρετε ένα `/homepage`, προσαρμόστε τη διαδρομή με αυτόν τον τρόπο:
+Για να αλλάξετε τον τρόπο με τον οποίο παράγεται η δεξιότερη κάθετος, δηλαδή αντί για `/home/` να πάρετε ένα `/home`, προσαρμόστε τη διαδρομή με αυτόν τον τρόπο:
```php
-$router->addRoute('[[/[/]]]', /* ... */);
+$router->addRoute('[[/[/]]]', /* ... */);
```
@@ -220,7 +220,7 @@ $router->addRoute('//www.%sld%.%tld%/%basePath%//addRoute('/[/]', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
]);
```
@@ -232,7 +232,7 @@ use Nette\Routing\Route;
$router->addRoute('/[/]', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
@@ -252,7 +252,7 @@ $router->addRoute('/[/]', [
Είναι μια καλή πρακτική να γράφετε τον πηγαίο κώδικα στα αγγλικά, αλλά τι γίνεται αν θέλετε ο ιστότοπός σας να έχει μεταφρασμένο URL σε διαφορετική γλώσσα; Απλές διαδρομές, όπως: "Η γλώσσα που θα χρησιμοποιηθεί για να μεταφραστεί σε άλλη γλώσσα":
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
θα δημιουργήσουν αγγλικές διευθύνσεις URL, όπως `/product/123` ή `/cart`. Αν θέλουμε να έχουμε παρουσιαστές και ενέργειες στη διεύθυνση URL μεταφρασμένες στα γερμανικά (π.χ. `/produkt/123` ή `/einkaufswagen`), μπορούμε να χρησιμοποιήσουμε ένα μεταφραστικό λεξικό. Για να το προσθέσουμε, χρειαζόμαστε ήδη μια "πιο ομιλητική" παραλλαγή της δεύτερης παραμέτρου:
@@ -262,7 +262,7 @@ use Nette\Routing\Route;
$router->addRoute('/', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterTable => [
// συμβολοσειρά στη διεύθυνση URL => παρουσιαστής
'produkt' => 'Product',
@@ -290,7 +290,7 @@ use Nette\Routing\Route;
$router->addRoute('//', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
@@ -313,7 +313,7 @@ $router->addRoute('//', [
use Nette\Routing\Route;
$router->addRoute('/', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
@@ -503,15 +503,15 @@ http://example.com/?presenter=Product&action=detail&id=123
Η παράμετρος του κατασκευαστή `SimpleRouter` είναι ένας προεπιλεγμένος παρουσιαστής & ενέργεια, δηλαδή ενέργεια που θα εκτελεστεί αν ανοίξουμε π.χ. το `http://example.com/` χωρίς πρόσθετες παραμέτρους.
```php
-// προεπιλογή παρουσιαστή 'Homepage' και δράσης 'default'
-$router = new Nette\Application\Routers\SimpleRouter('Homepage:default');
+// προεπιλογή παρουσιαστή 'Home' και δράσης 'default'
+$router = new Nette\Application\Routers\SimpleRouter('Home:default');
```
Συνιστούμε τον ορισμό του SimpleRouter απευθείας στη [διαμόρφωση |dependency-injection:services]:
```neon
services:
- - Nette\Application\Routers\SimpleRouter('Homepage:default')
+ - Nette\Application\Routers\SimpleRouter('Home:default')
```
@@ -611,7 +611,7 @@ class MyRouter implements Nette\Routing\Router
```php
[
- 'presenter' => 'Front:Homepage',
+ 'presenter' => 'Front:Home',
'action' => 'default',
]
```
diff --git a/application/el/templates.texy b/application/el/templates.texy
index 364d15388a..4b83599f45 100644
--- a/application/el/templates.texy
+++ b/application/el/templates.texy
@@ -42,7 +42,9 @@
- `templates//.latte`
- `templates/..latte`
-Αν δεν βρει το πρότυπο, η απάντηση είναι [σφάλμα 404 |presenters#Error 404 etc.].
+Αν το πρότυπο δεν βρεθεί, θα προσπαθήσει να ψάξει στον κατάλογο `templates` ένα επίπεδο πιο πάνω, δηλαδή στο ίδιο επίπεδο με τον κατάλογο με την κλάση παρουσιαστή.
+
+Εάν το πρότυπο δεν βρεθεί ούτε εκεί, η απάντηση είναι ένα [σφάλμα 404 |presenters#Error 404 etc.].
Μπορείτε επίσης να αλλάξετε την προβολή χρησιμοποιώντας το `$this->setView('otherView')`. Ή, αντί για αναζήτηση, καθορίστε απευθείας το όνομα του αρχείου προτύπου χρησιμοποιώντας τη διεύθυνση `$this->template->setFile('/path/to/template.latte')`.
@@ -148,7 +150,7 @@ Default Variables .[#toc-default-variables]
Το χαρακτηριστικό `n:href` είναι πολύ βολικό για τις ετικέτες HTML ``. Αν θέλουμε να εκτυπώσουμε τον σύνδεσμο αλλού, για παράδειγμα στο κείμενο, χρησιμοποιούμε το `{link}`:
```latte
-URL is: {link Homepage:default}
+URL is: {link Home:default}
```
Για περισσότερες πληροφορίες, ανατρέξτε στην ενότητα [Δημιουργία συνδέσμων |Creating Links].
diff --git a/application/en/@left-menu.texy b/application/en/@left-menu.texy
index 3506cff2c9..bc4b360cee 100644
--- a/application/en/@left-menu.texy
+++ b/application/en/@left-menu.texy
@@ -15,5 +15,8 @@ Nette Application
Further Reading
***************
+- [Why Use Nette?|www:10-reasons-why-nette]
+- [Installation |nette:installation]
+- [Create Your First Application! |quickstart:]
- [Best practices |best-practices:]
- [Troubleshooting |nette:troubleshooting]
diff --git a/application/en/ajax.texy b/application/en/ajax.texy
index 5e26e4ced2..f43ff28c2f 100644
--- a/application/en/ajax.texy
+++ b/application/en/ajax.texy
@@ -10,9 +10,13 @@ Modern web applications nowadays run half on a server and half in a browser. AJA
-An AJAX request can be detected using a method of a service [encapsulating a HTTP request |http:request] `$httpRequest->isAjax()` (detects based on the `X-Requested-With` HTTP header). There is also a shorthand method in presenter: `$this->isAjax()`.
-An AJAX request is no different from a normal one – a presenter is called with a certain view and parameters. It is, too, up to the presenter how will it react: it can use its routines to either return a fragment of HTML code (a snippet), an XML document, a JSON object or a piece of Javascript code.
+AJAX Request
+============
+
+An AJAX request does not differ from a classic request - the presenter is called with a specific view and parameters. It is also up to the presenter how to respond to it: it can use its own routine, which returns an HTML code fragment (HTML snippet), an XML document, a JSON object, or JavaScript code.
+
+On the server side, an AJAX request can be detected using the service method [encapsulating the HTTP request |http:request] `$httpRequest->isAjax()` (detects based on the HTTP header `X-Requested-With`). Inside the presenter, a shortcut is available in the form of the method `$this->isAjax()`.
There is a pre-processed object called `payload` dedicated to sending data to the browser in JSON.
@@ -60,6 +64,21 @@ npm install naja
```
+To create an AJAX request from a regular link (signal) or form submittion, simply mark the relevant link, form, or button with the class `ajax`:
+
+```html
+Go
+
+
+
+or
+
+```
+
Snippets
========
@@ -149,7 +168,7 @@ You can't redraw a dynamic snippet directly (redrawing of `item-1` has no effect
In the example above you have to make sure that for an AJAX request only one item will be added to the `$list` array, therefore the `foreach` loop will print just one dynamic snippet.
```php
-class HomepagePresenter extends Nette\Application\UI\Presenter
+class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* This method returns data for the list.
diff --git a/application/en/bootstrap.texy b/application/en/bootstrap.texy
index c7927f9733..c763e715a3 100644
--- a/application/en/bootstrap.texy
+++ b/application/en/bootstrap.texy
@@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```
-In configuration files, we can write usual notation `%projectId%` to access the parameter named `projectId`. By default, the Configurator populates the following parameters: `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` and `consoleMode`.
+In configuration files, we can write usual notation `%projectId%` to access the parameter named `projectId`.
Dynamic Parameters
@@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```
+Default Parameters
+------------------
+
+You can use the following static parameters in the configuration files:
+
+- `%appDir%` is the absolute path to the directory of `Bootstrap.php` file
+- `%wwwDir%` is the absolute path to the directory containing the `index.php` entry file
+- `%tempDir%` is the absolute path to the directory for temporary files
+- `%vendorDir%` is the absolute path to the directory where Composer installs libraries
+- `%debugMode%` indicates whether the application is in debug mode
+- `%consoleMode%` indicates whether the request came through the command line
+
+
Imported Services
-----------------
diff --git a/application/en/components.texy b/application/en/components.texy
index 218958b13f..bdf8052c3a 100644
--- a/application/en/components.texy
+++ b/application/en/components.texy
@@ -233,31 +233,34 @@ In the template, these messages are available in the variable `$flashes` as obje
Persistent Parameters
=====================
-It is often needed to keep some parameter in a component for the whole time of working with the component. It can be for example the number of the page in pagination. This parameter should be marked as persistent using the annotation `@persistent`.
+Persistent parameters are used to maintain state in components between different requests. Their value remains the same even after a link is clicked. Unlike session data, they are transferred in the URL. And they are transferred automatically, including links created in other components on the same page.
+
+For example, you have a content paging component. There can be several such components on a page. And you want all components to stay on their current page when you click on the link. Therefore, we make the page number (`page`) a persistent parameter.
+
+Creating a persistent parameter is extremely easy in Nette. Just create a public property and tag it with the attribute: (previously `/** @persistent */` was used)
```php
-class PollControl extends Control
+use Nette\Application\Attributes\Persistent; // this line is important
+
+class PaginatingControl extends Control
{
- /** @persistent */
- public int $page = 1;
+ #[Persistent]
+ public int $page = 1; // must be public
}
```
-This parameter will be automatically passed in every link as a `GET` parameter until the user leaves the page with this component.
+We recommend that you include the data type (e.g. `int`) with the property, and you can also include a default value. Parameter values can be [validated |#Validation of Persistent Parameters].
-.[caution]
-Never trust persistent parameters blindly because they can be faked easily (by overwriting the URL). Verify, for example, if the page number is within the correct interval.
+You can change the value of a persistent parameter when creating a link:
-In PHP 8, you can also use attributes to mark persistent parameters:
+```latte
+next
+```
-```php
-use Nette\Application\Attributes\Persistent;
+Or it can be *reset*, i.e. removed from the URL. It will then take its default value:
-class PollControl extends Control
-{
- #[Persistent]
- public int $page = 1;
-}
+```latte
+reset
```
@@ -378,7 +381,7 @@ Components in a Nette Application are the reusable parts of a web application th
1) it is renderable in a template
2) it knows which part of itself to render during an [AJAX request |ajax#invalidation] (snippets)
-3) it has the ability to store its state in a URL (persistence parameters)
+3) it has the ability to store its state in a URL (persistent parameters)
4) has the ability to respond to user actions (signals)
5) creates a hierarchical structure (where the root is the presenter)
@@ -403,6 +406,33 @@ Life Cycle of Component
[* lifecycle-component.svg *] *** *Life cycle of component* .<>
+Validation of Persistent Parameters
+-----------------------------------
+
+The values of [#persistent parameters] received from URLs are written to properties by the `loadState()` method. It also checks if the data type specified for the property matches, otherwise it will respond with a 404 error and the page will not be displayed.
+
+Never blindly trust persistent parameters because they can easily be overwritten by the user in the URL. For example, this is how we check if the page number `$this->page` is greater than 0. A good way to do this is to override the `loadState()` method mentioned above:
+
+```php
+class PaginatingControl extends Control
+{
+ #[Persistent]
+ public int $page = 1;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // here is set the $this->page
+ // follows the user value check:
+ if ($this->page < 1) {
+ $this->error();
+ }
+ }
+}
+```
+
+The opposite process, that is, collecting values from persistent properites, is handled by the `saveState()` method.
+
+
Signals in Depth
----------------
diff --git a/application/en/creating-links.texy b/application/en/creating-links.texy
index 3415287796..0fb783c609 100644
--- a/application/en/creating-links.texy
+++ b/application/en/creating-links.texy
@@ -52,7 +52,7 @@ The so-called [persistent parameters|presenters#persistent parameters] are also
Attribute `n:href` is very handy for HTML tags ``. If we want to print the link elsewhere, for example in the text, we use `{link}`:
```latte
-URL is: {link Homepage:default}
+URL is: {link Home:default}
```
@@ -88,19 +88,19 @@ The format is supported by all Latte tags and all presenter methods that work wi
The basic form is therefore `Presenter:action`:
```latte
-homepage
+home
```
If we link to the action of the current presenter, we can omit its name:
```latte
-homepage
+home
```
If the action is `default`, we can omit it, but the colon must remain:
```latte
-homepage
+home
```
Links may also point to other [modules]. Here, the links are distinguished into relative to the submodules, or absolute. The principle is analogous to disk paths, only instead of slashes there are colons. Let's assume that the actual presenter is part of module `Front`, then we will write:
@@ -119,7 +119,7 @@ A special case is [linking to itself|#Links to Current Page]. Here we'll write `
We can link to a certain part of the HTML page via a so-called fragment after the `#` hash symbol:
```latte
-link to Homepage:default and fragment #main
+link to Home:default and fragment #main
```
@@ -128,7 +128,7 @@ Absolute Paths
Links generated by `link()` or `n:href` are always absolute paths (i.e., they start with `/`), but not absolute URLs with a protocol and domain like `https://domain`.
-To generate an absolute URL, add two slashes to the beginning (e.g., `n:href="//Homepage:"`). Or you can switch the presenter to generate only absolute links by setting `$this->absoluteUrls = true`.
+To generate an absolute URL, add two slashes to the beginning (e.g., `n:href="//Home:"`). Or you can switch the presenter to generate only absolute links by setting `$this->absoluteUrls = true`.
Link to Current Page
@@ -213,13 +213,13 @@ Because [components] are separate reusable units that should have no relations t
If we want to link to presenters in the component template, we use the tag `{plink}`:
```latte
-homepage
+home
```
or in the code
```php
-$this->getPresenter()->link('Homepage:default')
+$this->getPresenter()->link('Home:default')
```
diff --git a/application/en/how-it-works.texy b/application/en/how-it-works.texy
index 2feed87b13..569d48065f 100644
--- a/application/en/how-it-works.texy
+++ b/application/en/how-it-works.texy
@@ -23,10 +23,10 @@ The directory structure looks something like this:
web-project/
├── app/ ← directory with application
│ ├── Presenters/ ← presenter classes
-│ │ ├── HomepagePresenter.php ← Homepage presenter class
+│ │ ├── HomePresenter.php ← Home presenter class
│ │ └── templates/ ← templates directory
│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Homepage/ ← templates for Homepage presenter
+│ │ └── Home/ ← templates for Home presenter
│ │ └── default.latte ← template for action `default`
│ ├── Router/ ← configuration of URL addresses
│ └── Bootstrap.php ← booting class Bootstrap
@@ -134,10 +134,10 @@ Just to be sure, let's try to recap the whole process with a slightly different
1) the URL will be `https://example.com`
2) we boot the application, create a container and run `Application::run()`
-3) the router decodes the URL as a pair `Homepage:default`
-4) an `HomepagePresenter` object is created
+3) the router decodes the URL as a pair `Home:default`
+4) an `HomePresenter` object is created
5) method `renderDefault()` is called (if exists)
-6) a template `templates/Homepage/default.latte` with a layout `templates/@layout.latte` is rendered
+6) a template `templates/Home/default.latte` with a layout `templates/@layout.latte` is rendered
You may have come across a lot of new concepts now, but we believe they make sense. Creating applications in Nette is a breeze.
diff --git a/application/en/modules.texy b/application/en/modules.texy
index 3cddb2754f..6312143fdd 100644
--- a/application/en/modules.texy
+++ b/application/en/modules.texy
@@ -104,7 +104,7 @@ Mapping
Defines the rules by which the class name is derived from the presenter name. We write them in [configuration] under the `application › mapping` key.
-Let's start with a sample that doesn't use modules. We'll just want the presenter classes to have the `App\Presenters` namespace. That means that a presenter such as `Homepage` should map to the `App\Presenters\HomepagePresenter` class. This can be achieved by the following configuration:
+Let's start with a sample that doesn't use modules. We'll just want the presenter classes to have the `App\Presenters` namespace. That means that a presenter such as `Home` should map to the `App\Presenters\HomePresenter` class. This can be achieved by the following configuration:
```neon
application:
@@ -124,7 +124,7 @@ application:
Api: App\Api\*Presenter
```
-Now presenter `Front:Homepage` maps to class `App\Modules\Front\Presenters\HomepagePresenter` and presenter `Admin:Dashboard` to class `App\Modules\Admin\Presenters\DashboardPresenter`.
+Now presenter `Front:Home` maps to class `App\Modules\Front\Presenters\HomePresenter` and presenter `Admin:Dashboard` to class `App\Modules\Admin\Presenters\DashboardPresenter`.
It is more practical to create a general (star) rule to replace the first two. The extra asterisk will be added to the class mask just for the module:
diff --git a/application/en/presenters.texy b/application/en/presenters.texy
index cc82288e56..680b937cf9 100644
--- a/application/en/presenters.texy
+++ b/application/en/presenters.texy
@@ -158,7 +158,7 @@ The `forward()` switches to the new presenter immediately without HTTP redirecti
$this->forward('Product:show');
```
-Example of temporary redirection with HTTP code 302 or 303:
+Example of a so-called temporary redirection with HTTP code 302 (or 303, if the current request method is POST):
```php
$this->redirect('Product:show', $id);
@@ -170,7 +170,7 @@ To achieve permanent redirection with HTTP code 301 use:
$this->redirectPermanent('Product:show', $id);
```
-You can redirect to another URL outside the application with the `redirectUrl()` method:
+You can redirect to another URL outside the application using the `redirectUrl()` method. The HTTP code can be specified as the second parameter, with the default being 302 (or 303, if the current request method is POST):
```php
$this->redirectUrl('https://nette.org');
@@ -239,46 +239,54 @@ public function actionData(): void
Persistent Parameters
=====================
-Persistent parameters are **transferred automatically** in links. This means that we do not have to explicitly specify them in every `link()` or `n:href` in the template, but they will still be transferred.
+Persistent parameters are used to maintain state between different requests. Their value remains the same even after a link is clicked. Unlike session data, they are passed in the URL. This is completely automatic, so there is no need to explicitly state them in `link()` or `n:href`.
-If your application has multiple language versions, then the current language is a parameter that must always be part of the URL. And it would be incredibly tiring to mention it in every link. That's not necessary with Nette. We simply mark the `lang` parameter as persistent in this way:
+Example of use? You have a multilingual application. The actual language is a parameter that needs to be part of the URL at all times. But it would be incredibly tedious to include it in every link. So you make it a persistent parameter named `lang` and it will carry itself. Cool!
+
+Creating a persistent parameter is extremely easy in Nette. Just create a public property and tag it with the attribute: (previously `/** @persistent */` was used)
```php
+use Nette\Application\Attributes\Persistent; // this line is important
+
class ProductPresenter extends Nette\Application\UI\Presenter
{
- /** @persistent */
- public string $lang;
+ #[Persistent]
+ public string $lang; // must be public
}
```
-If the current value of the parameter `lang` is `'en'`, then the URL created with `link()` or `n:href` in the template will contain `lang=en`. Great!
-
-However, we can also add parameter `lang` and by that change its value:
+If `$this->lang` has a value such as `'en'`, then links created using `link()` or `n:href` will also contain the `lang=en` parameter. And when the link is clicked, it will again be `$this->lang = 'en'`.
-```latte
-detail in English
-```
-
-Or, conversely, it can be removed by setting to null:
-
-```latte
-click here
-```
+For properties, we recommend that you include the data type (e.g. `string`) and you can also include a default value. Parameter values can be [validated |#Validation of Persistent Parameters].
-The persistent variable must be declared as public. We can also specify a default value. If the parameter has the same value as the default, it will not be included in the URL.
+Persistent parameters are passed between all actions of a given presenter by default. To pass them between multiple presenters, you need to define them either:
-Persistence reflects the hierarchy of presenter classes, thus parameter defined in a certain presenter or trait is then automatically transferred to each presenter inheriting from it or using the same trait.
-
-In PHP 8, you can also use attributes to mark persistent parameters:
+- in a common ancestor from which the presenters inherit
+- in the trait that the presenters use:
```php
-use Nette\Application\Attributes\Persistent;
-
-class ProductPresenter extends Nette\Application\UI\Presenter
+trait LangAware
{
#[Persistent]
public string $lang;
}
+
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ use LangAware;
+}
+```
+
+You can change the value of a persistent parameter when creating a link:
+
+```latte
+detail in Czech
+```
+
+Or it can be *reset*, i.e. removed from the URL. It will then take its default value:
+
+```latte
+click
```
@@ -302,7 +310,32 @@ What we have shown so far in this chapter will probably suffice. The following l
Requirement and Parameters
--------------------------
-The request handled by the presenter is the [api:Nette\Application\Request] object and is returned by the presenter's method `getRequest()`. It includes an array of parameters and each of them belongs either to some of the components or directly to the presenter (which is actually also a component, albeit a special one). So Nette redistributes the parameters and passes between the individual components (and the presenter) by calling the method `loadState(array $params)`, which is further described in the chapter [Components]. The parameters can be obtained by the method `getParameters(): array`, individually using `getParameter($name)`. Parameter values are strings or arrays of strings, they are basically raw data obtained directly from a URL.
+The request handled by the presenter is the [api:Nette\Application\Request] object and is returned by the presenter's method `getRequest()`. It includes an array of parameters and each of them belongs either to some of the components or directly to the presenter (which is actually also a component, albeit a special one). So Nette redistributes the parameters and passes between the individual components (and the presenter) by calling the method `loadState(array $params)`. The parameters can be obtained by the method `getParameters(): array`, individually using `getParameter($name)`. Parameter values are strings or arrays of strings, they are basically raw data obtained directly from a URL.
+
+
+Validation of Persistent Parameters
+-----------------------------------
+
+The values of [#persistent parameters] received from URLs are written to properties by the `loadState()` method. It also checks if the data type specified in the property matches, otherwise it will respond with a 404 error and the page will not be displayed.
+
+Never blindly trust persistent parameters, as they can easily be overwritten by the user in the URL. For example, this is how we check if `$this->lang` is among the supported languages. A good way to do this is to override the `loadState()` method mentioned above:
+
+```php
+class ProductPresenter extends Nette\Application\UI\Presenter
+{
+ #[Persistent]
+ public string $lang;
+
+ public function loadState(array $params): void
+ {
+ parent::loadState($params); // here is set the $this->lang
+ // follows the user value check:
+ if (!in_array($this->lang, ['en', 'cs'])) {
+ $this->error();
+ }
+ }
+}
+```
Save and Restore the Request
diff --git a/application/en/routing.texy b/application/en/routing.texy
index 55df69e79f..bb30283d14 100644
--- a/application/en/routing.texy
+++ b/application/en/routing.texy
@@ -93,12 +93,12 @@ The route will now accept the URL `https://any-domain.com/chronicle/`, which wil
Of course, the name of the presenter and the action can also be a parameter. For example:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
This route accepts, for example, a URL in the form `/article/edit` resp. `/catalog/list` and translates them to presenters and actions `Article:edit` resp. `Catalog:list`.
-It also gives to parameters `presenter` and `action` default values `Homepage` and `default` and therefore they are optional. So the route also accepts a URL `/article` and translates it as `Article:default`. Or vice versa, a link to `Product:default` generates a path `/product`, a link to the default `Homepage:default` generates a path `/`.
+It also gives to parameters `presenter` and `action` default values `Home` and `default` and therefore they are optional. So the route also accepts a URL `/article` and translates it as `Article:default`. Or vice versa, a link to `Product:default` generates a path `/product`, a link to the default `Home:default` generates a path `/`.
The mask can describe not only the relative path based on the site root, but also the absolute path when it begins with a slash, or even the entire absolute URL when it begins with two slashes:
@@ -160,7 +160,7 @@ Sequences may be freely nested and combined:
```php
$router->addRoute(
'[[-]/][/page-]',
- 'Homepage:default',
+ 'Home:default',
);
// Accepted URLs:
@@ -183,16 +183,16 @@ $router->addRoute('[!.html]', /* ... */);
Optional parameters (ie. parameters having default value) without square brackets do behave as if wrapped like this:
```php
-$router->addRoute('//', /* ... */);
+$router->addRoute('//', /* ... */);
// equals to:
-$router->addRoute('[/[/[]]]', /* ... */);
+$router->addRoute('[/[/[]]]', /* ... */);
```
-To change how the rightmost slash is generated, i.e. instead of `/homepage/` get a `/homepage`, adjust the route this way:
+To change how the rightmost slash is generated, i.e. instead of `/home/` get a `/home`, adjust the route this way:
```php
-$router->addRoute('[[/[/]]]', /* ... */);
+$router->addRoute('[[/[/]]]', /* ... */);
```
@@ -220,7 +220,7 @@ The second parameter of the route, which we often write in the format `Presenter
```php
$router->addRoute('/[/]', [
- 'presenter' => 'Homepage',
+ 'presenter' => 'Home',
'action' => 'default',
]);
```
@@ -232,7 +232,7 @@ use Nette\Routing\Route;
$router->addRoute('/[/]', [
'presenter' => [
- Route::Value => 'Homepage',
+ Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
@@ -252,7 +252,7 @@ Filters and Translations
It's a good practice to write source code in English, but what if you need your website to have translated URL to different language? Simple routes such as:
```php
-$router->addRoute('/', 'Homepage:default');
+$router->addRoute('/', 'Home:default');
```
will generate English URLs, such as `/product/123` or `/cart`. If we want to have presenters and actions in the URL translated to Deutsch (e.g. `/produkt/123` or `/einkaufswagen`), we can use a translation dictionary. To add it, we already need a "more talkative" variant of the second parameter:
@@ -262,7 +262,7 @@ use Nette\Routing\Route;
$router->addRoute('