HTML5 Semantics BadgeBeim „basteln“ an SemPress, meinem ersten WordPress Theme, habe ich das erste Mal praktische Erfahrungen mit Schema.org gesammelt und mir sind vor allem zwei Dinge klar geworden: 1. Warum Schema.org nach einer Art „Vererbungs“-Prinzip aufgebaut ist und 2. Wie Google mit Schema.org umgeht.

The http://schema.org/Thing

Das „einfachste“ Schema ist ein „Thing“ und hat folgende Attribute:

description TEXT A short description of the item.
image URL URL of an image of the item.
name TEXT The name of the item.
url URL URL of the item.

Da alle anderen Objekte auf dem „Thing“ aufbauen, kann man davon ausgehen dass man mind. auf diese vier Eigenschaften zugreifen kann und genau das ist der ganze Sinn hinter dieser Struktur.

Vor allem Google setzt massiv auf Schema.org, sei es beim Einsatz in der Suche (über die sogenannten Rich-Snippets)…

rich snippets example

…oder beim Anreichern der, über Google+ oder den +1 Button geteilten Links.

Google+ Example

Um das Parsen der Webseiten (zumindest für diese eher einfachen Ausgaben) auf ein Minimum zu reduzieren, ist die Grundstruktur immer gleich und alles darüber hinaus ist reine Kür. Wahrscheinlich werden aber 90% aller Anwendungen mit Titel (name), Beschreibung, Bild und URL auskommen.

Googles Umgang mit Schema.org

Wer seine Seite mit Schema.org auszeichnen möchte, sollte vor allem eines Beachten: Google+ (wahrscheinlich aber auch alle anderen Google Produkte) interpretiert immer das erste im Quellcode verwendete Schema!

Bei meiner ersten Implementierung von Schema.org habe ich mich etwas zu sehr an RSS bzw. Atom orientiert und folgenden Aufbau gewählt: Ein umschließendes Objekt um den Blog zu beschreiben und ein oder mehrere referenzierte Artikel.

<body itemscope itemtype="http://schema.org/Blog">
...
  <header id="branding" role="banner">
    <hgroup>
      <h1 id="site-title" itemprop="name"><?php bloginfo( 'name' ); ?></h1>
      <h2 id="site-description" itemprop="description"><?php bloginfo( 'description' ); ?></h2>
    </hgroup>
  </header>
...
  <article itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
  ...
  </article>
  <article itemprop="blogPost" itemscope itemtype="http://schema.org/BlogPosting">
  ...
  </article>
...
</body>

Egal ob es jetzt um mehrere Artikel (Startseite) oder nur einen Artikel (Post oder Page) gehandelt hat.

Das hat bei Google+ dazu geführt, dass die notizBlog-Links immer mit dem Titel, der Beschreibung und dem Bild des Blogs und nicht mit denen des Artikels verknüpft wurden. Es ist also gerade für Blogs wichtig, dass das Blog-Schema nur auf den Übersichtsseiten benutzt wird und die Einzelansichten lediglich mit „http://schema.org/BlogPosting“ bzw. „http://schema.org/WebPage“ ausgezeichnet werden.

17 thoughts on “Schema.org – what I’ve learned so far

  1. Mach weiter! Das hilft mir sehr. Nebenbei: Dieses „Thing“ lässt sich recht gut mit dem category Element im rss2 verbinden. Wenn ich mal wieder Zeit habe, werde ich das weiter eruieren. Könnte sein, dass ich mich bei der Wahl der Werte hierzu an genau diesem Schema orientieren werde. Muss aber erst mal sehen, inwieweit schema.org auch andere Sprachen unterstützt. RSS als Beschreibungssprache bietet dazu ja Möglichkeiten.

    Ich fürchte, so richtig weiter kommen werde ich mit meinem eigenen Blog erst im Urlaub. Und der wird im Winter sein.

  2. Noch ein Nachtrag. Musste mich erst mal davon erholen, als ich beim Lesen der „getting started“ seite bei schema.org fast mit dem Kopf auf der tastatur aufgeschlagen wäre. Man hat dort bei der Verwendung von itemprop=“url“ genau den gleichen Mist gebaut wie schon bei den Microformats.

    Ich zitiere mal das Beispiel (hoffentlich kriege ich das Markup richtig hin):

    <div itemscope itemtype=“http://schema.org/Person“>
    <a href=“alice.html“ itemprop=“url“>Alice Jones</a>
    </div>

    Was hier also ausgesagt wird, ist folgendes: Bei Inhalt des div-Containers handelt es sich um Angaben zu einer http://schema.org/Person. So weit, so schön. Desweiteren steht da, dass der Text „Alice Jones“ um eine url handelt. Das ist offensichtlich gelogen. Diese url (oder uri) hat schon rein formal zwei Fehler. Desweiteren ist zu sehen, dass „Alice Jones“ wohl eher der Name der Person ist. Also wäre hier ganz offensichtlich itemprop=“name“ korrekt. Diese Property ist, wie Du ja schon geschrieben hast, eine Property des Basistyps „Thing“. Und es würde absolut passen.

    Ausserdem ist das nicht nur gelogen, sondern auch überflüssig. In den html-Spezifikationen steht zum href Attribut, dass dieses eine url (oder uri) enthalten muss. Es ist völlig überflüssig, das noch mal extra hinzuschreiben (wenn das denn überhaupt ginge).

    Grundsätzlich überflüssig ist itemscope=“url“ deswegen nicht. Stell die folgendes Beispiel vor:

    <div itemscope itemtype=“http://schema.org/Person“>
    you can find my homepage at <a href=“alice.html“ itemprop=“url“>alice.html</a>
    </div>

    So macht das Sinn und ist korrekt. Das itemprop=“url“ bezieht sich nicht auf das href Attribut, sondern auf den Inhalt des Containers.

    • Semantisch hast du sicherlich recht. URL müsste eigentlich nicht sein, da <a /> immer eine URL ist… Ich sehe URL aber eher so: „zeichnet die URL aus die zu dem Objekt gehört“. Sind innerhalb eines Objekts mehrere URLs, kann man mit itemprop="url" definieren welche direkt zu dem Objekt gehört und welche einfach „nur“ Links sind…

      Trotzdem finde ich die Dokumentation/Verwendung von URL etwas komisch… Der rich-snippets-test von Google zeigt etwas komische Ergebnisse für

      <a href="..." itemprop="name url">Max Mustermann</a>

      und zwar:

      rich snippets test: Schema.org

      Ich hoffe die Ausgabe ist nur etwas komisch und dass alles so passt… Ich hab nämlich keine Lust nur für den Namen noch mal ein extra <span /> einzubauen!

  3. So, wie ich das sehe, zeigt der rich-snippets-test von Google (kannst Du mir da mal die url geben?) genau das an, was korrekt ist.

    Grundsätzlich sollte es so sein, dass _Alles_, was in dem Person Container ist, Merkmale (Properties) dieser Person sind. Jedenfalls Alles, was irgendwie mit itemprop ausgezeichnet ist. Und dafür sollten dann auch logischerweise genau die itemprops verwendet werden, die den Inhalt des jeweiligen Containers korrekt beschreiben.

    Der Witz dabei ist, die itemprops beschreiben, wie jedes andere Attribut eines Containers auch, nicht irgend ein Attribut, sondern den Inhalt des Containers. In den meisten Fällen ist das eine semantische Beschreibung. Genauer: Die Attribute verfeinern die semantische Beschreibung, die dem Inhalt bereits durch die Wahl des richtigen Containers gegeben wurde. Eine gewisse Ausnahme bildet das a Element und das href Attribut, die beide kein semantisches, sondern ein technisches Attribut sind. Nichtsdestotrotz sind es Attribute des Containerinhalts, und nicht Attribute von Attributen. So Etwas gibt es nämlich weder in html noch in xml.

    Die Verwendung von itemprop=“url“ in dem Beispiel attributiert aber nicht den Inhalt, sondern ein anderes Attribut. Und das geht nicht.

    • So, wie ich das sehe, zeigt der rich-snippets-test von Google (kannst Du mir da mal die url geben?) genau das an, was korrekt ist.

      Er zeigt bei beidem den Namen, verlinkt auf die URL…. Aber eigentlich sollte „name“ doch nur den Namen und „url“ nur die URL anzeigen… Zumindest nach meinem Verständnis.

      Die URL zum rich-snippets-test ist übrigens: http://www.google.com/webmasters/tools/richsnippets?url=http%3A%2F%2Fnotiz.blog%2F2012%2F09%2F20%2F404-specification-not-found%2F&html=

    • Die Verwendung von itemprop=”url” in dem Beispiel attributiert aber nicht den Inhalt, sondern ein anderes Attribut. Und das geht nicht.

      Ahhhh, jetzt versteh ich was du meinst!!!

      Das ist in der Tat etwas inkonsistent, kommt aber auf die Definition des Formates an. Die Microdata Spezifikation sagt dazu folgendes:

      If the element is an a, area, or link element

      The value is the absolute URL that results from resolving the value of the element’s href attribute relative to the element at the time the attribute is set, or the empty string if there is no such attribute or if resolving it results in an error.

      Das bedeutet für mich aber auch, dass ich meine Implementierung umbauen muss. Das itemprop="name" muss in einen eigenen span und darf nicht an das a – Tag gehängt werden. Mist!

  4. Ja, ich denke, jetzt hast Du es 🙂

    Die Spezifikation besagt das vielleicht so. Aber das läuft der generellen html und xml Spezifikation zuwider. Es ist nun mal generell so, dass Attribute den Containerinhalt attributieren, nicht andere Attribute.

    Wie das mit den technischen Attributen href und z.B. src aussieht, kann ich im Moment nicht so recht abschätzen. Aber auch diese Attribute attributieren nicht ein anderes Attribut, sondern allenfalls den Container selbst. Ebenso ein Sonderfall sind die Attribute hreflang und rel resp. rev. Diese attributieren nicht den Containerinhalt, auch nicht den Container selbst, sondern das Ziel des Links. Hier könnte man vielleicht tatsächlich indirekt von einem Attribut des in diesem Fall href Attributs sprechen. Aber auch nur indirekt, denn die url ist nicht eigentlich das Ziel, sondern nur die Adresse des Ziels.

    Letztendlich kann man sagen, dass kein einziges Attribut existiert, das ein Attribut eines anderen Attributs ist. Diese Konstruktion ist weder in html noch in xml existent. Daher läuft diese Microdata Spezifikation der generellen html und xml Spezifikaton zuwider.

    Was Dein Modell angeht: Muss so nicht sein.

    Du hast doch den umgebenden Container. Der besagt, dass Alles da drin irgendeine Property von Person ist. Wenn also innerhalb dieses Containers irgendwelche urls auftauchen, dann sind diese urls per Definition urls dieser Person. Auch ohne nähere Beschreibung.

    O.k., mehr heute Abend. Muss weiter arbeiten 🙂

  5. Wurde gestern Abend Nix mehr. Mein Computer musste gestern Abend in der Firma bleiben. Daher jetzt.
    Vielleicht wird es einfacher, wenn ich zu dem Beispiel oben ein Parallelbeispiel bringe. Ich hoffe, Du kannst ein Bisschen programmieren. Das folgende Beispiel ist grob an php angelehnt, könnte aber ganz ähnlich auch in c++, c# oder java geschrieben werden. Zunächst noch mal das Beispiel in html:

    <div itemscope itemtype=”http://schema.org/Person”>
    <a href=”alice.html” itemprop=”name”>Alice Jones</a>
    </div>

    Ich hab das itemprop gleich mal berichtigt. Jetzt die gleiche Aussage als Klasse:

    class Person {
    name = Alice Jones;
    }

    Hier ist, genau wie oben, „Person“ der Container. Alles da drin ist eine Property von Person. Ich habe das an php angelehnt, weil ich aus Gründen der Übersichtlichkeit auf streng typisierte Properties verzichten will. In html gibt es (derzeit?) keine strenge Typisierung.

    Also, warum schreibe ich itemprop=“name“? Weil sonst zwar klar wäre, dass „Alice Jones“ eine Property von Person ist, aber nicht, was für eine. Du erinnerst Dich an „semantisch nähere Spezifikation“? Genau das greift hier. Aber wir sind mit dem Beispiel noch nicht am Ende:

    class Person {
    name = Alice Jones;
    url = alice.html;
    }

    Warum ist das zulässig, ohne itemprop=“url“? Weil „alice.html“ eine Property von Person ist, und weil das href Attribut, dessen Inhalt „alice.html“ ist, _immer_ eine url ist. „alice.html“ ist also bereits komplett semantisch spezifiziert.

    Es gibt Möglichkeiten, das noch näher zu spezifizieren. In xml gibt es dazu xlink. Für html hat man immerhin hreflang, rel und rev. Aber all Das ändert Nix daran, dass „alice.html“ eine url zu der Person ist.

    Etwas Anderes wäre noch anzumerken. Es gibt nicht _die_ url zu einer Person. Es ist immer möglich, einer Person mehrere urls zuzuordnen. Genauso, wie man einer Person mehrere Namen zuordnen kann. Im Grunde sind also alle Properties dieser Klasse Arrays.

    • Person ist da eventuell auch ein schlechtes Beispiel. Nehmen wie einen Artikel. Ein Artikel hat meistens einen Titel, einen Text, einen Autor und einen Permalink. Da der Text eines Artikels auch Links beinhalten kann, ist es nicht klar welcher der Links jetzt wirklich den Artikel auszeichnet und deshalb hat Google ein property für die URL eingeführt.

      URL ist in dem Fall vielleicht etwas zu missverständlich und man hätte vielleicht eher „Permalink“ benutzt, aber es sollte eben generisch sein und für alle Typen (Person, Review, …) gelten.

  6. Nachtrag:

    Wenn Du tatsächlich Google veranlassen wolltest, das so anzuzeigen, wie Du Dir das vorstellst, musst Du nicht den Namen in ein eigenes Span verfrachten, sondern die url als Inhalt eines Containers aufführen. Folgendes ginge:

    <div itemsope itemtype=“http://schema.org/Person“>
    <a href=“alice.html“ itemprop=“name“>Alice Jones</a>
    <span itemprop=“url“>alice.html</span>
    </div>

    oder
    <div itemsope itemtype=“http://schema.org/Person“>
    <a href=“alice.html“ itemprop=“url“>alice.html</a>
    <span itemprop=“name“>Alice Jones</span>
    </div>

    Wenn Du das tiefer verschachtelst, bekommst Du das Proplem, dass Du „Subproperties“ bekommst, was es so nicht gibt. Wenn Du in einer Klasse strukturierte Datentypen einbauen willst, baust Du weitere Klassen ein. Das geht hier auch so. Du musst dann erst mal ein itemtype einbauen, und damit einen Subtyp einhängen, dem Du wiederum neue Properties zuordnen kannst.

    • Ich weiß mittlerweile schon was du meinst 🙂

      …und prinzipiell hast du auch recht, wenn es um das Thema Konsistenz geht! Aber wie ich schon gepostet habe, steht in der Microdata-Spezifikation explizit, dass bei einem Link (a, link, o.Ä.) das href Attribut, statt dem „value“ interpretiert werden muss.

  7. O.k., dann sind wir uns, was die Theorie angeht, ja einig 🙂

    Dann zur Praxis. Da geht es zum Einen darum, wie man selber das Markup handhabt. Ich würde mich hier nach dem richt snippets von Google richten. Auf der anderen Seite der Parser: Hier würde ich das itemprop=“url“ entweder ignorieren oder prüfen.

    Zu Deinem article Beispiel: Das ist in der Tat so. Nur geht es nicht darum, welcher Link den Article als solchen auszeichnet. Das ist nur einer von möglicherweise vielen Links. Hier sagt itemprop=“url“ übrigens auch nur aus, dass das href Attribut eine url enthält, aber nicht, in was für einer Beziehung das Ziel der url zu dem Artikel steht. Hierzu kannst Du z.B. die rel und rev Attribute verwenden. Als Attributwerte eignen sich teilweise die Werte nach Dublin Core. Aber auch das w3c empfielt ein paar brauchbare link types.

    Der Link, der den Artikel als solchen auszeichnet, also der Link auf die Datei selbst, könnte z.B. mit rel=“dc:identifier“ ausgezeichnet werden. Der Permalink? Hmmm, momentan keine Ahnung, wenn dieser zu einer anderen Datei verweist. Müsste man mal suchen. Aber itemprop=“url“ hilft auch hier nicht weiter.

    Ich denke mal, dass Google hier mit der Spezifikation Mist gebaut hat.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.