Nette Documentation Preview

syntax
Как работят приложенията?
*************************

<div class=perex>

В момента четете основния документ на Nette. Ще научите всички принципи на работа на уеб приложенията. Всички подробности от А до Я, от момента на раждането до последния дъх на PHP скрипта. След като я прочетете, ще разберете:

- Как работи всичко това.
- какво представляват контейнерите Bootstrap, Presenter и DI
- как изглежда структурата на директорията

</div>


Структура на директорията .[#toc-directory-structure]
=====================================================

Отворете пример за скелет на уеб приложение, наречено [WebProject |https://github.com/nette/web-project], и можете да наблюдавате как се записват файловете.

Структурата на директорията изглежда по следния начин:

/--pre
<b>web-project/</b>
├── <b>app/</b>                      ← каталог с приложением
│   ├── <b>Основни/</b>              ← основни необходими класове
│   │   └── <b>RouterFactory.php</b> ← конфигуриране на URL адреси
│   ├── <b>UI/</b>                   ← презентатори, шаблони и др.
│   │   ├── <b>@layout.latte</b>     ← шаблон на споделено оформление
│   │   └── <b>Home/</b>             ← Директория за водещи
│   │       ├── <b>HomePresenter.php</b> ← Клас на Home Presenter
│   │       └── <b>default.latte</b> ← шаблон за действие default
│   └── <b>Bootstrap.php</b>         ← загрузочный класс Bootstrap
├── <b>bin/</b>                      ← скрипты командной строки
├── <b>config/</b>                   ← файлы конфигурации
│   ├── <b>common.neon</b>
│   └── <b>services.neon</b>
├── <b>log/</b>                      ← журналы ошибок
├── <b>temp/</b>                     ← временные файлы, кэш, …
├── <b>vendor/</b>                   ← библиотеки, установленные через Composer
│   ├── ...
│   └── <b>autoload.php</b>          ← автозагрузчик библиотек, установленных через Composer
├── <b>www/</b>                      ← публичный корневой каталог проекта
│   ├── <b>.htaccess</b>             ← правила mod_rewrite и т. д.
│   └── <b>index.php</b>             ← начальный файл, запускающий приложение
└── <b>.htaccess</b>                 ← запрещает доступ ко всем каталогам, кроме www
\--

Можете да променяте структурата на директориите по всякакъв начин, да преименувате или премествате папки и след това просто да редактирате пътищата до `log/` и `temp/` във файла `Bootstrap.php` и пътя до този файл в `composer.json` в раздела `autoload`. Нищо друго, никакво сложно преконфигуриране, никакви постоянни промени. Nette има [интелигентно автоматично откриване |bootstrap#development-vs-production-mode].

За малко по-големи приложения можем да разделим главната папка и папките с шаблони на подпапки (на диска) и пространства от имена (в кода), които наричаме [модули |modules].

Публичната директория `www/` може да бъде променена, без да се налага да инсталирате нещо друго. Всъщност често се случва, че поради спецификата на вашия хостинг ще трябва да я преименувате или да инсталирате т.нар. document-root към тази директория в конфигурацията на хостинга. Ако хостингът ви не позволява да създавате папки на едно ниво над публичната директория, предлагаме ви да потърсите друга хостинг услуга. В противен случай ще се изложите на значителен риск за сигурността.

Можете също така да качвате WebProject директно, включително Nette, с помощта на [Composer |best-practices:composer]:

```shell
composer create-project nette/web-project
```

В Linux или macOS задайте [разрешения за запис |nette:troubleshooting#Setting-Directory-Permissions] за директориите `log/` и `temp/`.

Приложението WebProject е готово за работа, не е необходимо да конфигурирате нищо друго и можете да го видите директно в браузъра си, като отворите папката `www/`.


HTTP заявка .[#toc-http-request]
================================

Всичко започва с това, че потребителят отваря страница в браузъра и браузърът подава HTTP заявка към сървъра. Заявката се изпраща към PHP файл, разположен в публичната директория `www/`, който се нарича `index.php`. Нека предположим, че това е заявка към `https://example.com/product/123` и ще бъде изпълнен.

Задачата му е следната:

1) инициализиране на средата
2) получаване на фабрика
3) стартиране на приложението Nette, което обработва заявката

Какъв вид фабрика? Ние не произвеждаме трактори, а уебсайтове! Изчакайте, след малко ще бъде обяснено.

Под "инициализиране на средата" разбираме например активирането на услугата [Tracy |tracy:], която е невероятен инструмент за регистриране или визуализиране на грешки. Той регистрира грешките на производствения сървър и ги показва директно на сървъра за разработка. Затова по време на инициализацията трябва да решите дали сайтът ще работи в производствен режим или в режим за разработчици. Nette използва автоматично откриване за това: ако стартирате сайта на localhost, той се стартира в режим за разработчици. Не е необходимо да конфигурирате каквото и да било и приложението е готово както за разработка, така и за внедряване в производството. Тези стъпки се следват и са описани подробно в главата [Bootstrap |bootstrap].

Третата точка (да, пропуснахме втората, но ще се върнем към нея) е да стартирате приложението. Класът `Nette\Application\Application` (наричан по-нататък `Application`) обработва HTTP заявките в Nette, така че когато казваме "стартиране на приложение", имаме предвид извикване на метод с име `run()` върху обект от този клас.

Nette е наставник, който ви напътства да пишете чисти приложения според доказани методологии. Най-проверяваният от тях се нарича **имплементиране на зависимости**, накратко DI. На този етап не искаме да ви натоварваме с обяснение на DI, тъй като това е разгледано в [отделна глава |dependency-injection:introduction], важното тук е, че ключовите обекти обикновено се създават от фабрика за обекти, наречена **DI контейнер** (съкратено DIC). Да, това е същата фабрика, която беше спомената преди време. Освен това той създава обекта `Application` за нас, така че първо се нуждаем от контейнер. Получаваме го с класа `Configurator` и му позволяваме да създаде обекта `Application`, да извика метода `run()` и това стартира приложението Nette. Точно това се случва във файла [index.php |bootstrap#index-php].


Приложението Nette .[#toc-nette-application]
============================================

Класът Application има една единствена задача: да отговори на HTTP заявка.

Приложенията, написани на Nette, са разделени на много така наречени презентатори (в други фреймуъркове може да срещнете термина *контролер*, което е същото нещо), които представляват класове, представящи определена страница на уебсайт: например начална страница; продукт в електронен магазин; регистрационна форма; rss-карта и т.н. В едно приложение може да има между един и хиляда презентатори.

Приложението започва с искане към т.нар. маршрутизатор да реши на кой от презентаторите да изпрати текущата заявка за обработка. Маршрутизаторът решава чия е отговорността. Той разглежда входния URL адрес `https://example.com/product/123`, който иска продукт `показать` с `id: 123` като действие. Добър навик е да записвате двойките водещ + действие, разделени с двоеточие: `Продукт:показать`.

Следователно маршрутизаторът е преобразувал URL адреса в двойка `Presenter:action` + параметри, в нашия случай `Product:show` + `id`: 123`. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Core/RouterFactory.php`, и ще го опишем подробно в главата [Маршрутизация |routing].

Да продължим. Приложението вече знае името на водещия и може да продължи. Чрез създаване на обект `ProductPresenter`, който е кодът на предентера `Product`. По-точно, той иска от контейнера DI да създаде презентатора, тъй като създаването на обекти е негова работа.

Водещият може да изглежда по следния начин:

```php
class ProductPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private ProductRepository $repository,
	) {
	}

	public function renderShow(int $id): void
	{
		// получаваме данни от модела и ги предаваме на шаблона
		$this->template->product = $this->repository->getProduct($id);
	}
}
```

Заявката се обработва от водещия. И задачата е ясна: да се изпълни действието `show` с `id: 123`. На езика preenter това означава да се извика методът `renderShow()` с параметър `$id`, равен на `123`.

Презентаторът може да извършва няколко действия, т.е. да има няколко метода `render<Action>()`. Препоръчваме ви обаче да разработвате преентери с едно или възможно най-малко действия.

Така че методът `renderShow(123)`, чийто код е измислен пример, е извикан, но на него можете да видите как данните се прехвърлят към шаблона, т.е. чрез запис в `$this->template`.

След това водещият връща отговор. Това може да бъде HTML страница, изображение, XML документ, файл, изпратен от диска, JSON или пренасочване към друга страница. Важно е да се отбележи, че ако не посочим изрично как да се отговори (какъвто е случаят с `ProductPresenter`), отговорът ще бъде шаблон, показващ HTML страница. Защо? Ами защото в 99% от случаите искаме да покажем шаблон, водещият приема това поведение по подразбиране и иска да улесни работата ни. Това е гледната точка на Нете.

Дори не е необходимо да посочваме кой шаблон да се визуализира; рамката сама ще определи пътя. В случая с действието `show` тя просто се опитва да зареди шаблона `show.latte` в директорията с класа `ProductPresenter`. Тя също така се опитва да намери оформлението във файла `@layout.latte` (повече за [търсенето на шаблони |templates#Template Lookup]).

Впоследствие шаблоните се визуализират. С това задачата на презентатора и на цялото приложение е изпълнена и работата е приключила. Ако шаблонът не съществува, ще бъде върната страница с грешка 404. Можете да прочетете повече за презентаторите на страницата [Презентатори |presenters].

[* request-flow.svg *]

За да сме сигурни, нека повторим целия процес, като използваме малко по-различен URL адрес:

1) URL адресът ще `https://example.com`
2) изтегляме приложението, създаваме контейнер и стартираме `Application::run()`
3) маршрутизаторът декодира URL адреса като двойка `Home:default`
4) обектът е създаден `HomePresenter`
5) извиква се методът `renderDefault()` (ако съществува)
6) шаблонът `default.latte` с оформлението `@layout.latte` се визуализира


Може би сега ще се сблъскате с много нови концепции, но ние смятаме, че те имат смисъл. Създаването на приложения в Nette е лесно.


Шаблони .[#toc-templates]
=========================

Що се отнася до шаблоните, Nette използва системата за шаблони [Latte |latte:]. Ето защо файловете на шаблоните се намират на адрес `.latte`. Latte се използва, защото е най-сигурната система за шаблони за PHP и в същото време е най-интуитивна. Не е необходимо да научавате много, достатъчно е да знаете PHP и няколко тага за Latte. Всичко ще научите от [документацията |templates].

В шаблона [създаваме връзки |creating-links] към други водещи и действия, както следва:

```latte
<a n:href="Product:show $productId">страница товара</a>
```

Просто напишете познатата двойка `Presenter:action` вместо истинския URL адрес и включете всички параметри. Трикът е `n:href`, който казва, че този атрибут ще бъде обработен от Nette. И тя ще генерира:

```latte
<a href="/product/456">страница товара</a>
```

Споменатият по-горе маршрутизатор е отговорен за генерирането на URL адреса. Всъщност маршрутизаторите в Nette са уникални с това, че могат не само да извършват преобразувания от URL към двойка презентатор:действие, но и обратното - да генерират URL от име на презентатор + действие + параметри.
Благодарение на това в Nette можете напълно да промените формата на URL адреса в цялото готово приложение, без да променяте нито един символ в шаблона или презентатора, само чрез промяна на маршрутизатора.
Поради това работи т.нар. канонизация - още една уникална функция на Nette, която подобрява SEO оптимизацията, като автоматично предотвратява дублираното съдържание в различни URL адреси.
Много програмисти намират това за невероятно.


Интерактивни компоненти .[#toc-interactive-components]
======================================================

Искаме да ви кажем още нещо за водещите: те имат вградена система от компоненти. По-възрастните може да си спомнят нещо подобно от Delphi или ASP.NET Web Forms. React или Vue.js са изградени на базата на нещо отдалечено подобно. В света на PHP фреймуърците това е напълно уникална функция.

Компонентите са отделни блокове за многократна употреба, които поставяме в страници (напр. презентатори). Те могат да бъдат [формуляри |forms:in-presenter], [решетки с данни |https://componette.org/contributte/datagrid/], менюта, анкети, изобщо всичко, което има смисъл да се използва многократно. Можем да създадем собствени компоненти или да използваме някои от [огромния брой |https://componette.org] компоненти с отворен код.

Компонентите променят из основи начина, по който разработваме приложения. Те ще открият нови възможности за създаване на страници от предварително дефинирани блокове. И те имат нещо общо с [Холивуд |components#Hollywood-Style].


Контейнер и конфигурация на DI .[#toc-di-container-and-configuration]
=====================================================================

Контейнерът DI (фабрика за обекти) е сърцето на цялото приложение.

Не се притеснявайте, това не е магическа черна кутия, както може да се предположи от предишните думи. Всъщност това е един доста скучен клас на PHP, генериран от Nette и съхраняван в директория с кеш. Той има много методи, наречени `createServiceAbcd()`, като всеки от тях създава и връща обект. Да, има и метод `createServiceApplication()`, който създава `Nette\Application\Application`, който ни е необходим във файла `index.php`, за да стартираме приложението. Съществуват и методи за подготовка на отделни презентатори. И така нататък.

Обектите, които контейнерът DI създава, по някаква причина се наричат услуги.

Особеността на този клас е, че той не се програмира от вас, а от рамката. Всъщност той генерира PHP код и го съхранява на диска. Просто давате инструкции за това какви обекти и как точно трябва да произвежда контейнерът. Тези инструкции са записани в [конфигурационни файлове |bootstrap#di-container-configuration] във [формат NEON |neon:format] и затова имат разширение `.neon`.

Файловете за конфигурация се използват изключително за обучение на контейнера DI. Така например, ако посоча `expiration: 14 days` в раздела за [сесията |http:configuration#session], контейнерът DI ще извика своя метод `setExpiration('14 days')` при създаването на обекта `Nette\Http\Session`, представляващ сесията, и по този начин конфигурацията ще стане реалност.

За вас е подготвена цяла глава, в която се описва какво можете да [конфигурирате |nette:configuring] и как да [дефинирате собствени услуги |dependency-injection:services].

След като стигнете до създаването на услуги, ще срещнете думата *autowiring*. Това е притурка, която ще улесни живота ви изключително много. Той може автоматично да предава обекти, когато са ви необходими (например към конструкторите на класа), без да е необходимо да правите каквото и да било. Ще видите, че контейнерът DI в Nette е малко чудо.


Какво следва? .[#toc-what-next]
===============================

Обхванахме основите на работата на приложенията в Nette. Засега много повърхностно, но скоро ще навлезете в дълбочина и ще създадете страхотни уеб приложения. Къде да продължим? Опитахте ли урока [Създаване на първото ви приложение |quickstart:]?

В допълнение към горното Nette разполага с цял арсенал от [полезни класове |utils:], [слой за бази данни |database:] и др. Опитайте се целенасочено да прегледате документацията. Или посетете [блога |https://blog.nette.org]. Ще откриете много интересни неща.

Нека тази рамка ви донесе много радост 💙.

Как работят приложенията?

В момента четете основния документ на Nette. Ще научите всички принципи на работа на уеб приложенията. Всички подробности от А до Я, от момента на раждането до последния дъх на PHP скрипта. След като я прочетете, ще разберете:

  • Как работи всичко това.
  • какво представляват контейнерите Bootstrap, Presenter и DI
  • как изглежда структурата на директорията

Структура на директорията

Отворете пример за скелет на уеб приложение, наречено WebProject, и можете да наблюдавате как се записват файловете.

Структурата на директорията изглежда по следния начин:

web-project/
├── app/                      ← каталог с приложением
│   ├── Основни/              ← основни необходими класове
│   │   └── RouterFactory.php ← конфигуриране на URL адреси
│   ├── UI/                   ← презентатори, шаблони и др.
│   │   ├── @layout.latte     ← шаблон на споделено оформление
│   │   └── Home/             ← Директория за водещи
│   │       ├── HomePresenter.php ← Клас на Home Presenter
│   │       └── default.latte ← шаблон за действие default
│   └── Bootstrap.php         ← загрузочный класс Bootstrap
├── bin/                      ← скрипты командной строки
├── config/                   ← файлы конфигурации
│   ├── common.neon
│   └── services.neon
├── log/                      ← журналы ошибок
├── temp/                     ← временные файлы, кэш, …
├── vendor/                   ← библиотеки, установленные через Composer
│   ├── ...
│   └── autoload.php          ← автозагрузчик библиотек, установленных через Composer
├── www/                      ← публичный корневой каталог проекта
│   ├── .htaccess             ← правила mod_rewrite и т. д.
│   └── index.php             ← начальный файл, запускающий приложение
└── .htaccess                 ← запрещает доступ ко всем каталогам, кроме www

Можете да променяте структурата на директориите по всякакъв начин, да преименувате или премествате папки и след това просто да редактирате пътищата до log/ и temp/ във файла Bootstrap.php и пътя до този файл в composer.json в раздела autoload. Нищо друго, никакво сложно преконфигуриране, никакви постоянни промени. Nette има интелигентно автоматично откриване.

За малко по-големи приложения можем да разделим главната папка и папките с шаблони на подпапки (на диска) и пространства от имена (в кода), които наричаме модули.

Публичната директория www/ може да бъде променена, без да се налага да инсталирате нещо друго. Всъщност често се случва, че поради спецификата на вашия хостинг ще трябва да я преименувате или да инсталирате т.нар. document-root към тази директория в конфигурацията на хостинга. Ако хостингът ви не позволява да създавате папки на едно ниво над публичната директория, предлагаме ви да потърсите друга хостинг услуга. В противен случай ще се изложите на значителен риск за сигурността.

Можете също така да качвате WebProject директно, включително Nette, с помощта на Composer:

composer create-project nette/web-project

В Linux или macOS задайте разрешения за запис за директориите log/ и temp/.

Приложението WebProject е готово за работа, не е необходимо да конфигурирате нищо друго и можете да го видите директно в браузъра си, като отворите папката www/.

HTTP заявка

Всичко започва с това, че потребителят отваря страница в браузъра и браузърът подава HTTP заявка към сървъра. Заявката се изпраща към PHP файл, разположен в публичната директория www/, който се нарича index.php. Нека предположим, че това е заявка към https://example.com/product/123 и ще бъде изпълнен.

Задачата му е следната:

  1. инициализиране на средата
  2. получаване на фабрика
  3. стартиране на приложението Nette, което обработва заявката

Какъв вид фабрика? Ние не произвеждаме трактори, а уебсайтове! Изчакайте, след малко ще бъде обяснено.

Под „инициализиране на средата“ разбираме например активирането на услугата Tracy, която е невероятен инструмент за регистриране или визуализиране на грешки. Той регистрира грешките на производствения сървър и ги показва директно на сървъра за разработка. Затова по време на инициализацията трябва да решите дали сайтът ще работи в производствен режим или в режим за разработчици. Nette използва автоматично откриване за това: ако стартирате сайта на localhost, той се стартира в режим за разработчици. Не е необходимо да конфигурирате каквото и да било и приложението е готово както за разработка, така и за внедряване в производството. Тези стъпки се следват и са описани подробно в главата Bootstrap.

Третата точка (да, пропуснахме втората, но ще се върнем към нея) е да стартирате приложението. Класът Nette\Application\Application (наричан по-нататък Application) обработва HTTP заявките в Nette, така че когато казваме „стартиране на приложение“, имаме предвид извикване на метод с име run() върху обект от този клас.

Nette е наставник, който ви напътства да пишете чисти приложения според доказани методологии. Най-проверяваният от тях се нарича имплементиране на зависимости, накратко DI. На този етап не искаме да ви натоварваме с обяснение на DI, тъй като това е разгледано в отделна глава, важното тук е, че ключовите обекти обикновено се създават от фабрика за обекти, наречена DI контейнер (съкратено DIC). Да, това е същата фабрика, която беше спомената преди време. Освен това той създава обекта Application за нас, така че първо се нуждаем от контейнер. Получаваме го с класа Configurator и му позволяваме да създаде обекта Application, да извика метода run() и това стартира приложението Nette. Точно това се случва във файла index.php.

Приложението Nette

Класът Application има една единствена задача: да отговори на HTTP заявка.

Приложенията, написани на Nette, са разделени на много така наречени презентатори (в други фреймуъркове може да срещнете термина контролер, което е същото нещо), които представляват класове, представящи определена страница на уебсайт: например начална страница; продукт в електронен магазин; регистрационна форма; rss-карта и т.н. В едно приложение може да има между един и хиляда презентатори.

Приложението започва с искане към т.нар. маршрутизатор да реши на кой от презентаторите да изпрати текущата заявка за обработка. Маршрутизаторът решава чия е отговорността. Той разглежда входния URL адрес https://example.com/product/123, който иска продукт показать с id: 123 като действие. Добър навик е да записвате двойките водещ + действие, разделени с двоеточие: Продукт:показать.

Следователно маршрутизаторът е преобразувал URL адреса в двойка Presenter:action + параметри, в нашия случай Product:show + id: 123. Вы можете увидеть, как выглядит маршрутизатор в файле `app/Core/RouterFactory.php, и ще го опишем подробно в главата Маршрутизация.

Да продължим. Приложението вече знае името на водещия и може да продължи. Чрез създаване на обект ProductPresenter, който е кодът на предентера Product. По-точно, той иска от контейнера DI да създаде презентатора, тъй като създаването на обекти е негова работа.

Водещият може да изглежда по следния начин:

class ProductPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private ProductRepository $repository,
	) {
	}

	public function renderShow(int $id): void
	{
		// получаваме данни от модела и ги предаваме на шаблона
		$this->template->product = $this->repository->getProduct($id);
	}
}

Заявката се обработва от водещия. И задачата е ясна: да се изпълни действието show с id: 123. На езика preenter това означава да се извика методът renderShow() с параметър $id, равен на 123.

Презентаторът може да извършва няколко действия, т.е. да има няколко метода render<Action>(). Препоръчваме ви обаче да разработвате преентери с едно или възможно най-малко действия.

Така че методът renderShow(123), чийто код е измислен пример, е извикан, но на него можете да видите как данните се прехвърлят към шаблона, т.е. чрез запис в $this->template.

След това водещият връща отговор. Това може да бъде HTML страница, изображение, XML документ, файл, изпратен от диска, JSON или пренасочване към друга страница. Важно е да се отбележи, че ако не посочим изрично как да се отговори (какъвто е случаят с ProductPresenter), отговорът ще бъде шаблон, показващ HTML страница. Защо? Ами защото в 99% от случаите искаме да покажем шаблон, водещият приема това поведение по подразбиране и иска да улесни работата ни. Това е гледната точка на Нете.

Дори не е необходимо да посочваме кой шаблон да се визуализира; рамката сама ще определи пътя. В случая с действието show тя просто се опитва да зареди шаблона show.latte в директорията с класа ProductPresenter. Тя също така се опитва да намери оформлението във файла @layout.latte (повече за търсенето на шаблони).

Впоследствие шаблоните се визуализират. С това задачата на презентатора и на цялото приложение е изпълнена и работата е приключила. Ако шаблонът не съществува, ще бъде върната страница с грешка 404. Можете да прочетете повече за презентаторите на страницата Презентатори.

За да сме сигурни, нека повторим целия процес, като използваме малко по-различен URL адрес:

  1. URL адресът ще https://example.com
  2. изтегляме приложението, създаваме контейнер и стартираме Application::run()
  3. маршрутизаторът декодира URL адреса като двойка Home:default
  4. обектът е създаден HomePresenter
  5. извиква се методът renderDefault() (ако съществува)
  6. шаблонът default.latte с оформлението @layout.latte се визуализира

Може би сега ще се сблъскате с много нови концепции, но ние смятаме, че те имат смисъл. Създаването на приложения в Nette е лесно.

Шаблони

Що се отнася до шаблоните, Nette използва системата за шаблони Latte. Ето защо файловете на шаблоните се намират на адрес .latte. Latte се използва, защото е най-сигурната система за шаблони за PHP и в същото време е най-интуитивна. Не е необходимо да научавате много, достатъчно е да знаете PHP и няколко тага за Latte. Всичко ще научите от документацията.

В шаблона създаваме връзки към други водещи и действия, както следва:

<a n:href="Product:show $productId">страница товара</a>

Просто напишете познатата двойка Presenter:action вместо истинския URL адрес и включете всички параметри. Трикът е n:href, който казва, че този атрибут ще бъде обработен от Nette. И тя ще генерира:

<a href="/product/456">страница товара</a>

Споменатият по-горе маршрутизатор е отговорен за генерирането на URL адреса. Всъщност маршрутизаторите в Nette са уникални с това, че могат не само да извършват преобразувания от URL към двойка презентатор:действие, но и обратното – да генерират URL от име на презентатор + действие + параметри. Благодарение на това в Nette можете напълно да промените формата на URL адреса в цялото готово приложение, без да променяте нито един символ в шаблона или презентатора, само чрез промяна на маршрутизатора. Поради това работи т.нар. канонизация – още една уникална функция на Nette, която подобрява SEO оптимизацията, като автоматично предотвратява дублираното съдържание в различни URL адреси. Много програмисти намират това за невероятно.

Интерактивни компоненти

Искаме да ви кажем още нещо за водещите: те имат вградена система от компоненти. По-възрастните може да си спомнят нещо подобно от Delphi или ASP.NET Web Forms. React или Vue.js са изградени на базата на нещо отдалечено подобно. В света на PHP фреймуърците това е напълно уникална функция.

Компонентите са отделни блокове за многократна употреба, които поставяме в страници (напр. презентатори). Те могат да бъдат формуляри, решетки с данни, менюта, анкети, изобщо всичко, което има смисъл да се използва многократно. Можем да създадем собствени компоненти или да използваме някои от огромния брой компоненти с отворен код.

Компонентите променят из основи начина, по който разработваме приложения. Те ще открият нови възможности за създаване на страници от предварително дефинирани блокове. И те имат нещо общо с Холивуд.

Контейнер и конфигурация на DI

Контейнерът DI (фабрика за обекти) е сърцето на цялото приложение.

Не се притеснявайте, това не е магическа черна кутия, както може да се предположи от предишните думи. Всъщност това е един доста скучен клас на PHP, генериран от Nette и съхраняван в директория с кеш. Той има много методи, наречени createServiceAbcd(), като всеки от тях създава и връща обект. Да, има и метод createServiceApplication(), който създава Nette\Application\Application, който ни е необходим във файла index.php, за да стартираме приложението. Съществуват и методи за подготовка на отделни презентатори. И така нататък.

Обектите, които контейнерът DI създава, по някаква причина се наричат услуги.

Особеността на този клас е, че той не се програмира от вас, а от рамката. Всъщност той генерира PHP код и го съхранява на диска. Просто давате инструкции за това какви обекти и как точно трябва да произвежда контейнерът. Тези инструкции са записани в конфигурационни файлове във формат NEON и затова имат разширение .neon.

Файловете за конфигурация се използват изключително за обучение на контейнера DI. Така например, ако посоча expiration: 14 days в раздела за сесията, контейнерът DI ще извика своя метод setExpiration('14 days') при създаването на обекта Nette\Http\Session, представляващ сесията, и по този начин конфигурацията ще стане реалност.

За вас е подготвена цяла глава, в която се описва какво можете да конфигурирате и как да дефинирате собствени услуги.

След като стигнете до създаването на услуги, ще срещнете думата autowiring. Това е притурка, която ще улесни живота ви изключително много. Той може автоматично да предава обекти, когато са ви необходими (например към конструкторите на класа), без да е необходимо да правите каквото и да било. Ще видите, че контейнерът DI в Nette е малко чудо.

Какво следва?

Обхванахме основите на работата на приложенията в Nette. Засега много повърхностно, но скоро ще навлезете в дълбочина и ще създадете страхотни уеб приложения. Къде да продължим? Опитахте ли урока Създаване на първото ви приложение?

В допълнение към горното Nette разполага с цял арсенал от полезни класове, слой за бази данни и др. Опитайте се целенасочено да прегледате документацията. Или посетете блога. Ще откриете много интересни неща.

Нека тази рамка ви донесе много радост 💙.