Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement of chapter "Výrazové prostředky" - updated version #1065

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions application/bg/ajax.texy
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ npm install naja
<script src="https://unpkg.com/naja@2/dist/Naja.min.js"></script>
```

Първо трябва да [инициализирате |https://naja.js.org/#/guide/01-install-setup-naja?id=initialization] библиотеката:

```js
naja.initialize();
```

За да превърнете обикновена връзка (сигнал) или подаване на форма в AJAX заявка, просто маркирайте съответната връзка, форма или бутон с класа `ajax`:

```html
Expand Down
106 changes: 70 additions & 36 deletions application/bg/bootstrap.texy
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,44 @@ use Nette\Bootstrap\Configurator;

class Bootstrap
{
public static function boot(): Configurator
private Configurator $configurator;
private string $rootDir;

public function __construct()
{
$this->rootDir = dirname(__DIR__);
// Конфигураторът отговаря за настройката на средата на приложението и услугите.
$this->configurator = new Configurator;
// Задайте директорията за временни файлове, генерирани от Nette (напр. компилирани шаблони)
$this->configurator->setTempDirectory($this->rootDir . '/temp');
}

public function bootWebApplication(): Nette\DI\Container
{
$rootDir = dirname(__DIR__);
$configurator = new Configurator;
//$configurator->setDebugMode('[email protected]');
$configurator->enableTracy($rootDir . '/log');
$configurator->setTempDirectory($rootDir . '/temp');
$configurator->createRobotLoader()
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}

private function initializeEnvironment(): void
{
// Nette е интелигентен и режимът за разработка се включва автоматично,
// или можете да го включите за определен IP адрес, като разкоментирате следния ред:
// $this->configurator->setDebugMode('[email protected]');

// Активира Tracy: най-добрият инструмент за отстраняване на грешки "швейцарско ножче".
$this->configurator->enableTracy($this->rootDir . '/log');

// RobotLoader: автоматично зарежда всички класове в дадената директория
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
$configurator->addConfig($rootDir . '/config/common.neon');
return $configurator;
}

private function setupContainer(): void
{
// Зареждане на конфигурационни файлове
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
```
Expand All @@ -40,16 +66,15 @@ class Bootstrap
index.php .[#toc-index-php]
===========================

В случая на уеб приложения началният файл е `index.php`, който се намира в публичната директория `www/`. Той позволява на класа `Bootstrap` да инициализира средата и връща `$configurator`, който създава контейнера DI. След това тя извлича услугата `Application`, която стартира уеб приложението:
Началният файл за уеб приложенията е `index.php`, разположен в публичната директория `www/`. Той използва класа `Bootstrap` за инициализиране на средата и създаване на контейнер DI. След това получава услугата `Application` от контейнера, която стартира уеб приложението:

```php
// инициализиране на средата + получаване на обект Configurator
$configurator = App\Bootstrap::boot();
// създаване на DI-контейнер
$container = $configurator->createContainer();
// DI-контейнерът ще създаде обект Nette\Application\Application
$bootstrap = new App\Bootstrap;
// Иницииране на средата + създаване на контейнер DI
$container = $bootstrap->bootWebApplication();
// Контейнерът DI създава обект Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
//стартиране на приложението Nette
// Стартирайте приложението Nette и обработете входящата заявка
$application->run();
```

Expand All @@ -66,19 +91,19 @@ Nette прави разграничение между два основни р
Ако искате да активирате режима за разработка в други случаи, например за програмисти, които имат достъп от определен IP адрес, можете да използвате `setDebugMode()`:

```php
$configurator->setDebugMode('23.75.345.200'); // един или повече IP адреси
$this->configurator->setDebugMode('23.75.345.200'); // един или повече IP адреси
```

Определено препоръчваме да комбинирате IP адреса с "бисквитка". Ще съхраним тайния токен в "бисквитката" `nette-debug', например, `secret1234`, а режимът за разработка ще бъде активиран за програмистите с тази комбинация от IP и "бисквитка".

```php
$configurator->setDebugMode('[email protected]');
$this->configurator->setDebugMode('[email protected]');
```

Можете да деактивирате напълно режима за разработчици, дори за localhost:

```php
$configurator->setDebugMode(false);
$this->configurator->setDebugMode(false);
```

Обърнете внимание, че стойността `true` активира плътно режима за разработчици, което никога не трябва да се случва на производствен сървър.
Expand All @@ -90,7 +115,7 @@ $configurator->setDebugMode(false);
За да улесним дебъгването, ще включим чудесния инструмент [Tracy |tracy:]. В режим за разработчици той визуализира грешките, а в производствен режим записва грешките в определена директория:

```php
$configurator->enableTracy($rootDir . '/log');
$this->configurator->enableTracy($this->rootDir . '/log');
```


Expand All @@ -100,7 +125,7 @@ $configurator->enableTracy($rootDir . '/log');
Nette използва кеш за DI-контейнер, RobotLoader, шаблони и др. Затова е необходимо да се зададе пътят до директорията, в която се съхранява кешът:

```php
$configurator->setTempDirectory($rootDir . '/temp');
$this->configurator->setTempDirectory($this->rootDir . '/temp');
```

В Linux или macOS задайте [разрешения за запис |nette:troubleshooting#Setting-Directory-Permissions] за директориите `log/` и `temp/`.
Expand All @@ -112,7 +137,7 @@ RobotLoader .[#toc-robotloader]
Обикновено искаме да заредим класовете автоматично с помощта на [RobotLoader |robot-loader:], така че трябва да го стартираме и да му позволим да зареди класовете от директорията, в която се намира `Bootstrap.php` (т.е. `__DIR__`) и всички негови поддиректории:

```php
$configurator->createRobotLoader()
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
```
Expand All @@ -126,7 +151,7 @@ $configurator->createRobotLoader()
Конфигураторът ви позволява да зададете часовата зона за вашето приложение.

```php
$configurator->setTimeZone('Europe/Prague');
$this->configurator->setTimeZone('Europe/Prague');
```


Expand All @@ -143,16 +168,17 @@ $configurator->setTimeZone('Europe/Prague');
Файловете за конфигурация се зареждат с помощта на `addConfig()`:

```php
$configurator->addConfig($rootDir . '/config/common.neon');
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
```

Методът `addConfig()` може да се извика няколко пъти, за да се добавят няколко файла.

```php
$configurator->addConfig($rootDir . '/config/common.neon');
$configurator->addConfig($rootDir . '/config/services.neon');
$configDir = $this->rootDir . '/config';
$this->configurator->addConfig($configDir . '/common.neon');
$this->configurator->addConfig($configDir . '/services.neon');
if (PHP_SAPI === 'cli') {
$configurator->addConfig($rootDir . '/config/cli.php');
$this->configurator->addConfig($configDir . '/cli.php');
}
```

Expand All @@ -169,7 +195,7 @@ if (PHP_SAPI === 'cli') {
Параметрите, използвани в конфигурационните файлове, могат да бъдат дефинирани [в раздела `parameters` |dependency-injection:configuration#parameters] и да бъдат взети (или презаписани) от метода `addStaticParameters()` (той има псевдоним `addParameters()`). Важно е, че различните стойности на параметрите водят до генериране на допълнителни DI-контейнери, т.е. допълнителни класове.

```php
$configurator->addStaticParameters([
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
```
Expand All @@ -183,15 +209,15 @@ $configurator->addStaticParameters([
Възможно е също така да се добавят динамични параметри към контейнер. Различните им стойности, за разлика от статичните параметри, не генерират нови контейнери DI.

```php
$configurator->addDynamicParameters([
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
```

Достъпът до променливите на средата е лесен с помощта на динамични параметри. Достъпът до тях се осъществява чрез `%env.variable%` в конфигурационните файлове.

```php
$configurator->addDynamicParameters([
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
```
Expand Down Expand Up @@ -226,7 +252,7 @@ services:
Създайте нов екземпляр и го вмъкнете в Bootstrap:

```php
$configurator->addServices([
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
```
Expand All @@ -235,13 +261,21 @@ $configurator->addServices([
Различни среди .[#toc-different-environments]
=============================================

Не се колебайте да персонализирате класа `Bootstrap` според нуждите си. Можете да добавите параметри към метода `boot()`, за да разделите уеб проектите, или да добавите други методи, като например `bootForTests()`, който инициализира средата за тестове на единици, `bootForCli()` за скриптове, извикани от командния ред, и т.н.
Не се колебайте да персонализирате класа `Bootstrap` според нуждите си. Можете да добавите параметри към метода `bootWebApplication()`, за да разграничите отделните уеб проекти. Като алтернатива можете да добавите и други методи, например `bootTestEnvironment()` за инициализиране на средата за unit тестове, `bootConsoleApplication()` за скриптове, извикани от командния ред, и т.н.

```php
public static function bootForTests(): Configurator
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // Инициализация на Nette Tester
$this->setupContainer();
return $this->configurator->createContainer();
}

public function bootConsoleApplication(): Nette\DI\Container
{
$configurator = self::boot();
Tester\Environment::setup(); // Инициализация Nette Tester
return $configurator;
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}
```
22 changes: 22 additions & 0 deletions application/bg/components.texy
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,28 @@ $this->redirect(/* ... */); // пренасочване
```


Пренасочване след сигнал .[#toc-redirection-after-a-signal]
===========================================================

След обработката на сигнал от компонент често следва пренасочване. Тази ситуация е подобна на формулярите - след изпращане на формуляр също пренасочваме, за да предотвратим повторното изпращане на данни, когато страницата се опреснява в браузъра.

```php
$this->redirect('this') // redirects to the current presenter and action
```

Тъй като компонентът е елемент за многократна употреба и обикновено не трябва да има пряка зависимост от конкретни презентатори, методите `redirect()` и `link()` автоматично интерпретират параметъра като сигнал за компонент:

```php
$this->redirect('click') // redirects to the 'click' signal of the same component
```

Ако трябва да пренасочите към друг презентатор или действие, можете да го направите чрез презентатора:

```php
$this->getPresenter()->redirect('Product:show'); // redirects to a different presenter/action
```


Постоянни параметри .[#toc-persistent-parameters]
=================================================

Expand Down
6 changes: 3 additions & 3 deletions application/bg/presenters.texy
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ArticlePresenter extends Nette\Application\UI\Presenter

Важното е, че `action<Action>()` се извиква преди `render<View>()`, така че в него можем евентуално да променим следващия жизнен цикъл, т.е. да променим шаблона за визуализиране и метода `render<View>()`която ще бъде извикана с помощта на `setView('otherView')`.

Параметрите от заявката се предават на метода. Възможно и препоръчително е да се посочат типове за параметрите, например `actionShow(int $id, string $slug = null)` - ако параметърът `id` липсва или ако не е цяло число, презентаторът ще върне [грешка 404 |#Error-404-etc] и ще прекрати операцията.
Параметрите от заявката се предават на метода. Възможно и препоръчително е да се посочат типове за параметрите, например `actionShow(int $id, ?string $slug = null)` - ако параметърът `id` липсва или ако не е цяло число, презентаторът ще върне [грешка 404 |#Error-404-etc] и ще прекрати операцията.


`handle<Signal>(args...)` .{toc: handle<Signal>()}
Expand Down Expand Up @@ -205,7 +205,7 @@ $this->redirect(/* ... */);
Грешка 404 и т.н. .[#toc-error-404-etc]
=======================================

Когато не можем да изпълним дадена заявка, защото например статията, която искаме да покажем, не съществува в базата данни, ще хвърлим грешка 404, като използваме метода `error(string $message = null, int $httpCode = 404)`, който представлява HTTP грешка 404:
Когато не можем да изпълним дадена заявка, защото например статията, която искаме да покажем, не съществува в базата данни, ще хвърлим грешка 404, като използваме метода `error(?string $message = null, int $httpCode = 404)`, който представлява HTTP грешка 404:

```php
public function renderShow(int $id): void
Expand Down Expand Up @@ -384,7 +384,7 @@ class ProductPresenter extends Nette\Application\UI\Presenter
Можете също така да извикате канонизацията ръчно с метода `canonicalize()`, който, както и методът `link()`, приема като аргументи водещия, действията и параметрите. Тя създава връзка и я сравнява с текущия URL адрес. Ако те са различни, се пренасочва към генерираната връзка.

```php
public function actionShow(int $id, string $slug = null): void
public function actionShow(int $id, ?string $slug = null): void
{
$realSlug = $this->facade->getSlugForId($id);
// пренасочва, ако $slug е различен от $realSlug
Expand Down
6 changes: 6 additions & 0 deletions application/cs/ajax.texy
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ npm install naja
<script src="https://unpkg.com/naja@2/dist/Naja.min.js"></script>
```

Nejprve je potřeba knihovnu [inicializovat |https://naja.js.org/#/guide/01-install-setup-naja?id=initialization]:

```js
naja.initialize();
```

Aby se z obyčejného odkazu (signálu) nebo odeslání formuláře vytvořil AJAXový požadavek, stačí označit příslušný odkaz, formulář nebo tlačítko třídou `ajax`:

```html
Expand Down
Loading
Loading