Note: Parts of this recipe are already using new schema.org elements from the upcoming integration of GoodRelations elements into schema.org.
This page describes how you can mark-up book item pages using GoodRelations or schema.org. The full background of modeling such data is given towards the end of the document. For a quick start, you need to understand the following:
div typeof="schema:Book gr:ProductOrServiceModel" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
<link rel="schema:author" resource="http://dbpedia.org/resource/Karl_May" />
link rel="schema:bookFormat" resource="http://schema.org/Hardcover" />
<span property="schema:isbn">1234567890123</span>
ISBN: <
...other properties from schema:Book or gr:SomeItems ...</div>
div itemscope itemtype="http://schema.org/Book" itemid="#product">
<link itemprop="additionalType" href="http://schema.org/ProductModel" />
<span itemprop="name">HTML for Idiots</span>
<link itemprop="author" resource="http://dbpedia.org/resource/Karl_May" />Karl May
Author: <link itemprop="bookFormat" resource="http://schema.org/Hardcover" />Hardcover
Format: <span itemprop="isbn">1234567890123</span>
ISBN: <div> </
Note: In theory, the itemtype and the additionalType values could be swapped, but not all schema.org parsers will consider the additionalType property, so put the more important information into the main itemtype. Also, this influences which properties you can attach. Since we want to use properties from http://schema.org/Book, we have to use this type for the main itemtype.
div typeof="gr:Offering" about="#offer">
<div property="gr:name">HTML for Idiots - Used Copy, $ 9.99</div>
<link rel="gr:hasBusinessFunction" resource="http://purl.org/goodrelations/v1#Sell" />
<div rel="gr:hasPriceSpecification">
<div typeof="gr:UnitPriceSpecification">Price:
<span property="gr:hasCurrency" content="USD">$</span>
<span property="gr:hasCurrencyValue" datatype="xsd:float">9.99</span>
<div property="gr:validThrough" datatype="xsd:dateTime"
< content="2012-11-30T23:59:59Z"></div>
div>
</div>
</div rel="gr:includes">
<div typeof="schema:Book gr:Individual" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
<link rel="schema:author" resource="http://dbpedia.org/resource/Karl_May" />
link rel="schema:bookFormat" resource="http://schema.org/Hardcover" />
<span property="schema:isbn">1234567890123</span>
ISBN: <
...other properties from schema:Book or gr:SomeItems ...div property="gr:condition>used</div>
Condition: < </div>
</div>
</div>
div itemscope itemtype="http://schema.org/Offer" itemid="#offer">
<div itemprop="name">HTML for Idiots - Used Copy, $ 9.99</div>
<link itemprop="businessFunction"
< href="http://purl.org/goodrelations/v1#Sell" />
div itemscope itemprop="priceSpecification"
< itemtype="http://schema.org/UnitPriceSpecification">Price:
meta itemprop="priceCurrency" content="USD">$
<span itemprop="price">9.99</span>
<meta itemprop="validThrough" content="2012-11-30T23:59:59Z" />
<div>
</div itemprop="itemOffered" itemscope itemtype="http://schema.org/Book" itemid="#product">
<link itemprop="additionalType" href="http://schema.org/IndividualProduct" />
<span itemprop="name">HTML for Idiots</span>
<link itemprop="author" resource="http://dbpedia.org/resource/Karl_May" />Karl May
Author: <link itemprop="bookFormat" resource="http://schema.org/Hardcover" />Hardcover
Format: <span itemprop="isbn">1234567890123</span>
ISBN: <div> </
Note: In theory, the itemtype and the additionalType values could be swapped, but not all schema.org parsers will consider the additionalType property, so put the more important information into the main itemtype. Also, this influences which properties you can attach. Since we want to use properties from http://schema.org/Book, we have to use this type for the main itemtype.
div typeof="gr:Offering" about="#offer">
<div property="gr:name">HTML for Idiots - $ 19.99 per copy</div>
<link rel="gr:hasBusinessFunction" resource="http://purl.org/goodrelations/v1#Sell" />
<div rel="gr:hasPriceSpecification">
<div typeof="gr:UnitPriceSpecification">Price:
<span property="gr:hasCurrency" content="USD">$</span>
<span property="gr:hasCurrencyValue" datatype="xsd:float">19.99</span>
<div property="gr:validThrough" datatype="xsd:dateTime"
< content="2012-11-30T23:59:59Z"></div>
div>
</div>
</div rel="gr:includes">
<div typeof="schema:Book gr:SomeItems" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
<link rel="schema:author" resource="http://dbpedia.org/resource/Karl_May" />
link rel="schema:bookFormat" resource="http://schema.org/Hardcover" />
<span property="schema:isbn">1234567890123</span>
ISBN: <
...other properties from schema:Book or gr:SomeItems ...div property="gr:condition>new</div>
Condition: < </div>
</div>
</div>
div itemscope itemtype="http://schema.org/Offer" itemid="#offer">
<div itemprop="name">HTML for Idiots - $ 19.99 per copy</div>
<link itemprop="businessFunction"
< href="http://purl.org/goodrelations/v1#Sell" />
div itemscope itemprop="priceSpecification"
< itemtype="http://schema.org/UnitPriceSpecification">Price:
meta itemprop="priceCurrency" content="USD">$
<span itemprop="price">19.99</span>
<meta itemprop="validThrough" content="2012-11-30T23:59:59Z" />
<div>
</div itemprop="itemOffered itemscope itemtype="http://schema.org/Book" itemid="#product">
<link itemprop="additionalType" href="http://schema.org/SomeProducts" />
<span itemprop="name">HTML for Idiots</span>
<link itemprop="author" resource="http://dbpedia.org/resource/Karl_May" />Karl May
Author: <link itemprop="bookFormat" resource="http://schema.org/Hardcover" />Hardcover
Format: <span itemprop="isbn">1234567890123</span>
ISBN: <div> </
Note: In theory, the itemtype and the additionalType values could be swapped, but not all schema.org parsers will consider the additionalType property, so put the more important information into the main itemtype. Also, this influences which properties you can attach. Since we want to use properties from http://schema.org/Book, we have to use this type for the main itemtype.
When we expose book data on the Web so that search engines and other computer-based services can process it, we have to be clear about the type of objects we are speaking, since the colloquial term "book" may represent two different types of objects:
vs.
So for instance, a publisher or a catalog with bibliographic data typically speaks about book titles, while an eBay page or online bookstore speaks about book copies.
Before you can markup book pages with GoodRelations, you have to be clear whether you are talking about book copies or book titles.
In fact, one can even it a third distinction, which is about disambiguating book titles into abstract pieces of creative work (e.g. "The Bible") vs. a particular manifestation thereof, like the King James Version of the Bible. We will not cover this in more detail in here, since for GoodRelations, both meanings of book titles can be treated using the same patterns.
GoodRelations disambiguates the broad notion of a product into three different types of entities:
1. A real product, like my laptop, my car with this VIN and mileage, a particular item on an eBay auction. The important thing is that all information said about that product relates to the same entity.
The respective GoodRelations class is gr:Individual. (The upcoming schema.org type is http://schema.org/IndividualProduct as a subtype of http://schema.org/Product.)
Examples are the items on eBay auction pages or used cars.
2. A product model, i.e. a datasheet, like "Nikon T90", "iPod Nano 16 GB", or similar. This is basically the abstract definition of product features for mass-produced commodities. The nice thing is that if you are able to spot the link from a product to its product model, you can enrich the often shallow product description (e.g. from a shop page) with the rich feature data from the model page on the manufacturer's site.
In theory, there are at least two ways of modeling product models:
GoodRelations treats product models as prototypes, since this allows using the same types (TV set, car, ...) and the same properties (weight, voltage,...) for products and product models alike, even though they mean different things for products vs. datasheets. (The weight of 5 kg for a TV set means that the TV set weighs 5 kg. The weight of 5 kg for a datasheet of a TV set means that each TV set of that make and model will, by default, weigh 5 kg.)
The respective GoodRelations class is gr:ProductOrServiceModel. (The upcoming schema.org type is http://schema.org/ProductModel.)
Examples are the product pages on manufacturers' sites, like Sony, Nikon, Volkswagen - the entities references are not products, but their blueprints.
3. Then we have a third case, in which the entities exposed on the Web are neither products nor product models, but instead "black boxes" of products, which themselves do not have a public identity. For example, an Amazon page for a new book does not expose publicly individual book copies, but just states that they have multiple ones on stock.
The main semantic difference is that multiple statements about the same entity do not imply that the statements refer to the same individual product. For instance, if you say that you bought that entity and that someone else bought it, too, it implies that you own books from the same bag of books, but not the same copy. (The identity criterion is different.)
The respective GoodRelations class is gr:SomeItems. (The upcoming schema.org type is http://schema.org/SomeProducts.)
These three subtypes are powerful, but it is of course also allowed to use the common abstraction gr:ProductOrService (in schema.org: http://schema.org/Product).
Now, modeling respective data using GoodRelations works by combining two classes per each product,
A Single Book Copy
div typeof="schema:Book gr:Individual" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
...other properties from schema:Book or gr:Individual ...
</div>
A Book Title
div typeof="schema:Book gr:ProductOrServiceModel" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
...other properties from schema:Book or gr:SomeItems ...
</div>
Some Books
div typeof="schema:Book gr:SomeItems" itemid="#product>
< <div property="gr:name">HTML for Idiots</div>
...other properties from schema:Book or gr:SomeItems ...
</div>