Objectives

Rework the tabbed navigation site from lab 04 to use EJS template

Setup

This is a complete archive a simple navigable web site form lab 04 (slightly simplified).

The site looks like this.

Download the archive and zip to your workspace. It structured like this:

This is already configured to work with the harp server. Open a shell in the navdemo folder and run the server:

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

Browse to http://localhost:9000/ ... the site should be available.

Because we are running the site under an EJS server, we can start to use EJS features.

Layout

Introduce the following file into the project:

_layout.ejs

<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="home.css">
    <title>Home Page</title>
  </head>
  <body>
    <%- yield %>
  </body>
</html>

Now we can simplify all the file. Rename each from .html to .ejs - and then replace the contents of each file with this simpler version:

index.ejs

<header id="header">
  <h1>
    Page I
  </h1>  
</header>

<nav id="navigation">
  <ul id="menu">  
    <li class="current"><a href="index.html">Mauris</a></li>  
    <li><a href="page1.html"> Cras </a></li>  
    <li><a href="page2.html">Proin</a></li>  
    <li><a href="page3.html">Integer</a></li>  
  </ul>  
</nav>

<main id="maincontent">
  <article id="primary">
    <p>
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat nisi  
      at sapien. Phasellus varius tincidunt ligula. Praesent nisi. Duis  
      sollicitudin. Donec dignissim, est vel auctor blandit, ante est laoreet  
      neque, non pellentesque mauris turpis eu purus.
    </p>    
    <p>
      Suspendisse mollis leo nec diam. Vestibulum pulvinar tellus sit amet nulla  
      fringilla semper. Aenean aliquam, urna et accumsan sollicitudin, tellus  
      pede lobortis velit, nec placerat dolor pede nec nibh. Donec fringilla. Duis  
      adipiscing diam at enim. Vestibulum nibh.
    </p>  
    <p>
      Nulla facilisi. Aliquam dapibus leo eget leo. Etiam vitae turpis sit amet  
      massa posuere cursus. Sed vitae justo quis tortor facilisis ultrices.  
      Integer id erat. Donec at felis ut erat interdum vestibulum. Quisque et eros.  
      Donec fringilla, est in condimentum venenatis, tortor velit vehicula sem, in  
      elementum quam sapien eu lectus. In dolor urna, ullamcorper vel, tempor sit  
      amet, semper ut, felis. Praesent nisi.
    </p>  
  </article>

  <aside id="secondary">
    <p>
      Fusce scelerisque viverra quam. Nam urna. Nullam urna libero, euismod at,  
      euismod sit amet, porttitor ac, mauris.
    </p>  
    <p>
      Vestibulum interdum aliquet lacus. Vestibulum egestas. Fusce adipiscing  
      quam sed metus.
    </p>  
    <p>
      Nullam dignissim aliquam dui. Proin laoreet, elit sed pulvinar  
      sollicitudin, urna arcu fermentum felis, in rhoncus nunc neque vitae  
      libero.
    </p>
  </aside>
</main>

<footer id="footer">
  <p>
    Proin quis orci eu erat molestie varius. Praesent condimentum  
    orci in lectus. Ut ipsum. In hac habitasse platea dictumst.
  </p>
</footer>

page1.ejs

<header id="header">
  <h1>
    Page II
  </h1>  
</header>

<nav id="navigation">
  <ul id="menu">  
    <li><a href="index.html"> Mauris </a></li>  
    <li class="current"> <a href="page1.html">Cras</li>  
    <li><a href="page2.html">Proin</a></li>  
    <li><a href="page3.html">Integer</a></li>   
  </ul>  
</nav>

<main id="maincontent">
  <article id="primary">
    <p>
      Phasellus non nibh ut lacus elementum pharetra. Vivamus sed orci ipsum.
      Nulla sapien eros, euismod ac ornare sed, consectetur sed dui. Integer gravida
      sem et turpis interdum in convallis eros placerat. Quisque auctor, velit sed
      blandit pharetra, felis diam ultricies erat, vel aliquet neque risus non lacus.
      Etiam non magna tortor, in rutrum augue. Donec nec enim ante, in tincidunt eros.
    </p>
    <p>
      Aenean ultrices, ante non scelerisque eleifend, libero dolor rutrum justo,
      vitae iaculis mi est id nisl. Nunc velit odio, luctus in imperdiet eget,
      pulvinar ac quam. Nullam ipsum arcu, euismod vel congue quis, ullamcorper
      sit amet massa. Vivamus et mauris ut ante sagittis sagittis quis eu velit.  
    </p> 
  </article>

  <aside id="secondary">
    <p>
      In faucibus turpis lacus, eget congue magna. Aenean vitae lacus sed mi pretium
      porttitor suscipit sit amet ipsum. Suspendisse potenti. 
    </p>
    <p>
      Nunc pharetra consectetur
      est eget tempus. Aenean ac iaculis dui. Morbi volutpat rutrum urna vitae suscipit.
      Vestibulum quam libero, lacinia id varius at, pharetra vitae metus. Proin sit amet
      euismod dolor. 
    </p>
  </aside>
</main>

<footer id="footer">
  <p>
    Proin quis orci eu erat molestie varius. Praesent condimentum  
    orci in lectus. Ut ipsum. In hac habitasse platea dictumst.
  </p>
</footer>

page2.ejs

<header id="header">
  <h1>
    Page III
  </h1>  
</header>

<nav id="navigation">
  <ul id="menu">  
    <li><a href="index.html"> Mauris </a></li>  
    <li><a href="page1.html"> Cras </a></li>  
    <li class="current"> <a href="page3.html">Proin</li>  
    <li><a href="page3.html">Integer</a></li>  
  </ul>  
</nav>

<main id="maincontent">
  <article id="primary">
    <p>
      Sed vitae erat convallis, iaculis diam eu, accumsan elit. Nullam nunc lectus, convallis nec finibus at, feugiat in elit. Cras porta, lacus in pretium malesuada, nisl ipsum venenatis nulla, a tempus diam est a dolor. Nam quis metus aliquet, tempus quam vel, hendrerit mi. In sollicitudin est ultrices tempus rutrum. 
    </p>
    <p>
      Aliquam pharetra, erat sed euismod ullamcorper, ex sem pretium lectus, nec porttitor nisl lectus nec turpis. Suspendisse eu tristique turpis, ut consectetur libero. Praesent feugiat nulla enim, eu consequat nisi maximus vitae. Morbi facilisis aliquet felis. Curabitur ullamcorper sit amet lacus vitae scelerisque. Nullam enim est, imperdiet nec purus nec, tristique vestibulum lectus. Nullam vel nisl consectetur, luctus purus et, auctor lacus. Donec ut dictum justo. Cras sed justo tincidunt, tincidunt lacus non, suscipit ex.
    </p> 
  </article>
  <aside id="secondary">
    <p>
      Duis gravida at neque fringilla posuere. Curabitur a consectetur sem. Fusce massa lacus, porta ut congue eu, ultrices ut lorem. Nam tempor pretium faucibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    </p>
    <p>
      Nullam vestibulum, erat sed sagittis volutpat, risus arcu dapibus mi, vitae rhoncus elit odio vel lectus. 
    </p>
  </aside>
</main>

<footer id="footer">
  <p>
    Proin quis orci eu erat molestie varius. Praesent condimentum  
    orci in lectus. Ut ipsum. In hac habitasse platea dictumst.
  </p>
</footer>

page3.ejs

<header id="header">
  <h1>
    Page IV
  </h1>  
</header>

<nav id="navigation">
  <ul id="menu">  
    <li><a href="index.html"> Mauris </a></li>  
    <li><a href="page1.html"> Cras </a></li>  
    <li><a href="page2.html">Proin</a></li>  
    <li class="current"> <a href="page3.html">Integer</a></li> 
  </ul>  
</nav>

<main id="maincontent">
  <article id="primary">
    <p>
      In sed rhoncus erat. Pellentesque vel turpis facilisis, fringilla ante non, auctor arcu. Sed convallis sapien nec felis consequat tristique id vel mauris. Ut aliquam nunc vitae pretium bibendum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec ultricies et massa vel iaculis. Fusce euismod sit amet nisi ac malesuada. 
    </p>
    <p>
      Sed pellentesque nisl rutrum urna condimentum, id ultrices mauris tincidunt. Vivamus porttitor metus ac lectus finibus luctus. Donec nec cursus turpis. Ut at orci turpis. Ut rutrum eros sed elementum aliquet. Aliquam turpis dui, pulvinar eget iaculis vitae, convallis vitae turpis. Phasellus velit odio, blandit sit amet metus ac, fermentum cursus velit. Nulla a odio odio. 
    </p>  
  </article>

  <aside id="secondary">
    <p>
      Integer sit amet nisi nec sem euismod rutrum porttitor eu nisi. Morbi arcu ipsum, placerat vitae diam id, finibus pulvinar ipsum. Nunc ac ex iaculis, eleifend elit id, finibus massa. 
    </p>
    <p>
      Vestibulum gravida, tortor ut laoreet interdum, turpis arcu molestie neque, at posuere neque elit vitae ligula. Etiam ut consectetur lectus. Phasellus commodo urna ut fermentum congue. Mauris vitae metus ut turpis ornare scelerisque. 
    </p>
  </aside>
</main>

<footer id="footer">
  <p>
    Proin quis orci eu erat molestie varius. Praesent condimentum  
    orci in lectus. Ut ipsum. In hac habitasse platea dictumst.
  </p>
</footer>

We have also replaced <div>s with approproate semantic elements. Browse to http://localhost:9000/ to make sure it is serving correctly.

Footer

Create a new folder in the project called includes and introduce the following:

includes/footer.ejs

<footer id="footer">
  <p>
    Proin quis orci eu erat molestie varius. Praesent condimentum  
    orci in lectus. Ut ipsum. In hac habitasse platea dictumst.
  </p>
</footer>

In each of the main templates, replace the footer not with this:


<%- partial("includes/_footer.ejs") %>

Browse to http://localhost:9000/ to make sure it is serving correctly.

Navigation

We can now try the same with the navigation section:

includes/nav.ejs

<nav id="navigation">
  <ul id="menu">
    <li class="current"><a href="index.html">Mauris</a></li>
    <li><a href="page1.html"> Cras </a></li>
    <li><a href="page2.html">Proin</a></li>
    <li><a href="page3.html">Integer</a></li>
  </ul>
</nav>

Replace the nav section in each file with this:


<%- partial("includes/_nav.ejs") %>

Browse to http://localhost:9000/ to make sure it is serving correctly.

However, there will be a problem: not matter which page we visit, the first navigation entry remains highlighted.

This is because the <nav> is now shared - it always marks the first element as active:

...
    <li class="current"><a href="index.html">Mauris</a></li>
...

One solution would be to reverse the last change - and keep the <nav> section individual to each page. An alternative is implemented in the next step....

Dynamic Navigation

Edit _layout.ejs, introducing a new element in the <head> section:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>.min.js"></script>

This is the complete version:

_layout.ejs

<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="home.css">
    <title>Home Page</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  </head>
  <body>
    <%- yield %>
  </body>
</html>

Replace include/_nav.ejs with the following:

includes/_nav.ejs

<nav id="navigation">
  <ul id="menu">
    <li id="Mauris">  <a href="index.html"> Mauris </a></li>
    <li id="Cras">    <a href="page1.html"> Cras </a></li>
    <li id="Proin">   <a href="page2.html"> Proin </a></li>
    <li id="Integer"> <a href="page3.html"> Integer </a></li>
  </ul>
</nav>

<script>
  $("#<%=id%>").addClass("current");
</script>

In all four of our main pages, change the partial include to the following:

index.ejs

...
<%- partial("includes/_nav.ejs", { id: "Mauris" }) %>
...

page1.ejs

...
<%- partial("includes/_nav.ejs", { id: "Cras" }) %>
...

page2.ejs

...
<%- partial("includes/_nav.ejs", { id: "Proin" }) %>
...

page3.ejs

...
<%- partial("includes/_nav.ejs", { id: "Integer" }) %>
...

Browse to http://localhost:9000/ to make sure it is serving correctly.

Solution

This is a complete archive of the site created in this lab:

Exercise 1: Compile

Try the harp compile command from a shell inside the project folder. Explore the generated www folder. It should be a complete (non ejs) version of the site.

Exercise 2: Publish

Publish the site using the surge service.

Exercise 3: Add additional pages

Introduce pages V an VI. You might be interested, perhaps, in using a lorem upsum generator for the content: