Thursday 5 April 2018

Web Tutorial: Multilingual Easter Form (Part 3/3)

Now to send some email!

To do that, we first have to add a form opening and closing tag to your about View. Use these helpers. The route is sendmail, and the method, which is POST, needs to be specified.

about\index.html.erb
<div class="lblAbout">

</div>

<hr />

<%= form_tag("/sendmail/", method: "post") do %>
  <%= label_tag(:txtName, "Name", class:"lblName") %>
  <%= text_field_tag(:txtName) %>
  <br /><br />
  <%= label_tag(:txtEmail, "Email", class:"lblEmail") %>
  <%= text_field_tag(:txtEmail) %>
  <br /><br />
  <%= button_tag("Send mail", class:"lblSendEmail") %>
<% end %>


See the route in the form opening tag? Yep, we'll need to define the route.

routes.rb
Rails.application.routes.draw do
    get "about/" => "about#index"
    get "langs/index" => "langs#index"
    get "langs/index/:lang" => "langs#index"
    post "sendmail/" => "sendmail#index"

    root "about#index"
end


Then add the Model. Nothing goes in here.

sendmail.rb
class Sendmail

end


And the Controller. Here, we assign the values of variables name and email to the values of the input textboxes.

sendmail_controller.rb
class SendmailController < ApplicationController
      def index
          @email = params[:txtEmail]
          @name = params[:txtName]
      end
end


Build the sendmail View using span tags and the variables. Note that the class names of the span tags have been included - lblMailSentTo and lblMailAt.

sendmail\index.html.erb
<span class="lblMailSentTo"></span> <%=@name%> <span class="lblMailAt"></span> <%=@email%>.


Let's add more stuff in your JavaScript to display the message in the correct language.

assets/javascripts/application.js
    var labels =
    [
        {
            "name" : "lblTitle",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Happy Easter 2018!"
                },   
                {
                    "lang" : "cn",
                    "val" : "2018复活节快乐!"
                }
            ]           
        },
        {
            "name" : "lblName",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Name"
                },
                {
                    "lang" : "cn",
                    "val" : "名称"
                }
            ]
        },
        {
            "name" : "lblEmail",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Email"
                },
                {
                    "lang" : "cn",
                    "val" : "电子邮件"
                }
            ]
        },
        {
            "name" : "lblSendEmail",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Send mail"
                },
                {
                    "lang" : "cn",
                    "val" : "发送邮件"
                }
            ]
        },
        {
            "name" : "lblAbout",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Easter is the celebration of the resurrection of Jesus from the tomb on the third day after his cruxifixion. Learn more about the meaning of Easter including the history and holiday symbols like easter eggs, the bunny, and lilies."
                },
                {
                    "lang" : "cn",
                    "val" : "复活节是在耶稣受难之后第三天从坟墓复活耶稣的庆祝活动。了解更多关于复活节的含义,包括复活节彩蛋,兔子和百合花等历史和假日符号。"
                }
            ]
        },
        {
            "name" : "lblFooter",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "&copy; 2018 Teochew Thunder "
                },
                {
                    "lang" : "cn",
                    "val" : "&copy; 潮州雷"
                }
            ]
        },
        {
            "name" : "lblMailSentTo",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "Mail sent to"
                },
                {
                    "lang" : "cn",
                    "val" : "邮件发送"
                }
            ]
        },
        {
            "name" : "lblMailAt",
            "content" :
            [
                {
                    "lang" : "en",
                    "val" : "at email:"
                },
                {
                    "lang" : "cn",
                    "val" : ":"
                }
            ]
        }
    ]


Now click on the "Send mail" button. Looks good, doesn't it? But we're not done, because this sucker isn't sending email yet.






Add this to the sendmail Controller. This line uses the layout easter_mailer to send mail.

sendmail_controller.rb
class SendmailController < ApplicationController
      def index
          @email = params[:txtEmail]
          @name = params[:txtName]
          EasterMailer.easter_email(@name, @email).deliver
      end
end


Now define the easter_mailer View.

easter_mailer/easter_email.html.erb
<h1>
    Name:<%=name%>
    Email:<%=email%>
</h1>


Make one for a text-only version

easter_mailer\easter_email.text.erb
    Name:<%=name%>
    Email:<%=email%>


In the mailers directory of your app folder, create this file. What happens is that any emails sent out will run the easter_email() function. This function will run the Rails method mail(). You just need to pass in the destination email address and the subject. Here, we also specify the data used for both HTML and text formats.

mailers\easter_mailer.rb
class EasterMailer < ApplicationMailer
    default from: 'easter@example.com'
   
    def easter_email(name,email)
        mail(to: "teochewthunder@gmail.com", subject: name + " has requested to know more about Easter!") do |format|
              format.html {
            render locals: { name: name, email: email }
              }
              format.text {
            render locals: { name: name, email: email }
              }
        end
    end   
end


Then, in the file below, add these lines. You need to customize this. In my case, I'm using Gmail and these are my settings. (No, my password is not "xxxxxxxxxx"!) Note that this is just for development, and you may need to do more configuration in other environments.

config/environments/development.rb
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.perform_deliveries = true
  config.action_mailer.smtp_settings = {
  :address        => 'smtp.gmail.com',
  #:domain         => 'mail.google.com',
  :domain         => 'localhost:3000',
  :port           => 25,
  :user_name      => 'teochewthunder@gmail.com',
  :password       => 'xxxxxxxxxx',
  :authentication => :plain,
  :enable_starttls_auto => true
}


Now click on the send mail button! Uh-oh...



Apparently, Gmail didn't like that. You'll probably get an email like this.


Click on the "allowing access to less secure apps" link and allow. For now, anyway. You might want to reset this after the tutorial.




Now try again! Aaaand.... we've got mail!


Yes I know, this is pretty sloppy formatting. But it worked, and you should probably do better when you have the time or inclination.


Final notes

Sending email programmatically is a damn sight easier with a framework. Because it sure isn't fun doing it in raw code.

It goes without saying, of course, that you want to use a dedicated email account or forwarding address for this.

In this tutorial, I didn't cover user input formatting. Not because it's not important - it is pretty damn important - but there was no risk of SQL Injection. Although, we could have taken some steps to filter out Cross-site Scripting.

Anyway, out of scope. Hope you had fun.

Mail the odds be ever in your favor,
T___T

No comments:

Post a Comment