15.00 One page per book
Table of contents
- Build the book template
- Review the pages
- Do more later: Add more stores
- Do more later 2: schema.org data
- Do more later 3: Conditionals
- What you’ve learned
This article tells you how to create one page for each book.
The portfolio page is looking great. But if you click through on one of the covers, you get an empty page.
You need to write code that automatically generates one page per book. If you look back to the Amazon example, earlier, you’ve done the list page and you’re now writing the single-book show page.
Open the file in _layouts called book_template.html, and make it use the template you’ve used for all the other pages so far by pasting the following right at the top of the file. Delete the TODO comment in the process.
---
layout: default
---
Learn more later
- You are using an adapted Jekyll plugin to generate all the pages-per-book. The authors of the plugin have written docs which you can read later, though we have edited their plugin substantially to tailor it for Day of Code. Within your codebase, review
_config.yml
, where you’ll see the configuration linepage_gen-dirs: true
, and you’ll see the edited plugin code itself in the_plugins/data_page_generator.rb
, as instructed in their docs.
Now if you click through from a cover on the portfolio page, you’ll not get a missing link, but since your book_template.html page is empty, there’s not much to see:
Let’s add some code.
Build the book template
The code at _plugins/data_page_generator.rb
runs when you start the Jekyll server. It uses Ruby programming to iterate through the data source and create multiple HTML files using the book_template.html
page as a template. Jekyll provides the page
variable to access the JSON data store in _data/processed_books.json. The data structure in the JSON file is like this:
1
2
3
4
5
6
7
8
9
10
[
{
"title": "Solid State Physics",
"isbn": "9781466512320",
"amz_uk_url": "http://www.amazon.co.uk/gp/product/1466512326",
"image_path": "9781466512320.jpg",
"author": "Javier E. Hasbun and Trinanjan Datta"
<!-- etc -->
}
]
You get data out of that structure by using the keys: page.title
, page.isbn
, page.author
and so on.
Copy and paste the following code into book_template.html underneath the frontmatter (the ---
bit).
<header class="portfolio-header">
<h1 class="secondary">• Coming soon •</h1>
</header>
<main class="portfolio-page">
<figure>
<img class="cover--large" src="/images/covers/{{page.isbn}}.jpg" alt="Cover of ISBN {{page.isbn}} {{page.title}}"/>
</figure>
<section>
<p class="metadata">
{{page.series}}
{{page.series_number}}
</p>
<h1>{{page.title}}</h1>
<p>{{page.subtitle}}</p>
<h2>{{page.author}}</h2>
<p>{{page.blurb}}</p>
{% if page.reviews.size > 0 %}
<hr/>
<p><span class="massive">“</span>{{page.reviews}}</p>
{% endif %}
<ul class="metadata">
<li>
<span>ISBN</span>
{{page.isbn}}
</li>
{% if page.pub_date.size > 0 %}
<li>
<span>Published</span>
{{page.pub_date | date: "%d %b %Y"}}
</li>
{% endif %}
{% if page.gbp_price%}
<li>
<span>Price</span>
${{ page.usd_price }} / £{{ page.gbp_price }}
</li>
{% endif %}
{% if page.page_count.size > 0 %}
<li>
<span>Pages</span>
{{page.page_count}}
</li>
{% endif %}
{% if page.format.size > 0 %}
<li>
<span>Format</span>
{{ page.format }}
</li>
{% endif %}
</ul>
<p class="metadata">{{page.subject}}</p>
<h3>Buy {{page.title}}</h3>
<ul class="shops">
<li>
<a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.wordery_url }}">Wordery</a>
</li>
</ul>
</section>
</main>
Review the pages
Click through from any cover on the portfolio page and you should now see your book data, one page per book.
Learn more later
- You can see the JSON data created from ONIX in _data/processed_books.json.
- You can see the code that created it in the lib folder.
- Track down the element and class names referenced here, such as
metadata
andportfolio-header
, in the main.css file, to see how they’re defined.
Do more later: Add more stores
See if you can add more links to the page to more retailers. The code below will help you.
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.waterstones_url }}">Waterstones </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.foyles_url }}">Foyles </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.book_depository_url }}">Book Depository</a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.wh_smith_url }}">WHSmith </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.blackwells_url }}">Blackwells </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.oxfam_url }}">Oxfam </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_uk_url }}">Amazon UK </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_us_url }}">Amazon US </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_ca_url }}">Amazon CA </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_de_url }}">Amazon DE </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_br_url }}">Amazon BR </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_mx_url }}">Amazon MX </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_fr_url }}">Amazon FR </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_es_url }}">Amazon ES </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_jp_url }}">Amazon JP </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.amz_in_url }}">Amazon IN </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.kobo_url }}">Kobo </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.infini-beam_url }}">Infinibeam </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.google_play_url }}">Google Play </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.hive_url }}">Hive </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.booktopia_url }}">Booktopia </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.barnes_and_noble_url }}">Barnes & Noble </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.worldcat_url }}">Worldcat </a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.books_a_million_url }}">Books A Million</a></li>
<li><a class="bookstore" rel="noreferrer" target="_blank" href="{{ page.book_finder_url }}">Book Finder </a></li>
Click through to see if some of the retailers have your book in stock.
Do more later 2: schema.org data
You can improve the SEO of your webpage by including structured data as recommended by Schema.org. Below is some code you can add.
<!-- add to the top of book_template.html, underneath the front matter -->
{%
include structuredData.html
title = page.title
author = page.author
isbn = page.isbn
pub_date = page.pub_date
usd_price = page.usd_price
gbp_price = page.gbp_price
url = page.url
%}
<!-- Add to a new file called structuredData.html, in the _includes folder -->
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"Book",
"@id": "http://silveroakpress.com/{{ include.isbn }}",
"name" : "{{ include.title }}",
"author": {
"@type":"Person",
"name":"{{ include.author }}"
},
"url" : "{{ include.url }}",
"workExample" : [{
"@type": "Book",
"@id": "http://silveroakpress.com/{{ include.isbn }}",
"isbn": "{{ include.isbn }}",
"datePublished": "{{ include.pub_date }}",
"bookFormat": "http://schema.org/Paperback",
"potentialAction":{
"@type":"ReadAction",
"target":
{
"@type":"EntryPoint",
"urlTemplate":"http://www.barnesandnoble.com/s/{{include.isbn}}",
"actionPlatform":[
"http://schema.org/DesktopWebPlatform",
"http://schema.org/IOSPlatform",
"http://schema.org/AndroidPlatform"
]
},
"expectsAcceptanceOf":{
"@type":"Offer",
"Price":"{{include.usd_price}}",
"priceCurrency":"USD",
"eligibleRegion" : {
"@type":"Country",
"name":"US"
},
"availability": "http://schema.org/InStock"
}
}
}]
}
</script>
Then look in the Inspector to see the results.
Do more later 3: Conditionals
Amend the HTML code in book_template.html so that the banner at the top of the page changes according to the pub date:
{% assign todays_date = "now" | date: "%Y%m%d" %}
{% if page.pub_date_iso > todays_date %}
<h1 class="secondary">• Coming soon •</h1>
{% else %}
<h1 class="secondary">• Recently published •</h1>
{% endif %}
What you’ve learned
- You can use other people’s open source code to perform certain tasks, such as you’ve done here to generate the static pages
- You call methods on the
page
variable, which are named using the keys in the JSON data store