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

More accurate specification of the current presenter and view #1016

Closed
wants to merge 46 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
ad29ee0
di: added Global State and Singletons
dg Mar 1, 2023
33a5e79
typo
dg Mar 13, 2023
d6d2555
```bash -> shell
dg Mar 14, 2023
44cd690
composer: improved content
dg Mar 14, 2023
38c3fa9
contributing/documentation: improved
dg Mar 20, 2023
2af8489
contributing/code: rewritten
dg Apr 8, 2023
bd86fe9
presenter Homepage -> Home
dg Mar 14, 2023
be57009
added new page 'installation'
dg Mar 15, 2023
bf945e6
home restruct
dg Mar 16, 2023
338d8c5
home: added sponsor
dg Apr 8, 2023
24ba949
quickstart: reference to installation
dg Mar 16, 2023
0b82ebb
added best-practices:lets-create-contact-form (removed pla)
dg Mar 7, 2023
925fb1a
packages: removed installation info
dg Mar 17, 2023
00a4f67
typo in Latte (#970)
janvalentik Mar 20, 2023
e6ede1d
di/passing-dependencies: better class & variables naming
dg Mar 21, 2023
4dfe968
di/passing-dependencies: highlighting inject info
dg Mar 21, 2023
73b3c27
di/passing-dependencies: added constructor hell
dg Mar 21, 2023
ef53cef
di: added FAQ
dg Mar 1, 2023
3d3fb3e
typo (#972)
berbeflo Mar 23, 2023
ca516be
Typo (#973)
johny-patera Mar 25, 2023
c54b483
php-generator: fixes
dg Mar 23, 2023
54fc2ec
persistent parameters: improved info
dg Mar 27, 2023
5cd2752
form reuse: improved
dg Mar 27, 2023
2106763
retranslated by GPT-4 (only EN version)
dg Mar 28, 2023
71729a1
inject injection: improved
dg Mar 29, 2023
89b7224
latte: added perex to cookbook
dg Apr 4, 2023
2f21671
tracy: improved
dg Apr 5, 2023
ea62e48
tracy: Adding a line to the Tracy activation code sample (#991)
mildabre Apr 7, 2023
6f4dee1
form: improvements (#995)(#996)(#997)(#998)
mildabre Apr 7, 2023
3decfab
application: improvements (#990)(#993)(#999)(#1002)
mildabre Apr 7, 2023
9861824
wording (#1000) (#1001)
mildabre Apr 7, 2023
9953432
latte: added {formContainer}
dg Apr 9, 2023
156353a
typo (#1004)
mildabre Apr 11, 2023
f0ba9e0
troubleshooting: testing .htaccess / mod_rewrite
dg Apr 14, 2023
ae6153c
10-reasons-why-nette: rewritten
dg Apr 16, 2023
7e781cb
latte: added "why use"
dg Apr 18, 2023
34c63d3
Typo (#1008)
diegosardina Apr 24, 2023
e89fbb2
Typos. (#1010)
radekdostal Apr 26, 2023
b17c6e8
application: improved leftmenu
dg May 14, 2023
3909369
typo (cs) (#1013)
Dzardys May 17, 2023
3302b2e
added: AVIF support (#1011)
jhabaj May 22, 2023
4be96ac
php-generator: better info about PSR
dg May 22, 2023
b64b740
coding-standard: added image of signature/body separation
dg May 22, 2023
60bf5cd
migration guide for Nette 4.0 [WIP]
dg Feb 10, 2023
0956ea5
assistant wip
dg Apr 19, 2023
b4f8883
More accurate specification of the current presenter and view
mildabre May 30, 2023
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
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions application/bg/@left-menu.texy
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@

Допълнително четене
*******************
- [Защо да използвате Nette? |www:10-reasons-why-nette]
- [Инсталация |nette:installation]
- [Създайте първото си приложение! |quickstart:]
- [Най-добри практики |best-practices:]
- [Отстраняване на неизправности |nette:troubleshooting]
25 changes: 22 additions & 3 deletions application/bg/ajax.texy
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ AJAX и фрагменти

</div>

Заявката AJAX може да бъде открита чрез метода на услугата, който [капсулира HTTP заявката |http:request] `$httpRequest->isAjax()` (определя се въз основа на HTTP заглавието `X-Requested-With`). Съществува и съкратен метод в програмата за представяне: `$this->isAjax()`.

Заявката AJAX не се различава от обикновената заявка - водещият се извиква с определено представяне и параметри. От водещия зависи и как ще реагира: той може да използва процедурите си, за да върне фрагмент от HTML код, XML документ, JSON обект или част от Javascript код.
Заявка AJAX .[#toc-ajax-request]
================================

Заявката AJAX не се различава от класическата заявка - водещият се извиква с определен изглед и параметри. От водещия също зависи как да отговори на нея: той може да използва своя собствена процедура, която връща фрагмент от HTML код (HTML snippet), XML документ, JSON обект или JavaScript код.

От страна на сървъра AJAX заявката може да бъде открита с помощта на метода на услугата, [капсулиращ HTTP заявката |http:request] `$httpRequest->isAjax()` (открива се въз основа на HTTP заглавието `X-Requested-With`). Вътре в презентатора е наличен пряк път под формата на метода `$this->isAjax()`.

Съществува предварително обработен обект `payload`, предназначен за изпращане на данни към браузъра във формат JSON.

Expand Down Expand Up @@ -60,6 +64,21 @@ npm install naja
<script src="https://unpkg.com/naja@2/dist/Naja.min.js"></script>
```

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

```html
<a n:href="go!" class="ajax">Go</a>

<form n:name="form" class="ajax">
<input n:name="submit">
</form>

or
<form n:name="form">
<input n:name="submit" class="ajax">
</form>
```


Извадки .[#toc-snippety]
========================
Expand Down Expand Up @@ -149,7 +168,7 @@ $this->isControlInvalid('footer'); // -> true
В горния пример трябва да се уверите, че само един елемент ще бъде добавен към масива `$list`, когато бъде направена заявката AJAX, така че цикълът `foreach` ще изведе само един динамичен фрагмент.

```php
class HomepagePresenter extends Nette\Application\UI\Presenter
class HomePresenter extends Nette\Application\UI\Presenter
{
/**
* Этот метод возвращает данные для списка.
Expand Down
15 changes: 14 additions & 1 deletion application/bg/bootstrap.texy
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ $configurator->addStaticParameters([
]);
```

Конфигурационните файлове могат да използват нормалния запис `%projectId%` за достъп до параметъра с име `projectId`. По подразбиране конфигураторът попълва следните параметри: `appDir`, `wwwDir`, `tempDir`, `vendorDir`, `debugMode` и `consoleMode`.
В конфигурационните файлове можем да запишем обичайната нотация `%projectId%`, за да получим достъп до параметъра с име `projectId`.


Динамични параметри .[#toc-dynamic-parameters]
Expand All @@ -197,6 +197,19 @@ $configurator->addDynamicParameters([
```


Параметри по подразбиране .[#toc-default-parameters]
----------------------------------------------------

Можете да използвате следните статични параметри в конфигурационните файлове:

- `%appDir%` е абсолютният път до директорията на файла `Bootstrap.php`
- `%wwwDir%` е абсолютният път до директорията, съдържаща входния файл `index.php`
- `%tempDir%` е абсолютният път до директорията за временни файлове
- `%vendorDir%` е абсолютният път до директорията, в която Composer инсталира библиотеки
- `%debugMode%` показва дали приложението е в режим на отстраняване на грешки
- `%consoleMode%` показва дали заявката е постъпила от командния ред


Внесени услуги .[#toc-imported-services]
----------------------------------------

Expand Down
62 changes: 46 additions & 16 deletions application/bg/components.texy
Original file line number Diff line number Diff line change
Expand Up @@ -233,31 +233,34 @@ $this->redirect(/* ... */); // пренасочване
Постоянни параметри .[#toc-persistent-parameters]
=================================================

Често е необходимо да се запази даден параметър в компонент за целия период на експлоатация на компонента. Това може да бъде например номер на страница в странирането. Този параметър трябва да бъде отбелязан като постоянен с помощта на анотацията `@persistent`.
Постоянните параметри се използват за поддържане на състоянието на компонентите между различните заявки. Тяхната стойност остава същата дори след щракване върху връзката. За разлика от данните за сесията, те се прехвърлят в URL адреса. И се прехвърлят автоматично, включително връзките, създадени в други компоненти на същата страница.

Например, имате компонент за страниране на съдържание. На една страница може да има няколко такива компонента. И искате всички компоненти да останат на текущата си страница, когато щракнете върху връзката. Затова правим номера на страницата (`page`) постоянен параметър.

Създаването на постоянен параметър е изключително лесно в Nette. Просто създайте публично свойство и го маркирайте с атрибута: (преди се използваше `/** @persistent */` )

```php
class PollControl extends Control
use Nette\Application\Attributes\Persistent; // този ред е важен

class PaginatingControl extends Control
{
/** @persistent */
public int $page = 1;
#[Persistent]
public int $page = 1; // трябва да бъдат публични
}
```

Този параметър ще се предава автоматично във всяка връзка като параметър `GET`, докато потребителят напусне страницата с този компонент.
Препоръчваме ви да включите типа данни (например `int`) към свойството, като можете да включите и стойност по подразбиране. Стойностите на параметрите могат да бъдат [валидирани |#Validation of Persistent Parameters].

.[caution]
Никога не се доверявайте сляпо на постоянни параметри, тъй като те могат лесно да бъдат подправени (чрез презаписване на URL адреса). Проверете например дали номерът на страницата е в правилния интервал.
Можете да променяте стойността на постоянен параметър, когато създавате връзка:

В PHP 8 можете също така да използвате атрибути, за да маркирате постоянни параметри:
```latte
<a n:href="this page: $page + 1">next</a>
```

```php
use Nette\Application\Attributes\Persistent;
Или може да бъде *ресетнат*, т.е. да бъде премахнат от URL адреса. След това той ще приеме стойността си по подразбиране:

class PollControl extends Control
{
#[Persistent]
public int $page = 1;
}
```latte
<a n:href="this page: null">reset</a>
```


Expand Down Expand Up @@ -378,7 +381,7 @@ interface PollControlFactory

1) може да се показва в шаблон
2) той знае каква част от себе си да покаже по време на [заявката AJAX |ajax#invalidation] (фрагменти)
3) може да съхранява състоянието си в URL (параметри за устойчивост).
3) има възможност да съхранява състоянието си в URL (постоянни параметри).
4) има възможност да реагира на действията (сигналите) на потребителя.
5) създава йерархична структура (където коренът е главният).

Expand All @@ -403,6 +406,33 @@ Nette\ComponentModel\Component { IComponent }
[* lifecycle-component.svg *] *** * Жизнен цикъл на компонента* .<>


Утвърждаване на постоянни параметри .[#toc-validation-of-persistent-parameters]
-------------------------------------------------------------------------------

Стойностите на [постоянните параметри, |#persistent parameters] получени от URL адреси, се записват в свойствата чрез метода `loadState()`. Той също така проверява дали типът данни, зададен за свойството, съвпада, в противен случай ще отговори с грешка 404 и страницата няма да бъде показана.

Никога не се доверявайте сляпо на постоянните параметри, защото те лесно могат да бъдат пренаписани от потребителя в URL адреса. Например, така проверяваме дали номерът на страницата `$this->page` е по-голям от 0. Добър начин да направите това е да презапишете метода `loadState()`, споменат по-горе:

```php
class PaginatingControl extends Control
{
#[Persistent]
public int $page = 1;

public function loadState(array $params): void
{
parent::loadState($params); // тук се задава $this->page
// следва проверката на потребителската стойност:
if ($this->page < 1) {
$this->error();
}
}
}
```

Противоположният процес, т.е. събирането на стойности от постоянни пропъртита, се обработва от метода `saveState()`.


Сигнали в дълбочина .[#toc-signals-in-depth]
--------------------------------------------

Expand Down
14 changes: 7 additions & 7 deletions application/bg/creating-links.texy
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
Атрибутът `n:href` е много полезен за HTML тагове. `<a>`. Ако искаме да покажем връзката на друго място, например в текста, използваме `{link}`:

```latte
URL: {link Homepage:default}
URL: {link Home:default}
```


Expand Down Expand Up @@ -88,7 +88,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Следователно основната форма е `Presenter:action`:

```latte
<a n:href="Homepage:default">главная страница</a>
<a n:href="Home:default">главная страница</a>
```

Ако се позоваваме на действието на текущия водещ, можем да пропуснем името му:
Expand All @@ -100,7 +100,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Ако действието е `default`, можем да го пропуснем, но двоеточието трябва да остане:

```latte
<a n:href="Homepage:">главная страница</a>
<a n:href="Home:">главная страница</a>
```

Връзките могат да сочат и към други [модули |modules]. Тук връзките се разграничават на относителни към подмодули или абсолютни. Принципът е подобен на дисковите пътища, само че с двоеточия вместо с наклонени черти. Да предположим, че водещият е част от модул `Front`, тогава записваме:
Expand All @@ -119,7 +119,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Можем да направим връзка към определена част от HTML страницата чрез така наречения фрагмент след символа хеш `#`:

```latte
<a n:href="Homepage:#main">ссылка на Homepage:default и фрагмент #main</a>
<a n:href="Home:#main">ссылка на Home:default и фрагмент #main</a>
```


Expand All @@ -128,7 +128,7 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);

Връзките, генерирани от `link()` или `n:href`, винаги са абсолютни пътища (т.е. започват с `/`), но не и абсолютни URL адреси с протокол и домейн, като `https://domain`.

За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например `n:href="//Homepage:"`). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете `$this->absoluteUrls = true`.
За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например `n:href="//Home:"`). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете `$this->absoluteUrls = true`.


Връзка към текущата страница .[#toc-link-to-current-page]
Expand Down Expand Up @@ -213,13 +213,13 @@ $url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Ако искаме да направим препратка към презентаторите в шаблона на компонента, използваме тага `{plink}`:

```latte
<a href="{plink Homepage:default}">главная страница</a>
<a href="{plink Home:default}">главная страница</a>
```

или в кода

```php
$this->getPresenter()->link('Homepage:default')
$this->getPresenter()->link('Home:default')
```


Expand Down
10 changes: 5 additions & 5 deletions application/bg/how-it-works.texy
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
<b>web-project/</b>
├── <b>app/</b> ← каталог с приложением
│ ├── <b>Presenters/</b> ← классы презентеров
│ │ ├── <b>HomepagePresenter.php</b> ← Класс презентера главной страницы
│ │ ├── <b>HomePresenter.php</b> ← Класс презентера главной страницы
│ │ └── <b>templates/</b> ← директория шаблонов
│ │ ├── <b>@layout.latte</b> ← шаблон общего макета
│ │ └── <b>Homepage/</b> ← шаблоны презентера главной страницы
│ │ └── <b>Home/</b> ← шаблоны презентера главной страницы
│ │ └── <b>default.latte</b> ← шаблон действия `default`
│ ├── <b>Router/</b> ← конфигурация URL-адресов
│ └── <b>Bootstrap.php</b> ← загрузочный класс Bootstrap
Expand Down Expand Up @@ -134,10 +134,10 @@ class ProductPresenter extends Nette\Application\UI\Presenter

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


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