Blog Page with code

In this example below you will see how to do a Blog Page with code with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by captnstarburst, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright captnstarburst ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Blog Page with code</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://fonts.googleapis.com/css?family=Dosis|Playfair+Display+SC" rel="stylesheet">
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css'>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <!-- NAVBAR -->
<nav class="navbar navbar-dark bg-dark navbar-expand-md">
  <a class="navbar-brand" href="#">Conor's Blog</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

  <div class="collapse navbar-collapse justify-content-start" id="navbarToggler">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="#">Blog<span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="https://www.conorhinchee.com">Home</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#section_contact">Contact</a>
      </li>
    </ul>
  </div>

  <div class="navbar-collapse justify-content-end">
    <form class="form-inline">
      <input class="form-control search mr-sm-4" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-warning my-2 my-sm-1" type="submit"><span class="navbar-search">Search</span></button>
    </form>
  </div>
</nav>
<!-- NAVBAR -->

<div class="container-fluid">
  <div class="row blog-nav">
    <div class="col-12">
      <p class="blog-nav">
        <a href="/blog"> >Blog Home &nbsp; </a>
        <a href=""> > Programming &nbsp; </a> >>NodeJS </p>
    </div>
  </div>
  <div class="row title-row">
    <div class="col-12">
      <h1 class="text-center header title-txt">NodeMailer, OAuth2, and Gmail</h1>
    </div>
  </div>
  <div class="row content-row justify-content-center">
    <div class="col-md-8 col-sm-10">

      <p><img src="https://nodemailer.com/nm_logo_200x136.png" class="img-fluid thumbnail article-img left" />Nodemailer is a module for Node.js applications used to send emails! This blog post is my step by step guide/reminder of how to get nodemailer and gmail working together. Nodemailers' OAuth <a href="https://nodemailer.com/smtp/oauth2/">docs</a> are extremely handy and I would recommend reading for a bit of a better understanding on how nodemailer works and the code that is being used and modifying to send some emails from a contact form. The prerequisites for this post is an understanding of the frontend, NodeJS, and Express. If you ran into issus getting gmail and OAuth working together click <a href="#oauth">here</a> to skip the boring bits, otherwise keep reading</p>

      <p>So lets start with our form tag. The attributes I will be using are method and action attributes. The method attribute will be set to "post" which will append our form-data inside the body of our HTTP request. The action attribute will be set to "/send" in my example, the action attribute indicates the route our information will be posted to. Finally I set the autocomplete attribute to "off", just personal preference.</p>
      <ol>
        <li>
          <code> &lt;form method="post" action="/send" autocomplete="off"&gt;</code>
        </li>
      </ol>

      <p>In between the form tag will be heart of our form. Made up of a few input tags, a textarea tag, Recaptcha for spam control, and the submit button. Class attributes set for specific styling, Id's for client side "verification",and finally the type/required
        that take advantage of styling and form submission requirments implemented with in HTML5. The npm middleware body-parser will look for the name attribute after submission so this attribute is imperative.</p>

      <ol>
        <li>
          <code> &lt;form method="post" action="/send" autocomplete="off"&gt;</code>
        </li>
        <li>
          <code> &lt;input class="sendEmail" type="text" placeholder="Name" name="name" id="contact_name" required&gt;</code>
        </li>
        <li>
          <code> &lt;input class="sendEmail" type="email" placeholder="Email" name="email" id="contact_email" required&gt;</code>
        </li>
        <li>
          <code> &lt;textarea placeholder="Message" name="message" id="contact_message" required&gt;&lt;/textarea&gt;</code>
        </li>
        <li>
          <code> &lt;div class="portfolio-txt text-danger" id="captcha_required"&gt;&lt;/div&gt;</code>
        </li>
        <li>
          <code> &lt;div class="g-recaptcha" data-sitekey="6LcGUE8UAAAAACCW2ysEaknWG9xglt3AW63AXvya" data-theme="dark"&gt;&lt;/div&gt;</code>
        </li>
        <li>
          <code> &lt;button class="btn btn-primary btn-block" type="submit"&gt;&lt;span class="header"&gt;Submit&lt;span>&lt;/button&gt;</code>
        </li>
        <li>
          <code>&lt;/form&gt;</code>
        </li>
      </ol>

      <p>Add some bootstrap styling and some flair to customize for our visitors! Here is what I came up with.</p>

      <img src="https://conorhinchee.com/imgs/blog/Screenshot-Contact-Me.png" class="img-fluid thumbnail big-img" />

      <p>On the backend side, go through a few npm installs to get the middleware that will be utilized. In the terminal, cd to the project folder and run the following commands to install nodemailer and body-parser respectively.</p>

      <code class="terminal">moarwaffles:~/workspace $ npm install nodemailer --save<span class="cursor">|</span></code>
      <p>&</p>
      <code class="terminal">moarwaffles:~/workspace $ npm install body-parser --save<span class="cursor">|</span></code>

      <p>Those packages will install and it's time to start working on our servers code! Bare code should look something like this</p>

      <ol>
        <li class="no-indent">
          <code>
                const express = require('express');
              </code>
        </li>
        <li class="no-indent">
          <code>
                const path = require('path');
              </code>
        </li>
        <li class="no-indent">
          <code>
                const mailer = require('nodemailer');
              </code>
        </li>
        <li class="no-indent">
          <code>
                const bodyParser = require('body-parser');
              </code>
        </li>
        <li class="no-indent">
          <code>&nbsp;</code>
        </li>
        <li class="no-indent">
          <code>
                const app = express();
              </code>
        </li>
        <li class="no-indent">
          <code>
                const port = process.env.PORT;
              </code>
        </li>
        <li class="no-indent">
          <code>&nbsp;</code>
        </li>
        <li class="no-indent">
          <code>app.use(express.static(path.join(__dirname, 'public')));</code>
        </li>
        <li class="no-indent">
          <code>&nbsp;</code>
        </li>
        <li class="no-indent">
          <code>app.get('/', function(req, res){</code>
        </li>
        <li>
          <code>res.sendFile(path.join(__dirname + '/index.html'));</code>
        </li>
        <li class="no-indent">
          <code>});</code>
        </li>
        <li class="no-indent">
          <code>&nbsp;</code>
        </li>
        <li class="no-indent">
          <code>app.get('/*', function(req, res){</code>
        </li>
        <li>
          <code>res.status(404);</code>
        </li>
        <li>
          <code>res.send('404 Not Found!');</code>
        </li>
        <li class="no-indent">
          <code>});</code>
        </li>
        <li class="no-indent">
          <code>&nbsp;</code>
        </li>
        <li class="no-indent">
          <code>app.listen(port, function(){</code>
        </li>
        <li>
          <code>console.log("listening to port" + port);</code>
        </li>
        <li class="no-indent">
          <code>});</code>
        </li>
      </ol>

      <p>I went ahead and required the middleware that was just installed. Next enable express to use the body-parser and since it wont be parsing a nested object, set the extended url encoded to <a href="https://stackoverflow.com/questions/39870867/what-does-app-usebodyparser-json-do"
          target="_blank">false</a> and use JSON format.</p>

      <ol>
        <li class="no-indent">
          <code>//middle-ware body parser</code>
        </li>
        <li class="no-indent">
          <code>app.use(bodyParser.urlencoded({ extended: false}));</code>
        </li>
        <li class="no-indent">
          <code>app.use(bodyParser.json());</code>
        </li>
      </ol>

      <p id="oauth">There is a way to send emails using gmail and nodemailer without OAuth2 integration by enabling <a href="https://myaccount.google.com/lesssecureapps" target="_blank">less secure apps</a>. Even after enabling less secure apps I had trouble getting
        emails to send. So I began researching enabling OAuth2 which is 2 step process.</p>

      <p>Step One: visit and login at <a href="https://console.developers.google.com" target="_blank">https://console.developers.google.com</a> click on select project, create new project and give your project a name.</p>

      <div class="row">
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-Google-Console.png" class="img-fluid thumbnail big-img" />
        </div>
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-Create-Project.png" class="img-fluid thumbnail big-img" />
        </div>
      </div>

      <p>Next select the key/credential nav on the left side of the page and select create credentials! The Next screen select the Web Application radio button and insert your domain name under Authorized JavaScript Origins and for Authorized redirect URIs
        enter <b>https://developers.google.com/oauthplayground</b> press create button and it will return our client ID and secret ID</p>

      <div class="row">
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-Create-Credentials.png" class="img-fluid thumbnail big-img" />
        </div>
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-Web-APP.png" class="img-fluid thumbnail big-img" />
        </div>
      </div>

      <p>Step Two: Navigate to <a href="https://developers.google.com/oauthplayground/" target="_blank">https://developers.google.com/oauthplayground/</a> and click on the OAuth configuration button on the right which looks like the settings cog. Check mark
        the use your own OAuth credentials and input the client ID and secret ID we received in the following step. Next under the step 1 catagory enter <b>https://mail.google.com</b> in the text field. Click Authorize. The next screen will be a log in.</p>

      <div class="row">
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-OAuth-Playground.png" class="img-fluid thumbnail big-img" />
        </div>
        <div class="col-md-6 col-sm-12">
          <img src="https://conorhinchee.com/imgs/blog/Screenshot-Sign-In.png" class="img-fluid thumbnail big-img" />
        </div>
      </div>

      <p>Final screen will return to the OAuth playground and we will be presented with our refresh token. Click the box to indicate to not let the token expire and we finally have all the information neccessary to send emails via gmail with the node mailer</p>

      <img src="https://conorhinchee.com/imgs/blog/Screenshot-OAuth-Token.png" class="img-fluid thumbnail big-img" />

      <p>Back to our server's code, create a new post route with the name "/send" which will take a request and response variable. I will use some HTML formatting to make the emails I get pretty, use the auth object set with our OAuth2 information, and on
        the way to receiving emails from our contact form</p>

      <ol>
        <li>
          <code>app.post('/send', (req, res) => {</code>
        </li>
        <li>
          <code>const output = `</code>
        </li>
        <li class="second-indent">
          <code> &lt;h1&gt;New Contact from home page&lt;/h1&gt;</code>
        </li>
        <li class="second-indent">
          <code>&lt;h3&gt;Details:&lt;/h3&gt;</code>
        </li>
        <li class="second-indent">
          <code>&lt;ul&gt;</code>
        </li>
        <li class="third-indent">
          <code>&lt;li&gt;name : ${req.body.name&lt;/li&gt;</code>
        </li>
        <li class="third-indent">
          <code>&lt;li&gt;email : ${req.body.email}&lt;/li&gt;</code>
        </li>
        <li class="second-indent">
          <code>&lt;/ul&gt;</code>
        </li>
        <li class="second-indent">
          <code>&lt;p&gt;message : ${req.body.message}&lt;/p&gt;</code>
        </li>
        <li>
          <code>`;</code>
        </li>
        <li>
          <code>&nbsp;</code>
        </li>
        <li>
          <code>var transporter = mailer.createTransport({</code>
        </li>
        <li class="second-indent">
          <code>host: "smtp.gmail.com",</code>
        </li>
        <li class="second-indent">
          <code>port: 465,</code>
        </li>
        <li class="second-indent">
          <code>secure: true,</code>
        </li>
        <li class="second-indent">
          <code>auth: {</code>
        </li>
        <li class="third-indent">
          <code>type: "OAuth2",</code>
        </li>
        <li class="third-indent">
          <code>user: 'captnstarburst@gmail.com',</code>
        </li>
        <li class="third-indent">
          <code>clientId: '184691020745-hne9n5dfh9nmd5v1kn8gfq9m461f9c81.apps.googleusercontent.com',</code>
        </li>
        <li class="third-indent">
          <code>clientSecret: process.env.GMAIL_SECRET,</code>
        </li>
        <li class="third-indent">
          <code>refreshToken: '1/YseG0hJCQklhoWbIsMGZhIqIpRJD0EFDShoBDsRggys'</code>
        </li>
        <li class="second-indent">
          <code>}</code>
        </li>
        <li>
          <code>});</code>
        </li>
        <li>
          <code>&nbsp;</code>
        </li>
        <li>
          <code>var mailOptions = {</code>
        </li>
        <li class="second-indent">
          <code>from: '"Home Page Contact" captnstarburst@gmail.com',</code>
        </li>
        <li class="second-indent">
          <code>to: 'captnstarburst@gmail.com',</code>
        </li>
        <li class="second-indent">
          <code>from: '"Home Page Contact" conorphinchee@gmail.com',</code>
        </li>
        <li class="second-indent">
          <code>subject: 'Contact Request',</code>
        </li>
        <li class="second-indent">
          <code>html: output</code>
        </li>
        <li>
          <code>};</code>
        </li>
        <li>
          <code>transporter.sendMail(mailOptions, function(error, info){</code>
        </li>
        <li class="second-indent">
          <code>if (error) {</code>
        </li>
        <li class="third-indent">
          <code>console.log("error sending mail :" + error);</code>
        </li>
        <li class="third-indent">
          <code>//send res error to user</code>
        </li>
        <li class="second-indent">
          <code>} else {</code>
        </li>
        <li class="third-indent">
          <code>console.log('Email sent: ' + info.response);</code>
        </li>
        <li class="third-indent">
          <code>//send res success to user</code>
        </li>
        <li class="second-indent">
          <code>}</code>
        </li>
        <li>
          <code>});</code>
        </li>
      </ol>

      <p class="text-center">Feel free to fork my github repo for this post or maybe continue reading my blog! </p>

    </div>
  </div>
  <div class="row page-nav justify-content-center">
    <div class="col-8">
      <button class="btn btn-secondary left"><span class="header btn-txt"><- Previous Aricle</span></button>
      <button class="btn btn-secondary right"><span class="header btn-txt">  Next Article -></span></button>
    </div>
  </div>
  <div class="row footer">
    <div class="col-12 text-center">
      <hr class="blog-line" />
      <h5 class="header white-txt">Coded by Conor Hinchee </h5>
    </div>
  </div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/captnstarburst/blog-page-with-code-pVWObe */
body {
  background-image: url("https://conorhinchee.com/imgs/blog/paperBG.png");
}

.navbar-brand {
  font-family: "Playfair Display SC", serif;
}

.header {
  font-family: "Playfair Display SC", serif;
}

p {
  font-family: "Dosis", sans-serif;
  font-size: 1.5em;
}

.title-row {
  padding-top: 5%;
}

.title-txt {
  text-decoration: underline;
  text-shadow: 1px 1px 1px blue;
}

.blog-nav {
  padding-top: 1%;
}

.content-row {
  padding-top: 1%;
}
.content-row p {
  text-align: justify;
  hyphens: auto;
}

.thumbnail {
  border: 2px solid black;
}

.article-img {
  width: 20%;
}

.left {
  float: left;
  margin-right: 10px;
  margin-bottom: 10px;
}

.right {
  float: right;
  margin-left: 10px;
  margin-bottom: 10px;
}

.big-img {
  margin-bottom: 5%;
}

.page-nav {
  padding-top: 5%;
}

code {
  background: grey;
  color: white;
  display: block;
}

li {
  text-indent: 20px;
}

li:nth-child(1) {
  text-indent: 0;
}

li:last-child {
  text-indent: 0;
}

.no-indent {
  text-indent: 0;
}

.second-indent {
  text-indent: 40px;
}

.third-indent {
  text-indent: 60px;
}

.terminal {
  background: black;
  color: #ACBF60;
}

@media screen and (min-width: 2560px) {
  .navbar-brand {
    font-size: 3em;
  }

  .nav-link {
    font-size: 2em;
  }

  .navbar-nav > li {
    padding-left: 15px;
    padding-right: 15px;
  }

  h1 {
    font-size: 5em;
  }

  h3 {
    font-size: 3em;
  }

  h5 {
    font-size: 2.5em;
  }

  p {
    font-size: 2.5em;
  }

  .content-row p {
    padding-bottom: 3%;
  }

  .btn-txt {
    font-size: 2em;
  }
}
@media screen and (max-width: 1024px) {
  p {
    font-size: 1.2em;
  }

  h1 {
    font-size: 2em;
  }

  .article-img {
    width: 30%;
  }
}
@media screen and (max-width: 768px) {
  .article-img {
    width: 40%;
  }
}
@media screen and (max-width: 425px) {
  .article-img {
    width: 100%;
  }
}


/*Downloaded from https://www.codeseek.co/captnstarburst/blog-page-with-code-pVWObe */
$(document).ready(function($) {
  setInterval("cursorAnimation()", 1200);
});

function cursorAnimation() {
	$(".cursor")
		.animate(
			{
				opacity: 0
			},
			"fast",
			"swing"
		)
		.animate(
			{
				opacity: 1
			},
			"fast",
			"swing"
		);
}

Comments