11.30 DRY up your code

Table of contents

Edit this page

This article explains how to keep your code well-organised so it's maintainable.

The Portfolio page is looking a bit nicer. Presumably the index page is also looking better, too, now you have all those styles?

Go to your browser, and delete /portfolio/ from the address bar, so the URL goes back to being localhost:4000. The index.html page gets served by default, though you can also type localhost:4000/index or localhost:4000/index.html.

The index page not showing any useful styling changes

Oh. It looks the same. Why aren’t the styles applied to this page?

Troubleshoot

  • Before you scroll down to see the answer, try to think why the styles aren’t appearing on this page. Look at index.html in your text editor, and see if you can see what’s missing. Line 3 is a clue.

It’s because you haven’t added the stylesheet link in to the index.html page. Did you figure that out correctly? If not, next time, consider comparing a file that works with one that doesn’t.

To add the stylesheet link, copy the styles and font links (all the contents of the <head> </head> tags) from portfolio.html and paste into the same place in index.html.

A gif showing the user putting the links in the right place

Refresh your browser page. What a difference some CSS makes!

Now the browser is showing a nicely styled page

CSS classes

The header on the index page has a flowery pattern, unlike the one on the portfolio page, because its HTML has a different structure to that on the portfolio page.

The header in portfolio.html has an HTML tag called <header>:

  <header>
    <h1>Portfolio</h1>
  </header>

The HTML tag <header> is defined in the CSS like this:

  header {
    ...
    background-color: #03a9f4;
  }

That’s why the portfolio page looks like this: the colour #03a9f4 is blue. Screeshot of the portfolio page showing the header is blue

The <header> tag in index.html, however, has a class, primary-header:

  <header class="primary-header">
    <h1>Silver Oak Press</h1>
    <aside>New fiction, discovered</aside>
  </header>

That class is defined in the CSS like this:

  .primary-header {
    background-image: url(/images/bright-flowers.jpg);
    background-size: 100%;
  }

Which is what you see in the browser, too:

Screenshot of the index page with a nice bright banner image

Notice too that primary-header has a higher priority than header, so the bright-flowers instruction overrides the blue instruction. This is because of the CSS specificity rules, which determine which style “wins”. Read more about that later.

This is how CSS works. The selectors in the CSS match the elements in the HTML. More specific selectors override more generic ones. This is what is meant by the Cascade in Cascading Style Sheets.

Additionally, HTML classes get referenced in CSS with a preceeding ., HTML ids get referenced with a #, and HTML tags get referenced as their name, with no < >.

  • <header class="primary-header"> gets referenced in CSS as .primary-header
  • <header id="primary-header"> gets referenced in CSS as #primary-header
  • <header> gets referenced in CSS as header

This mechanism means you can define the styles once in CSS, and use them multiple times in the HTML. Programmers call this “keeping your code DRY”, where DRY stands for “Don’t Repeat Yourself”.

But when you copied and pasted the head styles from portfolio.html to index.html, you did the opposite of DRY. You duplicated code, and now you have got two pieces of identical code to maintain. What if you want to change font again? What if you have more pages? Duplication is bad because it makes code harder to maintain, edit and change. So you’re going to use a Jekyll template to put the shared code in one place, then insert the unique code for each page.

Create a template

Open the folder called _layouts. It currently contains one file, called book_template.html. Within this _layouts folder, create another file called default.html.

Copy all the lines in index.html and paste them into default.html.

Gif showing the user setting up the default layout

In default.html, delete the index-specific code between the <body> and </body> tags:

Gif showing the user setting up the default layout

Save the file. Next, type the following in between the <body> and </body> tags:

  {{ content }}

Save the file. The unique content on each page that uses the template will go where it says content.

Your template is complete, and now you’re going to use your template in your index and portfolio pages.

Apply the template to the index page

Go to the index.html page in your text editor, and delete all the code except for the bit between the <body> and </body> tags, so it looks like this:

Showing the user setting up the index page

Save your file and refresh your browser. Oh dear: you’ve lost your styles, which you can see if you open the Inspector.

Shows the styles have dropped

Let’s get them back again.

At the top of the index.html file in your text editor, paste in the following code, making sure there is no space or tabs before each line and they are flush to the left, and include both the --- lines:

---
layout: default
---

Save your file and refresh your browser. Great: the styles are back again:

Shows the styles are back

And do you see in your brower’s inspector that the browser has reconstituted the whole HTML file, using the template’s <head> code and the index page’s content?

Troubleshoot

  • If the styles are not back:
  • Is default.html within the _layouts folder?
  • Have you saved your new default.html page?
  • If that doesn’t fix it, look at the server log in your Terminal for clues.

See if you can do the same for the portfolio.html page. The instructions follow below, but see if you can do it yourself, without looking.


Apply the template to the portfolio page

Go to the portfolio.html page in your text editor and delete all the code except for the bit between the <body> and </body> tags.

Save your file and refresh your browser. This drops your styles, like last time. So you need to use your template, which includes the styles reference.

At the top of the file, paste in the following code, making sure there is no space or tabs before each line and they are flush to the left:

---
layout: default
---

Here’s the whole process:

Gif showing all the editing needed to set up the portfolio page with a layout, as previously described

Save your file and refresh your browser. Great: the styles are back again.

Do more later 1: choose your own background

If you have time now, or later after the Day of Code, choose your own background for the home page banner and amend the CSS to use it. There are some in the images folder, and the Unsplash website is a useful resource. Find an image you like and get its link, making sure it’s the image file not the website page URL by right-mouse-selecting “Copy Image address”, not “Copy link address”, and reference it in your CSS:

  .primary-header {
    background-image: url(https://images.unsplash.com/photo-1572467313081-e5451bcd2131);
    background-size: 100%;
  }

Even better, download the image to your assets/images/ folder and reference this file in your CSS like this:

  .primary-header {
    background-image: url(/images/bright-flowers.jpg);
    background-size: 100%;
  }

Refresh the page to see the effect:

Browser with a new header image

You might want to add background-position: 50% into your CSS definition to position the image better.

Do more later 2: Google analytics

  • Google Analytics code is a good example of code that should run on every page, but should only appear once in your codebase. If you have a Google account, follow their instructions to get your analytics code, and paste it into the <head> of your default.html like this:
<!doctype html>
<html lang="en">
  <head>
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-77263xxx-4"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag() { dataLayer.push(arguments); }
    gtag('js', new Date());
    gtag('config', 'UA-77263xxx-4');
  </script>
  ...
  </head>
  ...
</html>

What you’ve learned

  • Programmers like to keep code DRY so there’s less to maintain.