Skip to content

Commit afeb6ea

Browse files
committed
added best-practices:lets-create-contact-form (removed pla)
1 parent 499ace8 commit afeb6ea

34 files changed

+3632
-318
lines changed

best-practices/bg/@home.texy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
---------
2727
- [Повторна употреба на формуляри |form-reuse]
2828
- [Формуляр за създаване и редактиране на запис |creating-editing-form]
29+
- [Да създадем формуляр за контакт |lets-create-contact-form]
2930
- [Зависими полета за избор |https://blog.nette.org/bg/zavisimi-selektirasi-poleta-elegantno-v-nette-i-cist-js]
3031

3132
</div>
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
Да създадем формуляр за контакт
2+
*******************************
3+
4+
.[perex]
5+
Нека разгледаме как да създадем формуляр за контакт в Nette, включително изпращането му на имейл. Така че нека го направим!
6+
7+
Първо трябва да създадем нов проект. Както е обяснено в страницата " [Започване" |nette:installation]. А след това можем да започнем създаването на формуляра.
8+
9+
Най-лесният начин е да създадете [формуляра директно в Presenter |forms:in-presenter]. Можем да използваме предварително създадената страница `HomePresenter`. Ще добавим компонента `contactForm`, представляващ формата. Ще направим това, като напишем фабричния метод на `createComponentContactForm()` в кода, който ще създава компонента:
10+
11+
```php
12+
use Nette\Application\UI\Form;
13+
use Nette\Application\UI\Presenter;
14+
15+
class HomePresenter extends Presenter
16+
{
17+
protected function createComponentContactForm(): Form
18+
{
19+
$form = new Form;
20+
$form->addText('name', 'Name:')
21+
->setRequired('Enter your name');
22+
$form->addEmail('email', 'E-mail:')
23+
->setRequired('Enter your e-mail');
24+
$form->addTextarea('message', 'Message:')
25+
->setRequired('Enter message');
26+
$form->addSubmit('send', 'Send');
27+
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
28+
return $form;
29+
}
30+
31+
public function contactFormSucceeded(Form $form, $data): void
32+
{
33+
// sending an email
34+
}
35+
}
36+
```
37+
38+
Както можете да видите, създадохме два метода. Първият метод `createComponentContactForm()` създава нова форма. Тя има полета за име, имейл и съобщение, които добавяме с помощта на методите `addText()`, `addEmail()` и `addTextArea()`. Добавихме и бутон за изпращане на формуляра.
39+
Но какво ще стане, ако потребителят не попълни някои полета? В такъв случай трябва да го уведомим, че това е задължително поле. Направихме това с метода `setRequired()`.
40+
Накрая добавихме и [събитие |nette:glossary#events] `onSuccess`, което се задейства, ако формулярът е изпратен успешно. В нашия случай то извиква метода `contactFormSucceeded`, който се грижи за обработката на изпратения формуляр. След малко ще добавим това към кода.
41+
42+
Нека компонентът `contantForm` бъде визуализиран в шаблона `templates/Home/default.latte`:
43+
44+
```latte
45+
{block content}
46+
<h1>Contant Form</h1>
47+
{control contactForm}
48+
```
49+
50+
За да изпратим самия имейл, създаваме нов клас, наречен `ContactFacade`, и го поставяме във файла `app/Model/ContactFacade.php`:
51+
52+
```php
53+
<?php
54+
declare(strict_types=1);
55+
56+
namespace App\Model;
57+
58+
use Nette\Mail\Mailer;
59+
use Nette\Mail\Message;
60+
61+
class ContactFacade
62+
{
63+
public function __construct(
64+
private Mailer $mailer,
65+
) {
66+
}
67+
68+
public function sendMessage(string $email, string $name, string $message): void
69+
{
70+
$mail = new Message;
71+
$mail->addTo('[email protected]') // your email
72+
->setFrom($email, $name)
73+
->setSubject('Message from the contact form')
74+
->setBody($message);
75+
76+
$this->mailer->send($mail);
77+
}
78+
}
79+
```
80+
81+
Методът `sendMessage()` ще създаде и изпрати имейла. За целта той използва така наречения mailer, който предава като зависимост чрез конструктора. Прочетете повече за [изпращането на имейли |mail:].
82+
83+
Сега ще се върнем към презентатора и ще завършим метода `contactFormSucceeded()`. Той извиква метода `sendMessage()` на класа `ContactFacade` и му предава данните от формуляра. А как ще получим обекта `ContactFacade`? Той ще ни бъде предаден от конструктора:
84+
85+
```php
86+
use App\Model\ContactFacade;
87+
use Nette\Application\UI\Form;
88+
use Nette\Application\UI\Presenter;
89+
90+
class HomePresenter extends Presenter
91+
{
92+
public function __construct(
93+
private ContactFacade $facade,
94+
) {
95+
}
96+
97+
protected function createComponentContactForm(): Form
98+
{
99+
// ...
100+
}
101+
102+
public function contactFormSucceeded(stdClass $data): void
103+
{
104+
$this->facade->sendMessage($data->email, $data->name, $data->message);
105+
$this->flashMessage('The message has been sent');
106+
$this->redirect('this');
107+
}
108+
}
109+
```
110+
111+
След като имейлът бъде изпратен, показваме на потребителя т.нар. [флаш съобщение |application:components#flash-messages], с което потвърждаваме, че съобщението е изпратено, и след това пренасочваме към следващата страница, така че формулярът да не може да бъде изпратен отново с помощта на *refresh* в браузъра.
112+
113+
114+
Е, ако всичко е наред, би трябвало да можете да изпратите имейл от формуляра си за контакт. Поздравления!
115+
116+
117+
HTML шаблон за електронна поща .[#toc-html-email-template]
118+
----------------------------------------------------------
119+
120+
Засега се изпраща имейл с обикновен текст, съдържащ само съобщението, изпратено от формуляра. Но можем да използваме HTML в имейла и да го направим по-привлекателен. Ще създадем шаблон за него в Latte, който ще запазим в `app/Model/contactEmail.latte`:
121+
122+
```latte
123+
<html>
124+
<title>Message from the contact form</title>
125+
126+
<body>
127+
<p><strong>Name:</strong> {$name}</p>
128+
<p><strong>E-mail:</strong> {$email}</p>
129+
<p><strong>Message:</strong> {$message}</p>
130+
</body>
131+
</html>
132+
```
133+
134+
Остава да модифицираме `ContactFacade`, за да използваме този шаблон. В конструктора заявяваме класа `LatteFactory`, който може да създаде обекта `Latte\Engine`, [рендер на шаблона Latte |latte:develop#how-to-render-a-template]. Използваме метода `renderToString()`, за да визуализираме шаблона във файл, като първият параметър е пътят до шаблона, а вторият - променливите.
135+
136+
```php
137+
namespace App\Model;
138+
139+
use Nette\Bridges\ApplicationLatte\LatteFactory;
140+
use Nette\Mail\Mailer;
141+
use Nette\Mail\Message;
142+
143+
class ContactFacade
144+
{
145+
public function __construct(
146+
private Mailer $mailer,
147+
private LatteFactory $latteFactory,
148+
) {
149+
}
150+
151+
public function sendMessage(string $email, string $name, string $message): void
152+
{
153+
$latte = $this->latteFactory->create();
154+
$body = $latte->renderToString(__DIR__ . '/contactEmail.latte', [
155+
'email' => $email,
156+
'name' => $name,
157+
'message' => $message,
158+
]);
159+
160+
$mail = new Message;
161+
$mail->addTo('[email protected]') // your email
162+
->setFrom($email, $name)
163+
->setHtmlBody($body);
164+
165+
$this->mailer->send($mail);
166+
}
167+
}
168+
```
169+
170+
След това предаваме генерирания HTML имейл на метода `setHtmlBody()` вместо на оригиналния `setBody()`. Също така не е необходимо да посочваме темата на имейла в `setSubject()`, защото библиотеката я взема от елемента `<title>` в шаблона.
171+
172+
173+
Конфигуриране на .[#toc-configuring]
174+
------------------------------------
175+
176+
В кода на класа `ContactFacade` нашият имейл адрес на администратора `[email protected]` все още е твърдо кодиран. По-добре би било да го преместите в конфигурационния файл. Как да го направим?
177+
178+
Първо, модифицираме класа `ContactFacade` и заменяме низът за имейл с променлива, предадена от конструктора:
179+
180+
```php
181+
class ContactFacade
182+
{
183+
public function __construct(
184+
private Mailer $mailer,
185+
private LatteFactory $latteFactory,
186+
private string $adminEmail,
187+
) {
188+
}
189+
190+
public function sendMessage(string $email, string $name, string $message): void
191+
{
192+
// ...
193+
$mail = new Message;
194+
$mail->addTo($this->adminEmail)
195+
->setFrom($email, $name)
196+
->setHtmlBody($body);
197+
// ...
198+
}
199+
}
200+
```
201+
202+
Втората стъпка е да въведем стойността на тази променлива в конфигурацията. Във файла `app/config/services.neon` добавяме:
203+
204+
```neon
205+
services:
206+
- App\Model\ContactFacade(adminEmail: [email protected])
207+
```
208+
209+
И това е всичко. Ако в раздела `services` има много елементи и ви се струва, че имейлът се губи сред тях, можем да го направим променлива. Ще променим записа на:
210+
211+
```neon
212+
services:
213+
- App\Model\ContactFacade(adminEmail: %adminEmail%)
214+
```
215+
216+
И ще дефинираме тази променлива във файла `app/config/common.neon`:
217+
218+
```neon
219+
parameters:
220+
adminEmail: [email protected]
221+
```
222+
223+
И готово!
224+
225+
226+
{{sitename: Най-добри практики}}

best-practices/cs/@home.texy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Formuláře
2626
---------
2727
- [Znovupoužití formulářů |form-reuse]
2828
- [Formulář pro vytvoření i editaci záznamu |creating-editing-form]
29+
- [Vytváříme kontaktní formulář |lets-create-contact-form]
2930
- [Závislé selectboxy |https://blog.nette.org/cs/zavisle-selectboxy-elegantne-v-nette-a-cistem-javascriptu]
3031

3132
</div>

0 commit comments

Comments
 (0)