In a previous exercise, you marked up a catalogue page with the schema.org vocabulary using RDFa attributes. In this exercise, you will focus on marking up the cultural resources held by your organization—in this case, library holdings—so that they can be recognized as Products with associated Offers by search engines (analogous to products available in online stores).
Audience: Intermediate
Prerequisites: To complete this codelab, you should already be familiar with HTML, RDFa, and schema.org. A previous exercise offers a practical introduction to those concepts.
schema.org adopted the existing GoodRelations vocabulary as a way of expressing products and services that are available for sale. As it turns out, although some of the property and type names reflect a commercial bias, you can use the same vocabulary elements can to express non-commercial offers--such as the offer to lend a library resource to a patron.
In this exercise, you will turn the existing Book
entity into a
multi-typed entity by adding Product
to the type declaration. This enables the described resource to satisfy
properties expecting a value of either Book
or
Product
, and also makes a union of the properties from
those types available to further describe the resource.
Open book_step0.html
in a text
editor. You should see something like the following HTML source for the
web page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
<meta property="og:title" content="Deep work : rules for focused success in a distracted world">
<meta property="og:type" content="book">
<meta property="og:image" content="http://syndetics.com/index.aspx?isbn=9781455586691/MC.gif">
<meta property="og:description" content="One of the most valuable skills in our
economy is becoming increasingly rare. ...--">
<meta property="og:url" content="http://tpl.ca/detail.jsp?Entt=RDM3339716&R=3339716">
<meta property="og:site_name" content="Toronto Public Library">
</head>
<body vocab="http://schema.org/" typeof="Book" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
Note: In a pinch, you can use the browser development tools to
view and edit the source of the web page (CTRL-Shift-i
in
Chrome or Firefox, in the Elements or Inspector tab
respectively).
Product
to the type declaration
Add Product
to the typeof
attribute in the
<body>
element. Check the results with one or more
of the structured data testing tools.
You should see that both the Book
and Product
types are recognized. You may note, however, that Google's SDTT only
recognizes the first declared type; this is a limitation of their tool and does
not necessarily represent the results of their actual search engine.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
<meta property="og:title" content="Deep work : rules for focused success in a distracted world">
<meta property="og:type" content="book">
<meta property="og:image" content="http://syndetics.com/index.aspx?isbn=9781455586691/MC.gif">
<meta property="og:description" content="One of the most valuable skills in our
economy is becoming increasingly rare. ...--">
<meta property="og:url" content="http://tpl.ca/detail.jsp?Entt=RDM3339716&R=3339716">
<meta property="og:site_name" content="Toronto Public Library">
</head>
<body vocab="http://schema.org/" typeof="Book Product" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
Offer
Products link to their offers via the offers
property. The
expected range of the offers
property is an Offer
entity.
Declare each holding in the catalog record as a separate Offer
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
</head>
<body vocab="http://schema.org/" typeof="Book Product" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
<table>
<tbody><tr property="offers" typeof="Offer" resource="#offer1">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Agincourt">Agincourt</a></b>
</td>
<td>Book</td>
<td>Due: 2/5/2016</td>
<td>
<span title="Means not available. Item is on loan
to a customer. The person who has the item may return it by the
date specified or keep it longer if the item can be
renewed.">On loan</span>
</td>
<td>650.1 NEW</td>
</tr>
<tr property="offers" typeof="Offer" resource="#offer2">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Toronto%20Reference%20Library">Toronto Reference Library</a></b>
</td>
<td>Reference</td>
<td>Bus Sci & Tech 3rd Fl Reference Careers</td>
<td>
<span title="Means available. Item is on the
shelf at the library branch. Note: it's always a good idea
to call the branch to confirm that the item is there.">In
Library</span>
</td>
<td>650.1 NEW</td>
</tr>
</tbody></table>
---
Offer
While sellers of bibliographic items have a fairly clear mapping to
Offer
, the applicability
for libraries is a bit less obvious. To express individual items that are
available to purchase or borrow, begin by mapping your holding properties to
Offer
properties as follows:
seller
:
the attribute name is commercial, but it will be treated by schema.org
processors as the organization or individual offering the item; the fact that
it may be a loan instead of a sale can be handled as part of the Offer.
businessFunction
:
the closest match for "loan" is http://purl.org/goodrelations/v1#LeaseOut
and this overrides the default value of "for sale".
price
; if
your library does not charge for regular loans, set a price of
0.00
so that consuming applications can display a price
accordingly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
</head>
<body vocab="http://schema.org/" typeof="Book Product" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
<table>
<tbody><tr property="offers" typeof="Offer" resource="#offer1">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Agincourt"
property="seller" typeof="Library"><span property="name">Agincourt</span></a>
</b>
</td>
<td>Book
<link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut">
<meta property="price" content="0.00">
</td>
<td>Due: 2/5/2016</td>
<td>
<span title="Means not available. Item is on loan
to a customer. The person who has the item may return it by the
date specified or keep it longer if the item can be
renewed.">On loan</span>
</td>
<td>650.1 NEW</td>
</tr>
<tr property="offers" typeof="Offer" resource="#offer2">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Toronto%20Reference%20Library"
property="seller" typeof="Library"><span property="name">Toronto Reference Library</span></a>
</b>
</td>
<td>Reference
<link property="businessFunction" href="http://tpl.ca/using-the-library/borrowing-materials/#referenceitems">
<meta property="price" content="0.00">
</td>
<td>Bus Sci & Tech 3rd Fl Reference Careers</td>
<td>
<span title="Means available. Item is on the
shelf at the library branch. Note: it's always a good idea
to call the branch to confirm that the item is there.">In
Library</span>
</td>
<td>650.1 NEW</td>
</tr>
</tbody></table>
---
The item holding status best maps to the availability
property, which can take one of the following values:
<link property="availability" href="http://schema.org/InStock">
<link property="availability" href="http://schema.org/OutOfStock">
<link property="availability" href="http://schema.org/PreOrder" />
<link property="availability" href="http://schema.org/InStoreOnly">
If you have chosen to publicly display due dates in your system, you can
also use the availabilityStarts
property to provide an estimate of when the item will be available. The
property expects a date/time value in ISO8601 format following the pattern
YYYY-MM-DDThh:mm:ss
(with an optional positive or negative time
appended to indicate a time zone offset). Reminder: use the
content
attribute to supply the machine-readable counterparts for
human-readable values.
Reflect the availability of each holding in the markup of the page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
</head>
<body vocab="http://schema.org/" typeof="Book Product" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
<table>
<tbody><tr property="offers" typeof="Offer" resource="#offer1">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Agincourt"
property="seller" typeof="Library"><span property="name">Agincourt</span></a>
</b>
</td>
<td>Book
<link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut">
<meta property="price" content="0.00">
</td>
<td>Due: 2/5/2016
<link property="availability" href="http://schema.org/OutOfStock">
<meta property="availabilityStarts" href="2016-05-02">
</td>
<td>
<span title="Means not available. Item is on loan
to a customer. The person who has the item may return it by the
date specified or keep it longer if the item can be
renewed.">On loan</span>
</td>
<td>650.1 NEW</td>
</tr>
<tr property="offers" typeof="Offer" resource="#offer2">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Toronto%20Reference%20Library"
property="seller" typeof="Library"><span property="name">Toronto Reference Library</span></a>
</b>
</td>
<td>Reference
<link property="businessFunction" href="http://tpl.ca/using-the-library/borrowing-materials/#referenceitems">
<meta property="price" content="0.00">
</td>
<td>Bus Sci & Tech 3rd Fl Reference Careers
<link property="availability" href="http://schema.org/InStoreOnly">
</td>
<td>
<span title="Means available. Item is on the
shelf at the library branch. Note: it's always a good idea
to call the branch to confirm that the item is there.">In
Library</span>
</td>
<td>650.1 NEW</td>
</tr>
</tbody></table>
---
Earlier, you identified with which library each item is associated;
however, that may not be enough to identify the location of a given copy
of a resource. There are a number of other Offer
properties
that are suitable for providing more granular location information for
items:
sku
:
the attribute name stock keeping unit is overly specific, but
the intended role as an inventory identifier and physical locator for a
specific organization is a reasonable match for a call number.
serialNumber
:
as a unique identifier for a single item, serialNumber
is a
good match for barcodes.
availableAtOrFrom
:
ideally, one would use a Place
->
containedIn
-> Place
relationship to identify a
location within a given building, but in practice most sites will likely supply
a simple text value like "Stacks" or "Reference"
Add markup for the call number in the holdings page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8">
<title>Deep work : rules for focused success in a distracted world
: Newport, Cal, author.
: Book, Regular Print Book
: Toronto Public Library</title>
</head>
<body vocab="http://schema.org/" typeof="Book Product" resource="#book">
<link property="sameAs" href="http://calnewport.com/books/deep-work/">
...
<h1 property="name">Deep work : rules for focused success in a distracted world</h1>
...
<table>
<tbody><tr property="offers" typeof="Offer" resource="#offer1">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Agincourt"
property="seller" typeof="Library"><span property="name">Agincourt</span></a>
</b>
</td>
<td>Book
<link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut">
<meta property="price" content="0.00">
</td>
<td>Due: 2/5/2016
<link property="availability" href="http://schema.org/OutOfStock">
<meta property="availabilityStarts" href="2016-05-02">
</td>
<td>
<span title="Means not available. Item is on loan
to a customer. The person who has the item may return it by the
date specified or keep it longer if the item can be
renewed.">On loan</span>
</td>
<td property="sku">650.1 NEW</td>
</tr>
<tr property="offers" typeof="Offer" resource="#offer2">
<td>
<b><a href="http://tpl.ca/detail.jsp?Nr=p_cat_branch_name:Toronto%20Reference%20Library"
property="seller" typeof="Library"><span property="name">Toronto Reference Library</span></a>
</b>
</td>
<td>Reference
<link property="businessFunction" href="http://tpl.ca/using-the-library/borrowing-materials/#referenceitems">
<meta property="price" content="0.00">
</td>
<td property="availableAtOrFrom">Bus Sci & Tech 3rd Fl Reference Careers
<link property="availability" href="http://schema.org/InStoreOnly">
</td>
<td>
<span title="Means available. Item is on the
shelf at the library branch. Note: it's always a good idea
to call the branch to confirm that the item is there.">In
Library</span>
</td>
<td property="sku">650.1 NEW</td>
</tr>
</tbody></table>
---
Checkpoint: Your original HTML page should now look like book_step1.html.
In this exercise, you learned how to express library holdings using the GoodRelations agent-promise-object model, adapting commercial properties to non-commercial usage where necessary.
Next codelab: Periodicals
Dan Scott is a systems librarian at Laurentian University.
This work
is licensed under a Creative
Commons Attribution-ShareAlike 4.0 International License.