diff --git a/application/bg/how-it-works.texy b/application/bg/how-it-works.texy
index 3cdb0786e2..5ca8332a47 100644
--- a/application/bg/how-it-works.texy
+++ b/application/bg/how-it-works.texy
@@ -22,13 +22,13 @@
/--pre
web-project/
├── app/ ← каталог с приложением
-│ ├── Presenters/ ← классы презентеров
-│ │ ├── HomePresenter.php ← Класс презентера главной страницы
-│ │ └── templates/ ← директория шаблонов
-│ │ ├── @layout.latte ← шаблон общего макета
-│ │ └── Home/ ← шаблоны презентера главной страницы
-│ │ └── default.latte ← шаблон действия `default`
-│ ├── Router/ ← конфигурация URL-адресов
+│ ├── Основни/ ← основни необходими класове
+│ │ └── RouterFactory.php ← конфигуриране на URL адреси
+│ ├── UI/ ← презентатори, шаблони и др.
+│ │ ├── @layout.latte ← шаблон на споделено оформление
+│ │ └── Home/ ← Директория за водещи
+│ │ ├── HomePresenter.php ← Клас на Home Presenter
+│ │ └── default.latte ← шаблон за действие default
│ └── Bootstrap.php ← загрузочный класс Bootstrap
├── bin/ ← скрипты командной строки
├── config/ ← файлы конфигурации
@@ -91,7 +91,7 @@ Nette е наставник, който ви напътства да пишет
Приложението започва с искане към т.нар. маршрутизатор да реши на кой от презентаторите да изпрати текущата заявка за обработка. Маршрутизаторът решава чия е отговорността. Той разглежда входния URL адрес `https://example.com/product/123`, който иска продукт `показать` с `id: 123` като действие. Добър навик е да записвате двойките водещ + действие, разделени с двоеточие: `Продукт:показать`.
-Следователно маршрутизаторът е преобразувал URL адреса в двойка `Presenter:action` + параметри, в нашия случай `Product:show` + `id`: 123`. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Router/RouterFactory.php`, и ще го опишем подробно в главата [Маршрутизация |routing].
+Следователно маршрутизаторът е преобразувал URL адреса в двойка `Presenter:action` + параметри, в нашия случай `Product:show` + `id`: 123`. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Core/RouterFactory.php`, и ще го опишем подробно в главата [Маршрутизация |routing].
Да продължим. Приложението вече знае името на водещия и може да продължи. Чрез създаване на обект `ProductPresenter`, който е кодът на предентера `Product`. По-точно, той иска от контейнера DI да създаде презентатора, тъй като създаването на обекти е негова работа.
@@ -121,12 +121,9 @@ class ProductPresenter extends Nette\Application\UI\Presenter
След това водещият връща отговор. Това може да бъде HTML страница, изображение, XML документ, файл, изпратен от диска, JSON или пренасочване към друга страница. Важно е да се отбележи, че ако не посочим изрично как да се отговори (какъвто е случаят с `ProductPresenter`), отговорът ще бъде шаблон, показващ HTML страница. Защо? Ами защото в 99% от случаите искаме да покажем шаблон, водещият приема това поведение по подразбиране и иска да улесни работата ни. Това е гледната точка на Нете.
-Дори не е необходимо да указваме кой шаблон да се покаже, той сам извежда пътя до него според проста логика. В случая с водещия `Product` и действието `show`, той се опитва да провери дали някой от тези файлове с шаблони съществува спрямо директорията, в която се намира класът `ProductPresenter`:
+Дори не е необходимо да посочваме кой шаблон да се визуализира; рамката сама ще определи пътя. В случая с действието `show` тя просто се опитва да зареди шаблона `show.latte` в директорията с класа `ProductPresenter`. Тя също така се опитва да намери оформлението във файла `@layout.latte` (повече за [търсенето на шаблони |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-След това се показва шаблонът. Задачата на водещия и на цялото приложение вече е изпълнена. Ако шаблонът не съществува, ще бъде върната страница за грешка 404. Можете да прочетете повече за водещите на страницата [Водещи |presenters].
+Впоследствие шаблоните се визуализират. С това задачата на презентатора и на цялото приложение е изпълнена и работата е приключила. Ако шаблонът не съществува, ще бъде върната страница с грешка 404. Можете да прочетете повече за презентаторите на страницата [Презентатори |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ class ProductPresenter extends Nette\Application\UI\Presenter
3) маршрутизаторът декодира URL адреса като двойка `Home:default`
4) обектът е създаден `HomePresenter`
5) извиква се методът `renderDefault()` (ако съществува)
-6) шаблонът `templates/Home/default.latte` с оформлението `templates/@layout.latte` се визуализира
+6) шаблонът `default.latte` с оформлението `@layout.latte` се визуализира
Може би сега ще се сблъскате с много нови концепции, но ние смятаме, че те имат смисъл. Създаването на приложения в Nette е лесно.
diff --git a/application/bg/modules.texy b/application/bg/modules.texy
index ddecd3f1a8..1a78307330 100644
--- a/application/bg/modules.texy
+++ b/application/bg/modules.texy
@@ -2,29 +2,31 @@
******
.[perex]
-В Nette модулите са логическите единици, от които се състои едно приложение. Те включват главни модули, шаблони, евентуално компоненти и класове модели.
+Модулите внасят яснота в приложенията на Nette, като улесняват лесното им разделяне на логически единици.
-Един компонент за презентатори и един за шаблони няма да са достатъчни за реални проекти. Натрупването на десетки файлове в една папка е меко казано неорганизирано. Как да излезем от тази ситуация? Просто ги разделяме на поддиректории на диска и на пространства от имена в кода. Точно това правят модулите Nette.
-
-Така че нека забравим за една папка за презентатори и шаблони и вместо това да създадем модули като `Admin` и `Front`.
+Подобно на организирането на файловете в папки на твърдия диск, в Nette можем да разделим презентатори, шаблони и други спомагателни класове на модули. Как работи това на практика? Просто чрез включване на нови поддиректории в структурата. Ето един пример за структура с два модула - Front и Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← директория с модулями
-│ ├── Admin/ ← модуль Admin
-│ │ ├── Presenters/ ← его презентеры
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← модуль Front
-│ └── Presenters/ ← его презентеры
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Тази структура на директориите ще бъде отразена в пространствата за имена на класовете, така че например `DashboardPresenter` ще бъде в пространството `App\Modules\Admin\Presenters`:
+Тази структура на директориите е отразена в пространствата от имена на класовете, така че например `DashboardPresenter` се намира в пространството от имена `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Главното устройство `Dashboard` в модула `Admin` се обозначава в приложението с помощта на запис с двойна точка като `Admin:Dashboard`, а неговото действие `default` се обозначава като `Admin:Dashboard:default`.
-И откъде Nette знае, че `Admin:Dashboard` представлява класа `App\Modules\Admin\Presenters\DashboardPresenter`? Говорим за това, като използваме [картографирането |#Mapping] в конфигурацията.
-Така че дадената структура не е фиксирана и можете да я променяте по свое усмотрение.
+В приложението се позоваваме на презентатора `Dashboard` в рамките на модула `Admin`, като използваме запис с двоеточие като `Admin:Dashboard`. За неговото действие `default` го наричаме `Admin:Dashboard:default`.
-Модулите, разбира се, могат да съдържат всички други части, освен презентатори и шаблони, като компоненти, класове модели и др.
+Представената структура не е твърда; в конфигурацията можете [напълно |#mapping] да [я адаптирате към вашите нужди |#mapping]. .[tip]
+
+Модулите могат да включват всички други файлове, като компоненти и спомагателни класове, в допълнение към презентаторите и шаблоните. Ако обмисляте къде да ги поставите, помислете за използването на папка `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Вложени модули .[#toc-nested-modules]
-------------------------------------
-Модулите не трябва да образуват само плоска структура, можете да създавате и подмодули, например:
+Модулите могат да имат няколко нива на влагане, подобно на структурата на директориите на диска:
/--pre
-app/
-├── Modules/ ← директория с модулями
-│ ├── Blog/ ← модуль Blog
-│ │ ├── Admin/ ← подмодуль Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← подмодуль Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← модуль Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Така модулът `Blog` се разделя на подмодули `Admin` и `Front`. Това отново ще бъде отразено в пространствата от имена, които ще бъдат `App\Modules\Blog\Admin\Presenters` и т.н. Главният модул `Dashboard` в рамките на подмодула се нарича `Blog:Admin:Dashboard`.
+Модулът `Blog` е разделен на подмодули `Admin` и `Front`. Това е отразено и в пространствата от имена, които след това се появяват като `App\UI\Blog\Admin` и по подобен начин. За да се позовем на презентатора `Dashboard` в рамките на подмодула `Admin`, го наричаме `Blog:Admin:Dashboard`.
-Разклоненията могат да бъдат толкова дълбоки, колкото искате, така че можете да създавате подмодули.
+Влагането може да бъде толкова дълбоко, колкото е необходимо, като позволява създаването на подмодули.
+
+Например, ако в администрацията имате много презентатори, свързани с управлението на поръчки, като `OrderDetail`, `OrderEdit`, `OrderDispatch` и т.н., може да създадете модул `Order`, в който ще бъдат организирани презентатори като `Detail`, `Edit`, `Dispatch` и други.
Създаване на връзки .[#toc-creating-links]
@@ -102,46 +118,59 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
Картографиране .[#toc-mapping]
------------------------------
-Определя правилата, по които името на класа се извежда от главното име. Записваме ги в [конфигурацията |configuration] под ключа `application › mapping`.
+Съпоставянето определя правилата за извеждане на името на класа от името на водещия. Тези правила се посочват в [конфигурацията |configuration] под ключа `application › mapping`.
-Нека започнем с пример, при който не се използват модули. Искаме само главните класове да имат пространството от имена `App\Presenters`. Това означава, че искаме главното име, например `Home`, да се съпостави с класа `App\Presenters\HomePresenter`. Това може да се постигне със следната конфигурация:
+Всички примери в тази глава се основават на следната конфигурация за картографиране:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Името на водещия се заменя със звездичка и резултатът е името на класа. Лесно!
+За по-добро разбиране нека първо разгледаме приложение без модули. Искаме класовете на презентатора да попадат в пространството от имена `App\UI`. За да съпоставим презентатора `Home` с класа `App\UI\HomePresenter`, постигаме това със следната конфигурация:
-Ако разделим презентаторите на модули, можем да използваме различни карти за всеки модул:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Това съпоставяне се извършва чрез замяна на звездичката в маската `App\UI\*Presenter` с името на презентатора `Home`, в резултат на което се получава крайното име на класа `App\UI\HomePresenter`. Просто!
+
+Въпреки това, както можете да видите в примерите в тази и други глави, ние поставяме класовете на водещите в едноименни поддиректории, например водещият `Home` е картографиран към клас `App\UI\Home\HomePresenter`. Това се постига чрез удвояване на звездичката (изисква Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Сега нека преминем към картографиране на презентатори в модули. Можем да дефинираме специфични съпоставки за всеки модул:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Сега водещият `Front:Home` е определен от класа `App\Modules\Front\HomePresenter`, а презентер `Admin:Dashboard` - `App\AdminModule\DashboardPresenter`.
+Според тази конфигурация презентаторът `Front:Home` се съотнася към класа `App\UI\Front\Home\HomePresenter`, а презентаторът `Api:OAuth` се съотнася към класа `App\Api\OAuthPresenter`.
-Би било по-удобно да се създаде общо правило (звездичка), което да замени първите две правила, и да се добави допълнителна звездичка само за модула:
+Тъй като модулите `Front` и `Admin` имат сходен подход на картографиране и вероятно има повече такива модули, е възможно да се създаде общо правило, което да ги замени. Към маската на класа се добавя нова звездичка за модула:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Но какво става, ако използваме няколко вложени модула и имаме например главен модул `Admin:User:Edit`? В този случай сегментът със звездичка, представляващ модула за всяко ниво, просто ще се повтори и резултатът ще бъде класът `App\Modules\Admin\User\Presenters\EditPresenter`.
+За вложени модули на няколко нива, като например водещия `Admin:User:Edit`, сегментът със звездичка се повтаря за всяко ниво, в резултат на което се получава клас `App\UI\Admin\User\Edit\EditPresenter`.
-Алтернативен начин за записване е използването на масив от три сегмента вместо низ. Този запис е еквивалентен на предишния:
+Алтернативен запис е да се използва масив, съставен от три сегмента, вместо низ. Този запис е еквивалентен на предишния:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Стойността по подразбиране е `*Module\*Presenter`.
diff --git a/application/bg/templates.texy b/application/bg/templates.texy
index 850d3e2ecd..584b6cbff3 100644
--- a/application/bg/templates.texy
+++ b/application/bg/templates.texy
@@ -34,35 +34,81 @@ Nette използва системата за шаблони [Latte |latte:]. L
Той дефинира блок `content`, който се вмъква вместо `{include content}` в оформлението, и замества блока `title`, който презаписва `{block title}` в оформлението. Опитайте се да си представите резултата.
-Търсене на шаблони .[#toc-search-for-templates]
------------------------------------------------
+Търсене на шаблони .[#toc-template-lookup]
+------------------------------------------
+
+В презентаторите не е необходимо да посочвате кой шаблон трябва да бъде визуализиран; рамката автоматично ще определи пътя, което ще ви улесни при кодирането.
+
+Ако използвате структура от директории, в която всеки презентатор има своя собствена директория, просто поставете шаблона в тази директория под името на действието (т.е. изглед). Например, за действието `default` използвайте шаблона `default.latte`:
-Пътят към шаблоните се определя от главния модул с помощта на проста логика. Той ще се опита да провери дали има някой от тези файлове, разположен спрямо главната директория на класа, където `` е името на текущия главен модул, а `` е името на текущото събитие:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Ако използвате структура, в която презентаторите са заедно в една директория, а шаблоните - в папка `templates`, запишете я или във файл `..latte` или `/.latte`:
-Ако шаблонът не бъде намерен, ще се опита да търси в директорията `templates` едно ниво по-нагоре, т.е. на същото ниво като директорията с класа на водещия.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Ако шаблонът не бъде намерен и там, отговорът ще бъде [грешка 404 |presenters#Error 404 etc.].
+Директорията `templates` може да бъде поставена и едно ниво по-нагоре, на същото ниво като директорията с класовете на водещите.
-Можете също така да промените изгледа с помощта на `$this->setView('jineView')`. Или вместо да търсите директно, посочете името на файла с шаблона, като използвате `$this->template->setFile('/path/to/template.latte')`.
+Ако шаблонът не бъде намерен, презентаторът отговаря с [грешка 404 - страница не е намерена |presenters#Error 404 etc].
+
+Можете да промените изгледа, като използвате `$this->setView('anotherView')`. Възможно е също така директно да посочите файла с шаблона с помощта на `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Файловете, които се търсят за шаблони, могат да се променят чрез наслагване на метода [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], който връща масив от възможни имена на файлове.
+Файловете, в които се търсят шаблони, могат да се променят чрез надграждане на метода [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], който връща масив от възможни имена на файлове.
+
+
+Търсене на шаблони за оформление .[#toc-layout-template-lookup]
+---------------------------------------------------------------
+
+Nette също така автоматично търси файла с оформлението.
+
+Ако използвате структура на директориите, в която всеки водещ има своя собствена директория, поставете макета или в папката с водещия, ако е специфичен само за него, или на по-високо ниво, ако е общ за няколко водещи:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Ако използвате структура, в която презентаторите са групирани в една директория, а шаблоните са в папка `templates`, макетът ще се очаква на следните места:
-В тези файлове се очаква оформление:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` Разположение, общо за няколко високоговорителя
+Ако презентаторът е в [модул |modules], той ще търси и по-нагоре в дървото на директориите според вложеността на модула.
-Къде: `` е името на текущия водещ, а `` е името на оформлението, което по подразбиране е `'layout'`. Името може да бъде променено с помощта на `$this->setLayout('jinyLayout')`, така че ще бъдат изпробвани файлове `@jinyLayout.latte`.
+Името на макета може да бъде променено с помощта на `$this->setLayout('layoutAdmin')` и тогава то ще бъде очаквано във файла `@layoutAdmin.latte`. Можете също така директно да посочите файла с шаблона на оформлението, като използвате `$this->setLayout('/path/to/template.latte')`.
-Можете също така директно да посочите името на файла на шаблона за оформление, като използвате `$this->setLayout('/path/to/template.latte')`. Използването на `$this->setLayout(false)` деактивира проследяването на оформлението.
+Използването на `$this->setLayout(false)` или на тага `{layout none}` вътре в шаблона деактивира търсенето на оформление.
.[note]
-Файловете, в които се търсят шаблоните за оформление, могат да се променят чрез наслагване на метода [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], който връща масив от възможни имена на файлове.
+Файловете, в които се търсят шаблони за оформление, могат да бъдат променяни чрез надграждане на метода [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], който връща масив от възможни имена на файлове.
Променливи в шаблона .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template
Можете също така да си позволите лукса да шепнете в шаблоните, просто инсталирайте плъгина Latte в PhpStorm и поставете името на класа в началото на шаблона, за повече информация вижте статията "Latte: как да въведем системата":https://blog.nette.org/bg/latte-kak-da-izpolzvame-sistemata-ot-tipove:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Версия 3 на Latte предлага по-усъвършенстван начин за създаване на [разширение за |latte:creating-extension] всеки уеб проект. Ето кратък пример за такъв клас:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ final class LatteExtension extends Latte\Extension
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/cs/how-it-works.texy b/application/cs/how-it-works.texy
index 92ff5e9d9b..d58cd6c833 100644
--- a/application/cs/how-it-works.texy
+++ b/application/cs/how-it-works.texy
@@ -22,13 +22,13 @@ Adresářová struktura vypadá nějak takto:
/--pre
web-project/
├── app/ ← adresář s aplikací
-│ ├── Presenters/ ← presentery a šablony
-│ │ ├── HomePresenter.php ← třída presenteru Home
-│ │ └── templates/ ← adresář se šablonami
-│ │ ├── @layout.latte ← šablona layoutu
-│ │ └── Home/ ← šablony presenteru Home
-│ │ └── default.latte ← šablona akce 'default'
-│ ├── Router/ ← konfigurace URL adres
+│ ├── Core/ ← základní třídy nutné pro chod
+│ │ └── RouterFactory.php ← konfigurace URL adres
+│ ├── UI/ ← presentery, šablony & spol.
+│ │ ├── @layout.latte ← šablona layoutu
+│ │ └── Home/ ← adresář presenteru Home
+│ │ ├── HomePresenter.php ← třída presenteru Home
+│ │ └── default.latte ← šablona akce default
│ └── Bootstrap.php ← zaváděcí třída Bootstrap
├── bin/ ← skripty spouštěné z příkazové řádky
├── config/ ← konfigurační soubory
@@ -91,7 +91,7 @@ Aplikace psané v Nette se člení do spousty tzv. presenterů (v jiných framew
Application začne tím, že požádá tzv. router, aby rozhodl, kterému z presenterů předat aktuální požadavek k vyřízení. Router rozhodne, čí je to zodpovědnost. Podívá se na vstupní URL `https://example.com/product/123` a na základě toho, jak je nastavený, rozhodne, že tohle je práce např. pro **presenter** `Product`, po kterém bude chtít jako **akci** zobrazení (`show`) produktu s `id: 123`. Dvojici presenter + akce je dobrým zvykem zapisovat oddělené dvojtečkou jako `Product:show`.
-Tedy router transformoval URL na dvojici `Presenter:action` + parametry, v našem případě `Product:show` + `id: 123`. Jak takový router vypadá se můžete podívat v souboru `app/Router/RouterFactory.php` a podrobně ho popisujeme v kapitole [Routing].
+Tedy router transformoval URL na dvojici `Presenter:action` + parametry, v našem případě `Product:show` + `id: 123`. Jak takový router vypadá se můžete podívat v souboru `app/Core/RouterFactory.php` a podrobně ho popisujeme v kapitole [Routing].
Pojďme dál. Application už zná jméno presenteru a může pokračovat dál. Tím že vyrobí objekt třídy `ProductPresenter`, což je kód presenteru `Product`. Přesněji řečeno, požádá DI kontejner, aby presenter vyrobil, protože od vyrábění je tu on.
@@ -121,12 +121,9 @@ Takže, zavolala se metoda `renderShow(123)`, jejíž kód je sice smyšlený p
Následně presenter vrátí odpověď. Tou může být HTML stránka, obrázek, XML dokument, odeslání souboru z disku, JSON nebo třeba přesměrování na jinou stránku. Důležité je, že pokud explicitně neřekneme, jak má odpovědět (což je případ `ProductPresenter`), bude odpovědí vykreslení šablony s HTML stránkou. Proč? Protože v 99 % případů chceme vykreslit šablonu, tudíž presenter tohle chování bere jako výchozí a chce nám ulehčit práci. To je smyslem Nette.
-Nemusíme ani uvádět, jakou šablonu vykreslit, cestu k ní si odvodí podle jednoduché logiky. V případě presenteru `Product` a akce `show` zkusí, zda existuje jeden z těchto souborů se šablonou uložených relativně od adresáře s třídou `ProductPresenter`:
+Nemusíme ani uvádět, jakou šablonu vykreslit, cestu k ní si odvodí sám. V případě akce `show` jednodušše zkusí načíst šablonu `show.latte` v adresáři s třídou `ProductPresenter`. Taktéž se pokusí dohledat layout v souboru `@layout.latte` (podrobněji o [dohledávání šablon|templates#hledani-sablon]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Taktéž se pokusí dohledat layout v souboru `@layout.latte` a následně šablonu vykreslí. Tím je úkol presenteru i celé aplikace dokonán a dílo jest završeno. Pokud by šablona neexistovala, vrátí se stránka s chybou 404. Více se o presenterech dočtete na stránce [Presentery|presenters].
+A následně šablony vykreslí. Tím je úkol presenteru i celé aplikace dokonán a dílo jest završeno. Pokud by šablona neexistovala, vrátí se stránka s chybou 404. Více se o presenterech dočtete na stránce [Presentery|presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Pro jistotu, zkusme si zrekapitulovat celý proces s trošku jinou URL:
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/Home/default.latte` s layoutem např. `templates/@layout.latte`
+6) vykreslí se šablona např. `default.latte` s layoutem např. `@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 dd58b910d4..505e039ae3 100644
--- a/application/cs/modules.texy
+++ b/application/cs/modules.texy
@@ -2,29 +2,31 @@ Moduly
******
.[perex]
-Moduly představují v Nette logické celky, ze kterých se aplikace skládá. Jejich součástí jsou presentery, šablony, případně i komponenty a modelové třídy.
+Moduly vnášejí do Nette aplikací přehlednost díky snadnému členění do logických celků.
-S jednou složkou pro presentery a jednou pro šablony bychom si u reálných projektů nevystačili. Mít v jedné složce desítky souborů je minimálně nepřehledné. Jak z toho ven? Jednoduše je na disku rozdělíme do podadresářů a v kódu do jmenných prostorů. A přesně to jsou v Nette moduly.
-
-Zapomeňme tedy na jednu složku pro presentery a šablony a místo toho vytvoříme moduly, například `Admin` a `Front`.
+Podobně jako na pevném disku organizujeme soubory do jednotlivých složek, tak i v Nette můžeme presentery, šablony a další pomocné třídy rozdělovat do modulů. Jak to funguje v praxi? Jednoduše začleníme do struktury nové podadresáře. Příklad takové struktury se dvěma moduly Front a Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← adresář s moduly
+app/
+├── UI/
│ ├── Admin/ ← modul Admin
-│ │ ├── Presenters/ ← jeho presentery
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← modul Front
-│ └── Presenters/ ← jeho presentery
-│ └── ...
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← modul Front
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Tuto adresářovou strukturu budou reflektovat jmenné prostory tříd, takže třeba `DashboardPresenter` bude v prostoru `App\Modules\Admin\Presenters`:
+Tato adresářová struktura se odráží ve jmenných prostorech tříd, takže například `DashboardPresenter` se nachází ve jmenném prostoru `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Na presenter `Dashboard` uvnitř modulu `Admin` se v rámci aplikace odkazujeme pomocí dvojtečkové notace jako na `Admin:Dashboard`, na jeho akci `default` potom jako na `Admin:Dashboard:default`.
-A jak Nette vlastní ví, že `Admin:Dashboard` představuje třídu `App\Modules\Admin\Presenters\DashboardPresenter`? To mu řekneme pomocí [#mapování] v konfiguraci.
-Tedy uvedená struktura není pevná a můžete si ji upravit podle potřeb.
+Na presenter `Dashboard` uvnitř modulu `Admin` odkazujeme v aplikaci pomocí dvojtečkové notace jako na `Admin:Dashboard`. Na jeho akci `default` potom jako na `Admin:Dashboard:default`.
-Moduly mohou kromě presenterů a šablon samozřejmě obsahovat všechny další součásti, jako jsou třeba komponenty, modelové třídy, atd.
+Představená struktura není pevná; můžete si ji zcela [přizpůsobit dle svých potřeb|#mapování] v konfiguraci. .[tip]
+
+Moduly mohou kromě presenterů a šablon samozřejmě zahrnovat všechny ostatní soubory, jako jsou například komponenty a pomocné třídy. Pokud uvažujete, kam je zařadit, zvažte využití složky `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Vnořené moduly
--------------
-Moduly nemusí tvořit jen plochou strukturu, lze vytvářet i submoduly, například:
+Moduly mohou mít více úrovní zanoření, podobně jako adresářová struktura na disku:
/--pre
-app/
-├── Modules/ ← adresář s moduly
+app/
+├── UI/
│ ├── Blog/ ← modul Blog
│ │ ├── Admin/ ← submodul Admin
-│ │ │ ├── Presenters/
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← submodul Front
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodul Front
-│ │ ├── Presenters/
-│ │ └── ...
│ ├── Forum/ ← modul Forum
│ │ └── ...
\--
-Tedy modul `Blog` je rozdělen do submodulů `Admin` a `Front`. A opět se to odrazí na jmenných prostorech, které budou `App\Modules\Blog\Admin\Presenters` apod. Na presenter `Dashboard` uvnitř submodulu se odkazujeme jako `Blog:Admin:Dashboard`.
+Modul `Blog` je rozdělen na submoduly `Admin` a `Front`. To se projeví i ve jmenných prostorech, které pak budou vypadat jako `App\UI\Blog\Admin` a podobně. Na presenter `Dashboard` v rámci submodulu odkazujeme jako na `Blog:Admin:Dashboard`.
-Zanořování může pokračovat libovolně hluboko, lze tedy vytvářet sub-submoduly.
+Zanoření může být libovolně hluboké, což umožňuje vytvářet sub-submoduly.
+
+Pokud například v administraci máte mnoho presenterů týkajících se správy objednávek, jako jsou `OrderDetail`, `OrderEdit`, `OrderDispatch` atd., můžete pro lepší organizovanost vytvořit modul `Order`, ve kterém budou presentery `Detail`, `Edit`, `Dispatch` a další.
Vytváření odkazů
@@ -102,46 +118,59 @@ Viz [kapitola o routování |routing#Moduly].
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`.
+Mapování definuje pravidla pro odvozování názvu třídy z názvu presenteru. Specifikujeme 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 `Home` mapoval na třídu `App\Presenters\HomePresenter`. Toho lze docílit následující konfigurací:
+Všechny příklady v této kapitole vycházejí z následujícího mapování:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Název presenteru se nahradí za hvezdičku v masce třídy a výsledkem je název třídy. Snadné!
+Pro lepší pochopení si nejprve představíme aplikaci bez modulů. Chceme, aby třídy presenterů spadaly do jmenného prostoru `App\UI`. Aby se presenter `Home` mapoval na třídu `App\UI\HomePresenter`, což dosáhneme touto konfigurací:
-Pokud presentery členíme do modulů, můžeme pro každý modul mít vlastní mapování:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Mapování funguje tak, že název presenteru `Home` nahradí hvězdičku v masce `App\UI\*Presenter`, čímž získáme výsledný název třídy `App\UI\HomePresenter`. Jednoduché!
+
+Jak ale vidíte v ukázkách v této a dalších kapitolách, třídy presenterů umisťujeme do eponymních podadresářů, například presenter `Home` se mapuje na třídu `App\UI\Home\HomePresenter`. Toho dosáhneme zdvojením dvojtečky (vyžaduje Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Nyní přistoupíme k mapování presenterů do modulů. Pro každý modul můžeme definovat specifické mapování:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-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`.
+Podle této konfigurace se presenter `Front:Home` mapuje na třídu `App\UI\Front\Home\HomePresenter`, zatímco presenter `Api:OAuth` na třídu `App\Api\OAuthPresenter`.
-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:
+Protože moduly `Front` i `Admin` mají podobný způsob mapování a takových modulů bude nejspíš více, je možné vytvořit obecné pravidlo, které je nahradí. Do masky třídy tak přibude nová hvězdička pro modul:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Ale co když používáme vícenásobně zanořené moduly a máme třeba presenter `Admin:User:Edit`? V takovém případě se segment s hvězdičkou představující modul pro každou úroveň jednoduše zopakuje a výsledkem bude třída `App\Modules\Admin\User\Presenters\EditPresenter`.
+Pro vícenásobně zanořené moduly, jako je například presenter `Admin:User:Edit`, se segment s hvězdičkou opakuje pro každou úroveň a výsledkem je třída `App\UI\Admin\User\Edit\EditPresenter`.
Alternativním zápisem je místo řetězce použít pole skládající se ze tří segmentů. Tento zápis je ekvivaletní s předchozím:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Výchozí hodnotou je `*Module\*Presenter`.
diff --git a/application/cs/templates.texy b/application/cs/templates.texy
index 5d0de8dc1a..8caa687b44 100644
--- a/application/cs/templates.texy
+++ b/application/cs/templates.texy
@@ -37,29 +37,75 @@ Ta definuje blok `content`, který se vloží na místo `{include content}` v la
Hledání šablon
--------------
-Cestu k šablonám odvodí presenter podle jednoduché logiky. Zkusí, zda existuje jeden z těchto souborů umístěných relativně od adresáře s třídou presenteru, kde `` je název aktuálního presenteru a `` je název aktuální akce:
+Nemusíte v presenterech uvádět, jaká šablona se má vykreslit, framework cestu odvodí sám a ušetří vám psaní.
-- `templates//.latte`
-- `templates/..latte`
+Pokud používáte adresářovou strukturu, kde každý presenter má vlastní adresář, jednodušše umístěte šablonu do tohoto adresáře pod jménem akce (resp. view), tj. pro akci `default` použijte šablonu `default.latte`:
-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.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Pokud ani tam šablonu nenajde, je odpovědí [chyba 404|presenters#Chyba 404 a spol.].
+Pokud používáte strukturu, kde jsou společně presentery v jednom adresáři a šablony ve složce `templates`, uložte ji buď do souboru `..latte` nebo `/.latte`:
-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')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1. varianta
+ └── Home/
+ └── default.latte ← 2. varianta
+\--
+
+Adresář `templates` může být umístěn také o úroveň výš, tj. na stejné úrovni, jako je adresář s třídami presenterů.
+
+Pokud se šablona nenajde, presenter odpoví [chybou 404 - page not found|presenters#Chyba 404 a spol].
+
+View změníte pomocí `$this->setView('jineView')`. Také lze přímo určit soubor se šablonou pomocí `$this->template->setFile('/path/to/template.latte')`.
.[note]
Soubory, kde se dohledávají šablony, lze změnit překrytím metody [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], která vrací pole možných názvů souborů.
-Layout se očekává v těchto souborech:
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` layout společný pro více presenterů
+Hledání šablony layoutu
+-----------------------
+
+Nette také automaticky dohledává soubor s layoutem.
+
+Pokud používáte adresářovou strukturu, kde každý presenter má vlastní adresář, umístěte layout buď do složky s presenterem, pokud je specifický jen pro něj, nebo o úroveň výš, pokud je společný pro více presenterů:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← společný layout
+ └── Home/
+ ├── @layout.latte ← jen pro presenter Home
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Pokud používáte strukturu, kde jsou společně presentery v jednom adresáři a šablony ve složce `templates`, bude se layout očekávat na těchto místech:
+
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← společný layout
+ ├── Home.@layout.latte ← jen pro Home, 1. varianta
+ └── Home/
+ └── @layout.latte ← jen pro Home, 2. varianta
+\--
+
+Pokud se presenter nachází v [modulu|modules], bude se dohledávat i o další adresářové úrovně výš, podle zanoření modulu.
-Kde `` je název aktuálního presenteru a `` je název layoutu, což je standardně `'layout'`. Název lze změnit pomocí `$this->setLayout('jinyLayout')`, takže se budou zkoušet soubory `@jinyLayout.latte`.
+Název layoutu lze změnit pomocí `$this->setLayout('layoutAdmin')` a pak se bude očekávat v souboru `@layoutAdmin.latte`. Také lze přímo určit soubor se šablonou layoutu pomocí `$this->setLayout('/path/to/template.latte')`.
-Můžete také přímo určit jméno souboru se šablonou layoutu pomocí `$this->setLayout('/path/to/template.latte')`. Pomocí `$this->setLayout(false)` se dohledávání layoutu vypne.
+Pomocí `$this->setLayout(false)` nebo značky `{layout none}` uvnitř šablony se dohledávání layoutu vypne.
.[note]
Soubory, kde se dohledávají šablony layoutu, lze změnit překrytím metody [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], která vrací pole možných názvů souborů.
@@ -104,7 +150,7 @@ Anotace `@property-read` je určená pro IDE a statickou analýzu, díky ní bud
Luxusu našeptávání si můžete dopřát i v šablonách, stačí do PhpStorm nainstalovat plugin pro Latte a uvést na začátek šablony název třídy, více v článku "Latte: jak na typový systém":https://blog.nette.org/cs/latte-jak-na-typovy-system:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte ve verzi 3 nabízí pokročilejší způsob a to vytvoření si [extension |latte:creating-extension] pro každý webový projekt. Kusý příklad takové třídy:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Zaregistrujeme ji pomocí [konfigurace |configuration#Šablony Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/de/how-it-works.texy b/application/de/how-it-works.texy
index 010ba04907..fde1735364 100644
--- a/application/de/how-it-works.texy
+++ b/application/de/how-it-works.texy
@@ -22,13 +22,13 @@ Die Verzeichnisstruktur sieht in etwa so aus:
/--pre
web-project/
├── app/ ← Verzeichnis mit Anwendung
-│ ├── Presenters/ ← Presenter-Klassen
-│ │ ├── HomePresenter.php ← Home presenterklasse
-│ │ └── templates/ ← Vorlagenverzeichnis
-│ │ ├── @layout.latte ← Vorlage für gemeinsames Layout
-│ │ └── Home/ ← Vorlagen für Home-presenter
-│ │ └── default.latte ← Vorlage für Aktion `default`
-│ ├── Router/ ← Konfiguration von URL-Adressen
+│ ├── Core/ ← grundlegende notwendige Klassen
+│ │ └── RouterFactory.php ← Konfiguration der URL-Adressen
+│ ├── UI/ ← Moderatoren, Vorlagen & Co.
+│ │ ├── @layout.latte ← Vorlage für gemeinsames Layout
+│ │ └── Home/ ← Home Presenter Verzeichnis
+│ │ ├── HomePresenter.php ← Home Presenter Klasse
+│ │ └── default.latte ← Vorlage für Aktion default
│ └── Bootstrap.php ← bootende Klasse Bootstrap
├── bin/ ← Skripte für die Kommandozeile
├── config/ ← Konfigurationsdateien
@@ -91,7 +91,7 @@ In Nette geschriebene Anwendungen sind in viele so genannte Presenter unterteilt
Die Anwendung beginnt damit, dass sie den so genannten Router bittet, zu entscheiden, an welchen der Presenter die aktuelle Anfrage zur Bearbeitung weitergeleitet werden soll. Der Router entscheidet, wer dafür zuständig ist. Er sieht sich die Eingabe-URL `https://example.com/product/123` handelt, der ein Produkt mit `id: 123` als Aktion an `show` weiterleiten möchte. Es ist eine gute Angewohnheit, ein durch einen Doppelpunkt getrenntes Paar aus Präsentator + Aktion als `Product:show` zu schreiben.
-Der Router verwandelt also die URL in ein Paar `Presenter:action` + Parameter, in unserem Fall `Product:show` + `id: 123`. Sie können sehen, wie ein Router in der Datei `app/Router/RouterFactory.php` aussieht, und wir werden ihn im Kapitel [Routing] ausführlich beschreiben.
+Der Router verwandelt also die URL in ein Paar `Presenter:action` + Parameter, in unserem Fall `Product:show` + `id: 123`. Sie können sehen, wie ein Router in der Datei `app/Core/RouterFactory.php` aussieht, und wir werden ihn im Kapitel [Routing] ausführlich beschreiben.
Machen wir weiter. Die Anwendung kennt bereits den Namen des Präsentators und kann fortfahren. Sie erstellt ein Objekt `ProductPresenter`, das den Code des Presenters `Product` darstellt. Genauer gesagt, sie bittet den DI-Container um die Erstellung des Presenters, denn die Erstellung von Objekten ist seine Aufgabe.
@@ -121,12 +121,9 @@ So wurde die Methode `renderShow(123)` aufgerufen, deren Code ein fiktives Beisp
Anschließend gibt der Präsentator die Antwort zurück. Dies kann eine HTML-Seite, ein Bild, ein XML-Dokument, das Senden einer Datei von der Festplatte, JSON oder die Routing zu einer anderen Seite sein. Wichtig ist, dass, wenn wir nicht ausdrücklich sagen, wie zu antworten ist (was bei `ProductPresenter` der Fall ist), die Antwort darin besteht, die Vorlage mit einer HTML-Seite wiederzugeben. Und warum? Nun, weil wir in 99 % der Fälle eine Vorlage zeichnen wollen, so dass der Präsentator dieses Verhalten als Standard annimmt und uns die Arbeit erleichtern will. Das ist der Punkt von Nette.
-Wir müssen nicht einmal angeben, welche Vorlage gezeichnet werden soll, er leitet den Pfad dorthin nach einer einfachen Logik ab. Im Fall von presenter `Product` und action `show` versucht er zu sehen, ob eine dieser Vorlagendateien relativ zu dem Verzeichnis existiert, in dem sich die Klasse `ProductPresenter` befindet:
+Wir müssen nicht einmal angeben, welche Vorlage gerendert werden soll; das Framework wird den Pfad selbst ermitteln. Im Fall der Aktion `show` versucht es einfach, die Vorlage `show.latte` im Verzeichnis mit der Klasse `ProductPresenter` zu laden. Es versucht auch, das Layout in der Datei `@layout.latte` zu finden (mehr über die [Vorlagensuche |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Außerdem wird versucht, das Layout in der Datei `@layout.latte` zu finden, und dann wird die Vorlage gerendert. Nun ist die Aufgabe des Präsentators und der gesamten Anwendung abgeschlossen. Wenn die Vorlage nicht existiert, wird eine Seite mit dem Fehler 404 zurückgegeben. Weitere Informationen über Präsentatoren finden Sie auf der Seite [Präsentatoren |Presenters].
+Anschließend werden die Vorlagen gerendert. Damit ist die Aufgabe des Präsentators und der gesamten Anwendung abgeschlossen, und die Arbeit ist getan. Wenn die Vorlage nicht vorhanden wäre, würde eine 404-Fehlerseite zurückgegeben werden. Weitere Informationen über Präsentatoren finden Sie auf der Seite [Präsentatoren |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Um sicherzugehen, versuchen wir, den gesamten Prozess mit einer etwas anderen UR
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/Home/default.latte` mit einem Layout `templates/@layout.latte` wird gerendert
+6) eine Vorlage `default.latte` mit einem Layout `@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 090bd4702e..37b5f35f73 100644
--- a/application/de/modules.texy
+++ b/application/de/modules.texy
@@ -2,29 +2,31 @@ Module
******
.[perex]
-In Nette stellen Module die logischen Einheiten dar, aus denen eine Anwendung besteht. Sie umfassen Presenter, Templates, eventuell auch Komponenten und Modellklassen.
+Module bringen Klarheit in Nette-Anwendungen, indem sie eine einfache Unterteilung in logische Einheiten ermöglichen.
-Ein Verzeichnis für Presenter und eines für Templates würde für echte Projekte nicht ausreichen. Dutzende von Dateien in einem Ordner zu haben, ist zumindest unorganisiert. Wie kommt man da wieder raus? Wir teilen sie einfach in Unterverzeichnisse auf der Festplatte und in Namensräume im Code auf. Und das ist genau das, was die Nette-Module tun.
-
-Vergessen wir also einen einzigen Ordner für Präsentatoren und Vorlagen und erstellen wir stattdessen Module, zum Beispiel `Admin` und `Front`.
+Ähnlich wie bei der Organisation von Dateien in Ordnern auf einer Festplatte, können wir in Nette Presenter, Vorlagen und andere Hilfsklassen in Module unterteilen. Wie funktioniert das in der Praxis? Ganz einfach, indem man neue Unterverzeichnisse in die Struktur einfügt. Hier ist ein Beispiel für eine Struktur mit zwei Modulen, Front und Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← Verzeichnis mit Modulen
-│ ├── Admin/ ← Modul Admin
-│ │ ├── Presenters/ ← seine Presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← Modul Front
-│ └── Presenters/ ← seine Presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Diese Verzeichnisstruktur spiegelt sich in den Klassennamensräumen wider, so dass z. B. `DashboardPresenter` im Namensraum `App\Modules\Admin\Presenters` liegt:
+Diese Verzeichnisstruktur spiegelt sich in den Namespaces der Klassen wider, so befindet sich z.B. `DashboardPresenter` im Namespace `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Der Präsentator `Dashboard` innerhalb des Moduls `Admin` wird innerhalb der Anwendung mit der Doppelpunktschreibweise als `Admin:Dashboard` referenziert, und seine Aktion `default` als `Admin:Dashboard:default`.
-Und woher weiß Nette selbst, dass `Admin:Dashboard` die Klasse `App\Modules\Admin\Presenters\DashboardPresenter` repräsentiert? Dies wird durch ein [Mapping |#mapping] in der Konfiguration festgelegt.
-Die vorgegebene Struktur ist also nicht fest vorgegeben und kann nach Belieben verändert werden.
+In der Anwendung wird der Presenter `Dashboard` innerhalb des Moduls `Admin` mit Doppelpunkt als `Admin:Dashboard` bezeichnet. Für die Aktion `default` wird er als `Admin:Dashboard:default` bezeichnet.
-Module können neben Presentern und Templates natürlich auch alle anderen Elemente enthalten, wie z.B. Komponenten, Modellklassen, etc.
+Die vorgestellte Struktur ist nicht starr; Sie können [sie |#mapping] in der Konfiguration [vollständig an Ihre Bedürfnisse anpassen |#mapping]. .[tip]
+
+Module können neben Presentern und Vorlagen auch alle anderen Dateien, wie Komponenten und Hilfsklassen, enthalten. Wenn Sie überlegen, wo Sie diese ablegen wollen, sollten Sie einen Ordner `Accessory` verwenden:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Verschachtelte Module .[#toc-nested-modules]
--------------------------------------------
-Module müssen nicht nur eine flache Struktur bilden, Sie können auch Untermodule erstellen, zum Beispiel:
+Module können mehrere Verschachtelungsebenen haben, ähnlich wie eine Verzeichnisstruktur auf einer Festplatte:
/--pre
-app/
-├── Modules/ ← Verzeichnis mit Modulen
-│ ├── Blog/ ← Modul Blog
-│ │ ├── Admin/ ← Submodul Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← Submodul Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← Modul Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-So wird das Modul `Blog` in die Untermodule `Admin` und `Front` aufgeteilt. Dies spiegelt sich auch in den Namensräumen wider, die dann `App\Modules\Blog\Admin\Presenters` usw. lauten. Der Präsentator `Dashboard` innerhalb des Submoduls wird als `Blog:Admin:Dashboard` bezeichnet.
+Das Modul `Blog` ist in die Untermodule `Admin` und `Front` unterteilt. Dies spiegelt sich auch in den Namespaces wider, die dann als `App\UI\Blog\Admin` und ähnlich erscheinen. Um auf den Präsentator `Dashboard` innerhalb des Submoduls `Admin` zu verweisen, wird er als `Blog:Admin:Dashboard` bezeichnet.
-Die Verschachtelung kann beliebig tief gehen, so dass Sub-Submodule erstellt werden können.
+Die Verschachtelung kann so tief wie nötig sein und erlaubt die Erstellung von Sub-Submodulen.
+
+Wenn Sie zum Beispiel in der Verwaltung viele Präsentatoren haben, die mit der Auftragsverwaltung zusammenhängen, wie `OrderDetail`, `OrderEdit`, `OrderDispatch`, usw., könnten Sie ein `Order` Modul erstellen, in dem Präsentatoren wie `Detail`, `Edit`, `Dispatch` und andere organisiert werden.
Erstellen von Links .[#toc-creating-links]
@@ -99,49 +115,62 @@ Routing .[#toc-routing]
Siehe [Kapitel über Routing |routing#Modules].
-Abbildung .[#toc-mapping]
--------------------------
+Kartierung .[#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`.
+Mapping definiert die Regeln für die Ableitung des Klassennamens aus dem Presenter-Namen. Diese Regeln werden in der [Konfiguration |configuration] unter dem Schlüssel `application › mapping` angegeben.
-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:
+Alle Beispiele in diesem Kapitel basieren auf der folgenden Mapping-Konfiguration:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Der Name des Presenters wird durch das Sternchen in der Klassenmaske ersetzt und das Ergebnis ist der Klassenname. Einfach!
+Zum besseren Verständnis betrachten wir zunächst eine Anwendung ohne Module. Wir wollen, dass Presenter-Klassen in den Namensraum `App\UI` fallen. Um den Presenter `Home` auf die Klasse `App\UI\HomePresenter` abzubilden, erreichen wir dies mit der folgenden Konfiguration:
-Wenn wir die Vortragenden in Module unterteilen, können wir für jedes Modul eine eigene Zuordnung vornehmen:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Diese Zuordnung funktioniert, indem das Sternchen in der Maske `App\UI\*Presenter` durch den Presenter-Namen `Home` ersetzt wird, was zu dem endgültigen Klassennamen `App\UI\HomePresenter` führt. Einfach!
+
+Wie Sie jedoch in den Beispielen in diesem und anderen Kapiteln sehen können, platzieren wir Presenter-Klassen in gleichnamigen Unterverzeichnissen, z. B. wird der Presenter `Home` der Klasse `App\UI\Home\HomePresenter` zugeordnet. Dies wird durch die Verdoppelung des Sternchens erreicht (erfordert Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Gehen wir nun dazu über, Presenter in Modulen abzubilden. Für jedes Modul können wir spezifische Zuordnungen definieren:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-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`.
+Nach dieser Konfiguration wird der Präsentator `Front:Home` der Klasse `App\UI\Front\Home\HomePresenter` zugeordnet, während der Präsentator `Api:OAuth` der Klasse `App\Api\OAuthPresenter` zugeordnet wird.
-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:
+Da die Module `Front` und `Admin` einen ähnlichen Zuordnungsansatz haben und es wahrscheinlich noch mehr solcher Module gibt, ist es möglich, eine allgemeine Regel zu erstellen, die sie ersetzt. In der Klassenmaske wird ein neues Sternchen für das Modul hinzugefügt:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Was aber, wenn wir verschachtelte Module verwenden und einen Präsentator `Admin:User:Edit` haben? In diesem Fall wird das Segment mit dem Sternchen, das das Modul für jede Ebene darstellt, einfach wiederholt und das Ergebnis ist die Klasse `App\Modules\Admin\User\Presenters\EditPresenter`.
+Bei mehrstufig verschachtelten Modulen, wie z. B. dem Moderator `Admin:User:Edit`, wird das Sternchen-Segment für jede Stufe wiederholt, was zu der Klasse `App\UI\Admin\User\Edit\EditPresenter` führt.
-Eine alternative Schreibweise ist die Verwendung eines Arrays, das aus drei Segmenten anstelle einer Zeichenkette besteht. Diese Notation ist gleichwertig mit der vorherigen:
+Eine alternative Schreibweise ist die Verwendung eines Arrays, das aus drei Segmenten besteht, anstelle einer Zeichenkette. Diese Notation ist äquivalent zur vorherigen:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Der Standardwert ist `*Module\*Presenter`.
diff --git a/application/de/templates.texy b/application/de/templates.texy
index a21bd7266f..8860819f5f 100644
--- a/application/de/templates.texy
+++ b/application/de/templates.texy
@@ -34,35 +34,81 @@ Und dies könnte die Aktionsvorlage sein:
Sie definiert den Block `content`, der anstelle von `{include content}` in das Layout eingefügt wird, und definiert auch den Block `title` neu, der `{block title}` im Layout überschreibt. Versuchen Sie, sich das Ergebnis vorzustellen.
-Suche nach Templates .[#toc-search-for-templates]
--------------------------------------------------
+Vorlage nachschlagen .[#toc-template-lookup]
+--------------------------------------------
+
+In Presentern müssen Sie nicht angeben, welche Vorlage gerendert werden soll; das Framework bestimmt den Pfad automatisch, was die Codierung für Sie einfacher macht.
+
+Wenn Sie eine Verzeichnisstruktur verwenden, in der jeder Präsentator sein eigenes Verzeichnis hat, legen Sie die Vorlage einfach in diesem Verzeichnis unter dem Namen der Aktion (d. h. der Ansicht) ab. Verwenden Sie zum Beispiel für die Aktion `default` die Vorlage `default.latte`:
-Der Pfad zu den Vorlagen wird nach einer einfachen Logik hergeleitet. Es wird versucht zu sehen, ob eine dieser Vorlagendateien relativ zu dem Verzeichnis existiert, in dem sich die Presenter-Klasse befindet, wobei `` der Name des aktuellen Präsentators ist und `` der Name der aktuellen Aktion ist:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Wenn Sie eine Struktur verwenden, bei der sich die Präsentatoren in einem Verzeichnis und die Vorlagen in einem Ordner `templates` befinden, speichern Sie sie entweder in einer Datei `..latte` oder `/.latte`:
-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.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Wenn die Vorlage auch dort nicht gefunden wird, ist die Antwort ein [404-Fehler |presenters#Error 404 etc.].
+Das Verzeichnis `templates` kann auch eine Ebene höher platziert werden, auf derselben Ebene wie das Verzeichnis mit den Presenter-Klassen.
-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.
+Wenn die Vorlage nicht gefunden wird, antwortet der Präsentator mit dem [Fehler 404 - Seite nicht gefunden |presenters#Error 404 etc].
+
+Sie können die Ansicht mit `$this->setView('anotherView')` ändern. Es ist auch möglich, die Vorlagendatei direkt mit `$this->template->setFile('/path/to/template.latte')` anzugeben.
.[note]
-Sie können die Pfade, in denen Vorlagen gesucht werden, ändern, indem Sie die Methode [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()] überschreiben, die ein Array mit möglichen Dateipfaden zurückgibt.
+Dateien, in denen Vorlagen gesucht werden, können durch Überschreiben der Methode [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()] geändert werden, die ein Array mit möglichen Dateinamen zurückgibt.
+
+
+Layout-Vorlagen-Suche .[#toc-layout-template-lookup]
+----------------------------------------------------
+
+Nette sucht auch automatisch nach der Layout-Datei.
+
+Wenn Sie eine Verzeichnisstruktur verwenden, in der jeder Präsentator sein eigenes Verzeichnis hat, legen Sie das Layout entweder in dem Ordner mit dem Präsentator ab, wenn es nur für diesen spezifisch ist, oder eine Ebene höher, wenn es für mehrere Präsentatoren gemeinsam ist:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Wenn Sie eine Struktur verwenden, bei der die Vortragenden in einem Verzeichnis zusammengefasst sind und sich die Vorlagen in einem Ordner `templates` befinden, wird das Layout an den folgenden Stellen erwartet:
-Das Layout wird in den folgenden Dateien erwartet:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` gemeinsames Layout für mehrere Präsentatoren
+Befindet sich der Präsentator in einem [Modul |modules], wird er auch weiter oben im Verzeichnisbaum entsprechend der Verschachtelung des Moduls gesucht.
-`` ist der Name des aktuellen Präsentators und `` ist der Name des Layouts, der standardmäßig `'layout'` lautet. Der Name kann mit `$this->setLayout('otherLayout')` geändert werden, so dass `@otherLayout.latte` Dateien ausprobiert werden.
+Der Name des Layouts kann mit `$this->setLayout('layoutAdmin')` geändert werden und wird dann in der Datei `@layoutAdmin.latte` erwartet. Sie können die Layout-Vorlagendatei auch direkt mit `$this->setLayout('/path/to/template.latte')` angeben.
-Sie können auch direkt den Dateinamen der Layoutvorlage mit `$this->setLayout('/path/to/template.latte')` angeben. Durch die Verwendung von `$this->setLayout(false)` wird die Layout-Suche deaktiviert.
+Die Verwendung von `$this->setLayout(false)` oder des Tags `{layout none}` innerhalb der Vorlage deaktiviert die Layout-Suche.
.[note]
-Sie können die Pfade, in denen Vorlagen gesucht werden, ändern, indem Sie die Methode [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] überschreiben, die ein Array mit möglichen Dateipfaden zurückgibt.
+Die Dateien, in denen Layoutvorlagen gesucht werden, können durch Überschreiben der Methode [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] geändert werden, die ein Array mit möglichen Dateinamen zurückgibt.
Variablen in der Vorlage .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ Die `@property-read` Annotation ist für die IDE und die statische Analyse, sie
Sie können sich auch den Luxus gönnen, in Vorlagen zu flüstern. Installieren Sie einfach das Latte-Plugin in PhpStorm und geben Sie den Klassennamen am Anfang der Vorlage an, siehe den Artikel "Latte: how to type system":https://blog.nette.org/de/latte-wie-benutzt-man-das-typensystem:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte Version 3 bietet einen fortgeschritteneren Weg, indem es eine [Erweiterung |latte:creating-extension] für jedes Webprojekt erstellt. Hier ist ein grobes Beispiel für eine solche Klasse:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Wir registrieren sie mit [configuration |configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/el/how-it-works.texy b/application/el/how-it-works.texy
index f7a4be0a0b..8593798f00 100644
--- a/application/el/how-it-works.texy
+++ b/application/el/how-it-works.texy
@@ -22,13 +22,13 @@
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← βασικές αναγκαίες τάξεις
+│ │ └── RouterFactory.php ← διαμόρφωση των διευθύνσεων URL
+│ ├── UI/ ← παρουσιαστές, πρότυπα και λοιπά.
+│ │ ├── @layout.latte ← πρότυπο κοινής διάταξης
+│ │ └── Home/ ← Αρχικός κατάλογος παρουσιαστών
+│ │ ├── HomePresenter.php ← Κλάση οικιακού παρουσιαστή
+│ │ └── default.latte ← πρότυπο για τη δράση default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ composer create-project nette/web-project
Η εφαρμογή ξεκινά ζητώντας από τον λεγόμενο δρομολογητή να αποφασίσει ποιος από τους παρουσιαστές θα περάσει το τρέχον αίτημα για επεξεργασία. Ο δρομολογητής αποφασίζει ποιανού ευθύνη είναι. Κοιτάζει τη διεύθυνση URL εισόδου `https://example.com/product/123`, ο οποίος θέλει να `show` ένα προϊόν με `id: 123` ως ενέργεια. Είναι καλή συνήθεια να γράφετε τα ζεύγη παρουσιαστής + δράση χωρισμένα με άνω και κάτω τελεία ως `Product:show`.
-Έτσι, ο δρομολογητής μετατρέπει τη διεύθυνση URL σε ένα ζεύγος `Presenter:action` + παράμετροι, στην περίπτωσή μας `Product:show` + `id: 123`. Μπορείτε να δείτε πώς μοιάζει ένας δρομολογητής στο αρχείο `app/Router/RouterFactory.php` και θα τον περιγράψουμε αναλυτικά στο κεφάλαιο [Δρομολόγηση |Routing].
+Έτσι, ο δρομολογητής μετατρέπει τη διεύθυνση URL σε ένα ζεύγος `Presenter:action` + παράμετροι, στην περίπτωσή μας `Product:show` + `id: 123`. Μπορείτε να δείτε πώς μοιάζει ένας δρομολογητής στο αρχείο `app/Core/RouterFactory.php` και θα τον περιγράψουμε αναλυτικά στο κεφάλαιο [Δρομολόγηση |Routing].
Ας συνεχίσουμε. Η εφαρμογή γνωρίζει ήδη το όνομα του παρουσιαστή και μπορεί να συνεχίσει. Δημιουργώντας ένα αντικείμενο `ProductPresenter`, το οποίο είναι ο κώδικας του παρουσιαστή `Product`. Πιο συγκεκριμένα, ζητάει από το DI container τη δημιουργία του presenter, επειδή η παραγωγή αντικειμένων είναι η δουλειά του.
@@ -121,12 +121,9 @@ class ProductPresenter extends Nette\Application\UI\Presenter
Στη συνέχεια, ο παρουσιαστής επιστρέφει την απάντηση. Αυτό μπορεί να είναι μια σελίδα HTML, μια εικόνα, ένα έγγραφο XML, η αποστολή ενός αρχείου από το δίσκο, JSON ή η ανακατεύθυνση σε μια άλλη σελίδα. Σημαντικό είναι ότι, αν δεν πούμε ρητά πώς να απαντήσουμε (κάτι που συμβαίνει στην περίπτωση του `ProductPresenter`), η απάντηση θα είναι η απόδοση του προτύπου με μια σελίδα HTML. Γιατί; Λοιπόν, επειδή στο 99% των περιπτώσεων θέλουμε να σχεδιάσουμε ένα πρότυπο, οπότε ο παρουσιαστής θεωρεί αυτή τη συμπεριφορά ως προεπιλεγμένη και θέλει να διευκολύνει τη δουλειά μας. Αυτό είναι το νόημα της Nette.
-Δεν χρειάζεται καν να δηλώσουμε ποιο πρότυπο θέλουμε να σχεδιάσουμε, αυτός εξάγει τη διαδρομή προς αυτό σύμφωνα με απλή λογική. Στην περίπτωση του presenter `Product` και της δράσης `show`, προσπαθεί να δει αν ένα από αυτά τα αρχεία προτύπων υπάρχει σε σχέση με τον κατάλογο όπου βρίσκεται η κλάση `ProductPresenter`:
+Δεν χρειάζεται καν να καθορίσουμε ποιο πρότυπο θα αναπαραχθεί- το πλαίσιο θα βρει μόνο του τη διαδρομή. Στην περίπτωση της ενέργειας `show`, απλώς προσπαθεί να φορτώσει το πρότυπο `show.latte` στον κατάλογο με την κλάση `ProductPresenter`. Προσπαθεί επίσης να βρει τη διάταξη στο αρχείο `@layout.latte` (περισσότερα για την [αναζήτηση προτύπων |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Θα προσπαθήσει επίσης να βρει τη διάταξη στο αρχείο `@layout.latte` και στη συνέχεια θα αποδώσει το πρότυπο. Τώρα ολοκληρώνεται η εργασία του παρουσιαστή και ολόκληρης της εφαρμογής. Εάν το πρότυπο δεν υπάρχει, θα επιστραφεί μια σελίδα με σφάλμα 404. Μπορείτε να διαβάσετε περισσότερα για τους παρουσιαστές στη σελίδα [Παρουσιαστές |Presenters].
+Στη συνέχεια, τα πρότυπα αποδίδονται. Με αυτόν τον τρόπο ολοκληρώνεται η εργασία του παρουσιαστή και ολόκληρης της εφαρμογής, και η εργασία έχει τελειώσει. Εάν το πρότυπο δεν υπήρχε, θα επιστρεφόταν μια σελίδα σφάλματος 404. Μπορείτε να διαβάσετε περισσότερα για τους παρουσιαστές στη σελίδα [Παρουσιαστές |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ class ProductPresenter extends Nette\Application\UI\Presenter
3) ο δρομολογητής αποκωδικοποιεί τη διεύθυνση URL ως ζεύγος `Home:default`
4) δημιουργείται ένα αντικείμενο `HomePresenter`
5) καλείται η μέθοδος `renderDefault()` (αν υπάρχει)
-6) αποδίδεται ένα πρότυπο `templates/Home/default.latte` με διάταξη `templates/@layout.latte`
+6) αποδίδεται ένα πρότυπο `default.latte` με διάταξη `@layout.latte`
Μπορεί να έχετε συναντήσει πολλές νέες έννοιες τώρα, αλλά πιστεύουμε ότι βγάζουν νόημα. Η δημιουργία εφαρμογών στη Nette είναι πανεύκολη.
diff --git a/application/el/modules.texy b/application/el/modules.texy
index 3277cccce0..71b5e4b57a 100644
--- a/application/el/modules.texy
+++ b/application/el/modules.texy
@@ -2,29 +2,31 @@
********
.[perex]
-Στη Nette, οι ενότητες αντιπροσωπεύουν τις λογικές μονάδες που συνθέτουν μια εφαρμογή. Περιλαμβάνουν παρουσιαστές, πρότυπα, ενδεχομένως επίσης συστατικά και κλάσεις μοντέλων.
+Οι ενότητες φέρνουν σαφήνεια στις εφαρμογές Nette διευκολύνοντας τον εύκολο διαχωρισμό σε λογικές μονάδες.
-Ένας κατάλογος για τους παρουσιαστές και ένας για τα πρότυπα δεν θα ήταν αρκετός για πραγματικά έργα. Το να έχετε δεκάδες αρχεία σε έναν φάκελο είναι τουλάχιστον ανοργάνωτο. Πώς να απαλλαγείτε από αυτό; Απλώς τα χωρίζουμε σε υποκαταλόγους στο δίσκο και σε χώρους ονομάτων στον κώδικα. Και αυτό ακριβώς κάνουν τα modules της Nette.
-
-Ας ξεχάσουμε λοιπόν έναν ενιαίο φάκελο για τους παρουσιαστές και τα πρότυπα και ας δημιουργήσουμε αντ' αυτού ενότητες, για παράδειγμα `Admin` και `Front`.
+Παρόμοια με την οργάνωση των αρχείων σε φακέλους σε ένα σκληρό δίσκο, στη Nette μπορούμε να χωρίσουμε τους παρουσιαστές, τα πρότυπα και άλλες βοηθητικές κλάσεις σε ενότητες. Πώς λειτουργεί αυτό στην πράξη; Απλά με την ενσωμάτωση νέων υποκαταλόγων στη δομή. Ακολουθεί ένα παράδειγμα δομής με δύο ενότητες, Front και Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Αυτή η δομή καταλόγου θα αντικατοπτρίζεται από τα namespaces των κλάσεων, έτσι για παράδειγμα το `DashboardPresenter` θα βρίσκεται στο namespace `App\Modules\Admin\Presenters`:
+Αυτή η δομή καταλόγου αντικατοπτρίζεται στα namespaces των κλάσεων, έτσι για παράδειγμα, η `DashboardPresenter` βρίσκεται στο namespace `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Ο παρουσιαστής `Dashboard` μέσα στην ενότητα `Admin` αναφέρεται μέσα στην εφαρμογή χρησιμοποιώντας τον συμβολισμό της άνω και κάτω τελείας ως `Admin:Dashboard`, και η ενέργεια `default` ως `Admin:Dashboard:default`.
-Και πώς γνωρίζει η Nette proper ότι το `Admin:Dashboard` αντιπροσωπεύει την κλάση `App\Modules\Admin\Presenters\DashboardPresenter`; Αυτό καθορίζεται από την [αντιστοίχιση |#mapping] στη διαμόρφωση.
-Έτσι, η δεδομένη δομή δεν είναι αυστηρά καθορισμένη και μπορείτε να την τροποποιήσετε ανάλογα με τις ανάγκες σας.
+Στην εφαρμογή, αναφερόμαστε στον παρουσιαστή `Dashboard` μέσα στην ενότητα `Admin` χρησιμοποιώντας τον συμβολισμό της άνω και κάτω τελείας ως `Admin:Dashboard`. Για τη δράση του `default`, αναφερόμαστε σε αυτόν ως `Admin:Dashboard:default`.
-Οι ενότητες μπορούν φυσικά να περιέχουν όλα τα άλλα στοιχεία εκτός από τους παρουσιαστές και τα πρότυπα, όπως συστατικά, κλάσεις μοντέλων κ.λπ.
+Η δομή που παρουσιάζεται δεν είναι άκαμπτη- μπορείτε να [την προσαρμόσετε πλήρως στις ανάγκες σας |#mapping] στη διαμόρφωση. .[tip]
+
+Οι ενότητες μπορούν να περιλαμβάνουν όλα τα άλλα αρχεία, όπως συστατικά και βοηθητικές κλάσεις, εκτός από τους παρουσιαστές και τα πρότυπα. Αν σκέφτεστε πού να τα τοποθετήσετε αυτά, σκεφτείτε να χρησιμοποιήσετε έναν φάκελο `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Ενσωματωμένες ενότητες .[#toc-nested-modules]
---------------------------------------------
-Οι ενότητες δεν χρειάζεται να σχηματίζουν μόνο μια επίπεδη δομή, μπορείτε επίσης να δημιουργήσετε υποενότητες, για παράδειγμα:
+Οι ενότητες μπορούν να έχουν πολλαπλά επίπεδα ένθεσης, παρόμοια με μια δομή καταλόγου σε ένα δίσκο:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Έτσι, η ενότητα `Blog` χωρίζεται σε υποενότητες `Admin` και `Front`. Και πάλι, αυτό θα αντικατοπτρίζεται στα namespaces, τα οποία θα είναι `App\Modules\Blog\Admin\Presenters` κ.λπ. Ο παρουσιαστής `Dashboard` μέσα στην υποενότητα αναφέρεται ως `Blog:Admin:Dashboard`.
+Η ενότητα `Blog` χωρίζεται σε υποενότητες `Admin` και `Front`. Αυτό αντικατοπτρίζεται επίσης στα namespaces, τα οποία εμφανίζονται ως `App\UI\Blog\Admin` και παρόμοια. Για να αναφερθούμε στον παρουσιαστή `Dashboard` μέσα στην υποενότητα `Admin`, αναφερόμαστε σε αυτόν ως `Blog:Admin:Dashboard`.
-Η ένθεση μπορεί να προχωρήσει όσο βαθιά θέλετε, οπότε μπορούν να δημιουργηθούν υπο-υποενότητες.
+Η φωλεοποίηση μπορεί να είναι όσο βαθιά χρειάζεται, επιτρέποντας τη δημιουργία υπο-υπομονάδων.
+
+Για παράδειγμα, αν στη διαχείριση έχετε πολλούς παρουσιαστές που σχετίζονται με τη διαχείριση παραγγελιών, όπως `OrderDetail`, `OrderEdit`, `OrderDispatch`, κ.λπ., μπορείτε να δημιουργήσετε μια ενότητα `Order` στην οποία θα οργανωθούν παρουσιαστές όπως `Detail`, `Edit`, `Dispatch` και άλλοι.
Δημιουργία συνδέσμων .[#toc-creating-links]
@@ -102,46 +118,59 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
Χαρτογράφηση .[#toc-mapping]
----------------------------
-Καθορίζει τους κανόνες με τους οποίους το όνομα της κλάσης προκύπτει από το όνομα του παρουσιαστή. Τους γράφουμε στη [διαμόρφωση |configuration] κάτω από το κλειδί `application › mapping`.
+Η αντιστοίχιση ορίζει τους κανόνες για την εξαγωγή του ονόματος της κλάσης από το όνομα του παρουσιαστή. Οι κανόνες αυτοί καθορίζονται στη [διαμόρφωση |configuration] στο κλειδί `application › mapping`.
-Ας ξεκινήσουμε με ένα δείγμα που δεν χρησιμοποιεί ενότητες. Θα θέλουμε απλώς οι κλάσεις presenter να έχουν το namespace `App\Presenters`. Αυτό σημαίνει ότι ένας παρουσιαστής όπως το `Home` θα πρέπει να αντιστοιχίζεται στην κλάση `App\Presenters\HomePresenter`. Αυτό μπορεί να επιτευχθεί με την ακόλουθη διαμόρφωση:
+Όλα τα παραδείγματα σε αυτό το κεφάλαιο βασίζονται στην ακόλουθη διαμόρφωση χαρτογράφησης:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Το όνομα του παρουσιαστή αντικαθίσταται με τον αστερίσκο στη μάσκα κλάσης και το αποτέλεσμα είναι το όνομα της κλάσης. Εύκολο!
+Για καλύτερη κατανόηση, ας θεωρήσουμε πρώτα μια εφαρμογή χωρίς ενότητες. Θέλουμε οι κλάσεις του παρουσιαστή να εμπίπτουν στο χώρο ονομάτων `App\UI`. Για να αντιστοιχίσουμε τον παρουσιαστή `Home` στην κλάση `App\UI\HomePresenter`, το επιτυγχάνουμε με την ακόλουθη διαμόρφωση:
-Αν χωρίσουμε τους παρουσιαστές σε ενότητες, μπορούμε να έχουμε τη δική μας χαρτογράφηση για κάθε ενότητα:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Αυτή η αντιστοίχιση λειτουργεί αντικαθιστώντας τον αστερίσκο στη μάσκα `App\UI\*Presenter` με το όνομα του παρουσιαστή `Home`, με αποτέλεσμα το τελικό όνομα της κλάσης `App\UI\HomePresenter`. Απλό!
+
+Ωστόσο, όπως μπορείτε να δείτε στα παραδείγματα σε αυτό και σε άλλα κεφάλαια, τοποθετούμε τις κλάσεις παρουσιαστή σε επώνυμους υποκαταλόγους, π.χ. ο παρουσιαστής `Home` αντιστοιχίζεται στην κλάση `App\UI\Home\HomePresenter`. Αυτό επιτυγχάνεται με τον διπλασιασμό του αστερίσκου (απαιτεί Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Τώρα, ας προχωρήσουμε στην αντιστοίχιση των παρουσιαστών σε ενότητες. Μπορούμε να ορίσουμε συγκεκριμένες αντιστοιχίσεις για κάθε ενότητα:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Τώρα ο παρουσιαστής `Front:Home` αντιστοιχίζεται στην κλάση `App\Modules\Front\Presenters\HomePresenter` και ο παρουσιαστής `Admin:Dashboard` στην κλάση `App\Modules\Admin\Presenters\DashboardPresenter`.
+Σύμφωνα με αυτή τη διαμόρφωση, ο παρουσιαστής `Front:Home` αντιστοιχίζεται στην κλάση `App\UI\Front\Home\HomePresenter`, ενώ ο παρουσιαστής `Api:OAuth` αντιστοιχίζεται στην κλάση `App\Api\OAuthPresenter`.
-Είναι πιο πρακτικό να δημιουργήσετε έναν γενικό κανόνα (αστέρι) για να αντικαταστήσετε τους δύο πρώτους. Ο επιπλέον αστερίσκος θα προστεθεί στη μάσκα κλάσης μόνο για την ενότητα:
+Δεδομένου ότι οι ενότητες `Front` και `Admin` έχουν παρόμοια προσέγγιση αντιστοίχισης και είναι πιθανό να υπάρχουν περισσότερες τέτοιες ενότητες, είναι δυνατόν να δημιουργηθεί ένας γενικός κανόνας που να τις αντικαθιστά. Ένας νέος αστερίσκος για την ενότητα προστίθεται στη μάσκα κλάσης:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Τι γίνεται όμως αν χρησιμοποιούμε φωλιασμένες ενότητες και έχουμε έναν παρουσιαστή `Admin:User:Edit`; Σε αυτή την περίπτωση, το τμήμα με τον αστερίσκο που αντιπροσωπεύει την ενότητα για κάθε επίπεδο απλώς επαναλαμβάνεται και το αποτέλεσμα είναι η κλάση `App\Modules\Admin\User\Presenters\EditPresenter`.
+Για πολυεπίπεδες φωλιασμένες ενότητες, όπως ο παρουσιαστής `Admin:User:Edit`, το τμήμα αστερίσκου επαναλαμβάνεται για κάθε επίπεδο, με αποτέλεσμα την κλάση `App\UI\Admin\User\Edit\EditPresenter`.
-Ένας εναλλακτικός συμβολισμός είναι η χρήση ενός πίνακα που αποτελείται από τρία τμήματα αντί για συμβολοσειρά. Αυτή η σημειογραφία είναι ισοδύναμη με την προηγούμενη:
+Ένας εναλλακτικός συμβολισμός είναι η χρήση ενός πίνακα που αποτελείται από τρία τμήματα αντί για μια συμβολοσειρά. Αυτός ο συμβολισμός είναι ισοδύναμος με τον προηγούμενο:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Η προεπιλεγμένη τιμή είναι `*Module\*Presenter`.
diff --git a/application/el/templates.texy b/application/el/templates.texy
index 4b83599f45..39c2ddca2e 100644
--- a/application/el/templates.texy
+++ b/application/el/templates.texy
@@ -34,35 +34,81 @@
Ορίζει το μπλοκ `content`, το οποίο εισάγεται στη θέση του `{include content}` στη διάταξη, και επίσης επαναπροσδιορίζει το μπλοκ `title`, το οποίο αντικαθιστά το `{block title}` στη διάταξη. Προσπαθήστε να φανταστείτε το αποτέλεσμα.
-Αναζήτηση προτύπων .[#toc-search-for-templates]
------------------------------------------------
+Αναζήτηση προτύπου .[#toc-template-lookup]
+------------------------------------------
-Η διαδρομή προς τα πρότυπα προκύπτει σύμφωνα με μια απλή λογική. Προσπαθεί να δει αν ένα από αυτά τα αρχεία προτύπων υπάρχει σε σχέση με τον κατάλογο όπου βρίσκεται η κλάση presenter, όπου `` είναι το όνομα του τρέχοντος παρουσιαστή και `` είναι το όνομα της τρέχουσας δράσης:
+Στους παρουσιαστές, δεν χρειάζεται να καθορίσετε ποιο πρότυπο πρέπει να αποδοθεί- το πλαίσιο θα καθορίσει αυτόματα τη διαδρομή, διευκολύνοντας την κωδικοποίηση για εσάς.
-- `templates//.latte`
-- `templates/..latte`
+Αν χρησιμοποιείτε μια δομή καταλόγου όπου κάθε παρουσιαστής έχει το δικό του κατάλογο, απλά τοποθετήστε το πρότυπο σε αυτόν τον κατάλογο κάτω από το όνομα της ενέργειας (π.χ. προβολή). Για παράδειγμα, για τη δράση `default`, χρησιμοποιήστε το πρότυπο `default.latte`:
-Αν το πρότυπο δεν βρεθεί, θα προσπαθήσει να ψάξει στον κατάλογο `templates` ένα επίπεδο πιο πάνω, δηλαδή στο ίδιο επίπεδο με τον κατάλογο με την κλάση παρουσιαστή.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Εάν το πρότυπο δεν βρεθεί ούτε εκεί, η απάντηση είναι ένα [σφάλμα 404 |presenters#Error 404 etc.].
+Εάν χρησιμοποιείτε μια δομή όπου οι παρουσιαστές βρίσκονται μαζί σε έναν κατάλογο και τα πρότυπα σε έναν φάκελο `templates`, αποθηκεύστε το είτε σε ένα αρχείο `..latte` είτε στο `/.latte`:
-Μπορείτε επίσης να αλλάξετε την προβολή χρησιμοποιώντας το `$this->setView('otherView')`. Ή, αντί για αναζήτηση, καθορίστε απευθείας το όνομα του αρχείου προτύπου χρησιμοποιώντας τη διεύθυνση `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+Ο κατάλογος `templates` μπορεί επίσης να τοποθετηθεί ένα επίπεδο ψηλότερα, στο ίδιο επίπεδο με τον κατάλογο με τις κλάσεις παρουσιαστών.
+
+Εάν το πρότυπο δεν βρεθεί, ο παρουσιαστής απαντά με το [σφάλμα 404 - σελίδα δεν βρέθηκε |presenters#Error 404 etc].
+
+Μπορείτε να αλλάξετε την προβολή χρησιμοποιώντας το `$this->setView('anotherView')`. Είναι επίσης δυνατό να καθορίσετε απευθείας το αρχείο προτύπου με το `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Μπορείτε να αλλάξετε τις διαδρομές στις οποίες αναζητούνται τα πρότυπα υπερκαλύπτοντας τη μέθοδο [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], η οποία επιστρέφει έναν πίνακα πιθανών διαδρομών αρχείων.
+Τα αρχεία στα οποία αναζητούνται τα πρότυπα μπορούν να αλλάξουν με την παράκαμψη της μεθόδου [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], η οποία επιστρέφει έναν πίνακα πιθανών ονομάτων αρχείων.
+
+
+Αναζήτηση προτύπων διάταξης .[#toc-layout-template-lookup]
+----------------------------------------------------------
+
+Η Nette αναζητά επίσης αυτόματα το αρχείο διάταξης.
+
+Εάν χρησιμοποιείτε μια δομή καταλόγου όπου κάθε παρουσιαστής έχει το δικό του κατάλογο, τοποθετήστε τη διάταξη είτε στο φάκελο με τον παρουσιαστή, εάν αφορά μόνο αυτόν, είτε ένα επίπεδο ψηλότερα εάν είναι κοινή για πολλούς παρουσιαστές:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Εάν χρησιμοποιείτε μια δομή όπου οι παρουσιαστές είναι ομαδοποιημένοι σε έναν κατάλογο και τα πρότυπα βρίσκονται σε έναν φάκελο `templates`, η διάταξη αναμένεται στις ακόλουθες θέσεις:
-Η διάταξη αναμένεται στα ακόλουθα αρχεία:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` διάταξη κοινή για πολλούς παρουσιαστές
+Εάν ο παρουσιαστής βρίσκεται σε μια [ενότητα |modules], θα αναζητήσει επίσης πιο πάνω στο δέντρο καταλόγων σύμφωνα με την ένθεση της ενότητας.
-`` είναι το όνομα του τρέχοντος παρουσιαστή και `` είναι το όνομα της διάταξης, η οποία είναι εξ ορισμού `'layout'`. Το όνομα μπορεί να αλλάξει με το `$this->setLayout('otherLayout')`, έτσι ώστε να δοκιμάζονται τα αρχεία `@otherLayout.latte`.
+Το όνομα της διάταξης μπορεί να αλλάξει χρησιμοποιώντας το `$this->setLayout('layoutAdmin')` και τότε θα αναμένεται στο αρχείο `@layoutAdmin.latte`. Μπορείτε επίσης να καθορίσετε απευθείας το αρχείο προτύπου διάταξης χρησιμοποιώντας το `$this->setLayout('/path/to/template.latte')`.
-Μπορείτε επίσης να καθορίσετε απευθείας το όνομα του αρχείου του προτύπου διάταξης χρησιμοποιώντας το `$this->setLayout('/path/to/template.latte')`. Η χρήση του `$this->setLayout(false)` θα απενεργοποιήσει την αναζήτηση διάταξης.
+Η χρήση του `$this->setLayout(false)` ή της ετικέτας `{layout none}` μέσα στο πρότυπο απενεργοποιεί την αναζήτηση διάταξης.
.[note]
-Μπορείτε να αλλάξετε τις διαδρομές στις οποίες αναζητούνται τα πρότυπα με την παράκαμψη της μεθόδου [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], η οποία επιστρέφει έναν πίνακα πιθανών διαδρομών αρχείων.
+Τα αρχεία στα οποία αναζητούνται τα πρότυπα διάταξης μπορούν να αλλάξουν με την παράκαμψη της μεθόδου [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], η οποία επιστρέφει έναν πίνακα πιθανών ονομάτων αρχείων.
Μεταβλητές στο πρότυπο .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template
Μπορείτε επίσης να αφεθείτε στην πολυτέλεια του ψιθυρίσματος στα πρότυπα, απλά εγκαταστήστε το πρόσθετο Latte στο PhpStorm και καθορίστε το όνομα της κλάσης στην αρχή του προτύπου, δείτε το άρθρο "Latte: πώς να πληκτρολογήσετε το σύστημα":https://blog.nette.org/el/latte-pos-na-chresimopoiesete-to-systema-typon:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte έκδοση 3 προσφέρει έναν πιο προηγμένο τρόπο δημιουργώντας μια [επέκταση |latte:creating-extension] για κάθε έργο ιστού. Εδώ είναι ένα πρόχειρο παράδειγμα μιας τέτοιας κλάσης:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ final class LatteExtension extends Latte\Extension
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/en/how-it-works.texy b/application/en/how-it-works.texy
index 612d192393..cb0f291e1b 100644
--- a/application/en/how-it-works.texy
+++ b/application/en/how-it-works.texy
@@ -22,13 +22,13 @@ The directory structure looks something like this:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← basic necessary classes
+│ │ └── RouterFactory.php ← configuration of URL addresses
+│ ├── UI/ ← presenters, templates & co.
+│ │ ├── @layout.latte ← template of shared layout
+│ │ └── Home/ ← Home presenter directory
+│ │ ├── HomePresenter.php ← Home presenter class
+│ │ └── default.latte ← template for action default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Applications written in Nette are divided into many so-called presenters (in oth
The application starts by asking the so-called router to decide which of the presenters to pass the current request for processing. The router decides whose responsibility it is. It looks at the input URL `https://example.com/product/123` and, based on how it is set up, decides that this is a job, for example, for **presenter** `Product`, who wants to `show` a product with `id: 123` as an action. It is a good habit to write a pairs of presenter + action separated by a colon as `Product:show`.
-So the router transformed the URL into a pair `Presenter:action` + parameters, in our case `Product:show` + `id: 123`. You can see how a router looks like in file `app/Router/RouterFactory.php` and we will describe it in detail in chapter [Routing].
+So the router transformed the URL into a pair `Presenter:action` + parameters, in our case `Product:show` + `id: 123`. You can see how a router looks like in file `app/Core/RouterFactory.php` and we will describe it in detail in chapter [Routing].
Let's move on. The application already knows the name of the presenter and can continue. By creating an object `ProductPresenter`, which is the code of presenter `Product`. More precisely, it asks the DI container for creating the presenter, because producting objects is its job.
@@ -121,12 +121,9 @@ So, the method `renderShow(123)` was called, whose code is fictional example, bu
Subsequently, the presenter returns the answer. This can be an HTML page, an image, an XML document, sending a file from disk, JSON or redirecting to another page. Importantly, if we do not explicitly say how to respond (which is the case of `ProductPresenter`), the answer will be to render the template with an HTML page. Why? Well, because in 99% of cases we want to draw a template, so the presenter takes this behavior as the default and wants to make our work easier. That's Nette's point.
-We don't even have to state which template to draw, he derives the path to it according to simple logic. In the case of presenter `Product` and action `show`, it tries to see if one of these template files exists relative to the directory where class `ProductPresenter` is located:
+We don't even need to specify which template to render; the framework will deduce the path itself. In the case of the `show` action, it simply tries to load the `show.latte` template in the directory with the `ProductPresenter` class. It also attempts to find the layout in the `@layout.latte` file (more about [template searching |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-It will also try to find the layout in file `@layout.latte` and then it renders the template. Now the task of the presenter and the entire application is completed. If the template does not exist, a page with error 404 will be returned. You can read more about presenters on the [Presenters] page.
+Subsequently, the templates are rendered. This completes the task of the presenter and the entire application, and the work is done. If the template did not exist, a 404 error page would be returned. You can read more about presenters on the page [Presenters|presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Just to be sure, let's try to recap the whole process with a slightly different
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/Home/default.latte` with a layout `templates/@layout.latte` is rendered
+6) a template `default.latte` with a layout `@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 376ac872b9..b9fec2f2a0 100644
--- a/application/en/modules.texy
+++ b/application/en/modules.texy
@@ -2,29 +2,31 @@ Modules
*******
.[perex]
-In Nette, modules represent the logical units that make up an application. They include presenters, templates, possibly also components and model classes.
+Modules bring clarity to Nette applications by facilitating easy division into logical units.
-One directory for presenters and one for templates would not be enough for real projects. Having dozens of files in one folder is at least unorganized. How to get out of it? We simply split them into subdirectories on disk and into namespaces in the code. And that's exactly what the Nette modules do.
-
-So let's forget about a single folder for presenters and templates and instead create modules, for example `Admin` and `Front`.
+Similar to organizing files into folders on a hard drive, in Nette we can divide presenters, templates, and other auxiliary classes into modules. How does this work in practice? Simply by incorporating new subdirectories into the structure. Here’s an example of a structure with two modules, Front and Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-This directory structure will be reflected by the class namespaces, so for example `DashboardPresenter` will be in the `App\Modules\Admin\Presenters` namespace:
+This directory structure is reflected in the namespaces of the classes, so for example, `DashboardPresenter` is located in the namespace `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-The `Dashboard` presenter inside the `Admin` module is referenced within the application using the colon notation as `Admin:Dashboard`, and its `default` action as `Admin:Dashboard:default`.
-And how does Nette proper know that `Admin:Dashboard` represents the `App\Modules\Admin\Presenters\DashboardPresenter` class? This is determined by [#mapping] in the configuration.
-Thus, the given structure is not hard set and you can modify it according to your needs.
+In the application, we refer to the `Dashboard` presenter within the `Admin` module using colon notation as `Admin:Dashboard`. For its `default` action, we refer to it as `Admin:Dashboard:default`.
-Modules can of course contain all other items besides presenters and templates, such as components, model classes, etc.
+The structure presented is not rigid; you can [fully customize it to your needs|#mapping] in the configuration. .[tip]
+
+Modules can include all other files, such as components and auxiliary classes, in addition to presenters and templates. If you are considering where to place these, consider using an `Accessory` folder:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Nested Modules
--------------
-Modules don't have to form only a flat structure, you can also create submodules, for example:
+Modules can have multiple levels of nesting, similar to a directory structure on a disk:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Thus, the `Blog` module is divided into `Admin` and `Front` submodules. Again, this will be reflected in the namespaces, which will be `App\Modules\Blog\Admin\Presenters` etc. The presenter `Dashboard` inside the submodule is referred to as `Blog:Admin:Dashboard`.
+The `Blog` module is divided into `Admin` and `Front` submodules. This is also reflected in the namespaces, which then appear as `App\UI\Blog\Admin` and similarly. To refer to the `Dashboard` presenter within the `Admin` submodule, we refer to it as `Blog:Admin:Dashboard`.
-The nesting can go as deep as you like, so sub-submodules can be created.
+Nesting can be as deep as needed, allowing the creation of sub-submodules.
+
+For example, if in administration you have many presenters related to order management, such as `OrderDetail`, `OrderEdit`, `OrderDispatch`, etc., you might create an `Order` module in which presenters like `Detail`, `Edit`, `Dispatch`, and others will be organized.
Creating Links
@@ -102,46 +118,59 @@ See [chapter on routing |routing#Modules].
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.
+Mapping defines the rules for deriving the class name from the presenter name. These rules are specified in the [configuration|configuration] under the key `application › mapping`.
-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:
+All examples in this chapter are based on the following mapping configuration:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-The presenter name is replaced with the asterisk in the class mask and the result is the class name. Easy!
+For better understanding, let's first consider an application without modules. We want presenter classes to fall under the namespace `App\UI`. To map the `Home` presenter to the class `App\UI\HomePresenter`, we achieve this with the following configuration:
-If we divide presenters into modules, we can have our own mapping for each module:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+This mapping works by replacing the asterisk in the mask `App\UI\*Presenter` with the presenter name `Home`, resulting in the final class name `App\UI\HomePresenter`. Simple!
+
+However, as you can see in the examples in this and other chapters, we place presenter classes in eponymous subdirectories, e.g., the `Home` presenter is mapped to the class `App\UI\Home\HomePresenter`. This is achieved by doubling the asterisk (requires Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Now, let's move on to mapping presenters into modules. We can define specific mappings for each module:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Now presenter `Front:Home` maps to class `App\Modules\Front\Presenters\HomePresenter` and presenter `Admin:Dashboard` to class `App\Modules\Admin\Presenters\DashboardPresenter`.
+According to this configuration, the presenter `Front:Home` maps to the class `App\UI\Front\Home\HomePresenter`, while the presenter `Api:OAuth` maps to the class `App\Api\OAuthPresenter`.
-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:
+Since the `Front` and `Admin` modules have a similar mapping approach and there are likely to be more such modules, it is possible to create a general rule that replaces them. A new asterisk for the module is added to the class mask:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-But what if we use nested modules and have a presenter `Admin:User:Edit`? In this case, the segment with an asterisk representing the module for each level is simply repeated and the result is class `App\Modules\Admin\User\Presenters\EditPresenter`.
+For multi-level nested modules, such as the presenter `Admin:User:Edit`, the asterisk segment repeats for each level, resulting in the class `App\UI\Admin\User\Edit\EditPresenter`.
-An alternative notation is to use an array consisting of three segments instead of a string. This notation is equivalent to the previous one:
+An alternative notation is to use an array composed of three segments instead of a string. This notation is equivalent to the previous one:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-The default value is `*Module\*Presenter`.
diff --git a/application/en/templates.texy b/application/en/templates.texy
index 5107b4493a..8069d6b23d 100644
--- a/application/en/templates.texy
+++ b/application/en/templates.texy
@@ -34,35 +34,81 @@ And this might be the action template:
It defines block `content`, which is inserted in place of `{include content}` in the layout, and also re-defines block `title`, which overwrites `{block title}` in the layout. Try to imagine the result.
-Search for Templates
---------------------
+Template Lookup
+---------------
-The path to the templates is deduced according to simple logic. It tries to see if one of these template files exists relative to the directory where presenter class is located, where `` is the name of the current presenter and `` is the name of the current action:
+In presenters, you don't need to specify which template should be rendered; the framework will automatically determine the path, making coding easier for you.
-- `templates//.latte`
-- `templates/..latte`
+If you use a directory structure where each presenter has its own directory, simply place the template in this directory under the name of the action (i.e. view). For example, for the `default` action, use the `default.latte` template:
-If the template is not found, it will try to search in the `templates` directory one level up, i.e., at the same level as the directory with the presenter class.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-If the template is not found there either, the response is a [404 error|presenters#Error 404 etc.].
+If you use a structure where presenters are together in one directory and templates in a `templates` folder, save it either in a file `..latte` or `/.latte`:
-You can also change the view using `$this->setView('otherView')`. Or, instead of searching, directly specify the name of the template file using `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+The `templates` directory can also be placed one level higher, at the same level as the directory with presenter classes.
+
+If the template is not found, the presenter responds with [404 - page not found error|presenters#Error 404 etc].
+
+You can change the view using `$this->setView('anotherView')`. It is also possible to directly specify the template file with `$this->template->setFile('/path/to/template.latte')`.
.[note]
-You can change the paths where templates are searched by overriding the [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()] method, which returns an array of possible file paths.
+Files where templates are searched can be changed by overriding the method [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], which returns an array of possible file names.
+
+
+Layout Template Lookup
+----------------------
+
+Nette also automatically searches for the layout file.
+
+If you use a directory structure where each presenter has its own directory, place the layout either in the folder with the presenter, if it is specific only to them, or a level higher if it is common to multiple presenters:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+If you use a structure where presenters are grouped together in one directory and templates are in a `templates` folder, the layout will be expected in the following places:
-The layout is expected in the following files:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` layout common to multiple presenters
+If the presenter is in a [module|modules], it will also search further up the directory tree according to the module's nesting.
-`` is the name of the current presenter and `` is the name of the layout, which is by default `'layout'`. The name can be changed with `$this->setLayout('otherLayout')`, so that `@otherLayout.latte` files will be tried.
+The name of the layout can be changed using `$this->setLayout('layoutAdmin')` and then it will be expected in the file `@layoutAdmin.latte`. You can also directly specify the layout template file using `$this->setLayout('/path/to/template.latte')`.
-You can also directly specify the file name of the layout template using `$this->setLayout('/path/to/template.latte')`. Using `$this->setLayout(false)` will disable the layout searching.
+Using `$this->setLayout(false)` or the `{layout none}` tag inside the template disables layout search.
.[note]
-You can change the paths where templates are searched by overriding the [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] method, which returns an array of possible file paths.
+Files where layout templates are searched can be changed by overriding the method [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], which returns an array of possible file names.
Variables in the Template
@@ -104,7 +150,7 @@ The `@property-read` annotation is for IDE and static analysis, it will make aut
You can indulge in the luxury of whispering in templates too, just install the Latte plugin in PhpStorm and specify the class name at the beginning of the template, see the article "Latte: how to type system":https://blog.nette.org/en/latte-how-to-use-type-system:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte version 3 offers a more advanced way by creating an [extension |latte:creating-extension] for each web project. Here is a rough example of such a class:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ We register it using [configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/es/how-it-works.texy b/application/es/how-it-works.texy
index 1706cb62a5..e4e0447853 100644
--- a/application/es/how-it-works.texy
+++ b/application/es/how-it-works.texy
@@ -22,13 +22,13 @@ La estructura de directorios se parece a esto
/--pre
web-project/
├── app/ ← directorio con la aplicación
-│ ├── Presenters/ ← clases para presentadores
-│ │ ├── HomePresenter.php ← Home de inicio de la clase de presentador
-│ │ └── templates/ ← directorio de plantillas
-│ │ ├── @layout.latte ← plantilla de diseño compartida
-│ │ └── Home/ ← plantillas para Home presentador de inicio
-│ │ └── default.latte ← plantilla para la acción `default`
-│ ├── Router/ ← configuración de direcciones URL
+│ ├── Core/ ← clases básicas necesarias.
+│ │ └── RouterFactory.php ← configuración de direcciones URL.
+│ ├── UI/ ← presentadores, plantillas & co.
+│ │ ├── @layout.latte ← plantilla de maquetación compartida
+│ │ └── Home/ ← Home directorio del presentador
+│ │ ├── HomePresenter.php ← Clase del presentador de inicio
+│ │ └── default.latte ← plantilla para la acción default
│ └── Bootstrap.php ← clase de arranque Bootstrap
├── bin/ ← scripts para la línea de comandos
├── config/ ← archivos de configuración
@@ -91,7 +91,7 @@ Las aplicaciones escritas en Nette se dividen en muchos de los llamados presenta
La aplicación comienza pidiendo al llamado enrutador que decida a cuál de los presentadores debe pasar la petición actual para su procesamiento. El enrutador decide de quién es la responsabilidad. Mira la URL de entrada `https://example.com/product/123`, que quiere `show` un producto con `id: 123` como acción. Es una buena costumbre escribir pares de presentador + acción separados por dos puntos como `Product:show`.
-Así que el enrutador transforma la URL en un par `Presenter:action` + parámetros, en nuestro caso `Product:show` + `id: 123`. Puedes ver el aspecto de un enrutador en el archivo `app/Router/RouterFactory.php` y lo describiremos en detalle en el capítulo [Enrutamiento |Routing].
+Así que el enrutador transforma la URL en un par `Presenter:action` + parámetros, en nuestro caso `Product:show` + `id: 123`. Puedes ver el aspecto de un enrutador en el archivo `app/Core/RouterFactory.php` y lo describiremos en detalle en el capítulo [Enrutamiento |Routing].
Sigamos. La aplicación ya conoce el nombre del presentador y puede continuar. Creando un objeto `ProductPresenter`, que es el código del presentador `Product`. Más concretamente, le pide al contenedor DI que cree el presentador, porque producir objetos es su trabajo.
@@ -121,12 +121,9 @@ Así, se llamó al método `renderShow(123)`, cuyo código es ficticio ejemplo,
Posteriormente, el presentador devuelve la respuesta. Esta puede ser una página HTML, una imagen, un documento XML, el envío de un fichero desde disco, JSON o la redirección a otra página. Es importante destacar que, si no decimos explícitamente cómo responder (que es el caso de `ProductPresenter`), la respuesta será renderizar la plantilla con una página HTML. ¿Por qué? Pues porque en el 99% de los casos queremos dibujar una plantilla, así que el presentador toma este comportamiento por defecto y quiere facilitarnos el trabajo. Ese es el punto de Nette.
-Ni siquiera tenemos que indicar qué plantilla dibujar, él deriva la ruta hacia ella según una lógica simple. En el caso del presentador `Product` y la acción `show`, intenta ver si uno de estos archivos de plantilla existe en relación al directorio donde se encuentra la clase `ProductPresenter`:
+Ni siquiera necesitamos especificar qué plantilla renderizar; el framework deducirá la ruta por sí mismo. En el caso de la acción `show`, simplemente intenta cargar la plantilla `show.latte` en el directorio con la clase `ProductPresenter`. También intenta encontrar el diseño en el archivo `@layout.latte` (más información sobre la [búsqueda de plantillas |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-También intentará encontrar el diseño en el archivo `@layout.latte` y luego renderizará la plantilla. Ahora se completa la tarea del presentador y de toda la aplicación. Si la plantilla no existe, se devolverá una página con el error 404. Puedes leer más sobre los presentadores en la página de [Presentadores |Presenters].
+Posteriormente, se renderizan las plantillas. Esto completa la tarea del presentador y de toda la aplicación, y el trabajo está hecho. Si la plantilla no existiera, se devolvería una página de error 404. Puede leer más sobre los presentadores en la página [Presentadores |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Sólo para estar seguros, intentemos recapitular todo el proceso con una URL lig
3) el router decodifica la URL como un par `Home:default`
4) se crea un objeto `HomePresenter`
5) se llama al método `renderDefault()` (si existe)
-6) se renderiza una plantilla `templates/Home/default.latte` con un diseño `templates/@layout.latte`
+6) se renderiza una plantilla `default.latte` con un diseño `@layout.latte`
Puede que ahora te hayas encontrado con un montón de conceptos nuevos, pero creemos que tienen sentido. Crear aplicaciones en Nette es pan comido.
diff --git a/application/es/modules.texy b/application/es/modules.texy
index 644cab5c1f..4aad53bfc2 100644
--- a/application/es/modules.texy
+++ b/application/es/modules.texy
@@ -2,29 +2,31 @@ Módulos
*******
.[perex]
-En Nette, los módulos representan las unidades lógicas que componen una aplicación. Incluyen presentadores, plantillas, posiblemente también componentes y clases modelo.
+Los módulos aportan claridad a las aplicaciones Nette al facilitar su división en unidades lógicas.
-Un directorio para los presentadores y otro para las plantillas no serían suficientes para los proyectos reales. Tener docenas de archivos en una carpeta es, como mínimo, desorganizado. ¿Cómo salir de ello? Simplemente los dividimos en subdirectorios en el disco y en espacios de nombres en el código. Y eso es exactamente lo que hacen los módulos de Nette.
-
-Así que olvidémonos de una única carpeta para presentadores y plantillas y en su lugar creemos módulos, por ejemplo `Admin` y `Front`.
+De forma similar a la organización de archivos en carpetas en un disco duro, en Nette podemos dividir los presentadores, plantillas y otras clases auxiliares en módulos. ¿Cómo funciona esto en la práctica? Simplemente incorporando nuevos subdirectorios a la estructura. He aquí un ejemplo de estructura con dos módulos, Front y Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directorio con módulos
-│ ├── Admin/ ← módulo Admin
-│ │ ├── Presenters/ ← sus presentadores
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← módulo Front
-│ └── Presenters/ ← sus presentadores
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Esta estructura de directorios se reflejará en los espacios de nombres de las clases, así por ejemplo `DashboardPresenter` estará en el espacio de nombres `App\Modules\Admin\Presenters`:
+Esta estructura de directorios se refleja en los espacios de nombres de las clases, así por ejemplo, `DashboardPresenter` se encuentra en el espacio de nombres `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-El presentador `Dashboard` dentro del módulo `Admin` es referenciado dentro de la aplicación usando la notación de dos puntos como `Admin:Dashboard`, y su acción `default` como `Admin:Dashboard:default`.
-¿Y cómo sabe Nette que `Admin:Dashboard` representa la clase `App\Modules\Admin\Presenters\DashboardPresenter`? Esto se determina mediante el [mapeo |#mapping] en la configuración.
-Por lo tanto, la estructura dada no es rígida y puede modificarla según sus necesidades.
+En la aplicación, nos referimos al presentador `Dashboard` dentro del módulo `Admin` utilizando la notación de dos puntos como `Admin:Dashboard`. Para su acción `default`, nos referimos a él como `Admin:Dashboard:default`.
-Por supuesto, los módulos pueden contener todos los demás elementos además de presentadores y plantillas, como componentes, clases modelo, etc.
+La estructura presentada no es rígida; puede [adaptarla totalmente a sus necesidades |#mapping] en la configuración. .[tip]
+
+Los módulos pueden incluir todos los demás archivos, como componentes y clases auxiliares, además de presentadores y plantillas. Si está pensando dónde colocarlos, considere la posibilidad de utilizar una carpeta `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Módulos anidados .[#toc-nested-modules]
---------------------------------------
-Los módulos no tienen por qué formar sólo una estructura plana, también puedes crear submódulos, por ejemplo:
+Los módulos pueden tener múltiples niveles de anidamiento, similar a una estructura de directorios en un disco:
/--pre
-app/
-├── Modules/ ← directorio con módulos
-│ ├── Blog/ ← módulo Blog
-│ │ ├── Admin/ ← submódulo Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submódulo Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← módulo Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Así, el módulo `Blog` se divide en los submódulos `Admin` y `Front`. De nuevo, esto se reflejará en los espacios de nombres, que serán `App\Modules\Blog\Admin\Presenters`, etc. El presentador `Dashboard` dentro del submódulo se denomina `Blog:Admin:Dashboard`.
+El módulo `Blog` se divide en los submódulos `Admin` y `Front`. Esto también se refleja en los espacios de nombres, que aparecen como `App\UI\Blog\Admin` y similares. Para referirnos al presentador `Dashboard` dentro del submódulo `Admin`, lo denominamos `Blog:Admin:Dashboard`.
-El anidamiento puede ser tan profundo como se desee, por lo que pueden crearse submódulos.
+El anidamiento puede ser tan profundo como sea necesario, permitiendo la creación de sub-submódulos.
+
+Por ejemplo, si en administración tiene muchos presentadores relacionados con la gestión de pedidos, como `OrderDetail`, `OrderEdit`, `OrderDispatch`, etc., puede crear un módulo `Order` en el que se organizarán presentadores como `Detail`, `Edit`, `Dispatch`, y otros.
Creación de enlaces .[#toc-creating-links]
@@ -99,49 +115,62 @@ Enrutamiento .[#toc-routing]
Véase el [capítulo sobre en rutamiento|routing#Modules].
-Mapeo .[#toc-mapping]
----------------------
+Cartografía .[#toc-mapping]
+---------------------------
-Define las reglas por las que el nombre de la clase se deriva del nombre del presentador. Las escribimos en [configuración |configuration] bajo la clave `application › mapping`.
+El mapeo define las reglas para derivar el nombre de la clase del nombre del presentador. Estas reglas se especifican en la [configuración |configuration] bajo la clave `application › mapping`.
-Empecemos con un ejemplo que no utiliza módulos. Sólo querremos que las clases del presentador tengan el espacio de nombres `App\Presenters`. Eso significa que un presentador como `Home` debe mapearse a la clase `App\Presenters\HomePresenter`. Esto se puede lograr con la siguiente configuración:
+Todos los ejemplos de este capítulo se basan en la siguiente configuración de asignación:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-El nombre del presentador se sustituye por el asterisco en la máscara de clase y el resultado es el nombre de la clase. Muy fácil.
+Para una mejor comprensión, consideremos primero una aplicación sin módulos. Queremos que las clases presentadoras pertenezcan al espacio de nombres `App\UI`. Para asignar el presentador `Home` a la clase `App\UI\HomePresenter`, lo conseguimos con la siguiente configuración:
-Si dividimos a los presentadores en módulos, podemos tener nuestra propia asignación para cada módulo:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Este mapeo funciona reemplazando el asterisco en la máscara `App\UI\*Presenter` con el nombre del presentador `Home`, resultando en el nombre final de la clase `App\UI\HomePresenter`. Es muy sencillo.
+
+Sin embargo, como puede ver en los ejemplos de este y otros capítulos, colocamos las clases de presentador en subdirectorios epónimos, por ejemplo, el presentador `Home` se asigna a la clase `App\UI\Home\HomePresenter`. Esto se consigue duplicando el asterisco (requiere Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Pasemos ahora a la asignación de presentadores a módulos. Podemos definir asignaciones específicas para cada módulo:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Ahora el presentador `Front:Home` se asigna a la clase `App\Modules\Front\Presenters\HomePresenter` y el presentador `Admin:Dashboard` a la clase `App\Modules\Admin\Presenters\DashboardPresenter`.
+Según esta configuración, el presentador `Front:Home` se asigna a la clase `App\UI\Front\Home\HomePresenter`, mientras que el presentador `Api:OAuth` se asigna a la clase `App\Api\OAuthPresenter`.
-Es más práctico crear una regla general (estrella) para sustituir a las dos primeras. El asterisco adicional se añadirá a la máscara de clase sólo para el módulo:
+Puesto que los módulos `Front` y `Admin` tienen un enfoque de asignación similar y es probable que haya más módulos de este tipo, es posible crear una regla general que los sustituya. Se añade un nuevo asterisco para el módulo a la máscara de la clase:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Pero, ¿y si utilizamos módulos anidados y tenemos un presentador `Admin:User:Edit`? En este caso, el segmento con un asterisco que representa el módulo para cada nivel simplemente se repite y el resultado es la clase `App\Modules\Admin\User\Presenters\EditPresenter`.
+Para los módulos anidados de varios niveles, como el presentador `Admin:User:Edit`, el segmento del asterisco se repite para cada nivel, lo que da como resultado la clase `App\UI\Admin\User\Edit\EditPresenter`.
-Una notación alternativa es utilizar una matriz formada por tres segmentos en lugar de una cadena. Esta notación es equivalente a la anterior:
+Una notación alternativa consiste en utilizar una matriz compuesta por tres segmentos en lugar de una cadena. Esta notación es equivalente a la anterior:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-El valor por defecto es `*Module\*Presenter`.
diff --git a/application/es/templates.texy b/application/es/templates.texy
index 761f7a648e..44a0bbeb7a 100644
--- a/application/es/templates.texy
+++ b/application/es/templates.texy
@@ -34,35 +34,81 @@ Y esta podría ser la plantilla de acción:
Define el bloque `content`, que se inserta en lugar de `{include content}` en el diseño, y también redefine el bloque `title`, que sobrescribe `{block title}` en el diseño. Intenta imaginar el resultado.
-Búsqueda de plantillas .[#toc-search-for-templates]
----------------------------------------------------
+Búsqueda de plantillas .[#toc-template-lookup]
+----------------------------------------------
-La ruta a las plantillas se deduce según una lógica simple. Se intenta ver si uno de estos archivos de plantilla existe en relación con el directorio donde se encuentra la clase de presentador, donde `` es el nombre del presentador actual y `` es el nombre de la acción actual:
+En los presentadores, no es necesario especificar qué plantilla debe renderizarse; el framework determinará automáticamente la ruta, facilitándole la codificación.
-- `templates//.latte`
-- `templates/..latte`
+Si utiliza una estructura de directorios donde cada presentador tiene su propio directorio, simplemente coloque la plantilla en este directorio bajo el nombre de la acción (es decir, vista). Por ejemplo, para la acción `default`, utilice la plantilla `default.latte`:
-Si no se encuentra la plantilla, se intentará buscar en el directorio `templates` un nivel más arriba, es decir, al mismo nivel que el directorio con la clase presentadora.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Si la plantilla tampoco se encuentra allí, la respuesta es un [error 404 |presenters#Error 404 etc.].
+Si utiliza una estructura en la que los presentadores están juntos en un directorio y las plantillas en una carpeta `templates`, guárdela en un archivo `..latte` o en `/.latte`:
-También puede cambiar la vista utilizando `$this->setView('otherView')`. O, en lugar de buscar, especifique directamente el nombre del archivo de plantilla utilizando `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+El directorio `templates` también puede colocarse un nivel más arriba, al mismo nivel que el directorio con las clases de presentador.
+
+Si no se encuentra la plantilla, el presentador responde con el [error 404 - página no encontrada |presenters#Error 404 etc].
+
+Puede cambiar la vista utilizando `$this->setView('anotherView')`. También es posible especificar directamente el archivo de plantilla con `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Puede cambiar las rutas donde se buscan las plantillas anulando el método [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], que devuelve una matriz de posibles rutas de archivo.
+Los archivos en los que se buscan las plantillas pueden cambiarse anulando el método [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], que devuelve una matriz de posibles nombres de archivo.
+
+
+Búsqueda de plantillas de diseño .[#toc-layout-template-lookup]
+---------------------------------------------------------------
+
+Nette también busca automáticamente el archivo de diseño.
+
+Si utiliza una estructura de directorios en la que cada presentador tiene su propio directorio, coloque la maqueta en la carpeta con el presentador, si es específica sólo para él, o en un nivel superior si es común a varios presentadores:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Si utiliza una estructura en la que los presentadores están agrupados en un directorio y las plantillas se encuentran en una carpeta `templates`, la maquetación se esperará en los siguientes lugares:
-El diseño se espera en los siguientes archivos:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` diseño común a varios presentadores
+Si el presentador está en un [módulo |modules], también buscará más arriba en el árbol de directorios según el anidamiento del módulo.
-`` es el nombre del presentador actual y `` es el nombre de la maquetación, que por defecto es `'layout'`. El nombre puede cambiarse con `$this->setLayout('otherLayout')`, de modo que se intentarán los archivos `@otherLayout.latte`.
+El nombre de la presentación puede cambiarse utilizando `$this->setLayout('layoutAdmin')` y entonces se esperará en el archivo `@layoutAdmin.latte`. También puede especificar directamente el archivo de plantilla de presentación utilizando `$this->setLayout('/path/to/template.latte')`.
-También puede especificar directamente el nombre de archivo de la plantilla de maquetación con `$this->setLayout('/path/to/template.latte')`. El uso de `$this->setLayout(false)` desactivará la búsqueda de diseños.
+El uso de `$this->setLayout(false)` o de la etiqueta `{layout none}` dentro de la plantilla desactiva la búsqueda de diseños.
.[note]
-Puede cambiar las rutas donde se buscan las plantillas anulando el método [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], que devuelve una matriz de posibles rutas de archivo.
+Los archivos en los que se buscan las plantillas de diseño pueden modificarse modificando el método [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], que devuelve una matriz de posibles nombres de archivo.
Variables en la plantilla .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ La anotación `@property-read` es para IDE y análisis estático, hará que func
Puedes permitirte el lujo de susurrar en las plantillas también, simplemente instala el plugin Latte en PhpStorm y especifica el nombre de la clase al principio de la plantilla, ver el artículo "Latte: cómo escribir sistema:https://blog.nette.org/es/latte-como-utilizar-el-sistema-de-tipos":
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
La versión 3 de Latte ofrece una forma más avanzada creando una [extensión |latte:creating-extension] para cada proyecto web. He aquí un ejemplo aproximado de una clase de este tipo:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ La registramos usando [configuration|configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/fr/how-it-works.texy b/application/fr/how-it-works.texy
index 9c4358110a..57aeb786a4 100644
--- a/application/fr/how-it-works.texy
+++ b/application/fr/how-it-works.texy
@@ -22,13 +22,13 @@ La structure des répertoires ressemble à ceci :
/--pre
web-project/
├── app/ ← répertoire avec application
-│ ├── Presenters/ ← classes d'presenter
-│ │ ├── HomePresenter.php ← Home classe des présentateurs
-│ │ └── templates/ ← répertoire des modèles
-│ │ ├── @layout.latte ← modèle de disposition partagée
-│ │ └── Home/ ← Modèles pour le présentateur de la page d'accueil
-│ │ └── default.latte ← modèle pour l'action `default`
-│ ├── Router/ ← configuration des adresses URL
+│ ├── Core/ ← basic necessary classes
+│ │ └── RouterFactory.php ← configuration des adresses URL
+│ ├── UI/ ← presenters, templates & co.
+│ │ ├─── @layout.latte ← template of shared layout
+│ │ └── Home/ ← Home presenter directory
+│ │ ├── HomePresenter.php ← Classe Home Presenter
+│ │ └── default.latte ← template for action default
│ └── Bootstrap.php ← classe de démarrage Bootstrap
├── bin/ ← scripts pour la ligne de commande
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Les applications écrites dans Nette sont divisées en plusieurs présentateurs
L'application commence par demander à ce qu'on appelle le routeur de décider lequel des présentateurs doit transmettre la demande actuelle pour traitement. Le routeur décide de la responsabilité qui lui incombe. Il examine l'URL d'entrée `https://example.com/product/123`, qui veut `show` un produit avec `id: 123` comme action. C'est une bonne habitude d'écrire une paire présentateur + action séparée par un deux-points comme `Product:show`.
-Le routeur transforme donc l'URL en une paire `Presenter:action` + paramètres, dans notre cas `Product:show` + `id: 123`. Vous pouvez voir à quoi ressemble un routeur dans le fichier `app/Router/RouterFactory.php` et nous le décrirons en détail dans le chapitre [Routage |Routing].
+Le routeur transforme donc l'URL en une paire `Presenter:action` + paramètres, dans notre cas `Product:show` + `id: 123`. Vous pouvez voir à quoi ressemble un routeur dans le fichier `app/Core/RouterFactory.php` et nous le décrirons en détail dans le chapitre [Routage |Routing].
Continuons. L'application connaît déjà le nom du présentateur et peut continuer. En créant un objet `ProductPresenter`, qui est le code du présentateur `Product`. Plus précisément, elle demande au conteneur DI de créer le présentateur, car la production d'objets est son travail.
@@ -121,12 +121,9 @@ Ainsi, la méthode `renderShow(123)` a été appelée, dont le code est un exemp
Ensuite, le présentateur renvoie la réponse. Cela peut être une page HTML, une image, un document XML, l'envoi d'un fichier depuis le disque, JSON ou la redirection vers une autre page. Il est important de noter que si nous ne disons pas explicitement comment répondre (ce qui est le cas de `ProductPresenter`), la réponse sera de rendre le modèle avec une page HTML. Pourquoi ? Eh bien, parce que dans 99% des cas, nous voulons dessiner un modèle, donc le présentateur prend ce comportement par défaut et veut nous faciliter le travail. C'est le point de vue de Nette.
-Nous n'avons même pas besoin d'indiquer quel modèle dessiner, il dérive le chemin vers celui-ci selon une logique simple. Dans le cas du présentateur `Product` et de l'action `show`, il essaie de voir si l'un de ces fichiers modèles existe par rapport au répertoire où se trouve la classe `ProductPresenter`:
+Il n'est même pas nécessaire de spécifier le modèle à rendre ; le framework déduira lui-même le chemin d'accès. Dans le cas de l'action `show`, il essaie simplement de charger le modèle `show.latte` dans le répertoire contenant la classe `ProductPresenter`. Il tente également de trouver la mise en page dans le fichier `@layout.latte` (plus d'informations sur la [recherche de modèles |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Il essaiera également de trouver la mise en page dans le fichier `@layout.latte`, puis il effectuera le rendu du modèle. La tâche du présentateur et de l'ensemble de l'application est maintenant terminée. Si le modèle n'existe pas, une page d'erreur 404 sera renvoyée. Vous pouvez en savoir plus sur les présentateurs sur la page [Présentateurs |Presenters].
+Ensuite, les modèles sont rendus. La tâche du présentateur et de l'ensemble de l'application est ainsi achevée et le travail est terminé. Si le modèle n'existait pas, une page d'erreur 404 serait renvoyée. Pour en savoir plus sur les présentateurs, consultez la page [Présentateurs |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Juste pour être sûr, essayons de récapituler l'ensemble du processus avec une
3) le routeur décode l'URL comme une paire `Home:default`
4) un objet `HomePresenter` est créé
5) la méthode `renderDefault()` est appelée (si elle existe)
-6) un modèle `templates/Home/default.latte` avec une mise en page `templates/@layout.latte` est rendu
+6) un modèle `default.latte` avec une mise en page `@layout.latte` est rendu
Vous avez peut-être rencontré beaucoup de nouveaux concepts maintenant, mais nous pensons qu'ils ont un sens. Créer des applications dans Nette est un jeu d'enfant.
diff --git a/application/fr/modules.texy b/application/fr/modules.texy
index 754e97b5ad..8141be295d 100644
--- a/application/fr/modules.texy
+++ b/application/fr/modules.texy
@@ -2,29 +2,31 @@ Modules
*******
.[perex]
-Dans Nette, les modules représentent les unités logiques qui composent une application. Ils comprennent des présentateurs, des modèles, éventuellement aussi des composants et des classes de modèles.
+Les modules apportent de la clarté aux applications Nette en facilitant la division en unités logiques.
-Un répertoire pour les présentateurs et un autre pour les modèles ne seraient pas suffisants pour les projets réels. Avoir des dizaines de fichiers dans un seul dossier est pour le moins inorganisé. Comment s'en sortir ? Il suffit de les répartir en sous-répertoires sur le disque et en espaces de noms dans le code. Et c'est exactement ce que font les modules Nette.
-
-Oublions donc le dossier unique pour les présentateurs et les modèles et créons plutôt des modules, par exemple `Admin` et `Front`.
+À l'instar de l'organisation des fichiers en dossiers sur un disque dur, Nette permet de diviser les présentateurs, les modèles et les autres classes auxiliaires en modules. Comment cela fonctionne-t-il en pratique ? Simplement en incorporant de nouveaux sous-répertoires dans la structure. Voici un exemple de structure avec deux modules, Front et Admin :
/--pre
-app/
-├── Presenters/
-├── Modules/ ← répertoire avec les modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← ses présentateurs
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← ses présentateurs
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Cette structure de répertoire sera reflétée par les espaces de noms des classes, ainsi par exemple `DashboardPresenter` sera dans l'espace de noms `App\Modules\Admin\Presenters`:
+Cette structure de répertoires se reflète dans les espaces de noms des classes. Ainsi, par exemple, `DashboardPresenter` est situé dans l'espace de noms `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Le présentateur `Dashboard` dans le module `Admin` est référencé dans l'application en utilisant la notation deux points comme `Admin:Dashboard`, et son action `default` comme `Admin:Dashboard:default`.
-Et comment Nette proper sait-elle que `Admin:Dashboard` représente la classe `App\Modules\Admin\Presenters\DashboardPresenter`? Cela est déterminé par le [mappage |#mapping] dans la configuration.
-Ainsi, la structure donnée n'est pas figée et vous pouvez la modifier en fonction de vos besoins.
+Dans l'application, nous faisons référence au présentateur `Dashboard` dans le module `Admin` en utilisant la notation des deux points comme `Admin:Dashboard`. Pour son action `default`, nous l'appelons `Admin:Dashboard:default`.
-Les modules peuvent bien sûr contenir tous les éléments autres que les présentateurs et les modèles, tels que les composants, les classes de modèles, etc.
+La structure présentée n'est pas rigide ; vous pouvez [l'adapter entièrement à vos besoins |#mapping] dans la configuration. .[tip]
+
+Les modules peuvent inclure tous les autres fichiers, tels que les composants et les classes auxiliaires, en plus des présentateurs et des modèles. Si vous vous demandez où placer ces derniers, envisagez d'utiliser un dossier `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Modules imbriqués .[#toc-nested-modules]
----------------------------------------
-Les modules ne doivent pas uniquement former une structure plate, vous pouvez également créer des sous-modules, par exemple :
+Les modules peuvent avoir plusieurs niveaux d'imbrication, comme la structure d'un répertoire sur un disque :
/--pre
-app/
-├── Modules/ ← répertoire avec les modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← sous-module Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← sous-module Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Ainsi, le module `Blog` est divisé en sous-modules `Admin` et `Front`. Là encore, cela se reflétera dans les espaces de noms, qui seront `App\Modules\Blog\Admin\Presenters` etc. Le présentateur `Dashboard` à l'intérieur du sous-module est désigné par `Blog:Admin:Dashboard`.
+Le module `Blog` est divisé en sous-modules `Admin` et `Front`. Cela se reflète également dans les espaces de noms, qui apparaissent alors comme `App\UI\Blog\Admin` et similaires. Pour désigner le présentateur `Dashboard` au sein du sous-module `Admin`, nous l'appelons `Blog:Admin:Dashboard`.
-L'imbrication peut aller aussi loin que vous le souhaitez, de sorte que des sous-sous-modules peuvent être créés.
+L'imbrication peut être aussi poussée que nécessaire, ce qui permet de créer des sous-sous-modules.
+
+Par exemple, si dans l'administration vous avez de nombreux présentateurs liés à la gestion des commandes, tels que `OrderDetail`, `OrderEdit`, `OrderDispatch`, etc., vous pouvez créer un module `Order` dans lequel les présentateurs tels que `Detail`, `Edit`, `Dispatch`, et d'autres seront organisés.
Création de liens .[#toc-creating-links]
@@ -102,46 +118,59 @@ Voir le [chapitre sur le routage |routing#Modules].
Cartographie .[#toc-mapping]
----------------------------
-Définit les règles par lesquelles le nom de la classe est dérivé du nom du présentateur. On les inscrit dans la [configuration] sous la clé `application › mapping`.
+Le mappage définit les règles permettant de dériver le nom de la classe à partir du nom du présentateur. Ces règles sont spécifiées dans la [configuration |configuration] sous la clé `application › mapping`.
-Commençons par un exemple qui n'utilise pas de modules. Nous voulons simplement que les classes du présentateur aient l'espace de nom `App\Presenters`. Cela signifie qu'un présentateur tel que `Home` doit correspondre à la classe `App\Presenters\HomePresenter`. Ceci peut être réalisé par la configuration suivante :
+Tous les exemples de ce chapitre sont basés sur la configuration de mappage suivante :
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Le nom du présentateur est remplacé par l'astérisque dans le masque de classe et le résultat est le nom de la classe. Facile !
+Pour une meilleure compréhension, considérons d'abord une application sans modules. Nous voulons que les classes de présentateurs relèvent de l'espace de noms `App\UI`. Pour faire correspondre le présentateur `Home` à la classe `App\UI\HomePresenter`, nous procédons à la configuration suivante :
-Si nous divisons les présentateurs en modules, nous pouvons avoir notre propre mappage pour chaque module :
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Ce mappage fonctionne en remplaçant l'astérisque du masque `App\UI\*Presenter` par le nom du présentateur `Home`, ce qui donne le nom de classe final `App\UI\HomePresenter`. C'est simple !
+
+Cependant, comme vous pouvez le voir dans les exemples de ce chapitre et d'autres chapitres, nous plaçons les classes de présentateurs dans des sous-répertoires éponymes, par exemple, le présentateur `Home` est associé à la classe `App\UI\Home\HomePresenter`. Pour ce faire, il suffit de doubler l'astérisque (Nette Application 3.2 requise) :
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Passons maintenant au mappage des présentateurs dans les modules. Nous pouvons définir des correspondances spécifiques pour chaque module :
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Maintenant, le présentateur `Front:Home` correspond à la classe `App\Modules\Front\Presenters\HomePresenter` et le présentateur `Admin:Dashboard` à la classe `App\Modules\Admin\Presenters\DashboardPresenter`.
+Selon cette configuration, le présentateur `Front:Home` correspond à la classe `App\UI\Front\Home\HomePresenter`, tandis que le présentateur `Api:OAuth` correspond à la classe `App\Api\OAuthPresenter`.
-Il est plus pratique de créer une règle générale (étoile) pour remplacer les deux premières. L'astérisque supplémentaire sera ajouté au masque de classe uniquement pour le module :
+Étant donné que les modules `Front` et `Admin` ont une approche de mappage similaire et qu'il est probable qu'il y ait d'autres modules de ce type, il est possible de créer une règle générale qui les remplace. Un nouvel astérisque pour le module est ajouté au masque de classe :
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Mais qu'en est-il si nous utilisons des modules imbriqués et que nous avons un présentateur `Admin:User:Edit`? Dans ce cas, le segment avec un astérisque représentant le module pour chaque niveau est simplement répété et le résultat est la classe `App\Modules\Admin\User\Presenters\EditPresenter`.
+Pour les modules imbriqués à plusieurs niveaux, tels que le présentateur `Admin:User:Edit`, le segment astérisque se répète pour chaque niveau, ce qui donne la classe `App\UI\Admin\User\Edit\EditPresenter`.
-Une notation alternative consiste à utiliser un tableau composé de trois segments au lieu d'une chaîne de caractères. Cette notation est équivalente à la précédente :
+Une autre notation consiste à utiliser un tableau composé de trois segments au lieu d'une chaîne. Cette notation est équivalente à la précédente :
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-La valeur par défaut est `*Module\*Presenter`.
diff --git a/application/fr/templates.texy b/application/fr/templates.texy
index 8ecd733495..dc2ccff07f 100644
--- a/application/fr/templates.texy
+++ b/application/fr/templates.texy
@@ -34,35 +34,81 @@ Et ceci pourrait être le modèle d'action :
Il définit le bloc `content`, qui est inséré à la place de `{include content}` dans la mise en page, et redéfinit également le bloc `title`, qui écrase `{block title}` dans la mise en page. Essayez d'imaginer le résultat.
-Recherche de modèles .[#toc-search-for-templates]
--------------------------------------------------
+Recherche de modèles .[#toc-template-lookup]
+--------------------------------------------
-Le chemin vers les modèles est déduit selon une logique simple. Il essaie de voir si l'un de ces fichiers modèles existe par rapport au répertoire où se trouve la classe du présentateur, où `` est le nom du présentateur actuel et `` est le nom de l'action en cours :
+Dans les présentateurs, vous n'avez pas besoin de spécifier quel modèle doit être rendu ; le cadre détermine automatiquement le chemin, ce qui facilite le codage.
-- `templates//.latte`
-- `templates/..latte`
+Si vous utilisez une structure de répertoires dans laquelle chaque présentateur a son propre répertoire, placez simplement le modèle dans ce répertoire sous le nom de l'action (c'est-à-dire de la vue). Par exemple, pour l'action `default`, utilisez le modèle `default.latte`:
-Si le modèle n'est pas trouvé, il essaiera de chercher dans le répertoire `templates` au niveau supérieur, c'est-à-dire au même niveau que le répertoire contenant la classe du présentateur.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Si le modèle n'y est pas trouvé non plus, la réponse est une [erreur 404 |presenters#Error 404 etc.].
+Si vous utilisez une structure dans laquelle les présentateurs sont regroupés dans un répertoire et les modèles dans un dossier `templates`, enregistrez-les dans un fichier `..latte` soit dans un fichier `/.latte`:
-Vous pouvez également changer la vue en utilisant `$this->setView('otherView')`. Ou, au lieu de chercher, spécifiez directement le nom du fichier de modèle en utilisant `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+Le répertoire `templates` peut également être placé un niveau plus haut, au même niveau que le répertoire des classes de présentateurs.
+
+Si le modèle n'est pas trouvé, le présentateur répond par l'[erreur 404 - page non trouvée |presenters#Error 404 etc].
+
+Vous pouvez changer la vue en utilisant `$this->setView('anotherView')`. Il est également possible de spécifier directement le fichier de modèle avec `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Vous pouvez modifier les chemins dans lesquels les modèles sont recherchés en remplaçant la méthode [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], qui renvoie un tableau de chemins de fichiers possibles.
+Les fichiers dans lesquels les modèles sont recherchés peuvent être modifiés en remplaçant la méthode [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], qui renvoie un tableau de noms de fichiers possibles.
+
+
+Recherche de modèles de mise en page .[#toc-layout-template-lookup]
+-------------------------------------------------------------------
+
+Nette recherche également automatiquement le fichier de mise en page.
+
+Si vous utilisez une structure de répertoires dans laquelle chaque présentateur a son propre répertoire, placez le modèle soit dans le dossier du présentateur, s'il lui est propre, soit à un niveau supérieur s'il est commun à plusieurs présentateurs :
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Si vous utilisez une structure dans laquelle les présentateurs sont regroupés dans un répertoire et les modèles dans un dossier `templates`, la mise en page sera attendue aux endroits suivants :
-Le modèle est attendu dans les fichiers suivants :
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` mise en page commune à plusieurs présentateurs
+Si le présentateur se trouve dans un [module |modules], il cherchera également plus haut dans l'arborescence du répertoire en fonction de l'imbrication du module.
-`` est le nom du présentateur actuel et `` est le nom de la mise en page, qui est par défaut `'layout'`. Le nom peut être modifié avec `$this->setLayout('otherLayout')`, de sorte que les fichiers `@otherLayout.latte` seront essayés.
+Le nom de la présentation peut être modifié à l'aide de `$this->setLayout('layoutAdmin')` et sera alors attendu dans le fichier `@layoutAdmin.latte`. Vous pouvez également spécifier directement le fichier de modèle de présentation en utilisant `$this->setLayout('/path/to/template.latte')`.
-Vous pouvez également spécifier directement le nom du fichier du modèle de présentation en utilisant `$this->setLayout('/path/to/template.latte')`. L'utilisation de `$this->setLayout(false)` désactivera la recherche de la mise en page.
+L'utilisation de `$this->setLayout(false)` ou de la balise `{layout none}` à l'intérieur du modèle désactive la recherche de modèle.
.[note]
-Vous pouvez modifier les chemins dans lesquels les modèles sont recherchés en remplaçant la méthode [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], qui renvoie un tableau de chemins de fichiers possibles.
+Les fichiers dans lesquels les modèles de présentation sont recherchés peuvent être modifiés en remplaçant la méthode [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], qui renvoie un tableau de noms de fichiers possibles.
Variables dans le modèle .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ L'annotation `@property-read` est pour les IDE et l'analyse statique, elle fera
Vous pouvez aussi vous offrir le luxe de chuchoter dans les templates, il suffit d'installer le plugin Latte dans PhpStorm et de spécifier le nom de la classe au début du template, voir l'article "Latte : how to type system":https://blog.nette.org/fr/latte-comment-utiliser-le-systeme-de-type:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte version 3 propose un moyen plus avancé en créant une [extension |latte:creating-extension] pour chaque projet web. Voici un exemple approximatif d'une telle classe :
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Nous l'enregistrons en utilisant la [configuration |configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/hu/how-it-works.texy b/application/hu/how-it-works.texy
index 5101363032..24d0e0cba1 100644
--- a/application/hu/how-it-works.texy
+++ b/application/hu/how-it-works.texy
@@ -22,13 +22,13 @@ A könyvtárszerkezet valahogy így néz ki:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← alapvető szükséges osztályok
+│ │ └── RouterFactory.php ← URL címek konfigurálása
+│ ├── UI/ ← prezenterek, sablonok és társai.
+│ │ ├── @layout.latte ← a megosztott elrendezés sablonja
+│ │ └── Home/ ← Főoldal bemutatókönyvtár
+│ │ ├── HomePresenter.php ← Home prezenter osztály
+│ │ └── default.latte ← cselekvési sablon default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ A Nette-ben írt alkalmazások sok úgynevezett prezenterre oszlanak (más keret
Az alkalmazás azzal indul, hogy az ún. routertől kéri, hogy döntse el, hogy az aktuális kérést melyik prezenternek adja át feldolgozásra. A router dönti el, hogy kinek a felelőssége. Megnézi a bemeneti URL-t `https://example.com/product/123`, aki a `show` egy terméket `id: 123` művelettel akarja ellátni. Jó szokás a prezenter + akció párokat kettősponttal elválasztva `Product:show`-ként írni.
-Tehát a router az URL-t átalakította `Presenter:action` + paraméterek párrá, esetünkben `Product:show` + `id: 123`. A `app/Router/RouterFactory.php` fájlban láthatjuk, hogyan néz ki egy útválasztó, és ezt részletesen az [Útválasztás |Routing] fejezetben fogjuk leírni.
+Tehát a router az URL-t átalakította `Presenter:action` + paraméterek párrá, esetünkben `Product:show` + `id: 123`. A `app/Core/RouterFactory.php` fájlban láthatjuk, hogyan néz ki egy útválasztó, és ezt részletesen az [Útválasztás |Routing] fejezetben fogjuk leírni.
Lépjünk tovább. Az alkalmazás már ismeri a bemutató nevét, és folytathatja. Egy `ProductPresenter` objektum létrehozásával, amely a `Product` bemutató kódja. Pontosabban megkéri a DI konténert a prezenter létrehozására, mert az objektumok előállítása az ő feladata.
@@ -121,12 +121,9 @@ Tehát a `renderShow(123)` metódust hívtuk meg, amelynek kódja fiktív példa
Ezt követően a prezenter visszaadja a választ. Ez lehet egy HTML oldal, egy kép, egy XML dokumentum, egy fájl elküldése a lemezről, JSON vagy egy másik oldalra való átirányítás. Fontos, hogy ha nem mondjuk meg kifejezetten, hogyan kell válaszolni (ami a `ProductPresenter` esetében a helyzet), akkor a válasz az lesz, hogy a sablon egy HTML-oldallal jeleníti meg a sablont. Hogy miért? Nos, mert az esetek 99%-ában egy sablont szeretnénk kirajzolni, így a prezentáló ezt a viselkedést veszi alapértelmezettnek, és a mi munkánkat akarja megkönnyíteni. Ez a Nette lényege.
-Még csak meg sem kell adnunk, hogy melyik sablont rajzoljuk ki, egyszerű logika szerint levezeti az oda vezető utat. A presenter `Product` és az action `show` esetében megnézi, hogy létezik-e valamelyik sablonfájl a `ProductPresenter` osztály könyvtárához képest, ahol a osztály található:
+Még azt sem kell megadnunk, hogy melyik sablont kell megjelenítenünk; a keretrendszer magától levonja az útvonalat. A `show` akció esetében egyszerűen megpróbálja betölteni a `show.latte` sablont a `ProductPresenter` osztályt tartalmazó könyvtárban. Megpróbálja megtalálni az elrendezést is a `@layout.latte` fájlban (a [sablonkeresésről |templates#Template Lookup] bővebben).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Megpróbálja megtalálni az elrendezést is a `@layout.latte` fájlban, majd rendereli a sablont. Ezzel a prezenter és az egész alkalmazás feladata befejeződött. Ha a sablon nem létezik, akkor egy 404-es hibaüzenetű oldal fog visszakerülni. A prezenterekről bővebben a [Prezenterek |Presenters] oldalon olvashat.
+Ezt követően a sablonok megjelenítésre kerülnek. Ezzel a bemutató és az egész alkalmazás feladata befejeződik, és a munka elvégeztetett. Ha a sablon nem létezne, akkor egy 404-es hibaoldalt kapna vissza. A prezenterekről bővebben a [Prezenterek |presenters] oldalon olvashat.
[* request-flow.svg *]
@@ -137,7 +134,7 @@ A biztonság kedvéért próbáljuk meg az egész folyamatot egy kicsit más URL
3) a router dekódolja az URL-t, mint egy párat `Home:default`
4) létrejön egy `HomePresenter` objektum
5) a `renderDefault()` metódust meghívjuk (ha létezik)
-6) egy `templates/Home/default.latte` sablon `templates/@layout.latte` elrendezéssel megjelenik.
+6) egy `default.latte` sablon `@layout.latte` elrendezéssel megjelenik.
Lehet, hogy most sok új fogalommal találkoztál, de úgy gondoljuk, hogy van értelme. Az alkalmazások létrehozása a Nette-ben gyerekjáték.
diff --git a/application/hu/modules.texy b/application/hu/modules.texy
index e4ec0d80aa..ff2ba3fb63 100644
--- a/application/hu/modules.texy
+++ b/application/hu/modules.texy
@@ -2,29 +2,31 @@ Modulok
*******
.[perex]
-A Nette-ben a modulok az alkalmazást alkotó logikai egységeket jelentik. Ide tartoznak a prezenterek, sablonok, esetleg komponensek és modellosztályok.
+A modulok a Nette-alkalmazások áttekinthetőségét segítik elő azáltal, hogy megkönnyítik a logikai egységekre való egyszerű felosztást.
-Egy könyvtár a bemutatóknak és egy a sablonoknak nem lenne elég a valódi projektekhez. Több tucat fájl egy mappában való elhelyezése legalábbis rendezetlen. Hogyan szabadulhatunk meg ettől? Egyszerűen felosztjuk őket alkönyvtárakra a lemezen és névterekre a kódban. És pontosan ezt teszik a Nette modulok.
-
-Felejtsük el tehát az egyetlen mappát az előadóknak és a sablonoknak, és helyette hozzunk létre modulokat, például a `Admin` és a `Front`.
+Hasonlóan a fájlok mappákba rendezéséhez a merevlemezen, a Nette-ben modulokba oszthatjuk a prezentereket, sablonokat és más segédosztályokat. Hogyan működik ez a gyakorlatban? Egyszerűen úgy, hogy új alkönyvtárakat építünk be a struktúrába. Íme egy példa egy struktúrára két modullal, a Front és az Admin modulokkal:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Ezt a könyvtárszerkezetet az osztályok névterei is tükrözni fogják, így például a `DashboardPresenter` a `App\Modules\Admin\Presenters` névtérben lesz:
+Ez a könyvtárszerkezet tükröződik az osztályok névterében, így például a `DashboardPresenter` a `App\UI\Admin\Dashboard` névtérben található:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-A `Dashboard` prezenterre a `Admin` modulon belül az alkalmazáson belül a kettőspont jelöléssel `Admin:Dashboard`, a `default` műveletre pedig `Admin:Dashboard:default` néven hivatkozunk.
-És honnan tudja a Nette proper, hogy a `Admin:Dashboard` a `App\Modules\Admin\Presenters\DashboardPresenter` osztályt képviseli? Ezt a konfigurációban történő [leképezéssel |#mapping] határozzuk meg.
-A megadott struktúra tehát nem keményen meghatározott, és Ön az igényeinek megfelelően módosíthatja.
+Az alkalmazásban a `Dashboard` bemutatóra a `Admin` modulon belül a `Admin:Dashboard` kettőspont jelöléssel hivatkozunk a . A `default` műveletére `Admin:Dashboard:default` néven hivatkozunk.
-A modulok természetesen a prezentereken és sablonokon kívül minden más elemet is tartalmazhatnak, például komponenseket, modellosztályokat stb.
+A bemutatott struktúra nem merev; a konfigurációban [teljes mértékben az igényeihez igazíthatja |#mapping]. .[tip]
+
+A modulok a prezentereken és sablonokon kívül minden más fájlt, például komponenseket és segédosztályokat is tartalmazhatnak. Ha mérlegeli, hogy hol helyezze el ezeket, fontolja meg a `Accessory` mappa használatát:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Beágyazott modulok .[#toc-nested-modules]
-----------------------------------------
-A moduloknak nem kell csak sima struktúrát alkotniuk, létrehozhatunk például almodulokat is:
+A modulok több szinten is egymásba ágyazhatók, hasonlóan a lemezen lévő könyvtárstruktúrához:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Így a `Blog` modul `Admin` és `Front` almodulokra oszlik. Ez ismét tükröződik a névterekben, amelyek a `App\Modules\Blog\Admin\Presenters` stb. lesznek. Az almodulon belüli `Dashboard` bemutatót `Blog:Admin:Dashboard` néven említjük.
+A `Blog` modul `Admin` és `Front` almodulokra oszlik. Ez tükröződik a névterekben is, amelyek aztán `App\UI\Blog\Admin` és hasonló módon jelennek meg. A `Dashboard` bemutatóra a `Admin` almodulon belül `Blog:Admin:Dashboard` néven hivatkozunk.
-A beágyazás tetszőlegesen mélyre mehet, így al-almodulok hozhatók létre.
+A beágyazás olyan mély lehet, amilyen mélyre csak szükséges, lehetővé téve al-almodulok létrehozását.
+
+Például, ha az adminisztrációban sok, a rendeléskezeléshez kapcsolódó prezenter van, mint például `OrderDetail`, `OrderEdit`, `OrderDispatch`, stb., létrehozhat egy `Order` modult, amelyben a `Detail`, `Edit`, `Dispatch`, stb. típusú prezentereket szervezi.
Linkek létrehozása .[#toc-creating-links]
@@ -99,49 +115,62 @@ Hogy megtudjuk, hogy egy adott modulban vagy annak almoduljában vagyunk-e, hasz
Lásd [az útválasztásról szóló fejezetet |routing#Modules].
-Feltérképezés .[#toc-mapping]
------------------------------
+A feltérképezése .[#toc-mapping]
+---------------------------------
-Meghatározza azokat a szabályokat, amelyek alapján az osztály neve az előadó nevéből származik. Ezeket a [konfigurációban |configuration] a `application › mapping` kulcs alatt írjuk le.
+A leképezés határozza meg az osztálynévnek a bemutató nevéből való származtatásának szabályait. Ezek a szabályok a [konfigurációban |configuration] a `application › mapping` kulcs alatt vannak megadva.
-Kezdjük egy olyan példával, amely nem használ modulokat. Csak azt akarjuk, hogy a prezenter osztályok a `App\Presenters` névtérrel rendelkezzenek. Ez azt jelenti, hogy egy olyan prezenternek, mint a `Home`, a `App\Presenters\HomePresenter` osztályhoz kell kapcsolódnia. Ezt a következő konfigurációval érhetjük el:
+A fejezetben szereplő összes példa a következő leképezési konfiguráción alapul:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Az osztálymaszkban a prezenter nevét csillaggal helyettesítjük, és az eredmény az osztály neve lesz. Easy!
+A jobb megértés érdekében tekintsünk először egy modulok nélküli alkalmazást. Azt szeretnénk, ha a prezentáló osztályok a `App\UI` névtérbe tartoznának. Ahhoz, hogy a `Home` prezentert a `App\UI\HomePresenter` osztályhoz rendeljük, ezt a következő konfigurációval érjük el:
-Ha az előadókat modulokra osztjuk, akkor minden modulhoz saját leképezésünk lehet:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Ez a leképezés úgy működik, hogy a `App\UI\*Presenter` maszkban a csillagot a `Home` prezenter névvel helyettesítjük, így kapjuk a `App\UI\HomePresenter` végső osztálynevet. Egyszerű!
+
+Azonban, ahogyan azt az ebben és más fejezetekben található példákban láthatjuk, a prezenter osztályokat névadó alkönyvtárakba helyezzük, például a `Home` prezenter a `App\UI\Home\HomePresenter` osztályra van leképezve. Ezt a csillag megduplázásával érjük el (Nette Application 3.2 szükséges):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Most pedig térjünk rá az előadók modulokba való leképezésére. Minden egyes modulhoz sajátos hozzárendeléseket határozhatunk meg:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Most a `Front:Home` bemutatót a `App\Modules\Front\Presenters\HomePresenter` osztályra, a `Admin:Dashboard` bemutatót pedig a `App\Modules\Admin\Presenters\DashboardPresenter` osztályra képezzük le.
+E konfiguráció szerint a `Front:Home` bemutató a `App\UI\Front\Home\HomePresenter` osztályhoz, míg a `Api:OAuth` bemutató a `App\Api\OAuthPresenter` osztályhoz tartozik.
-Praktikusabb egy általános (csillag) szabályt létrehozni az első kettő helyett. Az extra csillagot csak a modul számára adjuk hozzá az osztálymaszkhoz:
+Mivel a `Front` és a `Admin` modulok hasonló leképezési megközelítéssel rendelkeznek, és valószínűleg több ilyen modul is létezik, létrehozható egy általános szabály, amely ezeket helyettesíti. Az osztálymaszkhoz egy új csillagot adunk a modulhoz:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-De mi van akkor, ha egymásba ágyazott modulokat használunk, és van egy bemutató `Admin:User:Edit`? Ebben az esetben a modult jelképező csillaggal ellátott szegmens minden szinten egyszerűen megismétlődik, és az eredmény a `App\Modules\Admin\User\Presenters\EditPresenter` osztály lesz.
+A többszintű, egymásba ágyazott modulok esetében, mint például a `Admin:User:Edit` bemutató, a csillagszegmens minden szinten megismétlődik, így a `App\UI\Admin\User\Edit\EditPresenter` osztály lesz az eredmény.
-Egy alternatív jelölés az, hogy a karakterlánc helyett egy három szegmensből álló tömböt használunk. Ez a jelölés egyenértékű az előzővel:
+Egy alternatív jelölés a karakterlánc helyett egy három szegmensből álló tömb használata. Ez a jelölés egyenértékű az előzővel:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Az alapértelmezett érték a `*Module\*Presenter`.
diff --git a/application/hu/templates.texy b/application/hu/templates.texy
index 71b205b7d1..d51d03bbc6 100644
--- a/application/hu/templates.texy
+++ b/application/hu/templates.texy
@@ -34,35 +34,81 @@ Az a szokásos, hogy az oldal az elrendezési sablonból + az akció sablonból
Meghatározza a `content` blokkot, amely az elrendezésben a `{include content}` helyére kerül, és újra definiálja a `title` blokkot is, amely felülírja az elrendezésben a `{block title}` blokkot. Próbálja meg elképzelni az eredményt.
-Sablonok keresése .[#toc-search-for-templates]
-----------------------------------------------
+Sablon keresés .[#toc-template-lookup]
+--------------------------------------
-A sablonok elérési útvonalát egyszerű logika szerint vezetjük le. Megpróbálja megnézni, hogy létezik-e valamelyik sablonfájl ahhoz a könyvtárhoz képest, ahol a prezenter osztály található, ahol a `` az aktuális prezenter neve és `` az aktuális művelet neve:
+A prezenterekben nem kell megadnia, hogy melyik sablont kell megjeleníteni; a keretrendszer automatikusan meghatározza az útvonalat, megkönnyítve ezzel a kódolást.
-- `templates//.latte`
-- `templates/..latte`
+Ha olyan könyvtárstruktúrát használ, ahol minden prezenternek saját könyvtára van, egyszerűen helyezze el a sablont ebben a könyvtárban az akció (pl. nézet) neve alatt. Például a `default` művelethez használja a `default.latte` sablont:
-Ha a sablon nem található, a program megpróbál a `templates` könyvtárban keresni egy szinttel feljebb, azaz ugyanazon a szinten, mint a bemutató osztályt tartalmazó könyvtár.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Ha a sablon ott sem található, a válasz [404-es hiba |presenters#Error 404 etc.].
+Ha olyan struktúrát használ, ahol az előadók együttesen egy könyvtárban vannak, a sablonok pedig a `templates` mappában, mentse el vagy egy fájlban `..latte` vagy a `/.latte`:
-A nézetet a `$this->setView('otherView')` segítségével is megváltoztathatja. Vagy a keresés helyett közvetlenül megadhatja a sablonfájl nevét a `$this->template->setFile('/path/to/template.latte')` segítségével.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+A `templates` könyvtár egy szinttel feljebb is elhelyezhető, ugyanazon a szinten, mint az előadói osztályokat tartalmazó könyvtár.
+
+Ha a sablon nem található, a prezenter [404 - page not found hibával |presenters#Error 404 etc] válaszol.
+
+A nézetet a `$this->setView('anotherView')` segítségével lehet megváltoztatni. Lehetőség van a sablonfájl közvetlen megadására is a `$this->template->setFile('/path/to/template.latte')` segítségével.
.[note]
-A [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()] metódus felülbírálásával módosíthatja azokat az elérési utakat, ahol a sablonok keresése történik, amely a lehetséges fájl elérési utak tömbjét adja vissza.
+A fájlokat, amelyekben a sablonok keresése történik, a [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()] metódus felülbírálásával lehet megváltoztatni, amely a lehetséges fájlnevek tömbjét adja vissza.
+
+
+Layout sablon keresés .[#toc-layout-template-lookup]
+----------------------------------------------------
+
+A Nette automatikusan megkeresi az elrendezési fájlt is.
+
+Ha olyan könyvtárstruktúrát használ, ahol minden előadónak saját könyvtára van, akkor az elrendezést vagy az előadóval közös mappába helyezze el, ha csak rá jellemző, vagy egy szinttel feljebb, ha több előadó számára közös:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Ha olyan struktúrát használ, ahol az előadók egy könyvtárban vannak csoportosítva, a sablonok pedig a `templates` mappában találhatók, az elrendezés a következő helyeken várható:
-Az elrendezés a következő fájlokban várható:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` több előadónál közös elrendezés
+Ha a bemutató egy [modulban |modules] van, akkor a modul beágyazottságának megfelelően a könyvtárfában feljebb is keresni fog.
-`` az aktuális előadó neve és `` az elrendezés neve, amely alapértelmezés szerint `'layout'`. A név megváltoztatható a `$this->setLayout('otherLayout')` segítségével, így a `@otherLayout.latte` fájlokat próbálja meg.
+Az elrendezés nevét a `$this->setLayout('layoutAdmin')` segítségével lehet megváltoztatni, majd a `@layoutAdmin.latte` fájlban várjuk el. Az elrendezés sablonfájlt közvetlenül is megadhatja a `$this->setLayout('/path/to/template.latte')` segítségével.
-Az elrendezéssablon fájlnevét közvetlenül is megadhatja a `$this->setLayout('/path/to/template.latte')` segítségével. A `$this->setLayout(false)` használata letiltja az elrendezés keresését.
+A `$this->setLayout(false)` vagy a `{layout none}` címke használata a sablonon belül kikapcsolja az elrendezéskeresést.
.[note]
-A [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] metódus felülbírálásával módosíthatja a sablonok keresési útvonalait, amely a lehetséges fájlútvonalak tömbjét adja vissza.
+A fájlok, amelyekben az elrendezési sablonok keresése történik, megváltoztathatók a [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] metódus felülbírálásával, amely a lehetséges fájlnevek tömbjét adja vissza.
Változók a sablonban .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ A `@property-read` annotáció az IDE és a statikus elemzés számára készül
A sablonokban is megengedheted magadnak a suttogás luxusát, csak telepítsd a Latte plugint a PhpStormban, és add meg az osztály nevét a sablon elején, lásd a "Latte: hogyan kell tipizálni a rendszert":https://blog.nette.org/hu/latte-hogyan-kell-hasznalni-a-tipusrendszert című cikket:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
A Latte 3. verziója egy fejlettebb módszert kínál, amely minden egyes webes projekthez egy [bővítményt |latte:creating-extension] hoz létre. Íme egy durva példa egy ilyen osztályra:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ A [configuration |configuration#Latte] segítségével regisztráljuk:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/it/how-it-works.texy b/application/it/how-it-works.texy
index 91e4f4e5ef..3222b1f408 100644
--- a/application/it/how-it-works.texy
+++ b/application/it/how-it-works.texy
@@ -22,13 +22,13 @@ La struttura delle directory è simile a questa:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← classi di base necessarie
+│ │ └── RouterFactory.php ← configurazione degli indirizzi URL
+│ ├── UI/ ← presenter, template & co.
+│ │ ├── @layout.latte ← modello di layout condiviso
+│ │ └── Home/ ← cartella del presentatore Home
+│ │ ├── HomePresenter.php ← Classe del presentatore della casa
+│ │ └── default.latte ← template per l'azione default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Le applicazioni scritte in Nette sono suddivise in molti cosiddetti presenter (i
L'applicazione inizia chiedendo al cosiddetto router di decidere a quale dei presenter passare la richiesta corrente per l'elaborazione. Il router decide di chi è la responsabilità. Osserva l'URL di ingresso `https://example.com/product/123`, che vuole `show` un prodotto con `id: 123` come azione. È buona abitudine scrivere le coppie presentatore + azione separate da due punti come `Product:show`.
-Quindi il router ha trasformato l'URL in una coppia `Presenter:action` + parametri, nel nostro caso `Product:show` + `id: 123`. Si può vedere l'aspetto di un router nel file `app/Router/RouterFactory.php` e lo descriveremo in dettaglio nel capitolo [Routing |Routing].
+Quindi il router ha trasformato l'URL in una coppia `Presenter:action` + parametri, nel nostro caso `Product:show` + `id: 123`. Si può vedere l'aspetto di un router nel file `app/Core/RouterFactory.php` e lo descriveremo in dettaglio nel capitolo [Routing |Routing].
Andiamo avanti. L'applicazione conosce già il nome del presentatore e può continuare. Creando un oggetto `ProductPresenter`, che è il codice del presentatore `Product`. Più precisamente, chiede al contenitore DI di creare il presentatore, perché produrre oggetti è il suo lavoro.
@@ -121,12 +121,9 @@ Quindi, è stato chiamato il metodo `renderShow(123)`, il cui codice è un esemp
Successivamente, il presentatore restituisce la risposta. Questa può essere una pagina HTML, un'immagine, un documento XML, l'invio di un file dal disco, JSON o il reindirizzamento a un'altra pagina. È importante notare che, se non si dice esplicitamente come rispondere (come nel caso di `ProductPresenter`), la risposta sarà il rendering del modello con una pagina HTML. Perché? Perché nel 99% dei casi vogliamo disegnare un modello, quindi il presentatore prende questo comportamento come predefinito e vuole semplificarci il lavoro. Questo è il punto di Nette.
-Non dobbiamo nemmeno dichiarare quale modello disegnare, lui ricava il percorso per raggiungerlo secondo una semplice logica. Nel caso del presenter `Product` e dell'azione `show`, cerca di vedere se esiste uno di questi file di template relativi alla directory in cui si trova la classe `ProductPresenter`:
+Non è nemmeno necessario specificare quale template rendere; il framework dedurrà da solo il percorso. Nel caso dell'azione `show`, cerca semplicemente di caricare il template `show.latte` nella cartella con la classe `ProductPresenter`. Cerca anche di trovare il layout nel file `@layout.latte` (maggiori informazioni sulla [ricerca dei template |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Cercherà anche di trovare il layout nel file `@layout.latte` e quindi eseguirà il rendering del modello. Ora il compito del presentatore e dell'intera applicazione è completato. Se il modello non esiste, verrà restituita una pagina con errore 404. Per saperne di più sui presentatori, consultare la pagina [Presentatori |Presenters].
+Successivamente, i modelli vengono renderizzati. Questo completa il compito del presentatore e dell'intera applicazione e il lavoro è terminato. Se il modello non esistesse, verrebbe restituita una pagina di errore 404. Per saperne di più sui presentatori, consultare la pagina [Presentatori |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Per sicurezza, proviamo a riepilogare l'intero processo con un URL leggermente d
3) il router decodifica l'URL come una coppia di oggetti `Home:default`
4) viene creato un oggetto `HomePresenter`
5) viene richiamato il metodo `renderDefault()` (se esiste)
-6) viene reso un modello `templates/Home/default.latte` con un layout `templates/@layout.latte`
+6) viene reso un modello `default.latte` con un layout `@layout.latte`
Potreste esservi imbattuti in molti concetti nuovi, ma crediamo che abbiano un senso. Creare applicazioni in Nette è un gioco da ragazzi.
diff --git a/application/it/modules.texy b/application/it/modules.texy
index 76b8af4e23..c4f80d189d 100644
--- a/application/it/modules.texy
+++ b/application/it/modules.texy
@@ -2,29 +2,31 @@ Moduli
******
.[perex]
-In Nette, i moduli rappresentano le unità logiche che compongono un'applicazione. Comprendono presentatori, modelli, eventualmente anche componenti e classi di modelli.
+I moduli conferiscono chiarezza alle applicazioni Nette, facilitando la suddivisione in unità logiche.
-Una cartella per i presentatori e una per i modelli non sarebbe sufficiente per i progetti reali. Avere decine di file in una cartella è quantomeno disorganizzato. Come uscirne? Semplicemente dividendoli in sottodirectory su disco e in spazi dei nomi nel codice. E questo è esattamente ciò che fanno i moduli Nette.
-
-Dimentichiamo quindi un'unica cartella per i presentatori e i modelli e creiamo invece dei moduli, ad esempio `Admin` e `Front`.
+Analogamente all'organizzazione dei file in cartelle su un disco rigido, in Nette possiamo dividere presentatori, modelli e altre classi ausiliarie in moduli. Come funziona in pratica? Semplicemente incorporando nuove sottodirectory nella struttura. Ecco un esempio di struttura con due moduli, Front e Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Questa struttura di cartelle si rifletterà negli spazi dei nomi delle classi, quindi ad esempio `DashboardPresenter` sarà nello spazio dei nomi `App\Modules\Admin\Presenters`:
+Questa struttura di directory si riflette negli spazi dei nomi delle classi, per cui, ad esempio, `DashboardPresenter` si trova nello spazio dei nomi `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Il presentatore `Dashboard` all'interno del modulo `Admin` è referenziato all'interno dell'applicazione usando la notazione dei due punti come `Admin:Dashboard`, e la sua azione `default` come `Admin:Dashboard:default`.
-E come fa Nette a sapere che `Admin:Dashboard` rappresenta la classe `App\Modules\Admin\Presenters\DashboardPresenter`? Questo è determinato dalla [mappatura |#mapping] nella configurazione.
-Pertanto, la struttura data non è rigida e può essere modificata in base alle proprie esigenze.
+Nell'applicazione, ci si riferisce al presentatore `Dashboard` all'interno del modulo `Admin` usando la notazione dei due punti come `Admin:Dashboard`. Per l'azione `default`, ci si riferisce ad essa come `Admin:Dashboard:default`.
-I moduli possono naturalmente contenere tutti gli altri elementi oltre ai presentatori e ai modelli, come componenti, classi di modelli, ecc.
+La struttura presentata non è rigida; è possibile [personalizzarla completamente in base alle proprie esigenze |#mapping] nella configurazione. .[tip]
+
+I moduli possono includere tutti gli altri file, come i componenti e le classi ausiliarie, oltre ai presentatori e ai modelli. Se si sta valutando dove collocare questi ultimi, si può prendere in considerazione l'uso di una cartella `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Moduli annidati .[#toc-nested-modules]
--------------------------------------
-I moduli non devono formare solo una struttura piatta, ma si possono anche creare sottomoduli, ad esempio:
+I moduli possono avere più livelli di annidamento, simili a una struttura di directory su disco:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Così, il modulo `Blog` è suddiviso nei sottomoduli `Admin` e `Front`. Anche in questo caso, ciò si rifletterà negli spazi dei nomi, che saranno `App\Modules\Blog\Admin\Presenters` e così via. Il presentatore `Dashboard` all'interno del sottomodulo viene chiamato `Blog:Admin:Dashboard`.
+Il modulo `Blog` è diviso nei sottomoduli `Admin` e `Front`. Questo si riflette anche negli spazi dei nomi, che appaiono come `App\UI\Blog\Admin` e simili. Per riferirsi al presentatore `Dashboard` all'interno del sottomodulo `Admin`, ci si riferisce ad esso come `Blog:Admin:Dashboard`.
-L'annidamento può andare in profondità quanto si vuole, quindi si possono creare dei sottomoduli.
+L'annidamento può essere profondo quanto necessario, consentendo la creazione di sottomoduli.
+
+Ad esempio, se nell'amministrazione sono presenti molti presentatori relativi alla gestione degli ordini, come `OrderDetail`, `OrderEdit`, `OrderDispatch`, ecc. si può creare un modulo `Order` in cui saranno organizzati presentatori come `Detail`, `Edit`, `Dispatch`, e altri.
Creazione di collegamenti .[#toc-creating-links]
@@ -102,46 +118,59 @@ Vedere il [capitolo sull'instradamento |routing#Modules].
Mappatura .[#toc-mapping]
-------------------------
-Definisce le regole con cui il nome della classe viene derivato dal nome del presentatore. Vengono scritte nella [configurazione |configuration] sotto la chiave `application › mapping`.
+La mappatura definisce le regole per derivare il nome della classe dal nome del presentatore. Queste regole sono specificate nella [configurazione |configuration] sotto la chiave `application › mapping`.
-Cominciamo con un esempio che non usa moduli. Vogliamo solo che le classi del presentatore abbiano lo spazio dei nomi `App\Presenters`. Ciò significa che un presentatore come `Home` deve mappare alla classe `App\Presenters\HomePresenter`. Questo si può ottenere con la seguente configurazione:
+Tutti gli esempi di questo capitolo si basano sulla seguente configurazione di mappatura:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Il nome del presentatore viene sostituito con l'asterisco nella maschera della classe e il risultato è il nome della classe. Facile!
+Per una migliore comprensione, consideriamo prima un'applicazione senza moduli. Vogliamo che le classi del presentatore rientrino nello spazio dei nomi `App\UI`. Per mappare il presentatore `Home` alla classe `App\UI\HomePresenter`, lo otteniamo con la seguente configurazione:
-Se dividiamo i presentatori in moduli, possiamo avere la nostra mappatura per ogni modulo:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Questa mappatura funziona sostituendo l'asterisco nella maschera `App\UI\*Presenter` con il nome del presenter `Home`, ottenendo il nome finale della classe `App\UI\HomePresenter`. Semplice!
+
+Tuttavia, come si può vedere negli esempi di questo e di altri capitoli, le classi dei presentatori sono collocate in sottodirectory eponime, ad esempio il presentatore `Home` è mappato nella classe `App\UI\Home\HomePresenter`. Questo si ottiene raddoppiando l'asterisco (richiede Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Passiamo ora alla mappatura dei presentatori nei moduli. Possiamo definire mappature specifiche per ogni modulo:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Ora il presentatore `Front:Home` mappa alla classe `App\Modules\Front\Presenters\HomePresenter` e il presentatore `Admin:Dashboard` alla classe `App\Modules\Admin\Presenters\DashboardPresenter`.
+In base a questa configurazione, il presentatore `Front:Home` si riferisce alla classe `App\UI\Front\Home\HomePresenter`, mentre il presentatore `Api:OAuth` si riferisce alla classe `App\Api\OAuthPresenter`.
-È più pratico creare una regola generale (asterisco) per sostituire le prime due. L'asterisco in più sarà aggiunto alla maschera di classe solo per il modulo:
+Poiché i moduli `Front` e `Admin` hanno un approccio di mappatura simile e probabilmente ci saranno altri moduli di questo tipo, è possibile creare una regola generale che li sostituisca. Un nuovo asterisco per il modulo viene aggiunto alla maschera della classe:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Ma cosa succede se utilizziamo moduli annidati e abbiamo un presentatore `Admin:User:Edit`? In questo caso, il segmento con l'asterisco che rappresenta il modulo per ogni livello viene semplicemente ripetuto e il risultato è la classe `App\Modules\Admin\User\Presenters\EditPresenter`.
+Per i moduli annidati a più livelli, come il presentatore `Admin:User:Edit`, il segmento dell'asterisco si ripete per ogni livello, dando luogo alla classe `App\UI\Admin\User\Edit\EditPresenter`.
Una notazione alternativa consiste nell'utilizzare un array composto da tre segmenti invece di una stringa. Questa notazione è equivalente alla precedente:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Il valore predefinito è `*Module\*Presenter`.
diff --git a/application/it/templates.texy b/application/it/templates.texy
index bb704a88f2..2d3412da33 100644
--- a/application/it/templates.texy
+++ b/application/it/templates.texy
@@ -34,35 +34,81 @@ E questo potrebbe essere il modello di azione:
Definisce il blocco `content`, che viene inserito al posto di `{include content}` nel layout, e ridefinisce anche il blocco `title`, che sovrascrive `{block title}` nel layout. Provate a immaginare il risultato.
-Ricerca dei modelli .[#toc-search-for-templates]
-------------------------------------------------
+Ricerca di modelli .[#toc-template-lookup]
+------------------------------------------
+
+Nei presentatori, non è necessario specificare quale template debba essere reso; il framework determinerà automaticamente il percorso, semplificando la codifica.
+
+Se si utilizza una struttura di cartelle in cui ogni presentatore ha una propria cartella, è sufficiente posizionare il template in questa cartella sotto il nome dell'azione (cioè della vista). Ad esempio, per l'azione `default`, utilizzare il modello `default.latte`:
-Il percorso dei modelli viene dedotto secondo una semplice logica. Si cerca di vedere se uno di questi file di template esiste relativamente alla directory in cui si trova la classe del presentatore, dove `` è il nome del presentatore corrente e `` è il nome dell'azione corrente:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Se si utilizza una struttura in cui i presentatori sono riuniti in una directory e i modelli in una cartella `templates`, salvare il tutto in un file `..latte` oppure `/.latte`:
-Se il modello non viene trovato, si cercherà nella cartella `templates` a un livello superiore, cioè allo stesso livello della cartella con la classe del presentatore.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Se il modello non viene trovato nemmeno lì, la risposta è un [errore 404 |presenters#Error 404 etc.].
+La directory `templates` può anche essere collocata un livello più in alto, allo stesso livello della directory con le classi dei presentatori.
-Si può anche cambiare la vista usando `$this->setView('otherView')`. Oppure, invece di cercare, specificare direttamente il nome del file del template usando `$this->template->setFile('/path/to/template.latte')`.
+Se il modello non viene trovato, il presentatore risponde con un [errore 404 - pagina non trovata |presenters#Error 404 etc].
+
+È possibile modificare la vista utilizzando `$this->setView('anotherView')`. È anche possibile specificare direttamente il file del modello con `$this->template->setFile('/path/to/template.latte')`.
.[note]
-È possibile modificare i percorsi in cui vengono cercati i modelli sovrascrivendo il metodo [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], che restituisce un array di possibili percorsi di file.
+I file in cui vengono cercati i modelli possono essere modificati sovrascrivendo il metodo [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], che restituisce un array di possibili nomi di file.
+
+
+Ricerca dei modelli di layout .[#toc-layout-template-lookup]
+------------------------------------------------------------
+
+Nette cerca automaticamente anche il file di layout.
+
+Se si utilizza una struttura di directory in cui ogni presentatore ha una propria directory, collocare il layout nella cartella del presentatore, se è specifico solo per lui, oppure a un livello superiore se è comune a più presentatori:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Se si utilizza una struttura in cui i presentatori sono raggruppati in una directory e i modelli si trovano in una cartella `templates`, il layout sarà previsto nei seguenti punti:
-Il layout è previsto nei seguenti file:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` layout comune a più presentatori
+Se il presentatore si trova in un [modulo |modules], cercherà anche più in alto nell'albero della directory, in base alla nidificazione del modulo.
-`` è il nome del presentatore corrente e `` è il nome del layout, che per impostazione predefinita è `'layout'`. Il nome può essere modificato con `$this->setLayout('otherLayout')`, in modo da provare i file `@otherLayout.latte`.
+Il nome del layout può essere modificato con `$this->setLayout('layoutAdmin')` e sarà previsto nel file `@layoutAdmin.latte`. È anche possibile specificare direttamente il file del modello di layout usando `$this->setLayout('/path/to/template.latte')`.
-È anche possibile specificare direttamente il nome del file del modello di layout con `$this->setLayout('/path/to/template.latte')`. L'uso di `$this->setLayout(false)` disabilita la ricerca dei layout.
+L'uso di `$this->setLayout(false)` o del tag `{layout none}` all'interno del template disabilita la ricerca del layout.
.[note]
-È possibile modificare i percorsi in cui vengono cercati i modelli sovrascrivendo il metodo [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], che restituisce un array di possibili percorsi di file.
+I file in cui vengono cercati i modelli di layout possono essere modificati sovrascrivendo il metodo [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], che restituisce un array di possibili nomi di file.
Variabili nel modello .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ L'annotazione `@property-read` è per l'IDE e l'analisi statica, farà funzionar
Ci si può concedere il lusso di sussurrare anche nei template, basta installare il plugin Latte in PhpStorm e specificare il nome della classe all'inizio del template, si veda l'articolo "Latte: come digitare il sistema":https://blog.nette.org/it/latte-come-usare-il-sistema-di-tipi:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
La versione 3 di Latte offre un metodo più avanzato, creando un'[estensione |latte:creating-extension] per ogni progetto web. Ecco un esempio approssimativo di una classe di questo tipo:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ La registriamo usando [configuration |configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/pl/how-it-works.texy b/application/pl/how-it-works.texy
index 9cbbb61f69..a2b0c8b57c 100644
--- a/application/pl/how-it-works.texy
+++ b/application/pl/how-it-works.texy
@@ -22,13 +22,13 @@ Struktura katalogów wygląda mniej więcej tak:
/--pre
web-project/
├── app/ ← adresář s aplikací
-│ ├── Presenters/ ← presentery a šablony
-│ │ ├── HomePresenter.php ← třída presenteru Home
-│ │ └── templates/ ← adresář se šablonami
-│ │ ├── @layout.latte ← šablona layoutu
-│ │ └── Home/ ← šablony presenteru Home
-│ │ └── default.latte ← šablona akce 'default'
-│ ├── Router/ ← konfigurace URL adres
+│ ├── Core/ ← podstawowe niezbędne klasy
+│ │ └── RouterFactory.php ← konfiguracja adresów URL
+│ ├── UI/ ← prezentery, szablony & co.
+│ │ ├── @layout.latte ← szablon udostępnionego layoutu
+│ │ └── Home/ ← Katalog główny prezentera
+│ │ ├── HomePresenter.php ← Klasa prezentera strony głównej
+│ │ └── default.latte ← szablon dla akcji default
│ └── Bootstrap.php ← zaváděcí třída Bootstrap
├── bin/ ← skripty spouštěné z příkazové řádky
├── config/ ← konfigurační soubory
@@ -91,7 +91,7 @@ Aplikacje napisane w Nette są podzielone na wiele prezenterów (w innych framew
Aplikacja rozpoczyna się od zapytania tzw. routera o decyzję, do którego prezentera przekazać bieżące żądanie do przetworzenia. Router decyduje o tym, czyja to odpowiedzialność. Patrzy na wejściowy URL `https://example.com/product/123`, którego poprosi o wyświetlenie (`show`) produktu z `id: 123` jako **akcji** . Dobrą praktyką jest zapisanie pary prezenter + akcja oddzielonej dwukropkiem jako `Product:show`.
-W ten sposób router przekształca adres URL w parę `Presenter:action` + parametry, w naszym przypadku `Product:show` + `id: 123`. Jak wygląda taki router, można zobaczyć w pliku `app/Router/RouterFactory.php`, a szczegółowo opisujemy go w rozdziale [Routing |Routing].
+W ten sposób router przekształca adres URL w parę `Presenter:action` + parametry, w naszym przypadku `Product:show` + `id: 123`. Jak wygląda taki router, można zobaczyć w pliku `app/Core/RouterFactory.php`, a szczegółowo opisujemy go w rozdziale [Routing |Routing].
Ruszajmy dalej. Aplikacja zna teraz nazwę prezentera i może przejść dalej. Produkując obiekt klasy `ProductPresenter`, który jest kodem prezentera `Product`. Dokładniej, prosi kontener DI o wyprodukowanie prezentera, ponieważ jest tam, aby go wyprodukować.
@@ -121,12 +121,9 @@ Wywołana jest więc metoda `renderShow(123)`, której kod jest fikcyjnym przyk
Następnie prezenter zwraca odpowiedź. Może to być strona HTML, obraz, dokument XML, wysłanie pliku z dysku, JSON, a nawet przekierowanie na inną stronę. Co ważne, o ile nie powiemy wprost prezenterowi, jak ma odpowiedzieć (co ma miejsce w przypadku `ProductPresenter`), odpowiedzią będzie renderowanie szablonu ze stroną HTML. Dlaczego? Ponieważ w 99% przypadków chcemy renderować szablon, więc prezenter przyjmuje to zachowanie jako domyślne i chce ułatwić nam pracę. O to właśnie chodzi w Nette.
-Nie musimy nawet określać, jaki szablon ma być renderowany, sam wywnioskuje ścieżkę do niego za pomocą prostej logiki. W przypadku prezentera `Product` i akcji `show`, spróbuje sprawdzić, czy istnieje jeden z tych plików szablonów przechowywanych względnie z katalogu klasy `ProductPresenter`:
+Nie musimy nawet określać, który szablon ma być renderowany; framework sam wydedukuje ścieżkę. W przypadku akcji `show`, po prostu próbuje załadować szablon `show.latte` w katalogu z klasą `ProductPresenter`. Próbuje również znaleźć układ w pliku `@layout.latte` (więcej o [wyszukiwaniu szablonów |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Spróbuje również prześledzić układ w pliku `@layout.latte`, a następnie wyrenderować szablon. W ten sposób kończy się zadanie prezentera i aplikacji, a praca zostaje zakończona. Jeśli szablon nie istnieje, zwrócona zostanie strona błędu 404. Więcej o prezenterach można przeczytać na stronie [Prezenterzy |presenters].
+Następnie szablony są renderowane. To kończy zadanie prezentera i całej aplikacji, a praca jest wykonywana. Jeśli szablon nie istnieje, zostanie zwrócona strona błędu 404. Więcej informacji na temat prezenterów można znaleźć na stronie [Prezenterzy |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Aby być bezpiecznym, spróbujmy podsumować cały proces z nieco innym adresem
3) router dekoduje adres URL jako parę `Home:default`
4) tworzony jest obiekt klasy `HomePresenter`
5) wywoływana jest metoda `renderDefault()` (jeśli istnieje)
-6) wyrenderować szablon np. `templates/Home/default.latte` z układem np. `templates/@layout.latte`
+6) wyrenderować szablon np. `default.latte` z układem np. `@layout.latte`
Teraz być może spotkałeś się z wieloma nowymi pojęciami, ale wierzymy, że mają one sens. Tworzenie aplikacji w Nette to ogromna bułka z masłem.
diff --git a/application/pl/modules.texy b/application/pl/modules.texy
index 488d8f50a3..4f553f6c90 100644
--- a/application/pl/modules.texy
+++ b/application/pl/modules.texy
@@ -2,29 +2,31 @@ Moduły
******
.[perex]
-W Nette moduły reprezentują logiczne jednostki, które tworzą aplikację. Należą do nich prezentery, szablony, ewentualnie komponenty i klasy modeli.
+Moduły zapewniają przejrzystość aplikacji Nette, ułatwiając podział na logiczne jednostki.
-Jeden komponent dla prezenterów i jeden dla szablonów nie wystarczyłby dla prawdziwych projektów. Posiadanie kilkudziesięciu plików w jednym folderze jest co najmniej niezorganizowane. Jak się z niego wydostać? Po prostu dzielimy je na podkatalogi na dysku i na przestrzenie nazw w kodzie. I właśnie to robią moduły Nette.
-
-Zapomnijmy więc o jednym folderze dla prezenterów i szablonów, a zamiast tego stwórzmy moduły, na przykład `Admin` i `Front`.
+Podobnie jak w przypadku organizowania plików w foldery na dysku twardym, w Nette możemy podzielić prezenterów, szablony i inne klasy pomocnicze na moduły. Jak to działa w praktyce? Po prostu poprzez włączenie nowych podkatalogów do struktury. Oto przykład struktury z dwoma modułami, Front i Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← adresář s moduly
-│ ├── Admin/ ← modul Admin
-│ │ ├── Presenters/ ← jeho presentery
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← modul Front
-│ └── Presenters/ ← jeho presentery
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Ta struktura katalogów będzie odzwierciedlona w przestrzeni nazw klas, więc na przykład `DashboardPresenter` będzie w przestrzeni `App\Modules\Admin\Presenters`:
+Ta struktura katalogów jest odzwierciedlona w przestrzeniach nazw klas, więc na przykład `DashboardPresenter` znajduje się w przestrzeni nazw `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Prezenter `Dashboard` wewnątrz modułu `Admin` jest określany w aplikacji za pomocą notacji z podwójną kropką jako `Admin:Dashboard`, a jego działanie `default` jest określane jako `Admin:Dashboard:default`.
-A skąd Nette own wie, że `Admin:Dashboard` reprezentuje klasę `App\Modules\Admin\Presenters\DashboardPresenter`? Mówimy to za pomocą [mapowania |#Mappings] w konfiguracji.
-Tak więc podana struktura nie jest stała i można ją modyfikować według potrzeb.
+W aplikacji odnosimy się do prezentera `Dashboard` w module `Admin` używając notacji dwukropka jako `Admin:Dashboard`. W przypadku akcji `default` odnosimy się do niej jako `Admin:Dashboard:default`.
-Moduły mogą oczywiście zawierać wszystkie inne części oprócz prezenterów i szablonów, jak komponenty, klasy modeli itp.
+Przedstawiona struktura nie jest sztywna; można [ją w pełni dostosować do własnych potrzeb |#mapping] w konfiguracji. .[tip]
+
+Moduły mogą zawierać wszystkie inne pliki, takie jak komponenty i klasy pomocnicze, oprócz prezenterów i szablonów. Jeśli zastanawiasz się, gdzie je umieścić, rozważ użycie folderu `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Moduły zagnieżdżone .[#toc-nested-modules]
------------------------------------------
-Moduły nie muszą tworzyć tylko płaskiej struktury, można też tworzyć np. submoduły:
+Moduły mogą mieć wiele poziomów zagnieżdżenia, podobnie jak struktura katalogów na dysku:
/--pre
-app/
-├── Modules/ ← adresář s moduly
-│ ├── Blog/ ← modul Blog
-│ │ ├── Admin/ ← submodul Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodul Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← modul Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Tak więc moduł `Blog` jest podzielony na podmoduły `Admin` i `Front`. I znowu będzie to odzwierciedlone w przestrzeni nazw, która będzie `App\Modules\Blog\Admin\Presenters` itd. Prezenter `Dashboard` wewnątrz submodułu jest określany jako `Blog:Admin:Dashboard`.
+Moduł `Blog` jest podzielony na podmoduły `Admin` i `Front`. Jest to również odzwierciedlone w przestrzeniach nazw, które następnie pojawiają się jako `App\UI\Blog\Admin` i podobnie. Aby odnieść się do prezentera `Dashboard` w podmodule `Admin`, odnosimy się do niego jako `Blog:Admin:Dashboard`.
-Rozgałęzienie może iść tak głęboko, jak chcesz, więc możesz tworzyć podmoduły.
+Zagnieżdżanie może być tak głębokie, jak potrzeba, umożliwiając tworzenie podmodułów.
+
+Na przykład, jeśli w administracji masz wiele prezenterów związanych z zarządzaniem zamówieniami, takich jak `OrderDetail`, `OrderEdit`, `OrderDispatch`, itp., możesz utworzyć moduł `Order`, w którym będą zorganizowane prezentery takie jak `Detail`, `Edit`, `Dispatch`, i inne.
Tworzenie linków .[#toc-creating-links]
@@ -102,46 +118,59 @@ Patrz [rozdział dotyczący routingu |routing#Modules].
Mapowanie .[#toc-mapping]
-------------------------
-Określa zasady, według których nazwa klasy jest wyprowadzana z nazwy prezentera. Zapisujemy je w [konfiguracji |configuration] pod kluczem `application › mapping`.
+Mapowanie definiuje zasady wyprowadzania nazwy klasy z nazwy prezentera. Reguły te są określone w [konfiguracji |configuration] pod kluczem `application › mapping`.
-Zacznijmy od próbki, która nie korzysta z modułów. Będziemy chcieli, aby klasy prezentera miały przestrzeń nazw `App\Presenters`. To znaczy, będziemy chcieli, aby prezenter, na przykład, `Home` mapował do klasy `App\Presenters\HomePresenter`. Można to osiągnąć dzięki następującej konfiguracji:
+Wszystkie przykłady w tym rozdziale są oparte na następującej konfiguracji mapowania:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Zastąp nazwę prezentera gwiazdką w masce klasy, a wynikiem będzie nazwa klasy. Spokojnie!
+Dla lepszego zrozumienia, rozważmy najpierw aplikację bez modułów. Chcemy, aby klasy prezenterów należały do przestrzeni nazw `App\UI`. Aby zmapować prezentera `Home` do klasy `App\UI\HomePresenter`, osiągniemy to za pomocą następującej konfiguracji:
-Jeśli złamiemy prezenterów na moduły, możemy mieć niestandardowe mapowanie dla każdego modułu:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Mapowanie to polega na zastąpieniu gwiazdki w masce `App\UI\*Presenter` nazwą prezentera `Home`, co daje końcową nazwę klasy `App\UI\HomePresenter`. Proste!
+
+Jednakże, jak widać w przykładach w tym i innych rozdziałach, umieszczamy klasy prezenterów w podkatalogach o tej samej nazwie, np. prezenter `Home` jest mapowany na klasę `App\UI\Home\HomePresenter`. Osiąga się to poprzez podwojenie gwiazdki (wymaga Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Przejdźmy teraz do mapowania prezenterów na moduły. Możemy zdefiniować konkretne mapowania dla każdego modułu:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Teraz prezenter `Front:Home` mapuje do klasy `App\Modules\Front\Presenters\HomePresenter`, a prezenter `Admin:Dashboard` mapuje do klasy `App\Modules\Admin\Presenters\DashboardPresenter`.
+Zgodnie z tą konfiguracją, prezenter `Front:Home` mapuje się do klasy `App\UI\Front\Home\HomePresenter`, podczas gdy prezenter `Api:OAuth` mapuje się do klasy `App\Api\OAuthPresenter`.
-Bardziej praktyczne będzie stworzenie ogólnej (gwiazdkowej) reguły, która zastąpi pierwsze dwie. W masce klasy zostanie dodana dodatkowa gwiazdka tylko dla tego modułu:
+Ponieważ moduły `Front` i `Admin` mają podobne podejście do mapowania i prawdopodobnie będzie więcej takich modułów, możliwe jest utworzenie ogólnej reguły, która je zastąpi. Nowa gwiazdka dla modułu jest dodawana do maski klasy:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Ale co w przypadku, gdy korzystamy z wielu zagnieżdżonych modułów i mamy np. prezentera `Admin:User:Edit`? W takim przypadku segment z gwiazdką reprezentujący moduł dla każdego poziomu zostanie po prostu powtórzony, a wynikiem będzie klasa `App\Modules\Admin\User\Presenters\EditPresenter`.
+W przypadku wielopoziomowych zagnieżdżonych modułów, takich jak prezenter `Admin:User:Edit`, segment gwiazdki powtarza się dla każdego poziomu, dając w rezultacie klasę `App\UI\Admin\User\Edit\EditPresenter`.
-Alternatywną notacją jest użycie tablicy składającej się z trzech segmentów zamiast ciągu. Ta notacja jest równoważna z poprzednią:
+Alternatywnym zapisem jest użycie tablicy złożonej z trzech segmentów zamiast łańcucha. Ta notacja jest równoważna poprzedniej:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Wartość domyślna to `*Module\*Presenter`.
diff --git a/application/pl/templates.texy b/application/pl/templates.texy
index a7dd044914..cb89c8cf68 100644
--- a/application/pl/templates.texy
+++ b/application/pl/templates.texy
@@ -34,35 +34,81 @@ I to będzie szablon akcji:
Definiuje blok `content`, który zostanie wstawiony w miejsce `{include content}` w układzie, a także redefiniuje blok `title`, który zastąpi `{block title}` w układzie. Spróbujcie sobie wyobrazić ten rezultat.
-Wyszukiwanie szablonów .[#toc-search-for-templates]
----------------------------------------------------
+Wyszukiwanie szablonów .[#toc-template-lookup]
+----------------------------------------------
-Ścieżka do szablonów jest wyprowadzana przez prezentera za pomocą prostej logiki. Spróbuje sprawdzić, czy jeden z tych plików znajduje się relatywnie od katalogu klasy prezentera, gdzie `` to nazwa aktualnego prezentera, a `` jest nazwą bieżącego zdarzenia:
+W prezenterach nie trzeba określać, który szablon ma być renderowany; framework automatycznie określi ścieżkę, ułatwiając kodowanie.
-- `templates//.latte`
-- `templates/..latte`
+Jeśli używasz struktury katalogów, w której każdy prezenter ma swój własny katalog, po prostu umieść szablon w tym katalogu pod nazwą akcji (tj. widoku). Na przykład dla akcji `default` należy użyć szablonu `default.latte`:
-Jeśli szablon nie zostanie znaleziony, spróbuje poszukać w katalogu `templates` o jeden poziom wyżej, czyli na tym samym poziomie co katalog z klasą prezentera.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Jeśli tam również nie zostanie znaleziony szablon, odpowiedzią będzie [błąd 404 |presenters#Error 404 etc.].
+Jeśli używasz struktury, w której prezenterzy znajdują się w jednym katalogu, a szablony w folderze `templates`, zapisz je w pliku `..latte` lub `/.latte`:
-Widok można również zmienić za pomocą strony `$this->setView('jineView')`. Lub, zamiast szukać bezpośrednio, określ nazwę pliku szablonu za pomocą `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+Katalog `templates` może być również umieszczony o jeden poziom wyżej, na tym samym poziomie co katalog z klasami prezenterów.
+
+Jeśli szablon nie zostanie znaleziony, prezenter odpowie [błędem 404 - nie znaleziono strony |presenters#Error 404 etc].
+
+Widok można zmienić za pomocą `$this->setView('anotherView')`. Możliwe jest również bezpośrednie określenie pliku szablonu za pomocą `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Pliki, w których wyszukiwane są szablony można zmienić nakładając na metodę [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], która zwraca tablicę możliwych nazw plików.
+Pliki, w których wyszukiwane są szablony, można zmienić, nadpisując metodę [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], która zwraca tablicę możliwych nazw plików.
+
+
+Wyszukiwanie szablonu układu .[#toc-layout-template-lookup]
+-----------------------------------------------------------
+
+Nette automatycznie wyszukuje również plik układu.
+
+Jeśli używasz struktury katalogów, w której każdy prezenter ma swój własny katalog, umieść układ w folderze z prezenterem, jeśli jest on specyficzny tylko dla niego, lub poziom wyżej, jeśli jest wspólny dla wielu prezenterów:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Jeśli używasz struktury, w której prezenterzy są zgrupowani w jednym katalogu, a szablony znajdują się w folderze `templates`, layout będzie oczekiwany w następujących miejscach:
-W tych plikach spodziewany jest układ:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` układ wspólny dla wielu prezenterów
+Jeśli prezenter znajduje się w [module |modules], będzie on również wyszukiwany dalej w drzewie katalogów zgodnie z zagnieżdżeniem modułu.
-Gdzie `` to nazwa aktualnego prezentera, a `` jest nazwą układu, którą domyślnie jest `'layout'`. Nazwę można zmienić za pomocą `$this->setLayout('jinyLayout')`, więc wypróbowane zostaną pliki `@jinyLayout.latte`.
+Nazwę layoutu można zmienić za pomocą `$this->setLayout('layoutAdmin')`, a następnie będzie ona oczekiwana w pliku `@layoutAdmin.latte`. Można również bezpośrednio określić plik szablonu układu za pomocą `$this->setLayout('/path/to/template.latte')`.
-Możesz również bezpośrednio określić nazwę pliku szablonu układu, używając `$this->setLayout('/path/to/template.latte')`. Użycie `$this->setLayout(false)` wyłączy śledzenie układu.
+Użycie `$this->setLayout(false)` lub znacznika `{layout none}` wewnątrz szablonu wyłącza wyszukiwanie układu.
.[note]
-Pliki, w których wyszukiwane są szablony układów można zmienić nakładając na metodę [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], która zwraca tablicę możliwych nazw plików.
+Pliki, w których przeszukiwane są szablony układu, można zmienić, nadpisując metodę [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], która zwraca tablicę możliwych nazw plików.
Zmienne w szablonie .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ Adnotacja `@property-read` jest dla IDE i analizy statycznej, sprawi, że szepta
Możesz również mieć luksus szeptania w szablonach, wystarczy zainstalować wtyczkę Latte w PhpStorm i umieścić nazwę klasy na początku szablonu, zobacz artykuł "Latte: jak wpisać system":https://blog.nette.org/pl/latte-jak-korzystac-z-systemu-typow, aby uzyskać więcej informacji:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte w wersji 3 oferuje bardziej zaawansowany sposób tworzenia [rozszerzenia |latte:creating-extension] dla każdego projektu internetowego. Oto krótki przykład takiej klasy:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Rejestrujemy go za pomocą [konfiguracji |configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/pt/how-it-works.texy b/application/pt/how-it-works.texy
index a73637f71e..c55012ce62 100644
--- a/application/pt/how-it-works.texy
+++ b/application/pt/how-it-works.texy
@@ -22,13 +22,13 @@ A estrutura do diretório é algo parecido com isto:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← classes básicas necessárias
+│ │ └── RouterFactory.php ← configuração de endereços URL
+│ ├── UI/ ← apresentadores, modelos e outros
+│ │ ├── @layout.latte ← modelo de layout compartilhado
+│ │ └── Home/ ← Diretório do apresentador Home
+│ │ ├── HomePresenter.php ← Classe do apresentador da página inicial
+│ │ └── default.latte ← template for action default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ As aplicações escritas em Nette são divididas em muitos dos chamados apresent
A aplicação começa pedindo ao chamado roteador que decida qual dos apresentadores deve passar o atual pedido de processamento. O roteador decide de quem é a responsabilidade. Ele analisa a URL de entrada `https://example.com/product/123`, que quer `show` um produto com `id: 123` como uma ação. É um bom hábito escrever um par de apresentador + ação separado por dois pontos como `Product:show`.
-Assim, o roteador transformou a URL em um par `Presenter:action` + parâmetros, em nosso caso `Product:show` + `id: 123`. Você pode ver como é um roteador no arquivo `app/Router/RouterFactory.php` e nós o descreveremos em detalhes no capítulo [Roteamento |Routing].
+Assim, o roteador transformou a URL em um par `Presenter:action` + parâmetros, em nosso caso `Product:show` + `id: 123`. Você pode ver como é um roteador no arquivo `app/Core/RouterFactory.php` e nós o descreveremos em detalhes no capítulo [Roteamento |Routing].
Vamos em frente. O pedido já conhece o nome do apresentador e pode continuar. Ao criar um objeto `ProductPresenter`, que é o código do apresentador `Product`. Mais precisamente, pede ao contêiner DI para criar o apresentador, pois a produção de objetos é sua função.
@@ -121,12 +121,9 @@ Então, o método `renderShow(123)` foi chamado, cujo código é um exemplo fict
Posteriormente, o apresentador retorna a resposta. Pode ser uma página HTML, uma imagem, um documento XML, o envio de um arquivo do disco, JSON ou o redirecionamento para outra página. É importante ressaltar que se não dissermos explicitamente como responder (que é o caso de `ProductPresenter`), a resposta será renderizar o template com uma página HTML. Por quê? Bem, porque em 99% dos casos queremos desenhar um template, então o apresentador toma este comportamento como padrão e quer tornar nosso trabalho mais fácil. Esse é o ponto de vista da Nette.
-Não temos nem mesmo que declarar qual modelo desenhar, ele deriva o caminho para ele de acordo com uma lógica simples. No caso do apresentador `Product` e da ação `show`, ele tenta ver se um destes arquivos de modelo existe em relação ao diretório onde se encontra a classe `ProductPresenter`:
+Não precisamos nem mesmo especificar o modelo a ser renderizado; a estrutura deduzirá o caminho por si só. No caso da ação `show`, ele simplesmente tenta carregar o modelo `show.latte` no diretório com a classe `ProductPresenter`. Ele também tenta encontrar o layout no arquivo `@layout.latte` (mais informações sobre a [pesquisa de modelos |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Ele também tentará encontrar o layout no arquivo `@layout.latte` e depois renderiza o modelo. Agora a tarefa do apresentador e de todo o pedido está concluída. Se o modelo não existir, uma página com erro 404 será devolvida. Você pode ler mais sobre os apresentadores na página [Apresentadores |Presenters].
+Em seguida, os modelos são renderizados. Isso conclui a tarefa do apresentador e de todo o aplicativo, e o trabalho está concluído. Se o modelo não existir, será retornada uma página de erro 404. Você pode ler mais sobre apresentadores na página [Apresentadores |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Só para ter certeza, vamos tentar recapitular todo o processo com uma URL ligei
3) o roteador decodifica a URL como um par `Home:default`
4) um objeto `HomePresenter` é criado
5) método `renderDefault()` é chamado (se existir)
-6) um modelo `templates/Home/default.latte` com um layout `templates/@layout.latte` é apresentado
+6) um modelo `default.latte` com um layout `@layout.latte` é apresentado
Você pode ter se deparado com muitos conceitos novos agora, mas acreditamos que eles fazem sentido. Criar aplicações em Nette é uma brisa.
diff --git a/application/pt/modules.texy b/application/pt/modules.texy
index 372dd0e467..93cdffe391 100644
--- a/application/pt/modules.texy
+++ b/application/pt/modules.texy
@@ -2,29 +2,31 @@ Módulos
*******
.[perex]
-Em Nette, os módulos representam as unidades lógicas que compõem uma aplicação. Eles incluem apresentadores, gabaritos, possivelmente também componentes e classes de modelos.
+Os módulos dão clareza aos aplicativos Nette, facilitando a divisão em unidades lógicas.
-Um diretório para apresentadores e um para modelos não seria suficiente para projetos reais. Ter dezenas de arquivos em uma pasta é pelo menos desorganizado. Como sair dela? Nós simplesmente os dividimos em subdiretórios em disco e em namespaces no código. E é exatamente isso que os módulos Nette fazem.
-
-Portanto, vamos esquecer uma única pasta para apresentadores e modelos e, em vez disso, criar módulos, por exemplo `Admin` e `Front`.
+Da mesma forma que organizamos os arquivos em pastas em um disco rígido, na Nette podemos dividir apresentadores, modelos e outras classes auxiliares em módulos. Como isso funciona na prática? Simplesmente incorporando novos subdiretórios à estrutura. Aqui está um exemplo de uma estrutura com dois módulos, Front e Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Esta estrutura de diretório será refletida pelos namespaces de classe, portanto, por exemplo `DashboardPresenter` estará no namespace `App\Modules\Admin\Presenters`:
+Essa estrutura de diretórios é refletida nos namespaces das classes, portanto, por exemplo, `DashboardPresenter` está localizado no namespace `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-O `Dashboard` apresentador dentro do módulo `Admin` é referenciado dentro da aplicação usando a notação de cólon como `Admin:Dashboard`, e sua ação `default` como `Admin:Dashboard:default`.
-E como a Nette propriamente dita sabe que `Admin:Dashboard` representa a classe `App\Modules\Admin\Presenters\DashboardPresenter`? Isto é determinado pelo [mapeamento |#mapping] na configuração.
-Assim, a estrutura dada não é difícil de definir e você pode modificá-la de acordo com suas necessidades.
+No aplicativo, nos referimos ao apresentador `Dashboard` dentro do módulo `Admin` usando a notação de dois pontos como `Admin:Dashboard`. Para sua ação `default`, nos referimos a ela como `Admin:Dashboard:default`.
-Os módulos podem naturalmente conter todos os outros itens além de apresentadores e modelos, tais como componentes, classes de modelos, etc.
+A estrutura apresentada não é rígida; você pode [personalizá-la totalmente de acordo com suas necessidades |#mapping] na configuração. .[tip]
+
+Os módulos podem incluir todos os outros arquivos, como componentes e classes auxiliares, além de apresentadores e modelos. Se estiver pensando em onde colocá-los, considere o uso de uma pasta `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Módulos aninhados .[#toc-nested-modules]
----------------------------------------
-Os módulos não precisam formar apenas uma estrutura plana, você também pode criar submódulos, por exemplo:
+Os módulos podem ter vários níveis de aninhamento, semelhante a uma estrutura de diretórios em um disco:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Assim, o módulo `Blog` está dividido em `Admin` e `Front` submódulos. Mais uma vez, isto se refletirá nos namespaces, que serão `App\Modules\Blog\Admin\Presenters` etc. O apresentador `Dashboard` dentro do submódulo é referido como `Blog:Admin:Dashboard`.
+O módulo `Blog` é dividido em submódulos `Admin` e `Front`. Isso também se reflete nos namespaces, que aparecem como `App\UI\Blog\Admin` e similares. Para nos referirmos ao apresentador `Dashboard` dentro do submódulo `Admin`, nos referimos a ele como `Blog:Admin:Dashboard`.
-O ninho pode ir tão fundo quanto você desejar, de modo que sub-submódulos podem ser criados.
+O aninhamento pode ser tão profundo quanto necessário, permitindo a criação de sub-submódulos.
+
+Por exemplo, se na administração você tem muitos apresentadores relacionados ao gerenciamento de pedidos, como `OrderDetail`, `OrderEdit`, `OrderDispatch`, etc., você pode criar um módulo `Order` no qual apresentadores como `Detail`, `Edit`, `Dispatch` e outros serão organizados.
Criação de links .[#toc-creating-links]
@@ -102,46 +118,59 @@ Ver [capítulo sobre roteamento |routing#Modules].
Mapeamento .[#toc-mapping]
--------------------------
-Define as regras pelas quais o nome da classe é derivado do nome do apresentador. Nós as escrevemos na [configuração |configuration] sob a chave `application › mapping`.
+O mapeamento define as regras para derivar o nome da classe do nome do apresentador. Essas regras são especificadas na [configuração |configuration] sob a chave `application › mapping`.
-Vamos começar com uma amostra que não utiliza módulos. Queremos apenas que as classes de apresentadores tenham o namespace `App\Presenters`. Isso significa que um apresentador como o `Home` deve mapear para a classe `App\Presenters\HomePresenter`. Isto pode ser conseguido através da seguinte configuração:
+Todos os exemplos deste capítulo são baseados na seguinte configuração de mapeamento:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-O nome do apresentador é substituído pelo asterisco na máscara da classe e o resultado é o nome da classe. Fácil!
+Para melhor compreensão, vamos primeiro considerar um aplicativo sem módulos. Queremos que as classes de apresentador se enquadrem no namespace `App\UI`. Para mapear o apresentador `Home` para a classe `App\UI\HomePresenter`, fazemos isso com a seguinte configuração:
-Se dividirmos os apresentadores em módulos, podemos ter nosso próprio mapeamento para cada módulo:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Esse mapeamento funciona substituindo o asterisco na máscara `App\UI\*Presenter` pelo nome do apresentador `Home`, resultando no nome final da classe `App\UI\HomePresenter`. Simples!
+
+Entretanto, como você pode ver nos exemplos deste e de outros capítulos, colocamos as classes de apresentador em subdiretórios homônimos, por exemplo, o apresentador `Home` é mapeado para a classe `App\UI\Home\HomePresenter`. Isso é feito duplicando-se o asterisco (requer o Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Agora, vamos passar a mapear os apresentadores em módulos. Podemos definir mapeamentos específicos para cada módulo:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Agora o apresentador `Front:Home` mapeia para a classe `App\Modules\Front\Presenters\HomePresenter` e o apresentador `Admin:Dashboard` para a classe `App\Modules\Admin\Presenters\DashboardPresenter`.
+De acordo com essa configuração, o apresentador `Front:Home` mapeia para a classe `App\UI\Front\Home\HomePresenter`, enquanto o apresentador `Api:OAuth` mapeia para a classe `App\Api\OAuthPresenter`.
-É mais prático criar uma regra geral (estrela) para substituir as duas primeiras. O asterisco extra será adicionado à máscara de classe apenas para o módulo:
+Como os módulos `Front` e `Admin` têm uma abordagem de mapeamento semelhante e é provável que haja mais módulos desse tipo, é possível criar uma regra geral que os substitua. Um novo asterisco para o módulo é adicionado à máscara de classe:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Mas e se usarmos módulos aninhados e tivermos um apresentador `Admin:User:Edit`? Neste caso, o segmento com um asterisco representando o módulo para cada nível é simplesmente repetido e o resultado é a classe `App\Modules\Admin\User\Presenters\EditPresenter`.
+Para módulos aninhados em vários níveis, como o apresentador `Admin:User:Edit`, o segmento de asterisco se repete para cada nível, resultando na classe `App\UI\Admin\User\Edit\EditPresenter`.
-Uma notação alternativa é utilizar um conjunto composto de três segmentos em vez de um fio. Esta notação é equivalente à anterior:
+Uma notação alternativa é usar uma matriz composta de três segmentos em vez de uma cadeia de caracteres. Essa notação é equivalente à anterior:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-O valor padrão é `*Module\*Presenter`.
diff --git a/application/pt/templates.texy b/application/pt/templates.texy
index 059e35178e..75e73e1d98 100644
--- a/application/pt/templates.texy
+++ b/application/pt/templates.texy
@@ -34,35 +34,81 @@ E este poderia ser o modelo de ação:
Ele define o bloco `content`, que é inserido no lugar de `{include content}` no layout, e também redefine o bloco `title`, que sobrescreve `{block title}` no layout. Tente imaginar o resultado.
-Busca de modelos .[#toc-search-for-templates]
----------------------------------------------
+Pesquisa de modelos .[#toc-template-lookup]
+-------------------------------------------
-O caminho para os modelos é deduzido de acordo com uma lógica simples. Ele tenta ver se um destes arquivos de gabaritos existe em relação ao diretório onde se encontra a classe apresentadora, onde `` é o nome do atual apresentador e `` é o nome da ação atual:
+Nos apresentadores, você não precisa especificar qual modelo deve ser renderizado; a estrutura determinará automaticamente o caminho, facilitando a codificação para você.
-- `templates//.latte`
-- `templates/..latte`
+Se você usar uma estrutura de diretórios em que cada apresentador tenha seu próprio diretório, basta colocar o modelo nesse diretório com o nome da ação (ou seja, visualização). Por exemplo, para a ação `default`, use o modelo `default.latte`:
-Se o modelo não for encontrado, ele tentará procurar no diretório `templates` um nível acima, ou seja, no mesmo nível que o diretório com a classe apresentadora.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Se o modelo também não for encontrado lá, a resposta é um [erro 404 |presenters#Error 404 etc.].
+Se você usar uma estrutura em que os apresentadores estejam juntos em um diretório e os modelos em uma pasta `templates`, salve-os em um arquivo `..latte` ou `/.latte`:
-Você também pode mudar a visão usando `$this->setView('otherView')`. Ou, em vez de procurar, especifique diretamente o nome do arquivo modelo usando `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+O diretório `templates` também pode ser colocado um nível acima, no mesmo nível do diretório com as classes de apresentador.
+
+Se o modelo não for encontrado, o apresentador responderá com o [erro 404 - página não encontrada |presenters#Error 404 etc].
+
+Você pode alterar a visualização usando `$this->setView('anotherView')`. Também é possível especificar diretamente o arquivo de modelo com `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Você pode alterar os caminhos onde os modelos são pesquisados substituindo o método de [formataçãoTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], que retorna um conjunto de possíveis caminhos de arquivos.
+Os arquivos onde os modelos são pesquisados podem ser alterados substituindo o método [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], que retorna uma matriz de possíveis nomes de arquivos.
+
+
+Pesquisa de modelos de layout .[#toc-layout-template-lookup]
+------------------------------------------------------------
+
+O Nette também procura automaticamente o arquivo de layout.
+
+Se você usar uma estrutura de diretórios em que cada apresentador tenha seu próprio diretório, coloque o layout na pasta com o apresentador, se for específico apenas para ele, ou em um nível superior, se for comum a vários apresentadores:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Se você usar uma estrutura em que os apresentadores estejam agrupados em um diretório e os modelos estejam em uma pasta `templates`, o layout será esperado nos seguintes locais:
-O layout é esperado nos seguintes arquivos:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` layout comum a vários apresentadores
+Se o apresentador estiver em um [módulo |modules], ele também pesquisará mais acima na árvore de diretórios, de acordo com o aninhamento do módulo.
-`` é o nome do atual apresentador e `` é o nome do layout, que é, por padrão, `'layout'`. O nome pode ser alterado com `$this->setLayout('otherLayout')`, para que os arquivos `@otherLayout.latte` sejam experimentados.
+O nome do layout pode ser alterado usando `$this->setLayout('layoutAdmin')` e, em seguida, ele será esperado no arquivo `@layoutAdmin.latte`. Você também pode especificar diretamente o arquivo de modelo de layout usando `$this->setLayout('/path/to/template.latte')`.
-Você também pode especificar diretamente o nome do arquivo do modelo de layout usando `$this->setLayout('/path/to/template.latte')`. O uso do `$this->setLayout(false)` desabilitará a busca do layout.
+O uso de `$this->setLayout(false)` ou da tag `{layout none}` dentro do modelo desativa a pesquisa de layout.
.[note]
-Você pode alterar os caminhos onde os modelos são pesquisados, substituindo o método [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], que retorna uma série de possíveis caminhos de arquivos.
+Os arquivos em que os modelos de layout são pesquisados podem ser alterados substituindo o método [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], que retorna uma matriz de possíveis nomes de arquivos.
Variáveis no modelo .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ A anotação `@property-read` é para IDE e análise estática, fará com que o
Você também pode se dar ao luxo de sussurrar nos modelos, basta instalar o plugin Latte no PhpStorm e especificar o nome da classe no início do modelo, veja o artigo "Latte: como digitar sistema":https://blog.nette.org/pt/latte-como-usar-o-sistema-de-tipo:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
A versão 3 do Latte oferece uma maneira mais avançada, criando uma [extensão |latte:creating-extension] para cada projeto web. Aqui está um exemplo rudimentar de tal classe:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Registramos usando [a configuração#Latte |configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/ro/how-it-works.texy b/application/ro/how-it-works.texy
index 75291693ee..c1cfda33f3 100644
--- a/application/ro/how-it-works.texy
+++ b/application/ro/how-it-works.texy
@@ -22,13 +22,13 @@ Structura directoarelor arată cam așa:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← cursuri de bază necesare
+│ │ └── RouterFactory.php ← configurare adrese URL
+│ ├── UI/ ← prezentări, șabloane & co.
+│ │ ├── @layout.latte ← șablon de prezentare partajată
+│ │ └── Home/ ← Directorul de prezentatori de acasă
+│ │ ├── HomePresenter.php ← Clasa de prezentator de acasă
+│ │ └── default.latte ← șablon pentru acțiune default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Aplicațiile scrise în Nette sunt împărțite în mai multe așa-numite prezen
Aplicația începe prin a cere așa-numitului router să decidă care dintre prezentatori să transmită cererea curentă pentru procesare. Routerul decide a cui este responsabilitatea. Acesta se uită la URL-ul de intrare `https://example.com/product/123`, care dorește să `show` un produs cu `id: 123` ca acțiune. Este un bun obicei să se scrie perechile prezentator + acțiune separate de două puncte ca `Product:show`.
-Astfel, routerul a transformat URL-ul într-o pereche `Presenter:action` + parametri, în cazul nostru `Product:show` + `id: 123`. Puteți vedea cum arată un router în fișierul `app/Router/RouterFactory.php` și îl vom descrie în detaliu în capitolul [Routing |Routing].
+Astfel, routerul a transformat URL-ul într-o pereche `Presenter:action` + parametri, în cazul nostru `Product:show` + `id: 123`. Puteți vedea cum arată un router în fișierul `app/Core/RouterFactory.php` și îl vom descrie în detaliu în capitolul [Routing |Routing].
Să mergem mai departe. Aplicația cunoaște deja numele prezentatorului și poate continua. Prin crearea unui obiect `ProductPresenter`, care este codul prezentatorului `Product`. Mai exact, solicită containerului DI crearea prezentatorului, deoarece producerea de obiecte este sarcina acestuia.
@@ -121,12 +121,9 @@ Așadar, a fost apelată metoda `renderShow(123)`, al cărei cod este un exemplu
Ulterior, prezentatorul returnează răspunsul. Acesta poate fi o pagină HTML, o imagine, un document XML, trimiterea unui fișier de pe disc, JSON sau redirecționarea către o altă pagină. Este important de reținut că, dacă nu spunem în mod explicit cum să răspundem (ceea ce este cazul `ProductPresenter`), răspunsul va fi redarea șablonului cu o pagină HTML. De ce? Ei bine, pentru că în 99% din cazuri dorim să desenăm un șablon, așa că prezentatorul ia acest comportament ca fiind implicit și dorește să ne ușureze munca. Acesta este punctul de vedere al lui Nette.
-Nici măcar nu trebuie să precizăm ce șablon să desenăm, el derivă calea către acesta conform unei logici simple. În cazul prezentatorului `Product` și al acțiunii `show`, el încearcă să vadă dacă unul dintre aceste fișiere șablon există în raport cu directorul în care se află clasa `ProductPresenter`:
+Nici măcar nu trebuie să specificăm ce șablon să redăm; cadrul va deduce singur calea. În cazul acțiunii `show`, acesta încearcă pur și simplu să încarce șablonul `show.latte` din directorul cu clasa `ProductPresenter`. De asemenea, încearcă să găsească aspectul în fișierul `@layout.latte` (mai multe informații despre [căutarea șabloanelor |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-De asemenea, va încerca să găsească aspectul în fișierul `@layout.latte` și apoi va reda șablonul. Acum sarcina prezentatorului și a întregii aplicații este finalizată. În cazul în care șablonul nu există, va fi returnată o pagină cu eroarea 404. Puteți citi mai multe despre prezentatori pe pagina [Prezentatori |Presenters].
+Ulterior, șabloanele sunt redate. Acest lucru încheie sarcina prezentatorului și a întregii aplicații, iar activitatea este finalizată. În cazul în care șablonul nu există, ar fi returnată o pagină de eroare 404. Puteți citi mai multe despre prezentatori pe pagina [Prezentatori |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Doar pentru a fi siguri, să încercăm să recapitulăm întregul proces cu un
3) routerul decodifică URL-ul ca o pereche `Home:default`
4) este creat un obiect `HomePresenter`
5) se apelează metoda `renderDefault()` (dacă există)
-6) este redat un șablon `templates/Home/default.latte` cu un layout `templates/@layout.latte`
+6) este redat un șablon `default.latte` cu un layout `@layout.latte`
Este posibil să fi întâlnit acum o mulțime de concepte noi, dar noi credem că acestea au sens. Crearea de aplicații în Nette este o joacă de copii.
diff --git a/application/ro/modules.texy b/application/ro/modules.texy
index 1e7cd0fee4..87fea200f7 100644
--- a/application/ro/modules.texy
+++ b/application/ro/modules.texy
@@ -2,29 +2,31 @@ Module
******
.[perex]
-În Nette, modulele reprezintă unitățile logice care alcătuiesc o aplicație. Acestea includ prezentatori, șabloane, eventual și componente și clase de model.
+Modulele aduc claritate aplicațiilor Nette, facilitând divizarea ușoară în unități logice.
-Un singur director pentru prezentatori și unul pentru șabloane nu ar fi suficient pentru proiectele reale. A avea zeci de fișiere într-un singur dosar este cel puțin neorganizat. Cum se poate ieși din asta? Pur și simplu le împărțim în subdirectoare pe disc și în spații de nume în cod. Și asta este exact ceea ce fac modulele Nette.
-
-Așadar, să uităm de un singur dosar pentru prezentatori și șabloane și să creăm în schimb module, de exemplu `Admin` și `Front`.
+Similar cu organizarea fișierelor în foldere pe un hard disk, în Nette putem împărți în module prezentatorii, șabloanele și alte clase auxiliare. Cum funcționează acest lucru în practică? Pur și simplu prin încorporarea de noi subdirectoare în structură. Iată un exemplu de structură cu două module, Front și Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Această structură de directoare va fi reflectată de spațiile de nume ale claselor, astfel încât, de exemplu, `DashboardPresenter` va fi în spațiul de nume `App\Modules\Admin\Presenters`:
+Această structură de directoare se reflectă în spațiile de nume ale claselor, astfel încât, de exemplu, `DashboardPresenter` se află în spațiul de nume `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Prezentatorul `Dashboard` din cadrul modulului `Admin` este referit în cadrul aplicației folosind notația de două puncte ca `Admin:Dashboard`, iar acțiunea `default` ca `Admin:Dashboard:default`.
-Și de unde știe Nette proper că `Admin:Dashboard` reprezintă clasa `App\Modules\Admin\Presenters\DashboardPresenter`? Acest lucru este determinat de [cartografierea |#mapping] din configurație.
-Așadar, structura dată nu este prestabilită și o puteți modifica în funcție de nevoile dumneavoastră.
+În aplicație, ne referim la prezentatorul `Dashboard` din cadrul modulului `Admin` folosind notația două puncte ca `Admin:Dashboard`. Pentru acțiunea `default`, ne referim la acesta ca `Admin:Dashboard:default`.
-Modulele pot conține, bineînțeles, toate celelalte elemente în afară de prezentatori și șabloane, cum ar fi componente, clase de modele etc.
+Structura prezentată nu este rigidă; [o |#mapping] puteți [personaliza complet |#mapping] în funcție [de nevoile dumneavoastră |#mapping] în cadrul configurației. .[tip]
+
+Modulele pot include toate celelalte fișiere, cum ar fi componentele și clasele auxiliare, pe lângă prezentatori și șabloane. Dacă vă gândiți unde să le plasați pe acestea, luați în considerare utilizarea unui dosar `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Module imbricate .[#toc-nested-modules]
---------------------------------------
-Modulele nu trebuie să formeze doar o structură plată, ci puteți crea și submodule, de exemplu:
+Modulele pot avea mai multe niveluri de anvelopare, similar cu o structură de directoare pe un disc:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Astfel, modulul `Blog` este împărțit în submodulele `Admin` și `Front`. Din nou, acest lucru se va reflecta în spațiile de nume, care vor fi `App\Modules\Blog\Admin\Presenters` etc. Prezentatorul `Dashboard` din interiorul submodulului este denumit `Blog:Admin:Dashboard`.
+Modulul `Blog` este împărțit în submodulele `Admin` și `Front`. Acest lucru se reflectă și în spațiile de nume, care apar apoi ca `App\UI\Blog\Admin` și similar. Pentru a ne referi la prezentatorul `Dashboard` din cadrul submodulului `Admin`, ne referim la acesta ca `Blog:Admin:Dashboard`.
-Anveloparea poate merge cât de adânc doriți, astfel încât pot fi create sub-submodule.
+Nesting-ul poate fi atât de adânc cât este necesar, permițând crearea de sub-submodule.
+
+De exemplu, dacă în administrație aveți mulți prezentatori legați de gestionarea comenzilor, cum ar fi `OrderDetail`, `OrderEdit`, , `OrderDispatch`, etc., puteți crea un modul `Order` în care vor fi organizați prezentatori precum `Detail`, `Edit`, `Dispatch`, și alții.
Crearea de legături .[#toc-creating-links]
@@ -102,46 +118,59 @@ A se vedea [capitolul privind rutarea |routing#Modules].
Cartografiere .[#toc-mapping]
-----------------------------
-Definește regulile prin care numele clasei este derivat din numele prezentatorului. Le scriem în [configurație |configuration] sub cheia `application › mapping`.
+Cartografierea definește regulile de derivare a numelui clasei din numele prezentatorului. Aceste reguli sunt specificate în [configurație |configuration] la cheia `application › mapping`.
-Să începem cu un exemplu care nu folosește module. Vom dori doar ca clasele de prezentator să aibă spațiul de nume `App\Presenters`. Aceasta înseamnă că un prezentator precum `Home` ar trebui să se mapeze la clasa `App\Presenters\HomePresenter`. Acest lucru poate fi realizat prin următoarea configurație:
+Toate exemplele din acest capitol se bazează pe următoarea configurație de mapare:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Numele prezentatorului este înlocuit cu un asterisc în masca clasei, iar rezultatul este numele clasei. Ușor!
+Pentru o mai bună înțelegere, să luăm mai întâi în considerare o aplicație fără module. Dorim ca clasele de prezentator să se încadreze în spațiul de nume `App\UI`. Pentru a mapa prezentatorul `Home` la clasa `App\UI\HomePresenter`, realizăm acest lucru cu următoarea configurație:
-Dacă împărțim prezentatorii în module, putem avea propria mapare pentru fiecare modul:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Această cartografiere funcționează prin înlocuirea asteriscului din masca `App\UI\*Presenter` cu numele prezentatorului `Home`, rezultând numele final al clasei `App\UI\HomePresenter`. Simplu!
+
+Cu toate acestea, după cum puteți vedea în exemplele din acest capitol și din alte capitole, plasăm clasele de prezentatori în subdirectoare eponime, de exemplu, prezentatorul `Home` este mapat în clasa `App\UI\Home\HomePresenter`. Acest lucru se realizează prin dublarea asteriscului (necesită Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Acum, să trecem la maparea prezentatorilor în module. Putem defini mape specifice pentru fiecare modul:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Acum, prezentatorul `Front:Home` se referă la clasa `App\Modules\Front\Presenters\HomePresenter` și prezentatorul `Admin:Dashboard` la clasa `App\Modules\Admin\Presenters\DashboardPresenter`.
+În conformitate cu această configurație, prezentatorul `Front:Home` se mapează la clasa `App\UI\Front\Home\HomePresenter`, în timp ce prezentatorul `Api:OAuth` se mapează la clasa `App\Api\OAuthPresenter`.
-Este mai practic să creăm o regulă generală (stea) care să le înlocuiască pe primele două. Asteriscul suplimentar va fi adăugat la masca clasei doar pentru modul:
+Deoarece modulele `Front` și `Admin` au o abordare similară de cartografiere și este posibil să existe mai multe astfel de module, este posibil să se creeze o regulă generală care să le înlocuiască. Un nou asterisc pentru modul este adăugat la masca clasei:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Dar ce se întâmplă dacă folosim module imbricate și avem un prezentator `Admin:User:Edit`? În acest caz, segmentul cu un asterisc care reprezintă modulul pentru fiecare nivel se repetă pur și simplu, iar rezultatul este clasa `App\Modules\Admin\User\Presenters\EditPresenter`.
+Pentru modulele imbricate pe mai multe niveluri, cum ar fi prezentatorul `Admin:User:Edit`, segmentul de asterisc se repetă pentru fiecare nivel, rezultând clasa `App\UI\Admin\User\Edit\EditPresenter`.
-O notație alternativă este utilizarea unui array format din trei segmente în loc de un șir de caractere. Această notație este echivalentă cu cea anterioară:
+O notație alternativă constă în utilizarea unei matrice compuse din trei segmente în locul unui șir de caractere. Această notație este echivalentă cu cea anterioară:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Valoarea implicită este `*Module\*Presenter`.
diff --git a/application/ro/templates.texy b/application/ro/templates.texy
index abcead647e..a12657b6f9 100644
--- a/application/ro/templates.texy
+++ b/application/ro/templates.texy
@@ -34,35 +34,81 @@ Iar acesta ar putea fi șablonul de acțiune:
Acesta definește blocul `content`, care este inserat în locul lui `{include content}` în machetă și, de asemenea, redefinește blocul `title`, care suprascrie `{block title}` în machetă. Încercați să vă imaginați rezultatul.
-Căutați șabloane .[#toc-search-for-templates]
----------------------------------------------
+Căutarea șablonului .[#toc-template-lookup]
+-------------------------------------------
+
+În prezentări, nu trebuie să specificați ce șablon trebuie redat; cadrul va determina automat calea, ceea ce vă ușurează codificarea.
+
+Dacă utilizați o structură de directoare în care fiecare prezentator are propriul director, plasați pur și simplu șablonul în acest director sub numele acțiunii (de exemplu, view). De exemplu, pentru acțiunea `default`, utilizați șablonul `default.latte`:
-Calea către șabloane este dedusă conform unei logici simple. Se încearcă să se vadă dacă unul dintre aceste fișiere șablon există în raport cu directorul în care se află clasa presenter, unde `` este numele prezentatorului curent și `` este numele acțiunii curente:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Dacă utilizați o structură în care prezentatorii sunt împreună într-un singur director, iar șabloanele într-un dosar `templates`, salvați-l fie într-un fișier `..latte` sau `/.latte`:
-Dacă șablonul nu este găsit, se va încerca căutarea în directorul `templates` cu un nivel mai sus, adică la același nivel cu directorul cu clasa de prezentator.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Dacă șablonul nu este găsit nici acolo, răspunsul este o [eroare 404 |presenters#Error 404 etc.].
+Directorul `templates` poate fi, de asemenea, plasat un nivel mai sus, la același nivel cu directorul cu clasele de prezentatori.
-De asemenea, puteți schimba vizualizarea folosind `$this->setView('otherView')`. Sau, în loc să căutați, specificați direct numele fișierului șablon folosind `$this->template->setFile('/path/to/template.latte')`.
+În cazul în care șablonul nu este găsit, prezentatorul răspunde cu [eroarea 404 - page not found |presenters#Error 404 etc].
+
+Puteți schimba vizualizarea folosind `$this->setView('anotherView')`. De asemenea, este posibilă specificarea directă a fișierului șablon cu `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Puteți modifica căile în care sunt căutate șabloanele prin suprascrierea metodei [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], care returnează o matrice de posibile căi de acces la fișiere.
+Fișierele în care sunt căutate șabloanele pot fi modificate prin suprascrierea metodei [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], care returnează o matrice de nume de fișiere posibile.
+
+
+Căutarea șabloanelor de prezentare .[#toc-layout-template-lookup]
+-----------------------------------------------------------------
+
+De asemenea, Nette caută automat fișierul de machetare.
+
+Dacă folosiți o structură de directoare în care fiecare prezentator are propriul director, plasați macheta fie în folderul cu prezentatorul, dacă este specifică doar acestuia, fie la un nivel superior, dacă este comună mai multor prezentatori:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Dacă utilizați o structură în care prezentatorii sunt grupați într-un singur director, iar șabloanele se află într-un dosar `templates`, macheta va fi așteptată în următoarele locuri:
-Prezentarea este așteptată în următoarele fișiere:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` aspect comun pentru mai mulți prezentatori
+Dacă prezentatorul se află într-un [modul |modules], se va căuta și mai sus în arborele de directoare, în funcție de structura de anvelopare a modulului.
-`` este numele prezentatorului curent și `` este numele structurii, care este în mod implicit `'layout'`. Numele poate fi schimbat cu `$this->setLayout('otherLayout')`, astfel încât să se încerce să se utilizeze fișierele `@otherLayout.latte`.
+Numele prezentării poate fi schimbat folosind `$this->setLayout('layoutAdmin')` și apoi va fi așteptat în fișierul `@layoutAdmin.latte`. De asemenea, puteți specifica direct fișierul șablon de prezentare folosind `$this->setLayout('/path/to/template.latte')`.
-De asemenea, puteți specifica direct numele de fișier al șablonului de machetă cu `$this->setLayout('/path/to/template.latte')`. Utilizarea `$this->setLayout(false)` va dezactiva căutarea de machete.
+Utilizarea `$this->setLayout(false)` sau a etichetei `{layout none}` în interiorul șablonului dezactivează căutarea de layout.
.[note]
-Puteți modifica căile de căutare a șabloanelor prin suprascrierea metodei [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], care returnează o matrice de posibile căi de acces la fișiere.
+Fișierele în care sunt căutate șabloanele de prezentare pot fi modificate prin suprascrierea metodei [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], care returnează o matrice de nume de fișiere posibile.
Variabilele din șablon .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ Adnotarea `@property-read` este pentru IDE și analiza statică, va face ca auto
Vă puteți permite și luxul de a șopti în șabloane, trebuie doar să instalați pluginul în PhpStorm și să specificați numele clasei la începutul șablonului, consultați articolul "Latte: cum se tastează sistemul":https://blog.nette.org/ro/latte-cum-se-utilizeaza-sistemul-de-tipuri:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte versiunea 3 oferă o metodă mai avansată prin crearea unei [extensii |latte:creating-extension] pentru fiecare proiect web. Iată un exemplu aproximativ al unei astfel de clase:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ O înregistrăm folosind [configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/ru/how-it-works.texy b/application/ru/how-it-works.texy
index 39b20c686c..6e3908f7e0 100644
--- a/application/ru/how-it-works.texy
+++ b/application/ru/how-it-works.texy
@@ -22,13 +22,13 @@
/--pre
web-project/
├── app/ ← каталог с приложением
-│ ├── Presenters/ ← классы презентеров
-│ │ ├── HomePresenter.php ← Класс презентера главной страницы
-│ │ └── templates/ ← директория шаблонов
-│ │ ├── @layout.latte ← шаблон общего макета
-│ │ └── Home/ ← шаблоны презентера главной страницы
-│ │ └── default.latte ← шаблон действия `default`
-│ ├── Router/ ← конфигурация URL-адресов
+│ ├── Core/ ← основные необходимые классы
+│ │ └── RouterFactory.php ← настройка URL-адресов
+│ ├── UI/ ← презентаторы, шаблоны и др.
+│ │ ├── @layout.latte ← шаблон общего макета
+│ │ └── Home/ ← Главная директория ведущих
+│ │ ├── HomePresenter.php ← Класс презентера дома
+│ │ └── default.latte ← шаблон для действий default
│ └── Bootstrap.php ← загрузочный класс Bootstrap
├── bin/ ← скрипты командной строки
├── config/ ← файлы конфигурации
@@ -91,7 +91,7 @@ Nette — это наставник, который направляет вас
Приложение начинает работу с того, что просит так называемый маршрутизатор решить, какому из презентеров передать текущий запрос на обработку. Маршрутизатор решает, чья это ответственность. Он просматривает входной URL `https://example.com/product/123` и, основываясь на том, как он настроен, решает, что это задание, например, для **презентера** `Product`, который хочет `показать` продукт с `id: 123` как действие. Хорошей привычкой является написание пар презентер + действие, разделенных двоеточием: `Продукт:показать`.
-Поэтому маршрутизатор преобразовал URL в пару `Presenter:action` + параметры, в нашем случае `Product:show` + `id`: 123`. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Router/RouterFactory.php`, и мы подробно опишем его в главе [Маршрутизация |routing].
+Поэтому маршрутизатор преобразовал URL в пару `Presenter:action` + параметры, в нашем случае `Product:show` + `id`: 123`. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Core/RouterFactory.php`, и мы подробно опишем его в главе [Маршрутизация |routing].
Давайте двигаться дальше. Приложение уже знает имя презентера и может продолжить работу. Путем создания объекта `ProductPresenter`, который является кодом презентера `Product`. Точнее, он просит контейнер DI создать презентера, потому что создание объектов — это его работа.
@@ -121,12 +121,9 @@ class ProductPresenter extends Nette\Application\UI\Presenter
После этого презентер возвращает ответ. Это может быть HTML-страница, изображение, XML-документ, отправка файла с диска, JSON или перенаправление на другую страницу. Важно отметить, что если мы явно не указываем, как реагировать (что имеет место в случае с `ProductPresenter`), ответом будет отображение шаблона с HTML-страницей. Почему? Ну, потому что в 99% случаев мы хотим отобразить шаблон, поэтому презентер принимает такое поведение по умолчанию и хочет облегчить нашу работу. Это точка зрения Nette.
-Нам даже не нужно указывать, какой шаблон нужно вывести, он сам выводит путь к нему в соответствии с простой логикой. В случае с презентером `Product` и действием `show`, он пытается проверить, существует ли один из этих файлов шаблонов относительно каталога, в котором находится класс `ProductPresenter`:
+Нам даже не нужно указывать, какой шаблон рендерить, фреймворк сам определит путь. В случае с действием `show` он просто попытается загрузить шаблон `show.latte` в директории с классом `ProductPresenter`. Он также попытается найти макет в файле `@layout.latte` (подробнее о [поиске шаблонов |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-И затем он отображает шаблон. Теперь задача презентера и всего приложения выполнена. Если шаблон не существует, будет возвращена страница с ошибкой 404. Подробнее о презентерах вы можете прочитать на странице [Презентеры |presenters].
+Затем происходит рендеринг шаблонов. На этом задача ведущего и всего приложения завершена, и работа закончена. Если шаблон не существует, будет возвращена страница с ошибкой 404. Подробнее о презентерах можно прочитать на странице [Презентеры |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ class ProductPresenter extends Nette\Application\UI\Presenter
3) маршрутизатор декодирует URL как пару `Home:default`
4) создается объект `HomePresenter`
5) вызывается метод `renderDefault()` (если существует)
-6) шаблон `templates/Home/default.latte` с макетом `templates/@layout.latte` отрисован
+6) шаблон `default.latte` с макетом `@layout.latte` отрисован
Возможно, сейчас вы столкнулись с множеством новых понятий, но мы считаем, что они имеют смысл. Создавать приложения в Nette — проще простого.
diff --git a/application/ru/modules.texy b/application/ru/modules.texy
index e7a6b8b277..89dfb1add9 100644
--- a/application/ru/modules.texy
+++ b/application/ru/modules.texy
@@ -2,29 +2,31 @@
******
.[perex]
-В Nette модули представляют собой логические единицы, из которых состоит приложение. Они включают ведущие, шаблоны, возможно, компоненты и классы моделей.
+Модули вносят ясность в приложения Nette, облегчая разделение на логические блоки.
-Одного компонента для презентаторов и одного для шаблонов будет недостаточно для реальных проектов. Наличие десятков файлов в одной папке по меньшей мере неорганизованно. Как выйти из этого положения? Мы просто разделяем их на подкаталоги на диске и на пространства имен в коде. И это именно то, что делают модули Nette.
-
-Поэтому давайте забудем о единой папке для ведущих и шаблонов и вместо этого создадим модули, например, `Admin` и `Front`.
+Подобно организации файлов в папки на жестком диске, в Nette мы можем разделить презентаторы, шаблоны и другие вспомогательные классы на модули. Как это работает на практике? Просто путем включения в структуру новых подкаталогов. Вот пример структуры с двумя модулями - Front и Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← директория с модулями
-│ ├── Admin/ ← модуль Admin
-│ │ ├── Presenters/ ← его презентеры
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← модуль Front
-│ └── Presenters/ ← его презентеры
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Эта структура каталогов будет отражена в пространствах имен классов, так, например, `DashboardPresenter` будет находиться в пространстве `App\Modules\Admin\Presenters`:
+Эта структура каталогов отражается в пространствах имен классов, так, например, `DashboardPresenter` находится в пространстве имен `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Ведущий `Dashboard` внутри модуля `Admin` обозначается в приложении с помощью двойной точечной нотации как `Admin:Dashboard`, а его действие `default` обозначается как `Admin:Dashboard:default`.
-А откуда Nette знает, что `Admin:Dashboard` представляет класс `App\Modules\Admin\Presenters\DashboardPresenter`? Мы говорим об этом, используя [отображение |#Mapping] в конфигурации.
-Таким образом, приведенная структура не является фиксированной, и вы можете изменять ее по своему усмотрению.
+В приложении мы ссылаемся на ведущего `Dashboard` в модуле `Admin` через двоеточие как `Admin:Dashboard`. Для его действия `default` мы ссылаемся на него как на `Admin:Dashboard:default`.
-Модули, конечно, могут содержать все другие части, помимо презентаторов и шаблонов, такие как компоненты, классы моделей и т.д.
+Представленная структура не является жесткой; вы можете [полностью настроить ее под свои нужды |#mapping] в конфигурации. .[tip]
+
+Модули могут включать в себя все остальные файлы, такие как компоненты и вспомогательные классы, в дополнение к ведущим и шаблонам. Если вы раздумываете над тем, где их разместить, рассмотрите возможность использования папки `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Вложенные модули .[#toc-nested-modules]
---------------------------------------
-Модули не обязательно должны формировать только плоскую структуру, вы также можете создавать, например, подмодули:
+Модули могут иметь несколько уровней вложенности, подобно структуре каталогов на диске:
/--pre
-app/
-├── Modules/ ← директория с модулями
-│ ├── Blog/ ← модуль Blog
-│ │ ├── Admin/ ← подмодуль Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← подмодуль Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← модуль Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Таким образом, модуль `Blog` разбивается на подмодули `Admin` и `Front`. И опять же это будет отражено в пространствах имен, которые будут `App\Modules\Blog\Admin\Presenters` и т.д. Ведущий `Dashboard` внутри подмодуля называется `Blog:Admin:Dashboard`.
+Модуль `Blog` делится на подмодули `Admin` и `Front`. Это также отражено в пространствах имен, которые отображаются как `App\UI\Blog\Admin` и аналогично. Для обозначения ведущего `Dashboard` в подмодуле `Admin` мы обозначаем его как `Blog:Admin:Dashboard`.
-Ветвление может быть настолько глубоким, насколько вы захотите, поэтому вы можете создавать подмодули.
+Вложенность может быть настолько глубокой, насколько это необходимо, что позволяет создавать подмодули.
+
+Например, если в администрировании есть много ведущих, связанных с управлением заказами, таких как `OrderDetail`, `OrderEdit`, `OrderDispatch`, и т. д., можно создать модуль `Order`, в котором будут организованы ведущие `Detail`, `Edit`, `Dispatch`, и другие.
Создание ссылок .[#toc-creating-links]
@@ -102,46 +118,59 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
Составление карты .[#toc-mapping]
---------------------------------
-Определяет правила, по которым имя класса выводится из имени ведущего. Мы записываем их в [конфигурацию |configuration] под ключом `application › mapping`.
+Mapping определяет правила получения имени класса из имени ведущего. Эти правила задаются в [конфигурации |configuration] под ключом `application › mapping`.
-Начнем с примера, в котором не используются модули. Мы просто хотим, чтобы классы ведущего имели пространство имен `App\Presenters`. То есть мы хотим, чтобы ведущий, например, `Home` отображался на класс `App\Presenters\HomePresenter`. Этого можно достичь с помощью следующей конфигурации:
+Все примеры в этой главе основаны на следующей конфигурации отображения:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Имя презентера заменяется звездочкой, и в результате получается название класса. Легко!
+Для лучшего понимания давайте сначала рассмотрим приложение без модулей. Мы хотим, чтобы классы ведущих относились к пространству имен `App\UI`. Чтобы сопоставить презентатор `Home` с классом `App\UI\HomePresenter`, мы используем следующую конфигурацию:
-Если мы разделим докладчиков на модули, то для каждого модуля у нас может быть свой маппинг:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Это сопоставление работает путем замены звездочки в маске `App\UI\*Presenter` на имя ведущего `Home`, в результате чего мы получаем конечное имя класса `App\UI\HomePresenter`. Просто!
+
+Однако, как вы можете видеть в примерах этой и других глав, мы размещаем классы ведущих в одноименных подкаталогах, например, ведущий `Home` отображается на класс `App\UI\Home\HomePresenter`. Это достигается удвоением звездочки (требуется Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Теперь перейдем к сопоставлению ведущих с модулями. Для каждого модуля мы можем определить конкретное сопоставление:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Теперь презентер `Front:Home` определяется классом `App\Modules\Front\HomePresenter`, а презентер `Admin:Dashboard` — `App\AdminModule\DashboardPresenter`.
+Согласно этой конфигурации, ведущий `Front:Home` соотносится с классом `App\UI\Front\Home\HomePresenter`, а ведущий `Api:OAuth` - с классом `App\Api\OAuthPresenter`.
-Удобнее будет создать общее правило (звездочка), которое заменит первые два правила и добавит дополнительную звездочку только для модуля:
+Поскольку модули `Front` и `Admin` имеют схожий подход к отображению и, скорее всего, таких модулей будет больше, можно создать общее правило, которое заменит их. В маску класса добавляется новая звездочка для модуля:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Но что если мы используем несколько вложенных модулей и у нас есть, например, ведущий `Admin:User:Edit`? В этом случае сегмент со звездочкой, представляющий модуль для каждого уровня, будет просто повторяться, и результатом будет класс `App\Modules\Admin\User\Presenters\EditPresenter`.
+Для многоуровневых вложенных модулей, таких как ведущий `Admin:User:Edit`, сегмент звездочки повторяется для каждого уровня, в результате чего получается класс `App\UI\Admin\User\Edit\EditPresenter`.
Альтернативной нотацией является использование массива, состоящего из трех сегментов, вместо строки. Эта нотация эквивалентна предыдущей:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Значение по умолчанию - `*Module\*Presenter`.
diff --git a/application/ru/templates.texy b/application/ru/templates.texy
index 75f2c784d0..f506d32046 100644
--- a/application/ru/templates.texy
+++ b/application/ru/templates.texy
@@ -34,35 +34,81 @@ Nette использует систему шаблонов [Latte |latte:]. Latt
Он определяет блок `content`, который вставляется вместо `{include content}` в макете, а также переопределяет блок `title`, который перезаписывает `{block title}` в макете. Попытайтесь представить себе результат.
-Поиск шаблонов .[#toc-search-for-templates]
--------------------------------------------
+Поиск шаблонов .[#toc-template-lookup]
+--------------------------------------
+
+В презентаторах вам не нужно указывать, какой шаблон должен быть отображен; фреймворк автоматически определит путь, облегчая вам кодирование.
+
+Если вы используете структуру каталогов, в которой у каждого ведущего есть своя директория, просто поместите шаблон в эту директорию под именем действия (т. е. представления). Например, для действия `default` используйте шаблон `default.latte`:
-Путь к шаблонам определяется ведущим с помощью простой логики. Он попытается проверить, есть ли один из этих файлов, расположенный относительно каталога класса ведущего, где `` это имя текущего ведущего, а `` это имя текущего события:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Если вы используете структуру, в которой ведущие находятся в одном каталоге, а шаблоны - в папке `templates`, сохраните их либо в файле `..latte` или `/.latte`:
-Если шаблон не найден, он попытается выполнить поиск в каталоге `templates` на один уровень выше, т.е. на том же уровне, что и каталог с классом ведущего.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Если шаблон не найден и там, ответом будет [ошибка 404 |presenters#Error 404 etc.].
+Каталог `templates` можно также разместить на один уровень выше, на том же уровне, что и каталог с классами ведущих.
-Вы также можете изменить вид с помощью `$this->setView('jineView')`. Или, вместо прямого поиска, укажите имя файла шаблона с помощью `$this->template->setFile('/path/to/template.latte')`.
+Если шаблон не найден, ведущий отвечает [ошибкой 404 - страница не найдена |presenters#Error 404 etc].
+
+Изменить вид можно с помощью `$this->setView('anotherView')`. Также можно напрямую указать файл шаблона с помощью `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Файлы, в которых производится поиск шаблонов, можно изменить, наложив метод [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], который возвращает массив возможных имен файлов.
+Файлы, в которых производится поиск шаблонов, можно изменить, переопределив метод [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], который возвращает массив возможных имен файлов.
+
+
+Поиск шаблонов макета .[#toc-layout-template-lookup]
+----------------------------------------------------
+
+Nette также автоматически ищет файл макета.
+
+Если вы используете структуру каталогов, в которой у каждого ведущего есть своя директория, поместите макет либо в папку с ведущим, если он предназначен только для него, либо на уровень выше, если он общий для нескольких ведущих:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Если вы используете структуру, в которой ведущие сгруппированы в одном каталоге, а шаблоны находятся в папке `templates`, макет будет находиться в следующих местах:
-В этих файлах ожидается компоновка:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` макет, общий для нескольких докладчиков
+Если ведущий находится в [модуле |modules], он также будет искать дальше по дереву каталогов в соответствии с вложенностью модуля.
-Где `` это имя текущего ведущего и `` это имя макета, которое по умолчанию равно `'layout'`. Имя может быть изменено с помощью `$this->setLayout('jinyLayout')`, поэтому будут опробованы файлы `@jinyLayout.latte`.
+Имя макета можно изменить с помощью `$this->setLayout('layoutAdmin')`, и тогда оно будет ожидаться в файле `@layoutAdmin.latte`. Вы также можете напрямую указать файл шаблона макета с помощью `$this->setLayout('/path/to/template.latte')`.
-Вы также можете напрямую указать имя файла шаблона макета с помощью `$this->setLayout('/path/to/template.latte')`. Использование `$this->setLayout(false)` отключает отслеживание макета.
+Использование тега `$this->setLayout(false)` или `{layout none}` внутри шаблона отключает поиск макета.
.[note]
-Файлы, в которых производится поиск шаблонов макета, можно изменить, наложив метод [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], который возвращает массив возможных имен файлов.
+Файлы, в которых производится поиск шаблонов макетов, можно изменить, переопределив метод [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], который возвращает массив возможных имен файлов.
Переменные в шаблоне .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template
Вы также можете позволить себе роскошь шептать в шаблонах, просто установите плагин Latte в PhpStorm и поместите имя класса в начало шаблона, более подробную информацию смотрите в статье "Latte: как набирать систему":https://blog.nette.org/ru/latte-kak-ispol-zovat-sistemu-tipov:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Latte версии 3 предлагает более продвинутый способ создания [расширения |latte:creating-extension] для каждого веб-проекта. Вот краткий пример такого класса:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ final class LatteExtension extends Latte\Extension
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/sl/how-it-works.texy b/application/sl/how-it-works.texy
index 0149fdc95f..53d08d145d 100644
--- a/application/sl/how-it-works.texy
+++ b/application/sl/how-it-works.texy
@@ -22,13 +22,13 @@ Struktura imenikov je videti nekako takole:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← osnovni potrebni razredi
+│ │ └── RouterFactory.php ← konfiguracija naslovov URL
+│ ├── UI/ ← predstavitev, predloge in podobno.
+│ │ ├── @layout.latte ← predloga skupne postavitve
+│ │ └── Home/ ← Domači imenik predstavnikov
+│ │ ├── HomePresenter.php ← Razred HomePresenter
+│ │ └── default.latte ← predloga za akcijo default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Aplikacije, napisane v okolju Nette, so razdeljene na številne tako imenovane p
Aplikacija se začne tako, da zahteva od tako imenovanega usmerjevalnika, da se odloči, kateremu od predstavnikov bo posredoval trenutno zahtevo v obdelavo. Usmerjevalnik se odloči, čigava je to odgovornost. Pregleda vhodni naslov URL `https://example.com/product/123`, ki želi `show` izdelek z `id: 123` kot dejanjem. Dobra navada je, da se pari predstavnik + akcija, ločeni z dvopičjem, zapišejo kot `Product:show`.
-Usmerjevalnik je torej pretvoril naslov URL v par `Presenter:action` + parametri, v našem primeru `Product:show` + `id: 123`. Kako je videti usmerjevalnik, si lahko ogledate v datoteki `app/Router/RouterFactory.php`, podrobno pa ga bomo opisali v poglavju [Usmerjanje |Routing].
+Usmerjevalnik je torej pretvoril naslov URL v par `Presenter:action` + parametri, v našem primeru `Product:show` + `id: 123`. Kako je videti usmerjevalnik, si lahko ogledate v datoteki `app/Core/RouterFactory.php`, podrobno pa ga bomo opisali v poglavju [Usmerjanje |Routing].
Pojdimo naprej. Aplikacija že pozna ime predavatelja in lahko nadaljuje. Z ustvarjanjem predmeta `ProductPresenter`, ki je koda predstavnika `Product`. Natančneje, za ustvarjanje predstavnika zaprosi vsebnik DI, saj je izdelovanje objektov njegova naloga.
@@ -121,12 +121,9 @@ Tako je bila klicana metoda `renderShow(123)`, katere koda je izmišljen primer,
Nato predstavnik vrne odgovor. To je lahko stran HTML, slika, dokument XML, pošiljanje datoteke z diska, JSON ali preusmeritev na drugo stran. Pomembno je, da če izrecno ne navedemo, kako odgovoriti (kar je primer `ProductPresenter`), bo odgovor prikaz predloge s stranjo HTML. Zakaj? No, ker v 99 % primerov želimo izrisati predlogo, zato predstavnik to vedenje sprejme kot privzeto in nam želi olajšati delo. To je Nettejeva poanta.
-Ni nam treba niti navesti, katero predlogo želimo narisati, on pot do nje izpelje po preprosti logiki. V primeru predstavnika `Product` in akcije `show`, poskuša preveriti, ali obstaja ena od teh datotek s predlogami glede na imenik, v katerem se nahaja razred `ProductPresenter`:
+Sploh nam ni treba navesti, katero predlogo je treba prikazati; ogrodje bo pot določilo samo. V primeru akcije `show` preprosto poskuša naložiti predlogo `show.latte` v imeniku z razredom `ProductPresenter`. Prav tako poskuša najti postavitev v datoteki `@layout.latte` (več o [iskanju predlog |templates#Template Lookup]).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Prav tako poskuša poiskati postavitev v datoteki `@layout.latte` in nato upodobi predlogo. Zdaj je naloga predstavnika in celotne aplikacije končana. Če predloga ne obstaja, se vrne stran z napako 404. Več o predstavitvah si lahko preberete na strani [Predstavitve |Presenters].
+Nato se predloge izrišejo. S tem je naloga predstavnika in celotne aplikacije končana in delo je opravljeno. Če predloga ne bi obstajala, bi se vrnila stran z napako 404. Več o predstavnikih si lahko preberete na strani [Predstavniki |presenters].
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Da bi se prepričali, poskusite celoten postopek ponoviti z nekoliko drugačnim
3) usmerjevalnik dekodira naslov URL kot par `Home:default`
4) ustvari se objekt `HomePresenter`
5) kličemo metodo `renderDefault()` (če obstaja)
-6) prikaže se predloga `templates/Home/default.latte` z razporeditvijo `templates/@layout.latte`
+6) prikaže se predloga `default.latte` z razporeditvijo `@layout.latte`
Morda ste zdaj naleteli na veliko novih konceptov, vendar verjamemo, da so smiselni. Ustvarjanje aplikacij v programu Nette je zelo enostavno.
diff --git a/application/sl/modules.texy b/application/sl/modules.texy
index c0c01ae28d..3eabed5fa2 100644
--- a/application/sl/modules.texy
+++ b/application/sl/modules.texy
@@ -2,29 +2,31 @@ Moduli
******
.[perex]
-V Nette moduli predstavljajo logične enote, ki sestavljajo aplikacijo. Vključujejo predstavnike, predloge, lahko tudi komponente in razrede modelov.
+Moduli vnašajo jasnost v aplikacije Nette, saj omogočajo enostavno razdelitev na logične enote.
-En imenik za predstavnike in en imenik za predloge za prave projekte ne bi bil dovolj. Če je v eni mapi na desetine datotek, je to vsaj neorganizirano. Kako to odpraviti? Preprosto jih razdelimo v podimenike na disku in v imenske prostore v kodi. In točno to naredijo moduli Nette.
-
-Pozabimo torej na eno mapo za predstavnike in predloge in namesto tega ustvarimo module, na primer `Admin` in `Front`.
+Podobno kot pri urejanju datotek v mape na trdem disku, lahko v Nette predstavnike, predloge in druge pomožne razrede razdelimo v module. Kako to deluje v praksi? Preprosto z vključevanjem novih podimenikov v strukturo. Tukaj je primer strukture z dvema moduloma, Front in Admin:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Ta struktura imenikov se bo odražala v imenskih prostorih razredov, tako da bo na primer `DashboardPresenter` v imenskem prostoru `App\Modules\Admin\Presenters`:
+Ta imeniška struktura se odraža v imenskih prostorih razredov, tako da se na primer `DashboardPresenter` nahaja v imenskem prostoru `App\UI\Admin\Dashboard`:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-Na predvajalnik `Dashboard` znotraj modula `Admin` se v aplikaciji sklicujemo z uporabo zapisa v dvopičju kot na `Admin:Dashboard`, na njegovo akcijo `default` pa kot na `Admin:Dashboard:default`.
-In kako Nette pravilno ve, da `Admin:Dashboard` predstavlja razred `App\Modules\Admin\Presenters\DashboardPresenter`? To je določeno s [preslikavo |#mapping] v konfiguraciji.
-Podana struktura torej ni trdno določena in jo lahko spreminjate glede na svoje potrebe.
+V aplikaciji se na predstavnik `Dashboard` znotraj modula `Admin` sklicujemo z uporabo zapisa v dvopičju kot `Admin:Dashboard`. Za njegovo akcijo `default` se sklicujemo na `Admin:Dashboard:default`.
-Moduli seveda lahko poleg predstavnikov in predlog vsebujejo tudi vse druge elemente, kot so komponente, razredi modelov itd.
+Predstavljena struktura ni toga; v konfiguraciji [jo |#mapping] lahko v [celoti prilagodite svojim potrebam |#mapping]. .[tip]
+
+Moduli lahko poleg predstavnikov in predlog vključujejo tudi vse druge datoteke, kot so komponente in pomožni razredi. Če razmišljate, kam jih umestiti, razmislite o uporabi mape `Accessory`:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
Vgnezdeni moduli .[#toc-nested-modules]
---------------------------------------
-Ni nujno, da moduli tvorijo le ravno strukturo, ustvarite lahko tudi podmodule, na primer:
+Moduli so lahko vgrajeni na več ravneh, podobno kot struktura imenikov na disku:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Tako je modul `Blog` razdeljen na podmodula `Admin` in `Front`. Tudi to se bo odražalo v imenskih prostorih, ki bodo `App\Modules\Blog\Admin\Presenters` itd. Predstavnik `Dashboard` znotraj podmodula se imenuje `Blog:Admin:Dashboard`.
+Modul `Blog` je razdeljen na podmodula `Admin` in `Front`. To se odraža tudi v imenskih prostorih, ki so nato prikazani kot `App\UI\Blog\Admin` in podobno. Če se želimo sklicevati na predstavnik `Dashboard` znotraj podmodula `Admin`, ga imenujemo `Blog:Admin:Dashboard`.
-Gnezdenje je lahko tako globoko, kot želite, zato lahko ustvarite podmodule.
+Gnezdenje je lahko tako globoko, kot je potrebno, kar omogoča ustvarjanje podmodulov.
+
+Če imate na primer v administraciji veliko predstavnikov, povezanih z upravljanjem naročil, kot so `OrderDetail`, `OrderEdit`, `OrderDispatch` itd., lahko ustvarite modul `Order`, v katerem bodo organizirani predstavniki, kot so `Detail`, `Edit`, `Dispatch` in drugi.
Ustvarjanje povezav .[#toc-creating-links]
@@ -102,46 +118,59 @@ Glejte [poglavje o usmerjanju |routing#Modules].
Kartiranje .[#toc-mapping]
--------------------------
-Določa pravila, po katerih se ime razreda izpelje iz imena predstavnika. Zapišemo jih v [konfiguracijo |configuration] pod ključ `application › mapping`.
+Mapiranje določa pravila za izpeljavo imena razreda iz imena predstavnika. Ta pravila so določena v [konfiguraciji |configuration] pod ključem `application › mapping`.
-Začnimo z vzorcem, ki ne uporablja modulov. Želeli bomo le, da imajo razredi predstavnikov imenski prostor `App\Presenters`. To pomeni, da mora biti predstavnik, kot je `Home`, preslikan v razred `App\Presenters\HomePresenter`. To lahko dosežemo z naslednjo konfiguracijo:
+Vsi primeri v tem poglavju temeljijo na naslednji konfiguraciji kartiranja:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-V maski razreda se ime predvajalnika nadomesti z zvezdico, rezultat pa je ime razreda. Enostavno!
+Za boljše razumevanje najprej obravnavajmo aplikacijo brez modulov. Želimo, da razredi predstavnikov spadajo v imenski prostor `App\UI`. Če želimo predstavnik `Home` preslikati v razred `App\UI\HomePresenter`, to dosežemo z naslednjo konfiguracijo:
-Če voditelje razdelimo na module, lahko za vsak modul pripravimo lastno preslikavo:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Ta preslikava deluje tako, da zvezdico v maski `App\UI\*Presenter` nadomestimo z imenom predstavnika `Home`, s čimer dobimo končno ime razreda `App\UI\HomePresenter`. Preprosto!
+
+Vendar, kot lahko vidite v primerih v tem in drugih poglavjih, umeščamo predstavitvene razrede v istoimenske podimenike, npr. predstavitveni razred `Home` je preslikan v razred `App\UI\Home\HomePresenter`. To dosežemo s podvojitvijo zvezdice (zahteva program Nette Application 3.2):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Sedaj se lotimo preslikave predstavnikov v module. Za vsak modul lahko opredelimo posebna preslikavanja:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Sedaj je predstavnik `Front:Home` preslikan v razred `App\Modules\Front\Presenters\HomePresenter`, predstavnik `Admin:Dashboard` pa v razred `App\Modules\Admin\Presenters\DashboardPresenter`.
+V skladu s to konfiguracijo se predstavnik `Front:Home` prikaže v razred `App\UI\Front\Home\HomePresenter`, predstavnik `Api:OAuth` pa v razred `App\Api\OAuthPresenter`.
-Bolj praktično je ustvariti splošno (zvezdno) pravilo, ki bo nadomestilo prvi dve. Dodatna zvezdica bo dodana maski razreda samo za ta modul:
+Ker imata modula `Front` in `Admin` podoben pristop k preslikavi in ker bo takih modulov verjetno več, je mogoče ustvariti splošno pravilo, ki ju nadomesti. V masko razreda se doda nova zvezdica za modul:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Kaj pa, če uporabljamo vgnezdene module in imamo predvajalnik `Admin:User:Edit`? V tem primeru se segment z zvezdico, ki predstavlja modul za vsako raven, preprosto ponovi in rezultat je razred `App\Modules\Admin\User\Presenters\EditPresenter`.
+Za večnivojske vgnezdene module, kot je predstavnik `Admin:User:Edit`, se segment z zvezdico ponovi za vsako raven, tako da nastane razred `App\UI\Admin\User\Edit\EditPresenter`.
Alternativni zapis je, da namesto niza uporabimo polje, sestavljeno iz treh segmentov. Ta zapis je enakovreden prejšnjemu:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Privzeta vrednost je `*Module\*Presenter`.
diff --git a/application/sl/templates.texy b/application/sl/templates.texy
index 66005783a9..966b1524a2 100644
--- a/application/sl/templates.texy
+++ b/application/sl/templates.texy
@@ -34,35 +34,81 @@ To pa je lahko predloga za dejanja:
V njej je opredeljen blok `content`, ki se v postavitev vstavi namesto bloka `{include content}`, prav tako pa je na novo opredeljen blok `title`, ki v postavitvi prepiše blok `{block title}`. Poskusite si predstavljati rezultat.
-Iskanje predlog .[#toc-search-for-templates]
---------------------------------------------
+Iskanje predloge .[#toc-template-lookup]
+----------------------------------------
-Pot do predlog se določi po preprosti logiki. Poskusi preveriti, ali obstaja ena od teh datotek s predlogami glede na imenik, v katerem se nahaja razred presenter, kjer `` je ime trenutnega predstavnika in `` je ime trenutnega dejanja:
+V predstavitvenih programih vam ni treba določiti, katera predloga naj se prikaže; ogrodje samodejno določi pot, kar vam olajša kodiranje.
-- `templates//.latte`
-- `templates/..latte`
+Če uporabljate imeniško strukturo, v kateri ima vsak predstavnik svoj imenik, preprosto postavite predlogo v ta imenik pod ime dejanja (npr. pogleda). Na primer, za dejanje `default` uporabite predlogo `default.latte`:
-Če predloge ne najde, jo poskuša poiskati v imeniku `templates` eno raven višje, tj. na isti ravni kot imenik z razredom predstavnika.
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-Če predloge ne najde niti tam, se kot odgovor prikaže [napaka 404 |presenters#Error 404 etc.].
+Če uporabljate strukturo, v kateri so predstavniki skupaj v enem imeniku, predloge pa v mapi `templates`, jo shranite bodisi v datoteko `..latte` ali . `/.latte`:
-Pogled lahko spremenite tudi z uporabo `$this->setView('otherView')`. Lahko pa namesto iskanja neposredno določite ime datoteke s predlogo z uporabo `$this->template->setFile('/path/to/template.latte')`.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
+
+Imenik `templates` lahko postavite tudi eno raven višje, na isto raven kot imenik z razredi predavateljev.
+
+Če predloge ni mogoče najti, se predstavitveni program odzove z [napako 404 - stran ni najdena |presenters#Error 404 etc].
+
+Prikaz lahko spremenite z uporabo spletne strani `$this->setView('anotherView')`. Datoteko s predlogo lahko določite tudi neposredno z uporabo `$this->template->setFile('/path/to/template.latte')`.
.[note]
-Poti, po katerih se iščejo predloge, lahko spremenite tako, da nadgradite metodo [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()], ki vrne polje možnih poti do datotek.
+Datoteke, v katerih se iščejo predloge, lahko spremenite tako, da nadgradite metodo [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()], ki vrne polje možnih imen datotek.
+
+
+Iskanje predlog za postavitev .[#toc-layout-template-lookup]
+------------------------------------------------------------
+
+Nette samodejno poišče tudi datoteko z maketo.
+
+Če uporabljate imeniško strukturo, v kateri ima vsak predavatelj svoj imenik, postavite postavitev bodisi v mapo s predavateljem, če je namenjena samo njemu, bodisi za stopnjo višje, če je skupna več predavateljem:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Če uporabljate strukturo, v kateri so predstavniki združeni v enem imeniku, predloge pa so v mapi `templates`, bo postavitev pričakovana na naslednjih mestih:
-Postavitev se pričakuje v naslednjih datotekah:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` postavitev, ki je skupna več predstavnikom
+Če je predstavnik v [modulu |modules], se bo poiskal tudi naprej po drevesu imenika v skladu z gnezdenjem modula.
-`` je ime trenutnega predavatelja in `` je ime postavitve, ki je privzeto `'layout'`. Ime lahko spremenite s `$this->setLayout('otherLayout')`, tako da se bodo poskušale uporabiti datoteke `@otherLayout.latte`.
+Ime postavitve lahko spremenite z uporabo spletne strani `$this->setLayout('layoutAdmin')`, nato pa jo boste pričakali v datoteki `@layoutAdmin.latte`. Datoteko s predlogo postavitve lahko določite tudi neposredno z uporabo `$this->setLayout('/path/to/template.latte')`.
-Ime datoteke za predlogo postavitve lahko določite tudi neposredno z uporabo `$this->setLayout('/path/to/template.latte')`. Z uporabo spletne strani `$this->setLayout(false)` bo iskanje postavitve onemogočeno.
+Uporaba `$this->setLayout(false)` ali oznake `{layout none}` znotraj predloge onemogoči iskanje postavitve.
.[note]
-Poti, po katerih se iščejo predloge, lahko spremenite tako, da nadgradite metodo [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], ki vrne polje možnih poti do datotek.
+Datoteke, v katerih se iščejo predloge postavitve, lahko spremenite tako, da nadgradite metodo [formatLayoutTemplateFiles() |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()], ki vrne polje možnih imen datotek.
Spremenljivke v predlogi .[#toc-variables-in-the-template]
@@ -104,7 +150,7 @@ Opomba `@property-read` je namenjena IDE in statični analizi, zaradi nje bo del
Privoščite si lahko tudi razkošje šepetanja v predlogah, samo namestite vtičnik Latte v PhpStorm in na začetku predloge navedite ime razreda, glejte članek "Latte: kako vtipkati sistem":https://blog.nette.org/sl/latte-kako-uporabljati-sistem-tipov:
```latte
-{templateType App\Presenters\ArticleTemplate}
+{templateType App\UI\Article\ArticleTemplate}
...
```
@@ -176,7 +222,7 @@ public function beforeRender(): void
Različica Latte 3 ponuja naprednejši način z ustvarjanjem [razširitve |latte:creating-extension] za vsak spletni projekt. Tukaj je približni primer takega razreda:
```php
-namespace App\Templating;
+namespace App\UI\Accessory;
final class LatteExtension extends Latte\Extension
{
@@ -214,7 +260,7 @@ Registriramo ga z uporabo [konfiguracije|configuration#Latte]:
```neon
latte:
extensions:
- - App\Templating\LatteExtension
+ - App\UI\Accessory\LatteExtension
```
diff --git a/application/tr/how-it-works.texy b/application/tr/how-it-works.texy
index 78f72c450c..50e09beecc 100644
--- a/application/tr/how-it-works.texy
+++ b/application/tr/how-it-works.texy
@@ -22,13 +22,13 @@ Dizin yapısı şuna benzer:
/--pre
web-project/
├── app/ ← directory with application
-│ ├── Presenters/ ← presenter classes
-│ │ ├── HomePresenter.php ← Home presenter class
-│ │ └── templates/ ← templates directory
-│ │ ├── @layout.latte ← template of shared layout
-│ │ └── Home/ ← templates for Home presenter
-│ │ └── default.latte ← template for action `default`
-│ ├── Router/ ← configuration of URL addresses
+│ ├── Core/ ← temel gerekli sınıflar
+│ │ └── RouterFactory.php ← URL adreslerinin yapılandırılması
+│ ├── UI/ ← presenters, templates & co.
+│ │ ├── @layout.latte ← paylaşılan düzen şablonu
+│ │ └── Home/ ← Ana Sayfa sunucu dizini
+│ │ ├── HomePresenter.php ← Ev sunucusu sınıfı
+│ │ └── default.latte ← eylem için şablon default
│ └── Bootstrap.php ← booting class Bootstrap
├── bin/ ← scripts for the command line
├── config/ ← configuration files
@@ -91,7 +91,7 @@ Nette'de yazılan uygulamalar, belirli bir web sitesi sayfasını temsil eden s
Uygulama, yönlendirici olarak adlandırılan kişiden mevcut talebin işlenmek üzere hangi sunuculara iletileceğine karar vermesini isteyerek başlar. Yönlendirici bunun kimin sorumluluğunda olduğuna karar verir. `https://example.com/product/123` ile bir ürünü `id: 123` eylem olarak isteyen **sunucu** `Product` için bir iş olduğuna karar verir. Sunucu + eylem çiftlerini iki nokta üst üste ile ayırarak `Product:show` şeklinde yazmak iyi bir alışkanlıktır.
-Böylece yönlendirici URL'yi bir `Presenter:action` + parametreler çiftine dönüştürdü, bizim durumumuzda `Product:show` + `id: 123`. Bir yönlendiricinin nasıl göründüğünü `app/Router/RouterFactory.php` dosyasında görebilirsiniz ve bunu [Yönlendirme |Routing] bölümünde ayrıntılı olarak açıklayacağız.
+Böylece yönlendirici URL'yi bir `Presenter:action` + parametreler çiftine dönüştürdü, bizim durumumuzda `Product:show` + `id: 123`. Bir yönlendiricinin nasıl göründüğünü `app/Core/RouterFactory.php` dosyasında görebilirsiniz ve bunu [Yönlendirme |Routing] bölümünde ayrıntılı olarak açıklayacağız.
Devam edelim. Uygulama zaten sunucunun adını biliyor ve devam edebilir. Sunum yapan kişinin kodu olan `ProductPresenter` nesnesini oluşturarak `Product`. Daha doğrusu, DI konteynerinden sunucuyu yaratmasını ister, çünkü nesneleri üretmek onun işidir.
@@ -121,12 +121,9 @@ Böylece, kodu kurgusal bir örnek olan `renderShow(123)` yöntemi çağrıldı,
Daha sonra, sunum yapan kişi yanıtı döndürür. Bu bir HTML sayfası, bir resim, bir XML belgesi, diskten bir dosya gönderme, JSON veya başka bir sayfaya yönlendirme olabilir. Daha da önemlisi, nasıl yanıt verileceğini açıkça belirtmezsek ( `ProductPresenter` adresinde olduğu gibi), yanıt şablonu bir HTML sayfası ile işlemek olacaktır. Neden mi? Çünkü vakaların %99'unda bir şablon çizmek isteriz, dolayısıyla sunum yapan kişi bu davranışı varsayılan olarak kabul eder ve işimizi kolaylaştırmak ister. Nette'in amacı da bu.
-Hangi şablonun çizileceğini belirtmemize bile gerek yok, basit bir mantıkla o şablona giden yolu türetiyor. Sunucu `Product` ve eylem `show` durumunda, bu şablon dosyalarından birinin `ProductPresenter` sınıfının bulunduğu dizine göre var olup olmadığını görmeye çalışır:
+Hangi şablonun işleneceğini belirtmemize bile gerek yoktur; framework yolu kendisi çıkaracaktır. `show` eylemi söz konusu olduğunda, basitçe `ProductPresenter` sınıfının bulunduğu dizindeki `show.latte` şablonunu yüklemeye çalışır. Ayrıca `@layout.latte` dosyasındaki düzeni bulmaya çalışır ( [şablon arama |templates#Template Lookup] hakkında daha fazla bilgi).
-- `templates/Product/show.latte`
-- `templates/Product.show.latte`
-
-Ayrıca `@layout.latte` dosyasında düzeni bulmaya çalışacak ve ardından şablonu oluşturacaktır. Artık sunucunun ve tüm uygulamanın görevi tamamlanmıştır. Şablon mevcut değilse, 404 hatalı bir sayfa döndürülecektir. Sunumcular hakkında daha fazla bilgiyi [Sunumcular |Presenters] sayfasında bulabilirsiniz.
+Daha sonra şablonlar işlenir. Bu, sunucunun ve tüm uygulamanın görevini tamamlar ve iş biter. Eğer şablon mevcut değilse, 404 hata sayfası döndürülür. Sunucular hakkında daha fazla bilgi için [Sunucular |presenters] sayfasına bakabilirsiniz.
[* request-flow.svg *]
@@ -137,7 +134,7 @@ Sadece emin olmak için, tüm süreci biraz farklı bir URL ile özetlemeye çal
3) yönlendirici URL'yi bir çift olarak çözer `Home:default`
4) bir `HomePresenter` nesnesi oluşturulur
5) `renderDefault()` yöntemi çağrılır (eğer varsa)
-6) `templates/@layout.latte` düzenine sahip bir `templates/Home/default.latte` şablonu oluşturulur
+6) `@layout.latte` düzenine sahip bir `default.latte` şablonu oluşturulur
Şu anda birçok yeni kavramla karşılaşmış olabilirsiniz, ancak bunların anlamlı olduğuna inanıyoruz. Nette'de uygulama oluşturmak çocuk oyuncağı.
diff --git a/application/tr/modules.texy b/application/tr/modules.texy
index 63da6e9e48..a4c42bffc3 100644
--- a/application/tr/modules.texy
+++ b/application/tr/modules.texy
@@ -2,29 +2,31 @@ Modüller
********
.[perex]
-Nette'de modüller bir uygulamayı oluşturan mantıksal birimleri temsil eder. Sunucuları, şablonları, muhtemelen bileşenleri ve model sınıflarını içerirler.
+Modüller, mantıksal birimlere kolayca bölünmeyi kolaylaştırarak Nette uygulamalarına netlik kazandırır.
-Sunucular için bir dizin ve şablonlar için bir dizin gerçek projeler için yeterli olmayacaktır. Bir klasörde düzinelerce dosya olması en azından düzensizdir. Bundan nasıl kurtulabiliriz? Basitçe onları diskteki alt dizinlere ve koddaki ad alanlarına böleriz. Nette modüllerinin yaptığı da tam olarak budur.
-
-Sunucular ve şablonlar için tek bir klasör oluşturmayı unutalım ve bunun yerine örneğin `Admin` ve `Front` gibi modüller oluşturalım.
+Dosyaları sabit diskte klasörler halinde düzenlemeye benzer şekilde, Nette'de sunum yapan kişileri, şablonları ve diğer yardımcı sınıfları modüllere bölebiliriz. Bu pratikte nasıl çalışır? Basitçe yapıya yeni alt dizinler ekleyerek. İşte Front ve Admin olmak üzere iki modüllü bir yapı örneği:
/--pre
-app/
-├── Presenters/
-├── Modules/ ← directory with modules
-│ ├── Admin/ ← module Admin
-│ │ ├── Presenters/ ← its presenters
-│ │ │ ├── DashboardPresenter.php
-│ │ │ └── templates/
-│ └── Front/ ← module Front
-│ └── Presenters/ ← its presenters
-│ └── ...
+app/
+├── UI/
+│ ├── Admin/ ← Admin module
+│ │ ├── @layout.latte
+│ │ ├── Dashboard/
+│ │ │ ├── DashboardPresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
+│ ├── Front/ ← Front module
+│ │ ├── @layout.latte
+│ │ ├── Home/
+│ │ │ ├── HomePresenter.php
+│ │ │ └── default.latte
+│ │ └── ...
\--
-Bu dizin yapısı sınıf ad alanları tarafından yansıtılacaktır, bu nedenle örneğin `DashboardPresenter` `App\Modules\Admin\Presenters` ad alanında olacaktır:
+Bu dizin yapısı sınıfların isim alanlarına da yansıtılır; örneğin `DashboardPresenter`, `App\UI\Admin\Dashboard` isim alanında yer alır:
```php
-namespace App\Modules\Admin\Presenters;
+namespace App\UI\Admin\Dashboard;
class DashboardPresenter extends Nette\Application\UI\Presenter
{
@@ -32,35 +34,49 @@ class DashboardPresenter extends Nette\Application\UI\Presenter
}
```
-`Admin` modülü içindeki `Dashboard` sunumcusuna uygulama içinde iki nokta üst üste gösterimi kullanılarak `Admin:Dashboard` şeklinde ve `default` eylemine `Admin:Dashboard:default` şeklinde referans verilir.
-Peki Nette proper `Admin:Dashboard` 'un `App\Modules\Admin\Presenters\DashboardPresenter` sınıfını temsil ettiğini nasıl biliyor? Bu, yapılandırmadaki [eşleme |#mapping] ile belirlenir.
-Bu nedenle, verilen yapı sabit değildir ve ihtiyaçlarınıza göre değiştirebilirsiniz.
+Uygulamada, `Admin` modülü içindeki `Dashboard` sunumcusuna iki nokta üst üste gösterimini kullanarak `Admin:Dashboard` olarak atıfta bulunuyoruz. `default` eylemi için `Admin:Dashboard:default` olarak adlandırıyoruz.
-Modüller elbette sunum yapanların ve şablonların yanı sıra bileşenler, model sınıfları vb. gibi diğer tüm öğeleri de içerebilir.
+Sunulan yapı katı değildir; yapılandırmada [ihtiyaçlarınıza göre tamamen özelleştirebilirsiniz |#mapping]. .[tip]
+
+Modüller, sunucular ve şablonların yanı sıra bileşenler ve yardımcı sınıflar gibi diğer tüm dosyaları da içerebilir. Bunları nereye yerleştireceğinizi düşünüyorsanız, bir `Accessory` klasörü kullanmayı düşünün:
+
+/--pre
+app/
+├── UI/
+│ ├── Admin/
+│ │ ├── Accessory/
+│ │ │ ├── FormFactory.php
+│ │ │ └── AdminLayout.php
+│ │ ├── Dashboard/
+│ │ └── ...
+\--
İç İçe Modüller .[#toc-nested-modules]
--------------------------------------
-Modüller sadece düz bir yapı oluşturmak zorunda değildir, örneğin alt modüller de oluşturabilirsiniz:
+Modüller, diskteki bir dizin yapısına benzer şekilde birden fazla iç içe geçme seviyesine sahip olabilir:
/--pre
-app/
-├── Modules/ ← directory with modules
-│ ├── Blog/ ← module Blog
-│ │ ├── Admin/ ← submodule Admin
-│ │ │ ├── Presenters/
+app/
+├── UI/
+│ ├── Blog/ ← Blog module
+│ │ ├── Admin/ ← Admin submodule
+│ │ │ ├── Dashboard/
+│ │ │ └── ...
+│ │ ├── Front/ ← Front submodule
+│ │ │ ├── @layout.latte
+│ │ │ ├── Home/
│ │ │ └── ...
-│ │ └── Front/ ← submodule Front
-│ │ ├── Presenters/
-│ │ └── ...
-│ ├── Forum/ ← module Forum
+│ ├── Forum/ ← Forum module
│ │ └── ...
\--
-Böylece, `Blog` modülü `Admin` ve `Front` alt modüllerine bölünmüştür. Yine, bu durum `App\Modules\Blog\Admin\Presenters` vb. isim alanlarına da yansıyacaktır. Alt modülün içindeki `Dashboard` sunucusu `Blog:Admin:Dashboard` olarak adlandırılır.
+ `Blog` modülü `Admin` ve `Front` alt modüllerine ayrılmıştır. Bu aynı zamanda `App\UI\Blog\Admin` ve benzer şekilde görünen isim alanlarına da yansıtılır. `Admin` alt modülü içindeki `Dashboard` sunucusuna atıfta bulunmak için, bunu `Blog:Admin:Dashboard` olarak adlandırıyoruz.
-İç içe geçme istediğiniz kadar derin olabilir, böylece alt alt modüller oluşturulabilir.
+Yerleştirme, alt alt modüllerin oluşturulmasına izin vererek gerektiği kadar derin olabilir.
+
+Örneğin, yönetimde `OrderDetail`, `OrderEdit`, `OrderDispatch`, vb. gibi sipariş yönetimiyle ilgili birçok sunucunuz varsa, `Detail`, `Edit`, `Dispatch` ve diğerleri gibi sunucuların düzenleneceği bir `Order` modülü oluşturabilirsiniz.
Bağlantı Oluşturma .[#toc-creating-links]
@@ -102,46 +118,59 @@ Yönlendirme .[#toc-routing]
Haritalama .[#toc-mapping]
--------------------------
-Sınıf adının sunum yapan kişinin adından türetildiği kuralları tanımlar. Bunları [yapılandırmada |configuration] `application › mapping` anahtarının altına yazıyoruz.
+Eşleme, sınıf adının sunum yapan kişinin adından türetilmesine ilişkin kuralları tanımlar. Bu kurallar [yapılandırmada |configuration] `application › mapping` anahtarı altında belirtilir.
-Modül kullanmayan bir örnekle başlayalım. Sadece sunum yapan sınıfların `App\Presenters` ad alanına sahip olmasını isteyeceğiz. Bu, `Home` gibi bir sunucunun `App\Presenters\HomePresenter` sınıfıyla eşleşmesi gerektiği anlamına gelir. Bu, aşağıdaki yapılandırma ile gerçekleştirilebilir:
+Bu bölümdeki tüm örnekler aşağıdaki eşleme yapılandırmasına dayanmaktadır:
```neon
application:
- mapping: App\Presenters\*Presenter
+ mapping: App\UI\*\**Presenter
```
-Sunum yapan kişinin adı sınıf maskesindeki yıldız işaretiyle değiştirilir ve sonuç sınıf adı olur. Kolay!
+Daha iyi anlamak için öncelikle modülsüz bir uygulama düşünelim. Sunucu sınıflarının `App\UI` ad alanı altında yer almasını istiyoruz. `Home` presenter'ı `App\UI\HomePresenter` sınıfına eşlemek için bunu aşağıdaki yapılandırma ile gerçekleştiriyoruz:
-Sunum yapanları modüllere ayırırsak, her modül için kendi eşlememizi yapabiliriz:
+```neon
+application:
+ mapping: App\UI\*Presenter
+```
+
+Bu eşleme, `App\UI\*Presenter` maskesindeki yıldız işaretini `Home` sunum yapan kişi adıyla değiştirerek çalışır ve sonuçta `App\UI\HomePresenter` nihai sınıf adı elde edilir. Çok basit!
+
+Ancak, bu ve diğer bölümlerdeki örneklerde görebileceğiniz gibi, sunum yapan sınıfları isimsiz alt dizinlere yerleştiriyoruz, örneğin, `Home` sunum yapan `App\UI\Home\HomePresenter` sınıfıyla eşleştirilmiştir. Bu, yıldız işaretinin iki katına çıkarılmasıyla elde edilir (Nette Application 3.2 gerektirir):
+
+```neon
+application:
+ mapping: App\UI\**Presenter
+```
+
+Şimdi, sunum yapan kişileri modüllerle eşleştirmeye geçelim. Her modül için özel eşlemeler tanımlayabiliriz:
```neon
application:
mapping:
- Front: App\Modules\Front\Presenters\*Presenter
- Admin: App\Modules\Admin\Presenters\*Presenter
+ Front: App\UI\Front\**Presenter
+ Admin: App\UI\Admin\**Presenter
Api: App\Api\*Presenter
```
-Şimdi `Front:Home` sunucusu `App\Modules\Front\Presenters\HomePresenter` sınıfıyla ve `Admin:Dashboard` sunucusu `App\Modules\Admin\Presenters\DashboardPresenter` sınıfıyla eşleşir.
+Bu yapılandırmaya göre, `Front:Home` sunucusu `App\UI\Front\Home\HomePresenter` sınıfıyla eşleşirken, `Api:OAuth` sunucusu `App\Api\OAuthPresenter` sınıfıyla eşleşir.
-İlk ikisini değiştirmek için genel bir (yıldız) kural oluşturmak daha pratiktir. Ekstra yıldız işareti sadece modül için sınıf maskesine eklenecektir:
+ `Front` ve `Admin` modülleri benzer bir eşleme yaklaşımına sahip olduğundan ve bu türden daha fazla modül olması muhtemel olduğundan, bunların yerini alan genel bir kural oluşturmak mümkündür. Sınıf maskesine modül için yeni bir yıldız işareti eklenir:
```neon
application:
mapping:
- *: App\Modules\*\Presenters\*Presenter
+ *: App\UI\*\**Presenter
Api: App\Api\*Presenter
```
-Peki ya iç içe modüller kullanıyorsak ve bir sunumcumuz varsa `Admin:User:Edit`? Bu durumda, her seviye için modülü temsil eden yıldız işaretli bölüm basitçe tekrarlanır ve sonuç `App\Modules\Admin\User\Presenters\EditPresenter` sınıfı olur.
+Sunum yapan kişi `Admin:User:Edit` gibi çok seviyeli iç içe modüller için yıldız işareti segmenti her seviye için tekrarlanır ve `App\UI\Admin\User\Edit\EditPresenter` sınıfı ortaya çıkar.
-Alternatif bir gösterim, bir dize yerine üç segmentten oluşan bir dizi kullanmaktır. Bu gösterim bir öncekine eşdeğerdir:
+Alternatif bir gösterim, dize yerine üç segmentten oluşan bir dizi kullanmaktır. Bu gösterim bir öncekine eşdeğerdir:
```neon
application:
mapping:
- *: [App\Modules, *, Presenters\*Presenter]
+ *: [App\UI, *, **Presenter]
+ Api: [App\Api, '', *Presenter]
```
-
-Varsayılan değer `*Module\*Presenter`'dur.
diff --git a/application/tr/templates.texy b/application/tr/templates.texy
index d817bc2d45..ca42448aad 100644
--- a/application/tr/templates.texy
+++ b/application/tr/templates.texy
@@ -34,35 +34,81 @@ Bu da eylem şablonu olabilir:
Düzende `{include content}` yerine eklenen `content` bloğunu tanımlar ve ayrıca düzende `{block title}` 'un üzerine yazılan `title` bloğunu yeniden tanımlar. Sonucu hayal etmeye çalışın.
-Şablon Arama .[#toc-search-for-templates]
------------------------------------------
+Şablon Arama .[#toc-template-lookup]
+------------------------------------
+
+Sunucularda, hangi şablonun işleneceğini belirtmenize gerek yoktur; çerçeve yolu otomatik olarak belirleyerek kodlamayı sizin için kolaylaştıracaktır.
+
+Her sunucunun kendi dizinine sahip olduğu bir dizin yapısı kullanıyorsanız, şablonu bu dizine eylemin adı (yani görünüm) altında yerleştirmeniz yeterlidir. Örneğin, `default` eylemi için `default.latte` şablonunu kullanın:
-Şablonların yolu basit bir mantığa göre çıkarılır. Sunucu sınıfının bulunduğu dizine göre bu şablon dosyalarından birinin var olup olmadığına bakılır, burada `` geçerli sunum yapan kişinin adı ve `` geçerli eylemin adıdır:
+/--pre
+app/
+└── UI/
+ └── Home/
+ ├── HomePresenter.php
+ └── default.latte
+\--
-- `templates//.latte`
-- `templates/..latte`
+Sunucuların tek bir dizinde ve şablonların `templates` klasöründe bir arada olduğu bir yapı kullanıyorsanız, bunu bir dosyaya kaydedin `..latte` veya `/.latte`:
-Şablon bulunamazsa, `templates` dizininde bir seviye yukarıda, yani sunum yapan sınıfın bulunduğu dizinle aynı seviyede arama yapmaya çalışacaktır.
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── Home.default.latte ← 1st variant
+ └── Home/
+ └── default.latte ← 2nd variant
+\--
-Şablon orada da bulunamazsa, yanıt [404 hatası |presenters#Error 404 etc.] olur.
+ `templates` dizini, sunum yapan sınıfların bulunduğu dizinle aynı seviyede, bir seviye daha yükseğe de yerleştirilebilir.
-Ayrıca `$this->setView('otherView')` adresini kullanarak görünümü değiştirebilirsiniz. Ya da arama yapmak yerine `$this->template->setFile('/path/to/template.latte')` adresini kullanarak şablon dosyasının adını doğrudan belirtin.
+Şablon bulunamazsa, sunum yapan kişi [404 - sayfa bulunamadı hatası |presenters#Error 404 etc] ile yanıt verir.
+
+Görünümü `$this->setView('anotherView')` adresini kullanarak değiştirebilirsiniz. Şablon dosyasını `$this->template->setFile('/path/to/template.latte')` ile doğrudan belirtmek de mümkündür.
.[note]
-Olası dosya yollarından oluşan bir dizi döndüren [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()] yöntemini geçersiz kılarak şablonların arandığı yolları değiştirebilirsiniz.
+Şablonların arandığı dosyalar, olası dosya adlarından oluşan bir dizi döndüren [formatTemplateFiles() |api:Nette\Application\UI\Presenter::formatTemplateFiles()] yöntemi geçersiz kılınarak değiştirilebilir.
+
+
+Düzen Şablonu Arama .[#toc-layout-template-lookup]
+--------------------------------------------------
+
+Nette ayrıca otomatik olarak yerleşim dosyasını arar.
+
+Her sunum yapan kişinin kendi dizinine sahip olduğu bir dizin yapısı kullanıyorsanız, düzeni ya sadece sunum yapan kişiye özelse sunum yapan kişinin bulunduğu klasöre ya da birden fazla sunum yapan kişi için ortaksa bir üst seviyeye yerleştirin:
+
+/--pre
+app/
+└── UI/
+ ├── @layout.latte ← common layout
+ └── Home/
+ ├── @layout.latte ← only for Home presenter
+ ├── HomePresenter.php
+ └── default.latte
+\--
+
+Sunum yapanların tek bir dizinde gruplandığı ve şablonların `templates` klasöründe bulunduğu bir yapı kullanıyorsanız, düzen aşağıdaki yerlerde beklenecektir:
-Düzen aşağıdaki dosyalarda beklenmektedir:
+/--pre
+app/
+└── Presenters/
+ ├── HomePresenter.php
+ └── templates/
+ ├── @layout.latte ← common layout
+ ├── Home.@layout.latte ← only for Home, 1st variant
+ └── Home/
+ └── @layout.latte ← only for Home, 2nd variant
+\--
-- `templates//@.latte`
-- `templates/.@.latte`
-- `templates/@.latte` birden fazla sunumcu için ortak düzen
+Sunucu bir [modüldeyse |modules], modülün iç içe geçmesine göre dizin ağacının daha yukarısında da arama yapacaktır.
-`` geçerli sunum yapan kişinin adı ve `