In this part of the tutorial we will learn to create a contact page. I must admit though that I do have some problems with getting the formating portion with css to work as expected. But We will have that worked out by the end of the tutorial and then apply a fix for that.
Contact Page
Routing
As with the pages we created in the last chapter, we will start by defining the contact page route. Open up the AppBundle routing file located at src/AppBundle/Resources/config/routing.yml and append the following routing rule.
# src/AppBundle/Resources/config/routing.yml /... app_contact: path: /contact defaults: { _controller: AppBundle:Page:contact } requirements: _method: GET|POST
Controller
Next lets add the action for the contact page to the Page Controller in the AppBundle located at src/AppBundle/Controller/PageController.php.
// src/AppBundle/Controller/PageController.php // .. public function contactAction() { return $this->render('AppBundle:Page:contact.html.twig'); } // ..
For now the action is very simple, it just renders the contact page view. We will come back to the controller later.
View
Create the contact page view at src/AppBundle/Resources/views/Page/contact.html.twig and add the following content.
{# src/AppBundle/Resources/views/Page/contact.html.twig #} {% extends 'AppBundle::layout.html.twig' %} {% block title %}{% trans %}nav.contact{% endtrans %}{% endblock%} {% block body %}{% trans %}nav.contact{% endtrans %}
{{ 'contact.msg'|trans({}, 'contact') }}
{% endblock %}
This template is also quite simple. It extends the AppBundle layout template, overrides the title block to set a custom title and defines some content for the body block.
Fix The Language files
As you can see the views above, give us another message. This need to get added to the Language Files. But we don’t want all the language files in the core system. So what we do is create another file.
The file is src/AppBundle/Resources/translations/contact.en.xliff (and in our case contact.de.xliff)
Put this into src/AppBundle/Resources/translations/contact.en.xliff:
Do you want to Contact us?
And src/AppBundle/Resources/translations/contact.de.xliff has this:
Sie wollen uns kontaktieren?
Linking to the page
Lastly we need to update the link in the application template located at app/Resources/views/base.html.twig to link to the contact page.
{% block navigation %} {% endblock %}
If you point your browser to http://hubshark.dev/app_dev.php/ and click the contact link in the navigation bar, you should see a very basic contact page displayed.
Contact Entity
Lets begin by creating a class that represents a contact enquiry from a user. We want to trap some basic information such as name, subject and enquiry body. Create a new file located at src/AppBundle/Entity/Contact.php and paste in the following content.
name; } public function setName($name) { $this->name = $name; } public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } public function getSubject() { return $this->subject; } public function setSubject($subject) { $this->subject = $subject; } public function getBody() { return $this->body; } public function setBody($body) { $this->body = $body; } }
Next we will create the form.
EnquiryType
Create a new file located at src/AppBundle/Form/ContactType.php and paste in the following content.
add('name',TextType::class); $builder->add('email',EmailType::class); $builder->add('subject',TextType::class); $builder->add('body',TextareaType::class); } public function getBlockPrefix() { return 'contact'; } }
Creating the form in the controller
Now we have defined the Enquiry entity and EnquiryType, we can update the contact action to use them. Replace the content of the contact action located at src/AppBundle/Controller/PageController.php with the following.
public function contactAction(Request $request) { $enquiry = new Contact(); $form = $this->createForm(ContactType::class, $enquiry); $this->request = $request; if ($request->getMethod() == 'POST') { $form->bind($request); if ($form->isValid()) { // Perform some action, such as sending an email // Redirect - This is important to prevent users re-posting // the form if they refresh the page return $this->redirect($this->generateUrl('app_contact')); } } return $this->render('AppBundle:Page:contact.html.twig', array( 'form' => $form->createView() )); }
We have used 2 new classes in our controller we need to import the namespaces.
- Update the controller
file located at src/AppBundle/Controller/PageController.php with the following. The statements should be placed under the existing use statement.
{% endblock %}Rendering the form
Thanks to Twig’s methods rendering forms is very simple.Replace the template code located at src/AppBundle/Resources/views/Page/contact.html.twig with the following.
{# src/AppBundle/Resources/views/Page/contact.html.twig #} {% extends 'AppBundle::layout.html.twig' %} {% block title %}{% trans %}nav.contact{% endtrans %}{% endblock%} {% block body %}{% trans %}nav.contact{% endtrans %}
{% for flashMessage in app.session.flashbag.get('blog-notice') %}{ { flashMessage }}{% endfor %}{{ 'contact.msg'|trans({}, 'contact') }}
Styling the form
Create a new file located at src/AppBundle/Resources/public/css/blog.css and paste in the following content.
.blog-notice { text-align: center; padding: 10px; background: #DFF2BF; border: 1px solid; color: #4F8A10; margin-bottom: 10px; } form.blog { font-size: 16px; } form.blog div { clear: left; margin-bottom: 10px; } form.blog label { float: left; margin-right: 10px; text-align: right; width: 100px; font-weight: bold; vertical-align: top; padding-top: 10px; } form.blog input[type="text"], form.blog input[type="email"] { width: 80%; line-height: 26px; font-size: 20px; min-height: 26px; } form.blog textarea { width: 80%; height: 150px; line-height: 26px; font-size: 20px; } form.blog input[type="submit"] { margin-left: 16%; width: 40%; line-height: 26px; font-size: 20px; min-height: 26px; } form.blog ul li { color: #ff0000; margin-bottom: 5px; }
We need to let the application know we want to use this stylesheet. We could import the stylesheet into the contact template but as other templates will also use this stylesheet later, it makes sense to import it into the AppBundle layout we created in chapter 1. Open up the BloggerBlogBundle layout located at src/AppBundle/Resources/views/layout.html.twig and replace with the following content.
{# src/AppBundle/Resources/views/layout.html.twig #} {% extends '::base.html.twig' %} {% block stylesheets %} {{ parent() }} {% endblock %} {% block sidebar %} Sidebar content {% endblock %}
In order for the asset function to correctly link up the the resource we need to copy over or link the bundle resources into the applications web folder. This can be done with the following
php bin/console assets:install web --symlink
Validators
Let’s begin by updating the Enquiry entity located at src/AppBundle/Entity/Contact.php to specify some Validators. Ensure you add the 5 new use statements at the top of the file.
addPropertyConstraint('name', new NotBlank()); $metadata->addPropertyConstraint('email', new Email()); $metadata->addPropertyConstraint('subject', new NotBlank()); $metadata->addPropertyConstraint('subject', new Length(array('max'=> 50))); $metadata->addPropertyConstraint('body', new Length(array('min'=> 50))); } // .. }
Update the controller
Update the Page controller located at src/AppBundle/Controller/PageController.php with the content below.
// src/AppBundle/Controller/PageController.php public function contactAction(Request $request) { // .. if ($form->isValid()) { $message = \Swift_Message::newInstance() ->setSubject('Contact enquiry from HubShark') ->setFrom('[email protected]') ->setTo($this->container->getParameter('app.emails.contact_email')) ->setBody($this->renderView('AppBundle:Page:contactEmail.txt.twig', array('enquiry' => $enquiry))); $this->get('mailer')->send($message); $this->get('session')->getFlashbag('hubshark-notice', 'Your contact enquiry was successfully sent. Thank you!'); // Redirect - This is important to prevent users re-posting // the form if they refresh the page return $this->redirect($this->generateUrl('app_contact')); } // .. }
To display the flash message we need to update the contact template located at src/AppBundle/Resources/views/Page/contact.html.twig. Update the content of the template with the following.
{# src/AppBundle/Resources/views/Page/contact.html.twig #} {# rest of template ... #}Contact Us
{% for flashMessage in app.session.flashbag.get('blog-notice') %}{ { flashMessage }}{% endfor %}Want to contact us?
{# rest of template ... #}
Register webmaster email
Create a new file at src/AppBundle/Resources/config/config.yml and paste in the following.
# src/AppBundle/Resources/config/config.yml parameters: # Contact email address app.emails.contact_email: [email protected]
In order for the Symfony2 application to use the new parameters, we need to import the config into the main application config file located at app/config/config.yml. To achieve this, update the imports directive at the top of the file to the following.
# app/config/config.yml imports: # .. existing import here - { resource: "@AppBundle/Resources/config/config.yml" }
Create the Email template
The body of the email is set to render a template. Create this template at src/AppBundle/Resources/views/Page/contactEmail.txt.twig and add the following.
{# src/AppBundle/Resources/views/Page/contactEmail.txt.twig #} A contact enquiry was made by {{ enquiry.name }} at {{ "now" | date("Y-m-d H:i") }}. Reply-To: {{ enquiry.email }} Subject: {{ enquiry.subject }} Body: {{ enquiry.body }}
One last thing left to do is…
…Fix the Language files
First one is
app/Resources/translations/messages.en.xliff
and you need to add this:
//...Name Subject //... Body
And the other one is the german file:
app/Resources/translations/messages.en.xliff
load this code into it:
//...Name Betreff //... Body
So now I want the look simular to the way we have it now. But I also want a Bootstrap appearence, it looks good and is responsive. So there are a few things to change in the base.html.twig file. I didn’t feel like detailing this reight now. So update app/Resources/views/base.html.twig with this:
{% block title %}{% trans %}blog.title{% endtrans %} {% trans %}blog.tagline{% endtrans %}{% endblock %} {% block stylesheets %} {% endblock %}{% block header %}{% endblock %} {% block navbar %} {% endblock %}{% block blog_title %}{% trans %}blog.title{% endtrans %}{% endblock %}
{% block blog_tagline %}{% trans %}blog.tagline{% endtrans %}{% endblock %}
{% block javascripts %} {% endblock %}{% block body %}{% endblock %} {% block sidebar %}{% endblock %}
{% block title %}{% trans %}blog.title{% endtrans %} {% trans %}blog.tagline{% endtrans %}{% endblock %} {% block stylesheets %} {% endblock %}{% block header %}{% endblock %} {% block navbar %} {% endblock %}{% block blog_title %}{% trans %}blog.title{% endtrans %}{% endblock %}
{% block blog_tagline %}{% trans %}blog.tagline{% endtrans %}{% endblock %}
{% block javascripts %} {% endblock %}{% block body %}{% endblock %} {% block sidebar %}{% endblock %}
The post Building with Symfony3 – part 5 appeared first on HubShark™.