Ustvarimo kontaktni obrazec
Oglejmo si, kako ustvariti obrazec za stik v Nette, vključno s pošiljanjem v e-pošto. Naredimo to!
Najprej moramo ustvariti nov projekt. Kot je razloženo na strani Začetek. Nato pa lahko začnemo ustvarjati obrazec.
Najlažje je obrazec ustvariti neposredno v programu Presenter. Uporabimo lahko vnaprej pripravljene
spletne strani HomePresenter
. Dodali bomo komponento contactForm
, ki predstavlja obrazec. To storimo
tako, da v kodo, ki bo izdelala komponento, zapišemo tovarniško metodo createComponentContactForm()
:
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class HomePresenter extends Presenter
{
protected function createComponentContactForm(): Form
{
$form = new Form;
$form->addText('name', 'Name:')
->setRequired('Enter your name');
$form->addEmail('email', 'E-mail:')
->setRequired('Enter your e-mail');
$form->addTextarea('message', 'Message:')
->setRequired('Enter message');
$form->addSubmit('send', 'Send');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
}
public function contactFormSucceeded(Form $form, $data): void
{
// sending an email
}
}
Kot lahko vidite, smo ustvarili dve metodi. Prva metoda createComponentContactForm()
ustvari nov obrazec. Ta ima
polja za ime, e-pošto in sporočilo, ki jih dodamo z metodami addText()
, addEmail()
in
addTextArea()
. Dodali smo tudi gumb za pošiljanje obrazca. Kaj pa, če uporabnik ne izpolni nekaterih polj? V tem
primeru mu moramo sporočiti, da gre za zahtevano polje. To smo storili z metodo setRequired()
. Na koncu smo dodali
še dogodek onSuccess
, ki se sproži, če je obrazec
uspešno oddan. V našem primeru pokliče metodo contactFormSucceeded
, ki poskrbi za obdelavo oddanega obrazca. To
bomo v kodo dodali v naslednjem trenutku.
Naj bo komponenta contantForm
prikazana v predlogi Home/default.latte
:
{block content}
<h1>Contant Form</h1>
{control contactForm}
Za pošiljanje samega elektronskega sporočila ustvarimo nov razred z imenom ContactFacade
in ga postavimo
v datoteko app/Model/ContactFacade.php
:
<?php
declare(strict_types=1);
namespace App\Model;
use Nette\Mail\Mailer;
use Nette\Mail\Message;
class ContactFacade
{
public function __construct(
private Mailer $mailer,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
$mail = new Message;
$mail->addTo('admin@example.com') // your email
->setFrom($email, $name)
->setSubject('Message from the contact form')
->setBody($message);
$this->mailer->send($mail);
}
}
Metoda sendMessage()
bo ustvarila in poslala elektronsko sporočilo. Za to uporablja tako imenovani mailer, ki ga
prek konstruktorja posreduje kot odvisnost. Preberite več o pošiljanju
e-pošte.
Zdaj se bomo vrnili k predstavniku in dokončali metodo contactFormSucceeded()
. Pokliče metodo
sendMessage()
razreda ContactFacade
in mu posreduje podatke iz obrazca. In kako dobimo objekt
ContactFacade
? Predal nam ga bo konstruktor:
use App\Model\ContactFacade;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class HomePresenter extends Presenter
{
public function __construct(
private ContactFacade $facade,
) {
}
protected function createComponentContactForm(): Form
{
// ...
}
public function contactFormSucceeded(stdClass $data): void
{
$this->facade->sendMessage($data->email, $data->name, $data->message);
$this->flashMessage('The message has been sent');
$this->redirect('this');
}
}
Ko je elektronsko sporočilo poslano, uporabniku prikažemo tako imenovano sporočilo flash, ki potrjuje, da je bilo sporočilo poslano, nato pa ga preusmerimo na naslednjo stran, tako da obrazca ni mogoče ponovno poslati z uporabo refresh v brskalniku.
Če vse deluje, bi morali biti sposobni poslati elektronsko sporočilo iz kontaktnega obrazca. Čestitamo!
Predloga e-pošte HTML
Za zdaj je poslano navadno besedilno e-poštno sporočilo, ki vsebuje samo sporočilo, poslano z obrazcem. Vendar lahko
v e-poštnem sporočilu uporabimo HTML in ga naredimo privlačnejšega. Za to bomo v Latte ustvarili predlogo, ki jo bomo
shranili v app/Model/contactEmail.latte
:
<html>
<title>Message from the contact form</title>
<body>
<p><strong>Name:</strong> {$name}</p>
<p><strong>E-mail:</strong> {$email}</p>
<p><strong>Message:</strong> {$message}</p>
</body>
</html>
Za uporabo te predloge je treba spremeniti spletno mesto ContactFacade
. V konstruktorju zahtevamo razred
LatteFactory
, ki lahko ustvari objekt Latte\Engine
, upodobljevalnik predloge Latte. Uporabimo metodo
renderToString()
za upodabljanje predloge v datoteko, pri čemer je prvi parameter pot do predloge, drugi pa
spremenljivke.
namespace App\Model;
use Nette\Bridges\ApplicationLatte\LatteFactory;
use Nette\Mail\Mailer;
use Nette\Mail\Message;
class ContactFacade
{
public function __construct(
private Mailer $mailer,
private LatteFactory $latteFactory,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
$latte = $this->latteFactory->create();
$body = $latte->renderToString(__DIR__ . '/contactEmail.latte', [
'email' => $email,
'name' => $name,
'message' => $message,
]);
$mail = new Message;
$mail->addTo('admin@example.com') // your email
->setFrom($email, $name)
->setHtmlBody($body);
$this->mailer->send($mail);
}
}
Ustvarjeno elektronsko sporočilo HTML nato posredujemo metodi setHtmlBody()
namesto prvotnega
setBody()
. Prav tako nam ni treba določiti predmeta e-pošte v setSubject()
, saj ga knjižnica prevzame
iz elementa <title>
v predlogi.
Konfiguracija
V kodi razreda ContactFacade
je še vedno trdno zakodirano naše upraviteljevo e-poštno sporočilo
admin@example.com
. Bolje bi bilo, če bi ga prenesli v konfiguracijsko datoteko. Kako to storiti?
Najprej spremenimo razred ContactFacade
in niz elektronske pošte nadomestimo s spremenljivko, ki jo posreduje
konstruktor:
class ContactFacade
{
public function __construct(
private Mailer $mailer,
private LatteFactory $latteFactory,
private string $adminEmail,
) {
}
public function sendMessage(string $email, string $name, string $message): void
{
// ...
$mail = new Message;
$mail->addTo($this->adminEmail)
->setFrom($email, $name)
->setHtmlBody($body);
// ...
}
}
Drugi korak je, da vrednost te spremenljivke vnesemo v konfiguracijo. V datoteko app/config/services.neon
dodamo:
services:
- App\Model\ContactFacade(adminEmail: admin@example.com)
In to je to. Če je v razdelku services
veliko elementov in se vam zdi, da se elektronsko sporočilo izgublja med
njimi, ga lahko naredimo za spremenljivko. Vnos bomo spremenili v:
services:
- App\Model\ContactFacade(adminEmail: %adminEmail%)
in to spremenljivko opredelimo v datoteki app/config/common.neon
:
parameters:
adminEmail: admin@example.com
In končano je!