Appearance
Contact
PODCAST
TIP
- We'll use the integrated Mailpit service to send (fake) mails in a development and testing environments
- You can access the Mailpit mailbox in the browser at
http://localhost:8025
(or click on the @-icon in the footer menu)
- The contact page contains some static content and a (dynamic) contact form
- In web.php, we keep the route as a view route to resources/views/contact.blade.php and embed the Livewire component in that view
Preparation
configure mail settings
- The mail is already set up for you in the
.env
file - See .env file for more information
Create a ContactForm component
- Create a new Livewire ContactForm component with
php artisan livewire:make ContactForm
- app/Livewire/Admin/ContactForm.php (the component class)
- resources/views/livewire/admin/contact-form.blade.php (the component view)
- Refactor the contact.blade.php view and embed the ContactForm component in it
- The page contains some static content and embeds (on line 8) the ContactForm component
php
<x-vinylshop-layout>
<x-slot name="title">The Vinyl Shop: contact info</x-slot>
<x-slot name="subtitle">Contact info</x-slot>
<div class="grid grid-cols-4 gap-4">
<x-tmk.section class="col-span-4 lg:col-span-3 lg:order-2">
{{-- embed the Livewire ContactForm component --}}
@livewire('contact-form')
</x-tmk.section>
<section class="col-span-4 lg:col-span-1 lg:order-1">
<h3>The Vinyl Shop</h3>
<p>Kleinhoefstraat 4</p>
<p class="pb-2 border-b">2440 Geel - Belgium</p>
<p class="flex items-center pt-2 cursor-pointer">
<x-phosphor-phone-call class="w-6 mr-2 text-gray-400"/>
<a href="tel:+3214562310" class="mr-2">+32(0)14/56.23.10</a>
</p>
<p class="flex items-center pt-2 cursor-pointer">
<x-heroicon-o-envelope-open class="w-6 mr-2 text-gray-400"/>
<a href="mailto:info@thevinylshop.com">info@thevinylshop.com</a>
</p>
</section>
</div>
{{-- <p>The Vinyl Shop</p>
<p><a href="mailto:info@thevinylshop.com">info@thevinylshop.com</a></p> --}}
</x-vinylshop-layout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Basic scaffolding
- Open app/Livewire/ContactForm.php and resources/views/livewire/contact-form.php
- Line 14 - 20: the form has three input fields (
name
,email
andmessage
) so we need three public properties in the component with there validation rules - Line 22 - 30: the form has a submit button, so we need a method for this
sendEmail()
- At this moment, the method only validates the input fields and, if all fields are valid, shows an info toast
php
<?php
namespace App\Livewire;
use App\Traits\SweetAlertTrait;
use Livewire\Attributes\Validate;
use Livewire\Component;
class ContactForm extends Component
{
use SweetAlertTrait;
// public properties
#[Validate('required|min:3|max:50')]
public $name;
#[Validate('required|email')]
public $email;
#[Validate('required|min:10|max:500')]
public $message;
// send email
public function sendEmail()
{
$this->validate();
$this->swalToast(
"<p class='font-bold mb-2'>Dear $this->name,</p>
<p>Thank you for your message.<br>We'll contact you as soon as possible.</p>",
'info',
);
}
public function render()
{
return view('livewire.contact-form');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Disable the submit button
- Remember that we added a
disabled
and thecolor
attributes to ourx-tmk.form.button
component - We can use the
disabled
attribute on the submit button to disable the button when the validation is not successful
- Line 10: add a public property
$canSubmit
with a default value offalse
- Line 10: if the error bag is empty, set the
$canSubmit
property totrue
, else set it tofalse
php
class ContactForm extends Component
{
// public properties
...
public $canSubmit = false;
// disable submit button until all fields are valid
public function updated($propertyName, $propertyValue)
{
$this->canSubmit = $this$this->getErrorBag()->isEmpty();
}
public function sendEmail() { ... }
public function render() { ... }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sending email
- After configuring our mail settings, we set up a mail template, pass some data to this template and send the mail itself
Create mailable
- In Laravel, each type of email sent by your application is represented as a mailable class
- Create a new mailable class with an associated view with the command:
bash
php artisan make:mail ContactMail --markdown=emails.contact
1
- The ContactMail.php mailable class is located in the app/Mail directory
- The contact.blade.php view is located in the resources/views/emails directory
- The --markdown option will create a markdown based view
(Besides a Markdown-based mail template, used in this site, you can also opt for HTML or text-based templates for the mail)
Send your first email
- Send an email inside the
sendMail()
method from ourContactForm
component and open Mailpit to see the result
- Line 23: make a new variable
$template
of theContactMail
mailable class - Line 24: the variable
$to
contains the email address (first parameter) and the name (second parameter) of the person who receives the email - Line 25: add the recipient using the
to()
method (on theMail
facade) - Line 26: send the mail using the
send()
method with$template
as parameter - Line 34: reset the form after sending the email
php
// send email
<?php
namespace App\Livewire;
use App\Mail\ContactMail;
use App\Traits\SweetAlertTrait;
use Illuminate\Mail\Mailables\Address;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Mail;
class ContactForm extends Component
{
...
// send email
public function sendEmail()
{
$this->validate();
// send email
$template = new ContactMail();
$to = new Address($this->email, $this->name);
Mail::to($to)
->send($template);
// show an info toast
$this->swalToast(
"<p class='font-bold mb-2'>Dear $this->name,</p>
<p>Thank you for your message.<br>We'll contact you as soon as possible.</p>",
'info',
);
// reset all public properties
$this->reset();
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
REMARKS
- You are not limited to the
to()
recipients. You can also add thecc()
andbcc()
recipients - All these methodes can handle multiple recipients with an array of recipients
- The second parameter (the name) of the
new Address()
method is optional - If you don't need the name of the recipient, you can omit the
new Address()
and just pass the email address as a string,
e.g.$to = 'john.doe@exmpale.com';
is the same as$to = new Address('john.doe@exmpale.com');
- Example:
php
// send email
$template = new ContactMail();
$to_1 = new Address($this->email, $this->name); // email + name
$to_2 = new Address('user2@example.com'); // email only
$to_3 = 'user3@example.com'; // email only (same as above)
Mail::to([$to_1, $to_2, $to_3])
->cc(['user3@example.com', 'user4@example.com'])
->bcc(['user5@example.com', 'user6@example.com'])
->send($template);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- All other mail settings (
subject
,body
,from
,replayTo
, ...) can be configured in theContactMail
class
Pass data to the mailable and update the mail template
- Add the data you want to use in the email as parameters to
new ContactMail()
to inject it into the constructor of mailable class and make it available in the mail template- ContactForm component: add an array with the data you want to inject into the constructor of the mailable (and use in the mail template)
- ContactMail mailable: add a public property (e.g.
$data
) and assign the injected data via te constructor to it - Update the Contact view and use the data from the mailable in the mail template
- fromName and fromEmail will be used to override the default from address in the mailable class
- subject will be used to override the default subject in the mailable class
- name, email and message will be used in the body of the email
php
public function sendEmail()
{
$this->validate();
// send email
$template = new ContactMail([
'fromName' => 'The Vinyl Shop - Info',
'fromEmail' => 'info@thevinylshop.com',
'subject' => 'The Vinyl Shop - Contact Form',
'name' => $this->name,
'email' => $this->email,
'message' => $this->message,
]);
$to = new Address($this->email, $this->name);
Mail::to($to)
->send($template);
// show an info toast
$this->swalToast(
"<p class='font-bold mb-2'>Dear $this->name,</p>
<p>Thank you for your message.<br>We'll contact you as soon as possible.</p>",
'info',
);
// reset all public properties
$this->reset();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
MARKDOWN FORMATTING
Don't use indentation in the markdown template because it will be rendered as pure text in the mail!
- Good formatting:
md
<x-mail::message>
# Dear {{ $data['name'] }},
Thanks for your message.<br>
We'll contact you as soon as possible.
...
</x-mail::message>
1
2
3
4
5
6
2
3
4
5
6
- Bad formatting:
md
<x-mail::message>
# Dear {{ $data['name'] }},
Thanks for your message.<br>
We'll contact you as soon as possible.
...
</x-mail::message>
1
2
3
4
5
6
2
3
4
5
6
- Bad formatting will be rendered as:
Extra features
- Check Laravel's mail documentation to discover extra mail features, e.g:
- add attachments
- publish and change the default mailable template (
x-mail::message
) - use an HTML-based or plain text mail template
- Publish the default mail component with the command
php artisan vendor:publish --tag=laravel-mail
so you can change the layout of the mail template - ...
EXERCISE: Add a contact field to the form
- Add a dropdown list to the form in order to choose a specific contact
- The list contains four options: Select a contact (
value=""
), Info, Billing and Support - This is a required field, so add it to your validation
- Depending on the choice of the user, the from (and carbon copy) address should be adjusted:
- info@thevinylshop.com with the name The Vinyl Shop - Info
- billing@thevinylshop.com with the name The Vinyl Shop - Billing
- or support@thevinylshop.com with the name The Vinyl Shop - Support