WebSchemas/ChainingLayoutElements

From W3C Wiki




Overlapping topics brought together


Intro

This document is an attempt at supporting ongoing discussions

  • about adding a reverse-mechanism to microdata
  • about how to chain WebPageElements to a WebPage
  • about how to chain WebPageElements to the Things they contain
  • about how to express the Order of WebPageElements
  • about how to express ItemLists / CollectionPages (over multiple pages)


Note: Examples will use the same HTML examples over and over again so to illustrate the differences in markup needed, depending on what needs to be expressed. They aren't meant to be implemented by publishers of structured data but serve as an experimental base to find out which solution(s) are best suited for the matters at hand.

Discussion history

Inverse mechanism for microdata


Chaining WebPageElement and WebPage


mainContentOfPage / mainEntity / primaryTopic


ItemList


@itemid


Possible solutions for chaining entities and specifying the main entity

  • All 'reverse relations' require adding an @itemprop-reverse attribute to microdata.


Chaining / Main entity examples

ItemPage, Article

  • ItemPage > relation > Article (mainContentOfPage / mainEntity)

These variants require the range of 'mainContentOfPage' to be expanded to Thing or that 'mainEntity' be added to schema.org/WebPage.

An ItemPage which has an Article as it's mainContentOfPage (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/ItemPage">
       <main>
           <article itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/Article">
             [...]
           </article>
       </main>
    </body>
</html>


An Article which is the mainContentOfPage of an ItemPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/ItemPage">
       <main>
           <article itemscope itemtype="http://schema.org/Article">
               [...]
               <link itemprop-reverse="mainContentOfPage" href="https://example.com" />
           </article>
       </main>
    </body>
</html>


An ItemPage which has an Article as it's mainEntity (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/ItemPage">
       <main>
           <article itemprop="mainEntity" itemscope itemtype="http://schema.org/Article">
             [...]
           </article>
       </main>
    </body>
</html>


An Article which is the mainEntity of an ItemPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/ItemPage">
       <main>
           <article itemscope itemtype="http://schema.org/Article">
               [...]
               <link itemprop-reverse="mainEntity" href="https://example.com" />
           </article>
       </main>
    </body>
</html>


CollectionPage, ItemList

  • CollectionPage > relation > ItemList (mainContentOfPage / mainEntity)

These variants require the range of 'mainContentOfPage' to be expanded to Thing or that 'mainEntity' be added to schema.org/WebPage.

A CollectionPage which has an ItemList as it's mainContentOfPage (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/ItemList">
                <ul>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                </ul>
            </div>
        </main>
    </body>
</html>


An ItemList which is the mainContentOfPage of a CollectionPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemscope itemtype="http://schema.org/ItemList">
                <ul>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                </ul>
                <link itemprop-reverse="mainContentOfPage" href="https://example.com" />
            </div>
        </main>
    </body>
</html>


A CollectionPage which has an ItemList as it's mainEntity (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainEntity" itemscope itemtype="http://schema.org/ItemList">
                <ul>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                </ul>
            </div>
        </main>
    </body>
</html>


An ItemList which is the mainEntity of a CollectionPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemscope itemtype="http://schema.org/ItemList">
                <ul>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                    <li>
                        [...]
                    </li>
                </ul>
                <link itemprop-reverse="mainEntity" href="https://example.com" />
            </div>
        </main>
    </body>
</html>


CollectionPage, ItemList, Product

  • CollectionPage > mainContentOfPage > ItemList
  • ItemList > relation > Product (itemListElement)

These variants is requires the schema.org/ItemList proposal to be integrated.

An ItemList which has Products as itemListElements (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/ItemList">
                <meta itemprop="itemListOrder" content="Unordered">
                <ul>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


Products which are itemListElements of an ItemList (up the DOM, reverse relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
       <main>
            <div itemid="#ItemList" itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/ItemList">
                <meta itemprop="itemListOrder" content="Unordered">
                <ul>
                   <li itemscope itemtype="http://schema.org/Product">
                       [...]
                       <link itemprop-reverse="itemListElement" href="#ItemList" />
                   </li>
                   <li itemscope itemtype="http://schema.org/Product">
                       [...]
                       <link itemprop-reverse="itemListElement" href="#ItemList" />
                   </li>
                   <li itemscope itemtype="http://schema.org/Product">
                       [...]
                       <link itemprop-reverse="itemListElement" href="#ItemList" />
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


CollectionPage, WebPageElement, ItemList, Product

  • CollectionPage > mainContentOfPage > WebPageElement
  • CollectionPage > relation > ItemList (mainEntity)
  • WebPageElement > hasPart > ItemList
  • ItemList > itemListElement > Product

These variants is require the schema.org/ItemList proposal to be integrated, as well as having 'hasPart' and 'mainEntity' being added

A CollectionPage which has an ItemList as it's mainEntity (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <link itemprop="mainEntity" href="#ItemList" />
        <main itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
            <div itemid="#ItemList" itemprop="hasPart" itemscope itemtype="http://schema.org/ItemList">
                <meta itemprop="itemListOrder" content="Unordered">
                <ul>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


An ItemList which is the mainEntity of a CollectionPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/CollectionPage">
        <main itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
            <div itemprop="hasPart" itemscope itemtype="http://schema.org/ItemList">
                <meta itemprop="itemListOrder" content="Unordered">
                <ul>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                   <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                       [...]
                   </li>
                </ul>
                <link itemprop-reverse="mainEntity" href="https://example.com">
            </div>
        </main>
    </body>
</html>


CollectionPage, WebPageElement

  • CollectionPage > relation > WebPageElement (mainContentOfPage / mainEntity)

These variants requires the range of 'mainContentOfPage' to be expanded to Thing or that 'mainEntity' be added to schema.org/WebPage.

A CollectionPage which has a WebPageElement as it's mainContentOfPage (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


A WebPageElement which is the mainContentOfPage of a CollectionPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                </ul>
                <link itemprop-reverse="mainContentOfPage" href="https://example.com" />
            </div>
        </main>
    </body>
</html>


A CollectionPage which has a WebPageElement as it's mainEntity (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainEntity" itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


A WebPageElement which is the mainEntity of a CollectionPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                   <li>
                       [...]
                   </li>
                </ul>
                <link itemprop-reverse="mainEntity" href="https://example.com" />
            </div>
        </main>
    </body>
</html>


CollectionPage, WebPageElement, ImageObject

  • CollectionPage > mainContentOfPage > WebPageElement
  • WebPageElement > relation > ImageObject (*Part*)

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WebPageElement which has multiple ImageObject parts (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main>
            <div itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li itemprop="hasPart" itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                   </li>
                   <li itemprop="hasPart" itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                   </li>
                   <li itemprop="hasPart" itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


Multiple ImageObjects which are part of a WebPageElement (up the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
       <main>
            <div itemid="#WebPageElement" itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop="isPartOf" href="#WebPageElement" />
                   </li>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop="isPartOf" href="#WebPageElement" />
                   </li>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop="isPartOf" href="#WebPageElement" />
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


Multiple ImageObjects which are part of a WebPageElement (up the DOM, reverse relation)
<html>
    <body itemscope itemtype="http://schema.org/CollectionPage">
       <main>
            <div itemid="#WebPageElement" itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/WebPageElement">
                <ul>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop-reverse="hasPart" href="#WebPageElement" />
                   </li>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop-reverse="hasPart" href="#WebPageElement" />
                   </li>
                   <li itemscope itemtype="http://schema.org/ImageObject">
                       [...]
                       <link itemprop-reverse="hasPart" href="#WebPageElement" />
                   </li>
                </ul>
            </div>
        </main>
    </body>
</html>


WebPage, WebSite

  • WebPage > relation > WebSite (*Part*)

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WebPage which is part of a WebSite (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <header>
            <section>
                <div itemprop="isPartOf" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
        </header>
    </body>
</html>


A WebPage which is part of a WebSite (up the DOM, reverse relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <header>
            <section>
                <div itemid="#WebSite" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
        </header>
        <link itemprop-reverse="hasPart" href="#WebSite" />
    </body>
</html>


WebPage, WPHeader, Website

  • WebPage > ispartOf > WebSite
  • WebPage > relation > WPHeader (*Part*)
  • WPHeader > hasPart > WebSite

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WebPage which has a WPHeader part (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header itemprop="hasPart" itemscope itemtype="http://schema.org/WPHeader">
            <section>
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
        </header>
    </body>
</html>


a WPHeader which is part of a WebPage (up the DOM, normal relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header itemscope itemtype="http://schema.org/WPHeader">
            <section>
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
    	    <link itemprop="isPartOf" href="https://example.com" />
        </header>
    </body>
</html>


a WPHeader which is part of a WebPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header itemscope itemtype="http://schema.org/WPHeader">
            <section>
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
    	    <link itemprop-reverse="hasPart" href="https://example.com" />
        </header>
    </body>
</html>


WebPage, WebPageElement, Website

  • WebPage > isPartOf > WebSite
  • WebPage > relation > WebPageElement (*Part*)
  • WebPageElement > hasPart > WebSite

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WebPage which has a WebPageElement part (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header>
            <section itemprop="hasPart" itemscope itemtype="http://schema.org/WebPageElement">
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
        </header>
    </body>
</html>


A WebpageElement which is part of a WebPage (up the DOM, normal relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header>
            <section itemscope itemtype="http://schema.org/WebPageElement">
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                       <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
                <link itemprop="isPartOf" href="https://example.com" />
            </section>
        </header>
    </body>
</html>


A WebpageElement which is part of a WebPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header>
            <section itemscope itemtype="http://schema.org/WebPageElement">
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
                <link itemprop-reverse="hasPart" href="https://example.com" />
            </section>
        </header>
    </body>
</html>


WebPage, WPHeader, WebPageElement, Website

  • WebPage > isPartOf > WebSite
  • WebPage > hasPart > WPHeader
  • WPHeader > relation > WebPageElement (*Part*)
  • WebPageElement > hasPart > WebSite

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WPHeader which has a WebPageElement part (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header itemprop="hasPart" itemscope itemtype="http://schema.org/WPHeader">
            <section itemprop="hasPart" itemscope itemtype="http://schema.org/WebPageElement">
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
            </section>
        </header>
    </body>
</html>


A WebPageElement which is part of a WPHeader (up the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
    	<link itemprop="isPartOf" href="#WebSite">
        <header itemid="#WPHeader" itemprop="hasPart" itemscope itemtype="http://schema.org/WPHeader">
            <section itemscope itemtype="http://schema.org/WebPageElement">
                <div itemid="#WebSite" itemprop="hasPart" itemscope itemtype="http://schema.org/WebSite">
                    <h1>
                        <a itemprop="url" href="https://example.com/some-page/">
                            <img itemprop="image" src="https://example.com/image.jpg">
                            <span itemprop="name">[website-name]</span>
                        </a>
                    </h1>
                    <div itemprop="description">
                        <p>[website-description]</p>
                    </div>
                </div>
                <link itemprop="isPartOf" href="#WPHeader" />
            </section>
        </header>
    </body>
</html>


WebPage, SiteNavigationElement

  • WebPage > relation > SiteNavigationElement (*Part*)

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A WebPage which has a SiteNavigationElement part (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <nav itemprop="hasPart" itemscope itemtype="http://schema.org/SiteNavigationElement">
            <ul>
                <li>
                    <a href="https://example.com">
                        <span>home</span>
                    </a>
                </li>
                <li>
                    <a href="https://example.com/products/">
                        <span>products</span>
                    </a>
                    <ul>
                        <li>
                            <a href="https://example.com/category-1/">
                                <span>product-category-1</span>
                            </a>
                        </li>
                        <li>
                            <a href="https://example.com/category-2/">
                                <span>product-category-2</span>
                            </a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="https://example.com/about-us/">
                        <span>about us</span>
                    </a>
                </li>
                <li>
                    <a href="https://example.com/contact/">
                        <span>contact</span>
                    </a>
                </li>
            </ul>
        </nav>
    </body>
</html>


A SiteNavigationElement which is part of a WebPage (up the DOM, reverse relation)
<html>
    <body itemid="https://example.com" itemscope itemtype="http://schema.org/WebPage">
        <nav itemscope itemtype="http://schema.org/SiteNavigationElement">
            <ul>
                <li>
                    <a href="https://example.com">
                        <span>home</span>
                    </a>
                </li>
                <li>
                    <a href="https://example.com/products/">
                        <span>products</span>
                    </a>
                    <ul>
                        <li>
                            <a href="https://example.com/category-1/">
                                <span>product-category-1</span>
                            </a>
                        </li>
                        <li>
                            <a href="https://example.com/category-2/">
                                <span>product-category-2</span>
                            </a>
                        </li>
                    </ul>
                </li>
                <li>
                    <a href="https://example.com/about-us/">
                        <span>about us</span>
                    </a>
                </li>
                <li>
                    <a href="https://example.com/contact/">
                        <span>contact</span>
                    </a>
                </li>
            </ul>
            <link itemprop-reverse="isPartOf" href="https://example.com" />
        </nav>
    </body>
</html>


WebPage, SiteNavigationElement, WebPage

  • WebPage > hasPart > SiteNavigationElement
  • SiteNavigationElement > relation > WebPage (*Part*)

These variants require 'hasPart' to be added as inverse of 'isPartOf'.

A SiteNavigationElement which has WebPage parts (down the DOM, normal relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <nav itemprop="hasPart" itemscope itemtype="http://schema.org/SiteNavigationElement">
            <ul>
                <li itemprop="hasPart" itemscope itemtype="http://schema.org/WebPage">
                    <a itemprop="url" href="https://example.com">
                        <span itemprop="name">home</span>
                    </a>
                </li>
                <li itemprop="hasPart" itemscope itemtype="http://schema.org/CollectionPage">
                    <a itemprop="url" href="https://example.com/products/">
                        <span itemprop="name">products</span>
                    </a>
                    <ul>
                        <li>
                            <a href="https://example.com/category-1/">
                                <span>product-category-1</span>
                            </a>
                        </li>
                        <li>
                            <a href="https://example.com/category-2/">
                                <span>product-category-2</span>
                            </a>
                        </li>
                    </ul>
                </li>
                <li itemprop="hasPart" itemscope itemtype="http://schema.org/AboutPage">
                    <a itemprop="url" href="https://example.com/about-us/">
                        <span itemprop="name">about us</span>
                    </a>
                </li>
                <li itemprop="hasPart" itemscope itemtype="http://schema.org/ContactPage">
                    <a itemprop="url" href="https://example.com/contact/">
                        <span itemprop="name">contact</span>
                    </a>
                </li>
            </ul>
        </nav>
    </body>
</html>


WebPages which are parts of a SiteNavigationElement (up the DOM, reverse relation)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <nav itemid="#SiteNavigationElement" itemprop="hasPart" itemscope itemtype="http://schema.org/SiteNavigationElement">
            <ul>
                <li itemscope itemtype="http://schema.org/WebPage">
                    <a itemprop="url" href="https://example.com">
                        <span itemprop="name">home</span>
                    </a>
                    <link itemprop-reverse="hasPart" href="#SiteNavigationElement" />
                </li>
                <li itemscope itemtype="http://schema.org/CollectionPage">
                    <a itemprop="url" href="https://example.com/products/">
                        <span itemprop="name">products</span>
                    </a>
                    <ul>
                        <li>
                            <a href="https://example.com/category-1/">
                                <span>product-category-1</span>
                            </a>
                        </li>
                        <li>
                            <a href="https://example.com/category-2/">
                                <span>product-category-2</span>
                            </a>
                        </li>
                    </ul>
                    <link itemprop-reverse="hasPart" href="#SiteNavigationElement" />
                </li>
                <li itemscope itemtype="http://schema.org/AboutPage">
                    <a itemprop="url" href="https://example.com/about-use/">
                        <span itemprop="name">about us</span>
                    </a>
                </li>
                <li itemscope itemtype="http://schema.org/ContactPage">
                    <a itemprop="url" href="https://example.com/contact/">
                        <span itemprop="name">contact</span>
                    </a>
                    <link itemprop-reverse="hasPart" href="#SiteNavigationElement" />
                </li>
            </ul>
        </nav>
    </body>
</html>


Possible solution for expressing WebPageElement order

Thing property

  • introduce isContainedIn > WebPageElement

WebPageElement properties

  • introduce contains > Thing
  • introduce previousElement > IRI
  • introduce nextElement > IRI


Note: Adding a property like 'elementPosition' would not help as WebPageElements can also be nested within each other. Making a top down order difficult to express with a numerated value.

WebPageElement order Example (requires @itemid)

<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <header itemid="#WPHeader" itemprop="hasPart" itemscope itemtype="http://schema.org/WPHeader">
             <div itemprop="contains" itemscope itemtype="http://schema.org/WebPageElement">
                 [...]
             </div>
             <link itemprop="nextElement" href="#SiteNavigationElement">
        </header>
         <nav itemid="#SiteNavigationElement" itemprop="hasPart" itemscope itemtype="http://schema.org/SiteNavigationElement">
             <div itemprop="contains" itemscope itemtype="http://schema.org/ItemList">
                 [...]
             </div>
             <link itemprop="previousElement" href="#WPHeader">
             <link itemprop="nextElement" href="#Product">
        </nav>
        <main itemid="#Product" itemprop="mainContentOfPage" itemscope itemtype="http://schema.org/Product">
             <link itemprop="previousElement" href="#SiteNavigationElement">
             <link itemprop="nextElement" href="#WPSideBar">
             <div itemprop="contains" itemscope itemtype="http://schema.org/WebPageElement">
                 [...]
             </div>
        </main>
        <aside itemid="#WPSideBar" itemprop="hasPart" itemscope itemtype="http://schema.org/WPSideBar">
             <section itemprop="contains" itemscope itemtype="http://schema.org/ItemList">
                 [...]
             </section>
             <link itemprop="previousElement" href="#Product">
             <link itemprop="nextElement" href="#WPFooter">
        </aside>
        <footer itemid="#WPFooter" itemprop="hasPart" itemscope itemtype="http://schema.org/WPFooter">
             <div itemprop="contains" itemscope itemtype="http://schema.org/ContactPoint">
                 [...]
             </div>
             <link itemprop="previousElement" href="#WPSideBar">
        </footer>
    </body>
</html>


Possible solutions for expressing ItemLists

ItemList properties

  • itemListElement > Text, Thing, ListItem
  • itemListOrder > Text, ItemListOrderType
  • numberOfItems > Number
  • ? introduce sortingValue > Text (for specifying the value used for sorting the ItemList)


itemListOrder values


Note: The references to HTML5 attributes, values and descriptions are not binding but are there to illustrate possible similarities.

ListItem properties

  • item > Thing
  • position > Text (or Integer or Number?) = <li value="7">
  • previousItem > IRI = <ol start="[prevNum + 1]">
  • nextItem > IRI = <ol> resolved by DOM


ItemList Examples

Breadcrumbs

A breadcrumb (without @itemid - Succeeds)
<html>
    <body itemscope itemtype="http://schema.org/WebPage">
        <div itemprop="breadcrumb" itemscope itemtype="http://schema.org/ItemList">
            <ol>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/CollectionPage">
                       <a itemprop="url" href="https://example.com/books/">
                           <span itemprop="name">Books</span>
                       </a>
                   </span>
                   <meta itemprop="position" content="1">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/CollectionPage">
                       <a itemprop="url" href="https://www.example.com/books/authors/">
                           <span itemprop="name">Authors</span>
                       </a>
                   </span>
                   <meta itemprop="position" content="2">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/WebPage">
                       <a itemprop="url" href="https://www.example.com/books/authors/stephen-king/">
                           <span itemprop="name">Stephen King</span>
                       </a>
                   </span>
                   <meta itemprop="position" content="3">
               </li>
            </ol>
        </div>
    </body>
</html>


A breadcrumb (using @itemid in combination with nextItem/previousItem - Succeeds)
<html>
   <body itemscope itemtype="http://schema.org/WebPage">
        <div itemprop="breadcrumb" itemscope itemtype="http://schema.org/ItemList">
            <ol>
               <li itemid="#ListItem-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/CollectionPage">
                       <a itemprop="url" href="https://example.com/books/">
                           <span itemprop="name">Books</span>
                       </a>
                   </span>
                   <link itemprop="nextItem" href="#ListItem-2">
               </li>
               <li itemid="#ListItem-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/CollectionPage">
                       <a itemprop="url" href="https://www.example.com/books/authors/">
                           <span itemprop="name">Authors</span>
                       </a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-1">
                   <link itemprop="nextItem" href="#ListItem-3">
               </li>
               <li itemid="#ListItem-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/WebPage">
                       <a itemprop="url" href="https://www.example.com/books/authors/stephen-king/">
                           <span itemprop="name">Stephen King</span>
                       </a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-2">
               </li>
            </ol>
        </div>
    </body>
</html>


Paginated Ordered ItemList

A paginated Ordered ItemList (without @itemid - Fails)
<!-- 1st page of a paginated Ordered ItemList -->

<html>
    <head>
        <link rel="canonical" href="https://www.example.com/article-listing/">
        <link rel="next" href="https://www.example.com/article-listing/page/2/">
    </head>
    <body itemscope itemtype="http://schema.org/CollectionPage">
<!-- Without @itemid there's no way of indicating each ItemList is a piece of a bigger ItemList -->
        <main itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListOrderAscending">
            <meta itemprop="numberOfItems" content="6">
<!-- Note the use of 'sortingValue', this could express the value the ItemList is sorted by -->
            <meta itemprop="sortingValue" content="date">
            <h1 itemprop="name">News</h1>
            <ol>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/january">[...]</a>
                   </span>
                   <meta itemprop="position" content="1">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/february">[...]</a>
                   </span>
                   <meta itemprop="position" content="2">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/march">[...]</a>
                   </span>
                   <meta itemprop="position" content="3">
               </li>
            </ol>
        </main>
    </body>
</html>

<!-- 2nd page of a paginated Ordered ItemList -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/article-listing/page/2/">
        <link rel="prev" href="http://www.example.com/article-listing/page/">
    </head>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListOrderAscending">
            <meta itemprop="numberOfItems" content="6">
            <meta itemprop="sortingValue" content="date">
            <h1 itemprop="name">News</h1>
            <ol start="4">
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/april">[...]</a>
                   </span>
                   <meta itemprop="position" content="4">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/may">[...]</a>
                   </span>
                   <meta itemprop="position" content="5">
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/june">[...]</a>
                   </span>
                   <meta itemprop="position" content="6">
               </li>
            </ol>
        </main>
    </body>
</html>


A paginated Ordered ItemList (using @itemid - Succeeds)
<!-- 1st page of a paginated Ordered ItemList -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/article-listing/">
        <link rel="next" href="http://www.example.com/article-listing/page/2/">
    </head>

    <body itemscope itemtype="http://schema.org/CollectionPage">
<!-- Every ItemList's @itemid uses the same IRI, thus describing the same entity on -->
<!-- multiple pages, making it possible to coalesce all their graphs into one graph. -->
        <main itemid="http://www.example.com/article-listing/#ItemList" itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListOrderAscending">
            <meta itemprop="numberOfItems" content="6">
<!-- Note the use of 'sortingValue', this could express the value the ItemList is sorted by -->
            <meta itemprop="sortingValue" content="date">
            <h1 itemprop="name">News</h1>
            <ol>
               <li itemid="#ListItem-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/january">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="http://schema.org/False">
                   <link itemprop="nextItem" href="#ListItem-2">
               </li>
               <li itemid="#ListItem-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/february">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-1">
                   <link itemprop="nextItem" href="#ListItem-3">
               </li>
               <li itemid="#ListItem-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/march">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-2">
                   <link itemprop="nextItem" href="#ListItem-4">
               </li>
            </ol>
        </main>
    </body>
</html>

<!-- 2nd page of a paginated Ordered ItemList -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/article-listing/page/2/">
        <link rel="prev" href="http://www.example.com/article-listing/page/">
    </head>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main itemid="http://www.example.com/article-listing/#ItemList" itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListOrderAscending">
            <meta itemprop="numberOfItems" content="6">
            <meta itemprop="sortingValue" content="date">
            <h1 itemprop="name">News</h1>
            <ol start="4">
               <li itemid="#ListItem-4" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/april">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-3">
                   <link itemprop="nextItem" href="#ListItem-5">
               </li>
               <li itemid="#ListItem-5" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/may">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-4">
                   <link itemprop="nextItem" href="#ListItem-6">
               </li>
               <li itemid="#ListItem-6" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem">
                   <span itemprop="item" itemscope itemtype="http://schema.org/Article">
                       <a itemprop="url" href="https://example.com/article/june">[...]</a>
                   </span>
                   <link itemprop="previousItem" href="#ListItem-5">
                   <link itemprop="nextItem" href="http://schema.org/False">
               </li>
            </ol>
        </main>
    </body>
</html>


Possible solutions for expressing Paginated WebPages

WebPage or Collection properties

  • ? introduce previousPart > IRI
  • ? introduce nextPart > IRI


Note: Downside to the 'previous/nextPart' being properties of WebPage is that once all multi-page graphs get merged into one, the 'previous/nextPart' properties have become obsolete. Creating the same issue as it did for ItemList and why ListItem was needed.

Maybe schema.org/Collection could be a solution for Webpage as ListItem is for ItemList, eg:

  • ItemList > itemListElement > ListItem > nextItem > IRI
  • WebPage > isPartOf > Collection > nextPart > IRI


Paginated CollectionPage Examples

A paginated CollectionPage (without @itemid - Fails)

<!-- 1st page of a paginated CollectionPage (which has an unordered ItemList) -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/category/">
        <link rel="next" href="http://www.example.com/category/page/2/">
    </head>
<!-- Without @itemid there's no way of indicating each CollectionPage is a piece of a bigger CollectionPage -->
    <body itemscope itemtype="http://schema.org/CollectionPage">
<!-- Without @itemid there's no way of indicating each ItemList is a piece of a bigger ItemList -->
        <main itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListUnordered">
            <meta itemprop="numberOfItems" content="6">
            <h1 itemprop="name">Products</h1>
            <ul>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
            </ul>
        </main>
    </body>
</html>

<!-- 2nd page of a paginated CollectionPage (which has an unordered ItemList) -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/category/2/">
        <link rel="prev" href="http://www.example.com/category/">
    </head>
    <body itemscope itemtype="http://schema.org/CollectionPage">
        <main itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListUnordered">
            <meta itemprop="numberOfItems" content="6">
            <h1 itemprop="name">Products</h1>
            <ul>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
            </ul>
        </main>
    </body>
</html>


A paginated CollectionPage (using @itemid - Succeeds)

<!-- 1st page of a paginated CollectionPage (which has an unordered ItemList) -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/category/">
        <link rel="next" href="http://www.example.com/category/page/2/">
    </head>
    <body itemid="http://www.example.com/category/" itemscope itemtype="http://schema.org/CollectionPage">
        <link itemprop="previousPart" href="http://schema.org/False">
        <link itemprop="nextPart" href="http://www.example.com/category/page/2/">
        <main itemid="http://www.example.com/category/#ItemList" itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="previousPart" href="http://schema.org/False">
            <link itemprop="nextPart" href="http://www.example.com/category/page/2/#ItemList">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListUnordered">
            <meta itemprop="numberOfItems" content="6">
            <h1 itemprop="name">Products</h1>
            <ul>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
            </ul>
        </main>
    </body>
</html>

<!-- 2nd page of a paginated CollectionPage (which has an unordered ItemList) -->

<html>
    <head>
        <link rel="canonical" href="http://www.example.com/category/2/">
        <link rel="prev" href="http://www.example.com/category/">
    </head>
    <body itemid="http://www.example.com/category/page/2/" itemscope itemtype="http://schema.org/CollectionPage">
        <link itemprop="previousPart" href="http://www.example.com/category/">
        <link itemprop="nextPart" href="http://schema.org/False">
        <main itemid="#ItemList" itemscope itemtype="http://schema.org/ItemList">
            <link itemprop="previousPart" href="http://www.example.com/category/page/#ItemList">
            <link itemprop="nextPart" href="http://schema.org/False">
            <link itemprop="itemListOrder" href="http://schema.org/ItemListUnordered">
            <meta itemprop="numberOfItems" content="6">
            <h1 itemprop="name">Products</h1>
            <ul>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
               <li itemprop="itemListElement" itemscope itemtype="http://schema.org/Product">
                   [...]
               </li>
            </ul>
        </main>
    </body>
</html>