Building pages with patterns

Look at how to reuse your pattern code when building-out the example pages in your pattern libraries.

Goal

We’re going to make a couple example pages in our ecommerce-pattern-library to see how the syntax works, and what it’s capable of doing.

We’ll explores the ideas of Jekyll’s include system, passing information into them and displaying multiple copies of the same pattern—but with different text & content.

  1. Type it, type it real good

    Remember the purpose of this lesson is to type the code out yourself—build up that muscle memory in your fingers!

1 Insert banners into pages

Continue on with your ecommerce-pattern-library repository.

We’ve already got our layouts working, so now, to see how this works, let’s add banners to the top of both our index.html & our products.html

In the final version of these two pages, in your website, you may not want banners at the top—and that’s completely okay—but follow along for now to see how the system works.

From your pattern library, copy one of your banner’s includes and paste it onto your homepage.

---
layout: default
---

{% pattern banner/banner %}

Now paste that same code into your products page too!

---
layout: default
---

{% pattern banner/banner %}

Open your website up in the browser and click between the two pages—they should look exactly the same—and have a banner!

2 Add variables for banner text

The first thing I want to adjust is text on the banner—I don’t want the text to be exactly the same for every page.

  • On the homepage the banner text should say one thing
  • On the products page the banner text should say something different

In the banner pattern’s code, we’re going to provide placeholder variables—similar to our layout—that will allow us to configure parts of the banner.

Remember that this code will look radically different from your banner. We’re learning a technique right now, not directly copying and pasting.

<div class="banner embed embed-24by10 push-1-2">
  <div class="banner-content pin-lc gutter">
    <h1 class="banner-title yotta push-1-2">{{include.heading}}</h1>
    <p class="banner-info exa italic max-length-no-center">{{include.text}}</p>
    {% pattern buttons/light %}
  </div>
  <i class="banner-icon icon i-256 pin-rb"><svg><use xlink:href="/images/icons.svg#ruby"></use></svg></i>
</div>

If you refresh in the browser now you should see both of those pieces of text disappear. That’s because we haven’t actually inserted anything into the placeholder variables yet.

  1. Line C

    Notice, that instead of actually placing text in the <h1> tag I’ve replaced it with a placeholder variable.

    • They’re always surrounded by two pairs of {—that’s part of Jekyll’s template engine
    • They always start with include.—that’s part of Jekyll’s include system
    • What comes after the dot is completely made up—you decide what you want to call it
  2. Line D

    I’ve added a second placeholder variable into the paragraph too.

3 Document all the include fields

Oh documentation, how do we love thee. By documenting the two placeholder variables we just created, Patternbot will help us copy and paste the include code by adding the variables.

Open up your banner’s _config.yml file so we can document the fields.

patterns:
  banner:
    fields:
      - name: heading
        type: string
        example: "Brilliant, stunning, bright"
      - name: text
        type: string
        example: "Geological marvels: gems, crystals, diamonds, geodes and much more!"

Now if you view the code in your pattern library you can see that it shows the fields that the pattern requires, with nice documentation.

The include code snippet is now updated too, which we’ll use in the next step.

  1. Line B

    We’ve targeted the banner.html file that we want to modify.

  2. Line C

    Add a new key underneath banner called fields—you likely already have title & description there.

  3. Line D

    The fields entry is an array—a list—so each item within it must start with a -

    We can then specify the name of the field, spelled exactly the same way you wrote it in {{include.heading}} except without the brackets or the include. parts.

  4. Line E

    Next up we should specify the “type” of information the field expects, refer to the list of types we look at during our “Fried data” exercise.

  5. Line F

    Finally we should specify an example of what to write in that field. Patternbot will also use this example to display within the pattern library.

4 Re-copy & re-paste the banner includes

Now that the pattern’s include code snippet has been updated, we can re–copy-n-paste it into the two pages.

We can then use the fields, within the include code, to adjust the text so our homepage’s banner is different than our product list’s banner.

---
layout: default
---

{% pattern banner/banner heading="Brilliant, stunning, bright" text="Geological marvels: gems, crystals, diamonds, geodes and much more!" %}
---
layout: default
---

{% pattern banner/banner heading="Crystals" text="See all the sparkly, wonderful crystals from the depths of the Earth." %}

Check it out in your browser and see the banner text change between the two pages!

  1. products.html — Line E

    Adjust the text in the banner to match the page more appropriately.

5 Tweak the image

Now I’d like to adjust the image on the banner. In this situation it’s an icon—but the technique can be used for absolutely anything. So it would work just as well for an image src itself.

You can put a placeholder variable anywhere! And pass it anything you want! Numbers, text, URLs, image paths—anything!

<div class="banner embed embed-24by10 push-1-2">
  <div class="banner-content pin-lc gutter">
    <h1 class="banner-title yotta push-1-2">{{include.heading}}</h1>
    <p class="banner-info exa italic max-length-no-center">{{include.text}}</p>
    {% pattern buttons/light %}
  </div>
  <i class="banner-icon icon i-256 pin-rb"><svg><use xlink:href="/images/icons.svg#{{include.icon}}"></use></svg></i>
</div>

Don’t forget the documentation!

patterns:
  banner:
    fields:
      - name: heading
        type: string
        example: "Brilliant, stunning, bright"
      - name: text
        type: string
        example: "Geological marvels: gems, crystals, diamonds, geodes and much more!"
      - name: icon
        type: string
        example: "ruby"

Now let’s insert the icon into our homepage:

---
layout: default
---

{% pattern banner/banner icon="ruby" heading="Brilliant, stunning, bright" text="Geological marvels: gems, crystals, diamonds, geodes and much more!" %}

And a different icon for our products page.

---
layout: default
---

{% pattern banner/banner icon="crystal" heading="Crystals" text="See all the sparkly, wonderful crystals from the depths of the Earth." %}

If you aren’t using icons within your banners—no problem! See if you can figure out how to apply a similar technique to the image’s src="" attribute.

  1. _patterns/banner/banner.html — Line G

    Notice how I’ve replaced the ID of the icon with a variable: {{include.icon}}. The variables can go absolutely anywhere we want in the HTML.

    This allows me to pick the name of one of the icons and insert it into this placeholder.

  2. index.html — Line E

    Notice how there’s now an icon="" field entry within the include.

6 Tweak & hide the button

For the button, I’d like it to be visible, with different text, on the homepage and invisible on the banner page.

We can make use of Jekyll’s if-statements to hide & show content inside patterns.

i. Modify your buttons

Step one is to modify your buttons so they can support text & URLs. Here’s an example:

<a class="btn btn-light" href="{{include.url}}">{{include.text}}</a>

Don’t forget to document the button fields within config.yml

patterns:
  light:
    fields:
      - name: text
        type: string
        example: "See collection"
      - name: url
        type: url
        example: "/crystals/"

ii. Modify the banner

Next up we’ll modify the banner a few different ways:

  1. We’ll add fields for the button’s URL & the button’s text
  2. Then we’ll pass the information from the banner into the button’s include
  3. Then we’ll add an if-statement to hide the button if the URL is missing

First we’ll update the banner’s documentation.

patterns:
  banner:
    fields:
      ⋮
      - name: button_text
        type: string
        example: "See collection"
        required: false
      - name: button_url
        type: url
        example: "/crystals/"
        required: false

Now update the banner’s HTML file.

<div class="banner embed embed-24by10 push-1-2">
  <div class="banner-content pin-lc gutter">
    <h1 class="banner-title yotta push-1-2">{{include.heading}}</h1>
    <p class="banner-info exa italic max-length-no-center">{{include.text}}</p>
    {% if include.button_url %}
      {% pattern buttons/light url=include.button_url text=include.button_text %}
    {% endif %}
  </div>
  <i class="banner-icon icon i-256 pin-rb"><svg><use xlink:href="/images/icons.svg#{{include.icon}}"></use></svg></i>
</div>

iii. Modify the page

Now if we edit the code within each page we can change the button’s text or hide it.

---
layout: default
---

{% pattern banner/banner button_text="See collection" button_url="/crystals/" heading="Brilliant, stunning, bright" text="Geological marvels: gems, crystals, diamonds, geodes and much more!" icon="ruby" %}

I’ve only done this on the homepage—and so my homepage has a button.

But the product page doesn’t have a button because those fields weren’t set in the include code.

  1. _patterns/banner/config.yml — Line H

    We can specify that fields are not required—this really just just for documentation purposes and shows in the pattern library.

  2. _patterns/banner/banner.html — Line E

    The if-statement is part of Jekyll/Liquid (Jekyll’s templating language). If we were to convert that to English, it would say this:

    “When there is something inside the variable include.button_url proceed to the next line.”

    By having this if-statement, if we were to not specify the button_url in the banner’s include code, then the button just wouldn’t show on the page.

  3. _patterns/banner/banner.html — Line F

    Now we pass the fields we defined for our banner, to adjust the button, into the button include itself.

    Notice how we’re saying: url=include.button_url:

    • url is the name of the field our buttons support
    • include.button_url is the placeholder from our banner itself
  4. _patterns/banner/banner.html — Line G

    Don’t forget to close the if-statement or Jekyll won’t render your page.

  5. index.html — Line E

    See how I’ve added the button_text & button_url fields to the banner include.

7 Highlight the navigation

The final thing I want to show you is passing information from the page itself into an include without changing the include code snippet.

In Jekyll each HTML file is a “page” which means that we always have access to a page variable.

We can store information at the top of each page, like we’re doing with the layout and retrieve it later to do something with.

So, let’s open up our products page, and add a new page variable to the top, like this:

---
layout: default
highlight_nav: crystals
---

{% pattern banner/banner heading="Crystals" text="See all the sparkly, wonderful crystals from the depths of the Earth." icon="crystal" %}

Now if I pop into my header pattern I can use more Jekyll if-statements to highlight the correct navigation item.

⋮
  <nav class="nav pad-t-1-2 pad-b-1-2 giga" role="navigation" id="nav">
    <ul class="list-group-inline push-0">
      <li class="gutter-1-2 {% if page.highlight_nav == 'crystals' %}current{% endif %}"><a href="/crystals/">Crystals</a></li>
      <li class="gutter-1-2 {% if page.highlight_nav == 'diamonds' %}current{% endif %}"><a href="#">Diamonds</a></li>
      <li class="gutter-1-2 {% if page.highlight_nav == 'gems' %}current{% endif %}"><a href="#">Gems</a></li>
    </ul>
  </nav>
⋮

Now if I refresh in the browser I see this:

My homepage doesn’t have any navigation highlighted.

But the crystals page is highlighted!

  1. products.html — Line C

    I made up a new variable here called highlight_nav, then I set it to the word crystals—all this stuff is made-up, those things don’t exist as part of Jekyll.

  2. _patterns/header/header.html — Lines D–F

    It’s difficult to clearly see, but there are if-statements within each class="" attribute.

    The if-statement is checking to see what the value of the highlight_nav variable is and when it matches one of the strings, the if-statement will execute and Jekyll will output a new class: .current