We might have wondered numerous times if there is a way we could travel back in time to change what had happened in life. Well, as fictional as it sounds, you are going to learn a method to perform this travel when it comes to digitized files! Yes, you read that right; this chapter is going to introduce you to a system that makes this possible. We will begin by giving you a solid conceptual understanding about version control with Git.
It's time to code the tastiest part of our restaurant website (sorry, that was a terrible pun). For our menu page, we'll use a three-column layout combined with some additional modal popups for our featured dishes. The following is a preview of what the page will look like:
Hyper-Text Markup Language, HTML, has been shaping the Internet in the last few decades. It defines how content is structured in web and the linkage between related pages. HTML keeps evolving from version 2 to HTML 4.1, and later XHTML 1.1. Thanks to those web applications and social network applications, HTML is now on the way to HTML5.
Did you find any droids? No, sir. If there were any on board, they must also have jettisoned. Send a scanning crew on board. I want every part of this ship checked. Yes, sir. I sense something...a presence I haven't felt since... Get me a scanning crew in here on the double. I want every part of this ship checked! Boy, it's lucky you had these compartments. I use them for smuggling.
As you can see, I've kept the layout pretty minimal, which is my style and will transfer well to the mobile view. Let's start by going over the page header style that is used for each section of the menu.
For each section of the menu, I'm using a <h2>
tag with the Bootstrap .page-header
class to make it stand out. Here's what the code looks like:
<h2 class="page-header">Appetizers</h2>
Since we don't want our site to look like a generic Bootstrap project, I'm going to customize the look and feel of the page-header
component:
.page-header { padding-bottom: (@padding * 1.5); margin: @margin 0; border-bottom: (@border-size * 5) @border-type @border-color; }
Open the CSS3 matching game folder as our working directory.
Download a background image from the following URL (we will use it as the background of the pop up):
Place the image in the images
folder.
Open index.html
into any text editor.
We will need a font for the game over pop up. Add the following font embedding CSS into the head
section:
<link href="http://fonts.googleapis.com/css?family=Orbitron:400,700" rel="stylesheet" type="text/css" >
Before the game
section, we add a div
named timer
to show the elapsed playing time. In addition, we add a new popup
section containing the HTML markup of the pop-up dialog:
<div id="timer"> Elapsed time: <span id="elapsed-time">00:00</span> </div> <section id="game"> <div id="cards"> <div class="card"> <div class="face front"></div> <div class="face back"></div> </div> <!-- .card --> </div> <!-- #cards --> </section> <!-- #game --> <section id="popup" class="hide"> <div id="popup-bg"> </div> <div id="popup-box"> <div id="popup-box-content"> <h1>You Won!</h1> <p>Your Score:</p> <p><span class='score'>13</span></p> </div> </div> </section>
We will now move on to the style sheet. As it is just for styling and not related to our logic yet, we can simply copy the matchgame.css
file from matching_game_with_game_over
in the code example bundle.
It is time to edit the game logic part. Open the html5games.matchgame.js
file in an editor.
Did you find any droids? No, sir. If there were any on board, they must also have jettisoned. Send a scanning crew on board. I want every part of this ship checked. Yes, sir. I sense something...a presence I haven't felt since... Get me a scanning crew in here on the double. I want every part of this ship checked!
As you can see, I've inserted some additional bottom padding, increased the vertical margin around the title, and beefed up the bottom border to give it a unique look. The fatter border also fits in better with the overall look and feel of the restaurant site.
Before we jump into the menu items, let's quickly talk about the page layout. Make sure you wrap the page in the page-body
class that you created for the About page. Each section of the menu has a col-lg-12
for the section title, and after that is a three-column layout that uses the col-lg-4
grid classes. In this case, I'm choosing a symmetrical layout as it makes sense for a menu. Here's some sample layout code:
<div class="row"> <div class="col-lg-12"> <h2 class="page-header">Appetizers</h2> </div> </div> <div class="row"> <div class="col-lg-4"> <h3>Item Name</h3> <p>Item description goes here.</p> <p class="price">$5</p> </div> <div class="col-lg-4"> <h3>Item Name</h3> <p>Item description goes here.</p> <p class="price">$5</p> </div> <div class="col-lg-4"> <h3>Item Name</h3> <p>Item description goes here.</p> <p class="price">$5</p> </div> </div>
The grid here should be pretty straightforward. Let's talk a bit more about the menu items. I'm using an <h3>
tag for the title of each menu item. This allows them to stand out and will help optimize our food titles for searching. You'll notice a new class named .price
that is attached to a <p>
tag and wrapped around a dollar price. I've created it because I want the price to stand out but don't want to use a header tag here. This is purely for readability of the menu and has nothing to do with searching, so a class is a better call:
.price { color: @red1; font-weight: 700; }
/css: This directory will contain all our custom CSS and the Bootstrap framework CSS files.
/fonts: This directory will be for holding any web fonts or icon web fonts. The directory isn't totally necessary, but I always include Font Awesome with all my projects so that I have an icon library to pull from.
/img: This directory will hold all the images for the project. For the boilerplate, we won't actually need any images, but we're setting this up for future projects too.
/js: This directory will hold any custom libraries and the Bootstrap framework's JavaScript file.
/partial: This directory will hold the pieces of code that we want to reuse in our templates, such as our header and footer.
_data.json: This is the file in which we will define any metadata that we want to use in our template. An example of this could be the page title for each web page.
As you can see, I'm using the @red1
color variable again and I've upped font-weight
to bold, or 700
. This will allow the price to stand out easily when read.
Near a few of the menu items, you'll notice a View link. This link will launch a modal to show an image of the food item. You could also add more information about the food item here if you like. For the purposes of this demo, I've added this modal to only a couple of the items, but you might want to add it for all food items on your restaurant website. Here's what our modal will look like once launched:
Now let's take a look at the code that is required to launch our food modal:
<div class="col-lg-4"> <h3>Green Salad</h3> <p>A great healthy start to your meal. <a href="#" data-toggle="modal" data-target="#salad-modal">View</a></p> <p class="price">$9</p> </div>
The code here is exactly the same, with only an addition of the View link that will trigger the modal:
<a href="#" data-toggle="modal" data-target="#salad-modal">View</a>
Now that we've set up the trigger, let's create the actual modal code. Here it is for review:
<!-- salad modal //--> <div class="modal fade" id="salad-modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">Appetizer</h4> </div> <div class="modal-body"> <div class="text-center"> <p><img src="img/salad.jpg" width="400" height="267" alt="Salad"></p> <h2>Green Salad</h2> <p>A great healthy start to your meal.</p> <p class="price">$9</p> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
You'll notice that this modal code is a bit simpler than the reservations one. That's for a couple of reasons. Firstly, we could be reusing this code on a number of items, so we should try and keep it simple if we can. Secondly, I don't want this to look like a generic Bootstrap modal. I want it to look like a nicer popup geared for a restaurant. So, by removing some of the default parts that aren't needed, we can provide a more customized look and feel. Let's go over what has changed:
<div class="modal-body"> <div class="text-center"> <p><img src="img/salad.jpg" width="400" height="267" alt="Salad"></p> <h2>Green Salad</h2> <p>A great healthy start to your meal.</p> <p class="price">$9</p> </div> </div>
First, you'll notice that I've inserted an image. The width is set to 400 pixels, which is a bit smaller than the overall width of our modal. Make sure you keep your image size within that limit. If you'd like to use a larger image, increase the size of your modal. You may even want to experiment with making your modal full screen.
The endsWith()
polyfill is described in detail at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith. String.endsWith()
is part of ES6 but can be polyfilled easily for pre-ES6 environments.
The other big difference with this modal is that I have deleted the .modal-footer
section. Remember that with Bootstrap, some of these parts are optional. Just because they are in the core code doesn't mean you can't experiment with them. In the case of the footer, the default content is a submit or cancel button. This doesn't make a ton of sense in the context of how we are using the modal, so just delete that part. We still have the Close button in the header of the modal, or the user can click outside the modal window to close it. Again, this is another example of customizing a Bootstrap component to make it your own. I encourage you to push the design of your modals even further.
You'll notice that on the menu, I've added a second modal under the Sandwich heading. Here's the code for that modal:
<!-- sandwich modal //--> <div class="modal fade" id="sandwich-modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">Sandwiches</h4> </div> <div class="modal-body"> <div class="center"> <p><img src="img/sandwich.jpg" width="400" height="274" alt="Sandwich"></p> <h2>Veggie Sandwich</h2> <p>tomatoes, lettuce, cheese, salsa.</p> <p class="price">$12</p> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
In your own restaurant website, if you do go by the route of the popup for every menu item, you may want to consider a cleaner approach for all your modal code. Currently, you need to create a new instance of the modal HTML for each food item. This could become quite long if you have a big menu. A better technique would be to create a template for the modal into which you can load your values. One way you can do this is with a JavaScript MVC library, such as Backbone or Angular. They will allow you to create a view for that page, with a template (such as a Handlebar template) that you can then load in the different values. This book isn't about JavaScript MVCs, so I won't go further into that subject, but this is just something to keep in mind as you build your production-ready restaurant website. The way that I've shown you will work for a large menu, but using an MVC may be a cleaner solution.
Condition |
Output |
---|---|
|
false |
|
false |
|
false |
|
false |
|
false |
|
false |
|
false |
|
false |
This concludes the Menu section. Before we move on to our last page, the Contact page, here's all the code for the menu:
<div class="container"> <!-- page body //--> <div class="page-body"> <!-- appetizers //--> <div class="row"> <div class="col-lg-12"> <h2 class="page-header">Appetizers</h2> </div> </div> <div class="row"> <div class="col-lg-4"> <h3>Garlic Bread</h3> <p>Delicious pan fried bread with olive oil.</p> <p class="price">$7</p> </div> <div class="col-lg-4"> <h3>Chicken Wings</h3> <p>One dozen wings, come in hot or bbq flavour.</p> <p class="price">$12</p> </div> <div class="col-lg-4"> <h3>Nachos</h3> <p>Great for sharing with friends. Tons of cheese and all the toppings.</p> <p class="price">$14</p> </div> </div> <div class="row"> <div class="col-lg-4"> <h3>Yam Fries</h3> <p>Servied with garlic mayo for dipping.</p> <p class="price">$8</p> </div> <div class="col-lg-4"> <h3>Green Salad</h3> <p>A great healthy start to your meal. <a href="#" data-toggle="modal" data-target="#salad-modal">View</a></p> <p class="price">$9</p> </div> <div class="col-lg-4"> <h3>Chips & Salsa</h3> <p>Crisp tortilla chips and dip.</p> <p class="price">$6</p> </div> </div> <!-- sandwiches //--> <div class="row"> <div class="col-lg-12"> <h2 class="page-header">Sandwiches <small>All sandwiches are served with yam fries or salad.</small></h2> </div> </div> <div class="row"> <div class="col-lg-4"> <h3>Veggie</h3> <p>tomatoes, lettuce, cheese, salsa. <a href="#" data-toggle="modal" data-target="#sandwich-modal">View</a></p> <p class="price">$12</p> </div> <div class="col-lg-4"> <h3>Turkey</h3> <p>turkey, lettuce, cranberry, cheese, tomato.</p> <p class="price">$14</p> </div> <div class="col-lg-4"> <h3>Roast Beef</h3> <p>roast beef, mustard, pickles.</p> <p class="price">$14</p> </div> </div> <!-- burgers //--> <div class="row"> <div class="col-lg-12"> <h2 class="page-header">Burgers <small>All burgers are served with yam fries or salad.</small></h2> </div> <div class="row"> <div class="col-lg-4"> <h3>Beef</h3> <p>tomatoes, lettuce, cheese, pickles.</p> <p class="price">$16</p> </div> <div class="col-lg-4"> <h3>Chicken</h3> <p>lettuce, cucumber, pickles.</p> <p class="price">$16</p> </div> <div class="col-lg-4"> <h3>Veggie</h3> <p>lettuce, mushrooms, salsa.</p> <p class="price">$14</p> </div> </div> </div> </div> </div> <%- partial("partial/_reservation-modal") %> <!-- salad modal //--> <div class="modal fade" id="salad-modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">Appetizer</h4> </div> <div class="modal-body"> <div class="text-center"> <p><img src="img/salad.jpg" width="400" height="267" alt="Salad"></p> <h2>Green Salad</h2> <p>A great healthy start to your meal.</p> <p class="price">$9</p> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> <!-- sandwich modal //--> <div class="modal fade" id="sandwich-modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">Sandwiches</h4> </div> <div class="modal-body"> <div class="text-center"> <p><img src="img/sandwich.jpg" width="400" height="274" alt="Sandwich"></p> <h2>Veggie Sandwich</h2> <p>tomatoes, lettuce, cheese, salsa.</p> <p class="price">$12</p> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->