Objectives

Refactor the bundle-store site to use EJS templates

Setup

This is an extended version of the Bundle Store site from lab 03:

Explore the site for few moments.

The site incorporates the navigation mechanism we devised in Lab 04. Here is th full source:

Download, unzip and have a close look at the sources.

This is how the project is structured:

├── apps.html
├── css
│   ├── grid.css
│   ├── home.css
│   ├── image.css
│   └── nav.css
├── directions.html
├── images
│   ├── background.gif
│   ├── banner.png
│   ├── business.png
│   ├── insanity.jpg
│   ├── ondesoft.jpg
│   └── ultimate.jpeg
└── index.html

Have a close look at each of the style sheets first. They embody all of the css techniques we have covered to date.

Inspect each of the html files - become familiar with how each page is now structured. In particular, note the divisions:

This structure is laid out via the grid style sheet:

grid.css

.container {
  display: grid;
  grid-template-columns: 5% 88% 5%;
  grid-gap: 1%;
}

#header {
  grid-column-start: 2;
  grid-column-end: span 2;
  text-align: center;
}

#navigation {
  grid-column-start: 2;
  text-align: center;
  border-bottom: 1px solid black;
}

#maincontent {
  grid-column-start: 2;
  display: grid;
  grid-template-columns: 70% 27%;
  grid-gap: 3%;
}

#primary {
  grid-column-start: 1;
}

#secondary {
  grid-column-start: 2;
}

#footer {
  grid-column-start: 2;
}

The navigation mechanism:

is adapted from the previous navigation lab:

nav.css

ul#menu li {
  display: inline;
  padding-right: 1em;
  padding-left: 1em;
}

ul#menu a {
  text-decoration: none;
}

#menu li.active a {
  background: #007e7e;
  padding: .5em 2em .5em 2em;
  color: white;
}

New Project

Create a new folder for this weeks lab called lab-05b. Taking the archive you have downloaded in the last step expand it in here. Your project should look exactly like this:

└── lab-05b
    └── bundle-store
        ├── apps.html
        ├── css
        │   ├── grid.css
        │   ├── home.css
        │   ├── image.css
        │   └── nav.css
        ├── directions.html
        ├── images
        │   ├── background.gif
        │   ├── banner.png
        │   ├── business.png
        │   ├── insanity.jpg
        │   ├── ondesoft.jpg
        │   └── ultimate.jpeg
        └── index.html

Now make the following changes to this structure:

── lab-05b
    └── bundle-store-ejs
        ├── harp.json
        └── public
            ├── apps.html
            ├── css
            │   ├── grid.css
            │   ├── home.css
            │   ├── image.css
            │   └── nav.css
            ├── directions.html
            ├── images
            │   ├── background.gif
            │   ├── banner.png
            │   ├── business.png
            │   ├── insanity.jpg
            │   ├── ondesoft.jpg
            │   └── ultimate.jpeg
            └── index.html

In the above we have

  • renamed the project folder to 'bundle-store-ejs'
  • created a new 'public' folder, with all the content moved in here
  • added a new 'harp.json' file.

This is the contents of the 'harp.json' file:

harp.json

{
  "globals":
  {

  }
}

We will now be 'serving' the web site via the harp web server we have just installed in the last lab. Open a command prompt and navigate to the project folder:

C:\dev\web-development\lab0-5b\bundle-store-ejs>harp server
------------
Harp v0.29.0 – Chloi Inc. 2012–2015
Your server is listening at http://localhost:9000/
Press Ctl+C to stop the server
---

The site is now deployed at

The changes we are about to make in this lab will mean that this is the only procedure for viewing our site.

To stop the server, enter Ctrl-C:

------------
Harp v0.29.0 – Chloi Inc. 2012–2015
Your server is listening at http://localhost:9000/
Press Ctl+C to stop the server
------------
^C

You may need stop and start the server periodically.

Ejs Partials

Rename each of the html files, removing '.html' and replacing this with .ejs:

├── harp.json
└── public
    ├── apps.ejs
    ├── css
    │   ├── grid.css
    │   ├── home.css
    │   ├── image.css
    │   └── nav.css
    ├── directions.ejs
    ├── images
    │   ├── background.gif
    │   ├── banner.png
    │   ├── business.png
    │   ├── insanity.jpg
    │   ├── ondesoft.jpg
    │   └── ultimate.jpeg
    └── index.ejs

Run the server again:

C:\dev\web-development\lab0-5b\bundle-store-ejs>harp server
------------
Harp v0.29.0 – Chloi Inc. 2012–2015
Your server is listening at http://localhost:9000/
Press Ctl+C to stop the server
---

The site should still work exactly the same as before:

Create a new folder in the project called partials, and create 2 new files in here:

_header.ejs

<div id="header">
  <h1>Welcome to the App Bundle Store</h1>
</div>

_footer.ejs

<div id="footer">
  <p> Contact us at : bundle@store.com, or visit us: <a href="directions.html"> directions </a></p>
</div>

The project structure now looks like this:

├── harp.json
└── public
    ├── apps.ejs
    ├── css
    │   ├── grid.css
    │   ├── home.css
    │   ├── image.css
    │   └── nav.css
    ├── directions.ejs
    ├── images
    │   ├── background.gif
    │   ├── banner.png
    │   ├── business.png
    │   ├── insanity.jpg
    │   ├── ondesoft.jpg
    │   └── ultimate.jpeg
    ├── index.ejs
    └── partials
        ├── _footer.ejs
        └── _header.ejs

Now edit each of the apps, index and directions files - replacing the header + footer in each of those files with these statements:

  ...
      <%- include('./partials/_header.ejs'); %>
  ...
      <%- include('./partials/_footer.ejs'); %>
  ...

So, for instance the directions.ejs file will now look like this:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bundle APP Store</title>
    <link rel="stylesheet" href="./css/home.css">
  </head>
  <body>
    <img src="images/banner.png" class="large-centre-img">
    <div class="container">
      <%- include('./partials/_header.ejs'); %>
      <div id="navigation">
        <ul id="menu">
          <li><a href="index.html">Home</a></li>
          <li><a href="apps.html">Apps</a></li>
          <li class="active"><a href="directions.html">Directions</a></li>
        </ul>
      </div>
      <div id="maincontent">
        <div id="primary">
          <h1>Directions</h1>
          <h2>Our store is located :</h2>
          <p>
            Take the M9 / N9 towards Waterford. At the first roundabout on approach to Waterford,
            take the first exit (signposted Waterford / Cork / Rosslare). At the next roundabout,
            take the third exit (signposted N25 / Cork / Waterford South). Proceed through the toll
            bridge (toll is €1.90 per car). Take the exit directly after the toll bridge (signposted
            Waterford South/R710). </p>
          <p>
            At the top of the off-ramp, go left at the small roundabout, then straight through two
            larger roundabouts (signposted R710/City Centre/Tramore). At the next roundabout (
            retail park on your left), take the first exit (signposted City Centre). Proceed down
            the Cork Road for approx 2km and the main entrance to WIT’s main campus is on the left.
            The College Street Campus is a further 2km towards the city centre on the left. </p>
          <hr>
        </div>
      </div>
      <%- include('./partials/_footer.ejs'); %>
    </div>
  </body>
</html>

Make sure you have made this change to all files - and now browse to the site:

Even though we are starting to radically alter the structure of the site, the site is still served exactly as it was before.

This is the power of templates, we can start to break up a site into reusable parts (partials) and have the site dynamically assembled by the server.

Ejs Layouts

Create a new file in the project:

_layout.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bundle APP Store</title>
    <link rel="stylesheet" href="./css/home.css">
  </head>
  <body>
    <img src="images/banner.png" class="large-centre-img">
    <div class="container">
      <%- yield %>
    </div>
  </body>
</html>

This is a master file, which all pages in the project will be based on. Pay close attention to this section:

  ...
    <div class="container">
      <%- yield %>
    </div>
  ...

Each page will be based on this structure - which means the pages can be significantly simplified:

index.ejs

<%- include('./partials/_header.ejs'); %>
<div id="navigation">
  <ul id="menu">
    <li class="active"><a href="index.html">Home</a></li>
    <li><a href="apps.html">Apps</a></li>
    <li><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <p>
      This store brings you <em> great app bundles </em> week after week. We select the best power user apps from a
      broad range of suppliers and combine them into great deals. These are the highest quality apps from the best
      publishers, at great prices. </p>
    <p>
      Whether you are interested in gaming or graphics design, software development or media production - we have the
      bundle for you. Each <a href="apps.html">app bundle</a> is designed to compliment the others, delivering you an
      exciting take on a scene. </p>
    <p class="guarantee">
      Our guarantee: at the store, we're committed to providing you, with an exceptional quality and reliability. Every
      application is checked in detail for stability, usability and inter-interoperability. If you are unhappy with any
      individual app in a bundle we will refund you the full amount for the complete suite, no questions asked. </p>
    <h2>Favourites</h2>
    <p> These are some of our favourites </p>
    <ul class="highlight">
      <li>Hype by Tumult</li>
      <li>Webstorm by Idea</li>
      <li>Sublime, by sublimetext.com</li>
      <li>Desktop Utility by Sweet Productions</li>
    </ul>
    <h2>Favourites</h2>
    <p> We will be reviewing these favourites in the coming weeks, so please check in again to find out why these are
      our favourite apps.</p>
    <p> Why not come in and walk aroud the store? Directions are included below. </p>
  </div>
  <div id="secondary">
    <h1>Weekly Deals</h1>
    <h2 class="special">Business Bundle</h2>
    <p>
      <img src="images/business.png" alt="Business Bundle" class="medium-right-img"> Here comes the next bundle for
      march. This time it's macware who publish a bundle. The so called macware Business Bundle contains 6 apps at a
      price of only €29.99 instead of €199.94. So you can save around 84%. </p>
    <h2 class="special">Insanity Deal</h2>
    <p>
      <img src="images/insanity.jpg" alt="Insanity Deal" class="medium-left-img"> With the new €5 Insanity Deals from
      Bundlehunt you receive every day a highly reduced app for €5 only with savings up to 75%. Not a real bundle but,
      as there are multiple apps for only €5 each, one new per day, for the days to come. </p>
  </div>
</div>
<%- include('./partials/_footer.ejs'); %>

apps.ejs

<%- include('./partials/_header.ejs'); %>
<div id="navigation">
  <ul id="menu">
    <li><a href="index.html">Home</a></li>
    <li class="active"><a href="apps.html">Apps</a></li>
    <li><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <h1>App Bundles</h1>
    <h3>Freebie</h3>
    <p>
      <img src="images/ondesoft.jpg" alt="One Soft" class="medium-right-img"> Stacksocial just published its so called
      Free Ondesoft Mac Tool Bundle, which contains 5 apps from Onesoft. The bundle is worth $146 will be probably
      available only a couple of days so you’d better hurry up to get it. </p>
    <hr>
    <h3>Macware Business Bundle</h3>
    <p>
      Here comes the next bundle for march. This time its macware who publish a bundle. The so called macware Business
      Bundle contains 6 apps at a price of only €29.99 instead of €199.94. So you can save around 84%. </p>
    <hr>
    <h3>Ultimate Bundle</h3>
    <p>
      <img src="images/ultimate.jpeg" alt="One Soft" class="medium-left-img"> This bundle is worth more than €400. So
      for just a little bit more than $10, you can make your bargain if you want just one of these apps. of dollars. We
      think, that the bundle will be online until the mid of October </p>
    <hr>
  </div>
</div>
<%- include('./partials/_footer.ejs'); %>

directions.ejs

<%- include('./partials/_header.ejs'); %>
<div id="navigation">
  <ul id="menu">
    <li><a href="index.html">Home</a></li>
    <li><a href="apps.html">Apps</a></li>
    <li class="active"><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <h1>Directions</h1>
    <h2>Our store is located :</h2>
    <p>
      Take the M9 / N9 towards Waterford. At the first roundabout on approach to Waterford, take the first exit
      (signposted Waterford / Cork / Rosslare). At the next roundabout, take the third exit (signposted N25 / Cork /
      Waterford South). Proceed through the toll bridge (toll is €1.90 per car). Take the exit directly after the toll
      bridge (signposted Waterford South/R710). </p>
    <p>
      At the top of the off-ramp, go left at the small roundabout, then straight through two larger roundabouts
      (signposted R710/City Centre/Tramore). At the next roundabout ( retail park on your left), take the first exit
      (signposted City Centre). Proceed down the Cork Road for approx 2km and the main entrance to WIT’s main campus is
      on the left. The College Street Campus is a further 2km towards the city centre on the left. </p>
    <hr>
  </div>
</div>
<%- include('./partials/_footer.ejs'); %>

In all of the above, notice how we no longer have an <head> section in any page, as it is part of the layout. Also, the body section and the container wrapper.

Make sure the site continues to work as expected.

Layout Adjustments

This is our current layout:

_layout.ejs

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bundle APP Store</title>
    <link rel="stylesheet" href="./css/home.css">
  </head>
  <body>
    <img src="images/banner.png" class="large-centre-img">
    <div class="container">
      <%- yield %>
    </div>
  </body>
</html>

We can revise it now to include the header/footer:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bundle APP Store</title>
    <link rel="stylesheet" href="./css/home.css">
  </head>
  <body>
    <img src="images/banner.png" class="large-centre-img">
    <div class="container">
      <%- include('./partials/_header.ejs'); %>
      <%- yield %>
      <%- include('./partials/_footer.ejs'); %>
    </div>
  </body>
</html>

This means we can delete the header/footer include from all of the pages.

Do this now, and verify that the site is still appearing correctly.

Secondary

In the partials folder, create the following new file:

_secondary.ejs

<div id="secondary">
  <h1>Weekly Deals</h1>
  <h2 class="special">Business Bundle</h2>
  <p>
    <img src="images/business.png" alt="Business Bundle" class="medium-right-img"> Here comes the next bundle for march.
    This time it's macware who publish a bundle. The so called macware Business Bundle contains 6 apps at a price of
    only €29.99 instead of €199.94. So you can save around 84%. </p>
  <h2 class="special">Insanity Deal</h2>
  <p>
    <img src="images/insanity.jpg" alt="Insanity Deal" class="medium-left-img"> With the new €5 Insanity Deals from
    Bundlehunt you receive every day a highly reduced app for €5 only with savings up to 75%. Not a real bundle but, as
    there are multiple apps for only €5 each, one new per day, for the days to come. </p>
</div>

The project looks like this now:

├── harp.json
└── public
    ├── _layout.ejs
    ├── apps.ejs
    ├── css
    │   ├── grid.css
    │   ├── home.css
    │   ├── image.css
    │   └── nav.css
    ├── directions.ejs
    ├── images
    │   ├── background.gif
    │   ├── banner.png
    │   ├── business.png
    │   ├── insanity.jpg
    │   ├── ondesoft.jpg
    │   └── ultimate.jpeg
    ├── index.ejs
    └── partials
        ├── _footer.ejs
        ├── _header.ejs
        └── _secondary.ejs

Edit index.html, and replace the secondary section with an include of this new file:

index.html

<div id="navigation">
  <ul id="menu">
    <li class="active"><a href="index.html">Home</a></li>
    <li><a href="apps.html">Apps</a></li>
    <li><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <p>
      This store brings you <em> great app bundles </em> week after week. We select the best power user apps from a
      broad range of suppliers and combine them into great deals. These are the highest quality apps from the best
      publishers, at great prices. </p>
    <p>
      Whether you are interested in gaming or graphics design, software development or media production - we have the
      bundle for you. Each <a href="apps.html">app bundle</a> is designed to compliment the others, delivering you an
      exciting take on a scene. </p>
    <p class="guarantee">
      Our guarantee: at the store, we're committed to providing you, with an exceptional quality and reliability. Every
      application is checked in detail for stability, usability and inter-interoperability. If you are unhappy with any
      individual app in a bundle we will refund you the full amount for the complete suite, no questions asked. </p>
    <h2>Favourites</h2>
    <p> These are some of our favourites </p>
    <ul class="highlight">
      <li>Hype by Tumult</li>
      <li>Webstorm by Idea</li>
      <li>Sublime, by sublimetext.com</li>
      <li>Desktop Utility by Sweet Productions</li>
    </ul>
    <h2>Favourites</h2>
    <p> We will be reviewing these favourites in the coming weeks, so please check in again to find out why these are
      our favourite apps.</p>
    <p> Why not come in and walk aroud the store? Directions are included below. </p>
  </div>
  <%- include('./partials/_secondary.ejs'); %>
</div>

Again, check the site - there should be no change.

Sharing Partials

Have a look at this version of the site:

In particular, notice how the 'Weekly Deals' is present in all three pages.

If we were not using partials, then we would have had to copy/paste this section into each page. With the template infrastructure in place, this becomes a trivial change:

apps.html

<div id="navigation">
  <ul id="menu">
    <li><a href="index.html">Home</a></li>
    <li class="active"><a href="apps.html">Apps</a></li>
    <li><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <h1>App Bundles</h1>
    <h3>Freebie</h3>
    <p>
      <img src="images/ondesoft.jpg" alt="One Soft" class="medium-right-img"> Stacksocial just published its so called
      Free Ondesoft Mac Tool Bundle, which contains 5 apps from Onesoft. The bundle is worth $146 will be probably
      available only a couple of days so you’d better hurry up to get it. </p>
    <hr>
    <h3>Macware Business Bundle</h3>
    <p>
      Here comes the next bundle for march. This time its macware who publish a bundle. The so called macware Business
      Bundle contains 6 apps at a price of only €29.99 instead of €199.94. So you can save around 84%. </p>
    <hr>
    <h3>Ultimate Bundle</h3>
    <p>
      <img src="images/ultimate.jpeg" alt="One Soft" class="medium-left-img"> This bundle is worth more than €400. So
      for just a little bit more than $10, you can make your bargain if you want just one of these apps. of dollars. We
      think, that the bundle will be online until the mid of October </p>
    <hr>
  </div>
  <%- include('./partials/_secondary.ejs'); %>
</div>

directions.html

<div id="navigation">
  <ul id="menu">
    <li><a href="index.html">Home</a></li>
    <li><a href="apps.html">Apps</a></li>
    <li class="active"><a href="directions.html">Directions</a></li>
  </ul>
</div>
<div id="maincontent">
  <div id="primary">
    <h1>Directions</h1>
    <h2>Our store is located :</h2>
    <p>
      Take the M9 / N9 towards Waterford. At the first roundabout on approach to Waterford, take the first exit
      (signposted Waterford / Cork / Rosslare). At the next roundabout, take the third exit (signposted N25 / Cork /
      Waterford South). Proceed through the toll bridge (toll is €1.90 per car). Take the exit directly after the toll
      bridge (signposted Waterford South/R710). </p>
    <p>
      At the top of the off-ramp, go left at the small roundabout, then straight through two larger roundabouts
      (signposted R710/City Centre/Tramore). At the next roundabout ( retail park on your left), take the first exit
      (signposted City Centre). Proceed down the Cork Road for approx 2km and the main entrance to WIT’s main campus is
      on the left. The College Street Campus is a further 2km towards the city centre on the left. </p>
    <hr>
  </div>
  <%- include('./partials/_secondary.ejs'); %>
</div>

Make these change now, and verify your site looks the same a this:

Solution

Exercise 1: Compile

From within the project folder, enter the following command:

harp compile

Then, explore the contents of a newly generated folder called 'www'.

  • What is in this folder?
  • Why would we need it?

Exercise 2: Deploy the site

Using lab05a as a guide, deploy this site using surge.