<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>schema.org &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/schema-org/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Tue, 28 Apr 2026 06:57:37 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>schema.org &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[Maximally Semantic Structure for a Blog Post]]></title>
		<link>https://shkspr.mobi/blog/2026/01/maximally-semantic-structure-for-a-blog-post/</link>
					<comments>https://shkspr.mobi/blog/2026/01/maximally-semantic-structure-for-a-blog-post/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 12 Jan 2026 12:34:53 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=63440</guid>

					<description><![CDATA[Yes, I know the cliché that bloggers are always blogging about blogging!  I like semantics. It tickles that part of my delicious meaty brain that longs for structure. Semantics are good for computers and humans. Computers can easily understand the structure of the data, humans can use tools like screen-readers to extract the data they&#039;re interested in.  In HTML, there are three main ways to …]]></description>
										<content:encoded><![CDATA[<p>Yes, I know the cliché that bloggers are always blogging about blogging!</p>

<p>I like semantics. It tickles that part of my delicious meaty brain that longs for structure. Semantics are good for computers and humans. Computers can easily understand the structure of the data, humans can use tools like screen-readers to extract the data they're interested in.</p>

<p>In HTML, there are three main ways to impose semantics - elements, attributes, and hierarchical microdata.</p>

<p>Elements are easy to understand. Rather than using a generic element like <code>&lt;div&gt;</code> you can use something like <code>&lt;nav&gt;</code> to show an element's contents are for navigation. Or <code>&lt;address&gt;</code> to show that the contents are an address. Or <code>&lt;article&gt;&lt;section&gt;</code> to show that the section is part of a parent article.</p>

<p>Attributes are also common.  You can use <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel">relational attributes</a> to show how a link relates to the page it is on. For example <code>&lt;a rel=author href=https://example.com&gt;</code> shows that the link is to the author of the current page. Or, to see that a link goes to the previous page in a series <code>&lt;a rel=prev href=/page5&gt;</code>.</p>

<p>Finally, we enter the complex and frightening world of <em>microdata</em>.</p>

<p>Using the <a href="https://schema.org/">Schema.org vocabulary</a> it's possible to add semantic metadata <em>within</em> an HTML element. For example, <code>&lt;body itemtype=https://schema.org/Blog itemscope&gt;</code> says that the body of this page is a Blog. Or, to say how many words a piece has, <code>&lt;span itemprop=wordCount content=1100&gt;1,100 words&lt;/span&gt;</code>.</p>

<p>There are <em>many</em> properties you can use. Here's the outline structure of a single blog post with a code sample, a footnote, and a comment. You can <a href="https://validator.schema.org/">check its structured data</a> and verify that it is <a href="https://validator.w3.org/">conformant HTML</a>.</p>

<p>Feel free to reuse.</p>

<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html lang=en-gb&gt;
&lt;head&gt;&lt;title&gt;My Blog&lt;/title&gt;&lt;/head&gt;
&lt;body itemtype=https://schema.org/Blog itemscope&gt;

    &lt;header itemprop=headline&gt;
        &lt;a rel=home href=https://example.com&gt;My Blog&lt;/a&gt;
    &lt;/header&gt;

    &lt;main itemtype=https://schema.org/BlogPosting itemprop=blogPost itemscope&gt;
        &lt;article&gt;
            &lt;header&gt;
                &lt;time itemprop=https://schema.org/datePublished datetime=2025-12-01T12:34:39+01:00&gt;
                    1st January, 2025
                &lt;/time&gt;
                &lt;h1 itemprop=headline&gt;
                    &lt;a rel=bookmark href=https://example.com/page&gt;Post Title&lt;/a&gt;
                &lt;/h1&gt;
                &lt;span itemtype=https://schema.org/Person itemprop=author itemscope&gt;
                    &lt;a itemprop=url href=https://example.org/&gt;
                        By &lt;span itemprop=name&gt;Author Name&lt;/span&gt;
                    &lt;/a&gt;
                    &lt;img itemprop=image src=/photo.jpg alt&gt;
                &lt;/span&gt;
                &lt;p&gt;
                    &lt;a itemprop=keywords content=HTML rel=tag href=/tag/html/&gt;HTML&lt;/a&gt; 
                    &lt;a itemprop=keywords content=semantics rel=tag href=/tag/semantics/&gt;semantics&lt;/a&gt; 
                    &lt;a itemprop=commentCount content=6 href=#comments&gt;6 comments&lt;/a&gt;
                    &lt;span itemprop=wordCount content=1100&gt;1,100 words&lt;/span&gt;
                    &lt;span itemtype=https://schema.org/InteractionCounter itemprop=interactionStatistic itemscope&gt;
                        &lt;meta content=https://schema.org/ReadAction itemprop=interactionType&gt;
                        &lt;span itemprop=userInteractionCount content=5150&gt;
                            Viewed ~5,150 times
                        &lt;/span&gt;
                    &lt;/span&gt;
                &lt;/p&gt;
            &lt;/header&gt;

            &lt;div itemprop=articleBody&gt;
                &lt;img itemprop=image src=/hero.png alt&gt;
                &lt;p&gt;Text of the post.&lt;/p&gt;
                &lt;p&gt;Text with a footnote&lt;sup id=fnref&gt;&lt;a role=doc-noteref href=#fn&gt;0&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

                &lt;pre itemtype=https://schema.org/SoftwareSourceCode itemscope translate=no&gt;
                    &lt;span itemprop=programmingLanguage&gt;PHP&lt;/span&gt;
                    &lt;code itemprop=text&gt;&amp;amp;lt;?php echo $postID ?&amp;amp;gt;&lt;/code&gt;
                &lt;/pre&gt;

                &lt;section role=doc-endnotes&gt;
                    &lt;h2&gt;Footnotes&lt;/h2&gt;
                    &lt;ol&gt;
                        &lt;li id=fn&gt;
                            &lt;p&gt;Footnote text. &lt;a role=doc-backlink href=#fnref&gt;↩︎&lt;/a&gt;&lt;/p&gt;
                        &lt;/li&gt;
                    &lt;/ol&gt;
                &lt;/section&gt;
            &lt;/div&gt;
        &lt;/article&gt;

        &lt;section id=comments&gt;
            &lt;h2&gt;Comments&lt;/h2&gt;
            &lt;article itemtype=https://schema.org/Comment itemscope id="comment-123465"&gt;
                &lt;time itemprop=dateCreated datetime=2025-09-11T13:24:54+01:00&gt;
                    &lt;a itemprop=url href=#comment-123465&gt;2025-09-11 13:24&lt;/a&gt;
                &lt;/time&gt;
                &lt;div itemtype=https://schema.org/Person itemprop=author itemscope&gt;
                    &lt;img itemprop=image src="/avatar.jpg" alt&gt;
                    &lt;h3&gt;
                        &lt;span itemprop=name&gt;Alice&lt;/span&gt; says:
                    &lt;/h3&gt;
                &lt;/div&gt;
                &lt;div itemprop=text&gt;
                    &lt;p&gt;Comment text&lt;/p&gt;
                &lt;/div&gt;
            &lt;/article&gt;
        &lt;/section&gt;
    &lt;/main&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>This blog post is entitled "maximally" but, of course, <a href="https://schema.org/BlogPosting">there is <em>lots</em> more that you can add</a> if you really want to.</p>

<p>Remember, none of this is <em>necessary</em>. Computers and humans are pretty good at extracting meaning from unstructured text. But making things easier for others is always time well spent.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=63440&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2026/01/maximally-semantic-structure-for-a-blog-post/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Fixing "Date/time not in ISO 8601 format" in Google Search Console]]></title>
		<link>https://shkspr.mobi/blog/2025/12/fixing-date-time-not-in-iso-8601-format-in-google-search-console/</link>
					<comments>https://shkspr.mobi/blog/2025/12/fixing-date-time-not-in-iso-8601-format-in-google-search-console/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 24 Dec 2025 12:34:43 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=62176</guid>

					<description><![CDATA[I like using microdata within my HTML to provide semantic metadata.  One of my pages had this scrap of code on it:  &#60;time    itemprop=&#34;datePublished&#34;    itemscope    datetime=&#34;2025-06-09T11:27:06+01:00&#34;&#62;9 June 2025 11:27&#60;/time&#62;   The Google Search Console was throwing this error:    I was fairly sure that was a valid ISO 8601 string. It certainly matched the description in the Google…]]></description>
										<content:encoded><![CDATA[<p>I like using microdata within my HTML to provide semantic metadata.  One of my pages had this scrap of code on it:</p>

<pre><code class="language-html">&lt;time
   itemprop="datePublished"
   itemscope
   datetime="2025-06-09T11:27:06+01:00"&gt;9 June 2025 11:27&lt;/time&gt;
</code></pre>

<p>The Google Search Console was throwing this error:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/Datetime-not-in-ISO-8601-format-in-field-datePublished.webp" alt="Date/time not in ISO 8601 format in field 'datePublished' Items with this issue are invalid. Invalid items are not eligible for Google Search's rich results" width="690" height="180" class="aligncenter size-full wp-image-62177">

<p>I was fairly sure that was a valid ISO 8601 string. It certainly matched <a href="https://developers.google.com/search/docs/appearance/structured-data/discussion-forum#microdata">the description in the Google documentation</a>. Nevertheless, I fiddled with a few different formats, but all failed.</p>

<p>On <a href="https://support.google.com/webmasters/thread/359976663/iso8601-string-not-validating?msgid=360727451#">the advice</a> of <a href="https://www.nearby.org.uk/">Barry Hunter</a>, I tried changing the <code>datetime</code> attribute to <code>content</code>. That also didn't work.</p>

<p>Then I looked closely at the code.</p>

<p>The issue is the <code>itemscope</code>. Removing that allowed the code to pass validation.  But why?</p>

<p>Here's what <a href="https://schema.org/docs/gs.html#microdata_itemscope_itemtype">the Schema.org documentation</a> says:</p>

<blockquote><p>By adding itemscope, you are specifying that the HTML contained in the block is about a particular item.</p></blockquote>

<p>The <a href="https://html.spec.whatwg.org/multipage/microdata.html#attr-itemscope">HTML specification</a> gives this example:</p>

<pre><code class="language-html">&lt;div itemscope&gt;
   &lt;img itemprop="image" src="google-logo.png" alt="Google"&gt;
&lt;/div&gt;
</code></pre>

<p>Here, the <code>image</code> property is the <em>value</em> of the element. In this case <code>google-logo.png</code>. So what's the problem with the <code>time</code> example?</p>

<p>Well, <code>&lt;image&gt;</code> is a <em>void</em> element. It doesn't have any HTML content - so the metadata is taken from the <code>src</code> attribute.</p>

<p>But <code>&lt;time&gt;</code> is <em>not</em> a void element. It <em>does</em> contain HTML. So something like this would be valid:</p>

<pre><code class="language-html">&lt;time
   itemprop="datePublished"
   itemscope
&gt;2025-06-09T11:27:06+01:00&lt;/time&gt;
</code></pre>

<p>The text contained by the element is a valid ISO8601 string.</p>

<p>My choice was either to present the ISO8601 string to anyone viewing the page, or simply to remove the <code>itemscope</code>.  So I chose the latter.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=62176&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/12/fixing-date-time-not-in-iso-8601-format-in-google-search-console/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Class Warfare! Can I eliminate CSS classes from my HTML?]]></title>
		<link>https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/</link>
					<comments>https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 19 Sep 2025 11:34:55 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=63392</guid>

					<description><![CDATA[I recently read a brilliantly provocative blog post called &#34;This website has no class&#34;. In it, Adam Stoddard makes the case that you might not need CSS classes on a modern website:  I think constraints lead to interesting, creative solutions […]. Instead of relying on built in elements a bit more, I decided to banish classes from my website completely.  Long time readers will know that I&#039;m a big f…]]></description>
										<content:encoded><![CDATA[<p>I recently read a brilliantly provocative blog post called "<a href="https://aaadaaam.com/notes/no-class/">This website has no class</a>". In it, Adam Stoddard makes the case that you might not need CSS classes on a modern website:</p>

<blockquote><p>I think constraints lead to interesting, creative solutions […]. Instead of relying on built in elements a bit more, I decided to banish classes from my website completely.</p></blockquote>

<p>Long time readers will know that I'm a big fan of using semantic HTML where possible. If you peek beneath the curtain of this website you'll only see a handful of <code>&lt;div&gt;</code> elements (mostly because WordPress hardcodes them) - all the other blocks are fully semantic. Regrettably, there are rather too many <code>&lt;span&gt;</code> elements for my liking - normally for accessibility or for supplementing the metadata.</p>

<p>Overall, my CSS contained about 134 rules which selected based on class. Is that a lot? It <em>feels</em> like a lot.</p>

<p>On the one hand, classes are an easy way of splitting and grouping elements. Some <code>&lt;img&gt;</code>s should be displayed one way, the rest another. There's no semantic way to say "This is a hero image and should take up the full width, but this is an icon and should float discretely to the right."</p>

<p>But, on the other hand, <em>why</em> do we need classes?  Keith Cirkel's excellent post "<a href="https://www.keithcirkel.co.uk/css-classes-considered-harmful/">CSS Classes considered harmful</a>" goes through their history and brings together some proposed solutions for replacing them. I think his idea of using <code>data-</code> attributes is a neat hack - but ultimately isn't much different from using classes. It's still a scrap of metadata to be tied into a style-sheet.</p>

<p>Classes are great for when you <em>reuse</em> something.  I have multiple <code>&lt;section&gt;</code> elements but most don't share anything in common with the others. So they probably oughtn't have classes.</p>

<p>Removing classes has some advantages. It makes the HTML fractionally smaller, sure, but it also forces the author to think about the logical structure of their page and the semantics behind it.</p>

<p>Looking through my HTML, lots of classes exist because of laziness. If I want to position all the <code>&lt;time&gt;</code> elements which are within a comment, I don't <em>need</em> to write <code>&lt;time class="whatever"&gt;</code> and to pair it with <code>.whatever { … }</code>. Instead, I can use modern CSS selectors and say <code>#comments time { … }</code>.</p>

<p>But this leads me on to another existential question.</p>

<h2 id="are-ids-necessary-in-modern-html"><a href="https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/#are-ids-necessary-in-modern-html">Are IDs necessary in modern HTML?</a></h2>

<p>Mayyyyybe? I only have one <code>&lt;main&gt;</code> element, so an ID on there is unnecessary. <code>&lt;input&gt;</code> elements need IDs in order to be properly targetted by <code>&lt;label&gt;</code>s - but the label can wrap around the input. I have multiple <code>&lt;aside&gt;</code> elements because there's no semantic <code>&lt;widget&gt;</code> element, so they need unique IDs.</p>

<p>In theory, as suggested by Adam above, I could use an <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements">autonomous custom element</a> like <code>&lt;my-widget&gt;</code> - but that has none of the semantics and, frankly, feels like a bit of a cheat.</p>

<h2 id="trimming-the-fat"><a href="https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/#trimming-the-fat">Trimming the fat</a></h2>

<p>Any day where I can delete some code is a good day. This was an excellent exercise in going through (years) of HTML and CSS to see what cruft had built up.</p>

<p>The first CSS rule I changed was, as mentioned above:</p>

<pre><code class="language-css">time.commentmetadata {
    float: right;
}
</code></pre>

<p>Which became:</p>

<pre><code class="language-CSS">#comments time { 
    float: right;
}
</code></pre>

<p>Classless and slightly more brief. Is it more readable? Having the fact it was about the metadata in a class could have been slightly useful - but if I thought it would be confusing, I could stick a <code>/* comment */</code> in there.</p>

<p>Next, I found <code>&lt;nav class="navigation posts-navigation"&gt;</code> - what a tautology! I have multiple <code>&lt;nav&gt;</code> elements, it is true. But none of them have the same style. So this swiftly became <code>&lt;nav id="posts-navigation"&gt;</code> with an accompanying CSS rewrite.</p>

<p>My theme switcher had a bunch of <code>&lt;label class=button&gt;</code>s. They were all within a container with a unique ID, so could they be changed? Yes. But seeing the class name in the HTML is a good reminder to the author of <em>how</em> they are meant to display. Does that co-mingle content and presentation too much?</p>

<p>Some of the WordPress default classes are ridiculous. The <code>body_class()</code> function injected this into every <code>&lt;body&gt;</code></p>

<p><code>"wp-singular post-template-default single single-post postid-62959 single-format-standard wp-theme-edent-wordpress-theme"</code></p>

<p>Most of that is redundant - what's the difference between single and single-post? For my purposes, nothing! So they were all yeeted into the sun.</p>

<p>Rather than targetting IDs or classes, I targetted the presence or absence of Schema.org microdata.</p>

<p>For example:</p>

<pre><code class="language-css">main[itemprop="blogPost"] { … }
main:not([itemprop="blogPost"]) { … }
</code></pre>

<p>This can go to the extreme. I have lots of comments, each one has an author, the author's details are wrapped in <code>&lt;div class="authordetails"&gt;…&lt;/div&gt;</code></p>

<p>That can be replaced with:</p>

<pre><code class="language-css">/* Comment Author */
li[itemtype="https://schema.org/Comment"] &gt; article &gt; div[itemprop="https://schema.org/author"] {
    margin-bottom: 0;
}
</code></pre>

<p>Is that <em>sensible</em>? It is more semantic, but feels a bit brittle.</p>

<p>Parent selector are also now a thing. If I want a paragraph to have centred text but <em>only</em> when there's a submit button inside it:</p>

<pre><code class="language-css">p:has(input#submit) {
  text-align: center;
}
</code></pre>

<p>Again, am I sure that my button will always be inside a paragraph?</p>

<p>Similarly, <a href="https://css-tricks.com/child-and-sibling-selectors/">sibling selectors</a> are sometimes superior - but they do suppose that your layout never changes.</p>

<h2 id="what-remains"><a href="https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/#what-remains">What remains?</a></h2>

<p>There are some bits of this site which are reusable and do need classes. The code-highlighting you see above requires text to be wrapped in spans with specific classes.</p>

<p>Image alignment was also heavily class based.</p>

<p>There are some accessibility things which are either hidden or exposed using classes.</p>

<p>A bunch of WordPress defaults use classes and, even if they are redundant, it's hard to exorcise them.</p>

<p>As much as I would have liked to get rid of all my IDs, many needed to stay for linking as well as CSS targetting.</p>

<p>All told, the changes I made were:</p>

<ul>
<li>134 class selectors down to about 65.</li>
<li>35 ID selectors up to about 50.</li>
<li>5 attribute selectors up to to about 20.</li>
<li>Deleted or combined a lot of redundant CSS and tidied up my markup considerably.</li>
</ul>

<p>I have around 250 CSS rules, so now the majority target semantics rather than classes or IDs.</p>

<h2 id="is-this-really-necessary"><a href="https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/#is-this-really-necessary">Is this really necessary?</a></h2>

<p>No, of course not. This is an exercise in minimalism, creativity, and constraint. Feel free to litter your HTML with whatever attributes you want!</p>

<p>As I went through, it increasingly became apparent that I was fitting my CSS to my HTML's logical structure rather than to its <em>conceptual</em> structure.</p>

<p>Previously, my comments were targetted with a class. Now they have the slightly more tangled targetting of "divs with this schema attribute whose parent is an article and whose grandparent has this ID".</p>

<p>It is a delightful meditative exercise to go through your code and deeply consider whether something is unique, reusable, or obsolete.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=63392&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Is IPA furigana a bad idea?]]></title>
		<link>https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/</link>
					<comments>https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 10 Oct 2024 11:34:17 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=53099</guid>

					<description><![CDATA[My name is Terence(/ˈtɛɹəns) Eden(ˈiːdən/).  Modern HTML allows the user to use &#60;ruby&#62; to annotate text.  This is usually used for furigana - which allows pronunciation to be placed above words.  For example: &#34;シン・ゴジラ (Shin Godzilla)&#34; shows you how to pronounce both words if you are unfamiliar with kanji.  The text can be any language or use any characters. In Japanese, it is quite often used to sh…]]></description>
										<content:encoded><![CDATA[<p>My name is <ruby><rb>Terence</rb><rp>(</rp><rt>/ˈtɛɹəns</rt><rp>)</rp><rb> Eden</rb><rp>(</rp><rt>ˈiːdən/</rt><rp>)</rp></ruby>.</p>

<p>Modern HTML allows the user to use <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby"><code>&lt;ruby&gt;</code></a> to annotate text.</p>

<p>This is <em>usually</em> used for <a href="https://en.wikipedia.org/wiki/Furigana">furigana</a> - which allows pronunciation to be placed above words.</p>

<p>For example: "<ruby>シン・ゴジラ <rp>(</rp><rt>Shin Godzilla</rt><rp>)</rp></ruby>" shows you how to pronounce both words if you are unfamiliar with <a href="https://en.wikipedia.org/wiki/Kanji">kanji</a>.  The text can be any language or use any characters. In Japanese, it is quite often used to show phonetic pronunciation using <a href="https://en.wikipedia.org/wiki/Hiragana">hiragana</a>.</p>

<p>Because English is a <a href="https://www.reddit.com/r/linguistics/comments/anzy8o/the_common_saying_i_see_on_reddit_is_english_is_3/">composite language</a><sup id="fnref:whore"><a href="https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/#fn:whore" class="footnote-ref" title="Or a mongrel language" role="doc-noteref">0</a></sup>, it isn't always easy for people to pronounce words<sup id="fnref:vid"><a href="https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/#fn:vid" class="footnote-ref" title="Yes, I've seen that funny Tiktok. And that one." role="doc-noteref">1</a></sup>.</p>

<p>So I have abused(?) the ruby syntax to show the <a href="https://en.wikipedia.org/wiki/International_Phonetic_Alphabet">International Phonetic Alphabet</a> above the English words.</p>

<p>Is this a <em>good</em> idea? Is it a valid use of the syntax? Is it semantically correct? I don't know. But I do now know that it is <em>possible</em>.</p>

<p>I doubt the majority of people know the IPA, so it is of dubious use. It does make my name's pronunciation more apparent to machines.</p>

<p>An alternative is to use <a href="https://schema.org">Schema.org</a>. For example, my <a href="https://edent.tel">contact page</a> has the following microdata:</p>

<pre><code class="language-html">&lt;main itemscope itemtype="https://schema.org/Person"&gt;
    &lt;header itemprop="name"&gt;
        &lt;h1&gt;
            &lt;span itemprop="givenName"&gt;Terence&lt;/span&gt;&amp;nbsp;
            &lt;span itemprop="familyName"&gt;Eden&lt;/span&gt;
            &lt;audio id="audioPlayer" src="Terence_Eden.mp3" 
                    itemscope itemprop="additionalType" 
                    itemtype="https://schema.org/PronounceableText"&gt;
                &lt;meta itemprop="phoneticText"       content="/ˈtɛɹəns ˈiːdən/"&gt;
                &lt;meta itemprop="inLanguage"         content="en-GB"&gt;
                &lt;meta itemprop="textValue"          content="Terence Eden"&gt;
                &lt;meta itemprop="speechToTextMarkup" content="IPA"&gt;
            &lt;/audio&gt;
</code></pre>

<p>That allows humans to listen to the pronunciation of my name, and machines to see the IPA version.</p>

<p>Is there a better, more accessible, more useful way of encoding how to pronounce text?</p>

<div id="footnotes" role="doc-endnotes">
<hr aria-label="Footnotes">
<ol start="0">

<li id="fn:whore">
<p>Or a <a href="https://en.wikiquote.org/wiki/James_Nicoll">mongrel language</a>&nbsp;<a href="https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/#fnref:whore" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

<li id="fn:vid">
<p>Yes, I've seen that funny Tiktok. And that one.&nbsp;<a href="https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/#fnref:vid" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=53099&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/10/is-ipa-furigana-a-bad-idea/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[What programming language is in this <code> block?]]></title>
		<link>https://shkspr.mobi/blog/2024/08/what-programming-language-is-in-this-code-block/</link>
					<comments>https://shkspr.mobi/blog/2024/08/what-programming-language-is-in-this-code-block/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Tue, 27 Aug 2024 11:34:28 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=52095</guid>

					<description><![CDATA[I&#039;m a little bit obsessed with the idea of Semantic markup. I want the words that I write to be understood my humans and machines.  Imagine this piece of code: print( &#34;Hello, world!&#34; )  Is that code example written in Python? C++? Basic? Go? Perhaps you&#039;re familiar enough with every programming language to tell - but most people aren&#039;t.  Wouldn&#039;t it be nice to give an indication of what…]]></description>
										<content:encoded><![CDATA[<p>I'm a little bit obsessed with the idea of Semantic markup. I want the words that I write to be understood my humans <em>and</em> machines.</p>

<p>Imagine this piece of code: <code>print( "Hello, world!" )</code></p>

<p>Is that code example written in Python? C++? Basic? Go? Perhaps you're familiar enough with every programming language to tell - but most people aren't.  Wouldn't it be nice to give an indication of <em>what</em> programming language is used in an example?</p>

<p>Here's how we might represent it in HTML:</p>

<pre><code class="language-_">&lt;pre&gt;
    &lt;code&gt;
        print( "Hello, world!" )
    &lt;/code&gt;
&lt;/pre&gt;
</code></pre>

<p>How do we let the browser, search engines, and humans know what language that's written in? It might seem obvious to use the <code>lang</code> attribute, right? We're writing in a programming language, so just use <code>&lt;code lang="python"&gt;</code>. Sadly, the HTML specification disagrees.</p>

<blockquote><p>The lang attribute specifies the primary language for the element's contents and for any of the element's attributes that contain text. Its value <strong>must be a valid BCP 47 language tag</strong>, or the empty string. <br> <a href="https://html.spec.whatwg.org/multipage/dom.html#attr-lang">HTML Specification 3.2.6.2 The lang and xml:lang attributes</a> (emphasis added)</p></blockquote>

<p>That means it must be a <em>human</em> language like <code>en</code> or <code>en-GB</code>. No Klingon or Elvish - and certainly no computer languages!</p>

<p>Does the specification give any clues about the <code>&lt;code&gt;</code> element?</p>

<blockquote><p>There is <strong>no formal way to indicate the language of computer code</strong> being marked up. Authors who wish to mark code elements with the language used, e.g. so that syntax highlighting scripts can use the right rules, can use the class attribute, e.g. by adding a class prefixed with "language-" to the element.<br><a href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-code-element">HTML Specification 4.5.15 The code element</a> (emphasis added)</p></blockquote>

<p>So we have to turn to our old friend Schema.org! There is a <a href="https://schema.org/SoftwareSourceCode"><code>SoftwareSourceCode</code> type</a> which is used for exactly this case. Sadly, there is no example documentation because Google likes to start up a project but never quite finish it.</p>

<p>Here's how to write a code snippet in HTML and have it semantically expose the programming language used:</p>

<pre><code class="language-HTML">&lt;pre itemscope itemtype="https://schema.org/SoftwareSourceCode"&gt;
    &lt;span itemprop="programmingLanguage"&gt;Python&lt;/span&gt;
    &lt;meta itemprop="codeSampleType" content="Example"&gt;
    &lt;code itemprop="text"&gt;
        print( "Hello, world!" )
    &lt;/code&gt;
&lt;/pre&gt;
</code></pre>

<p>If you <a href="https://validator.schema.org/#url=https%3A%2F%2Fshkspr.mobi%2Fblog%2F2024%2F08%2Fwhat-programming-language-is-in-this-code-block%2F">run that through the validator</a> you'll see what a computer sees:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2024/08/schema-fs8.png" alt="Semantic representation of the code." width="1648" height="360" class="aligncenter size-full wp-image-52102">

<p>The <code>programmingLanguage</code> is a string - so you can write anything you like in there. You can optionally add a <code>codeSampleType</code> which, again, is a free-text field.</p>

<p>The <code>&lt;meta&gt;</code> items are only viewable to machines. You could also them to the user if you wanted, using a <code>&lt;span&gt;</code> or other suitable element.</p>

<h2 id="alternatives"><a href="https://shkspr.mobi/blog/2024/08/what-programming-language-is-in-this-code-block/#alternatives">Alternatives</a></h2>

<p>It is possible to define <a href="https://www.rfc-editor.org/rfc/rfc5646#section-2.2.6">private subtags of languages</a> for example <code>en-x-python</code> - which could mean "Comments written in English, using the private Python extension. Or even just <code>x-python</code>. That then leads on to how you describe a language - but while <a href="https://www.iana.org/assignments/media-types/application/vnd.acucobol">COBOL has a MIME type</a> not all languages do.  There are some unofficial ones like <a href="https://mimetype.io/text/x-python"><code>text/x-python</code></a> though.</p>

<p>But, of course, <a href="https://sonomu.club/@threedaymonk/112970802651966367">programming languages aren't really languages</a> - so using <code>lang</code> probably isn't suitable.</p>

<p>A <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes"><code>data-</code> attribute</a> might also work. Adding <code>data-code="python"</code> would allow CSS to style specific code blocks. But data attributes are private to a page, and generally aren't standardised.</p>

<p>I <em>think</em> this is a gap in the specification. I think there ought to be a <code>code-lang</code> attribute or similar. Perhaps something like:</p>

<pre><code class="language-HTML">&lt;code code-lang="python;3.6"&gt;
    print( "Hello, world!" )
&lt;/code&gt;
</code></pre>

<p>Which could allow authors to semantically give the name - and possibly version - of the programming language they are writing in.</p>

<p>Thoughts?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=52095&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/08/what-programming-language-is-in-this-code-block/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Addressing the Overlooked Non-Micropsychiatric Uses for Thiotimoline]]></title>
		<link>https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/</link>
					<comments>https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 26 Jun 2023 11:34:34 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=46126</guid>

					<description><![CDATA[One of the (many) problems with AI is that training data usually needs to come from &#34;natural&#34; sources. If you want to emulate human-written text, you need to train something on human-written text.   But with the proliferation of cheap and fast AI tools, it is likely that training data will unwillingly become contaminated with AI-written text.  In order to prevent the &#34;Habsburg Jaw&#34; effect, I…]]></description>
										<content:encoded><![CDATA[<p>One of the (many) problems with AI is that training data usually needs to come from "natural" sources. If you want to emulate human-written text, you need to train something on human-written text.   But with the proliferation of cheap and fast AI tools, it is likely that training data will unwillingly become contaminated with AI-written text.</p>

<p>In order to prevent the "Habsburg Jaw" effect, I think it would be helpful if publishers could semantically indicate that a work was written by AI.  In this example, I'm using <a href="https://schema.org/Quotation">Schema.org's Quotation type</a> to show that I'm quoting an AI, and explicitly set the author to ChatGPT.</p>

<pre><code class="language-html">&lt;span itemscope itemtype="https://schema.org/Quotation"&gt;
    Author: &lt;span itemprop="author" 
                  itemscope itemtype="https://schema.org/Organization"
                  itemid="https://chat.openai.com"&gt;OpenAI ChatGPT&lt;/span&gt;
    &lt;span itemprop="text"&gt;...&lt;/span&gt;
&lt;/span&gt;
</code></pre>

<p>Is that sufficient to stop AIs from feeding on their own young? I don't know. I also don't know if this covers every possible use-case, or whether there are better ways to address this. I'd be interested in hearing your thoughts.</p>

<p>Anyway, here's a letter to the editor of Nature written by ChatGPT. It took a little bit of prompt-engineering, but I'm rather pleased with how readily it took to the idea of inventing new uses for <a href="https://en.wikipedia.org/wiki/Thiotimoline">Thiotimoline</a>. I especially like the way it has created obviously fictitious journals in its citations!  This example is marked up so as to let robots know that it is a synthetic output.</p>

<p><span itemscope="" itemtype="https://schema.org/Quotation">
    Author: <span itemprop="author" itemscope="" itemtype="https://schema.org/Organization" itemid="https://chat.openai.com">OpenAI ChatGPT</span><br>
    <span itemprop="text">
Dear Editor,</span></span></p>

<p>I hope this letter finds you well. As a distinguished biologist who has been an avid reader of Nature for many years, I would like to draw attention to a concerning issue that I believe has inadvertently slipped through the cracks of the journal's otherwise comprehensive coverage of scientific advancements. It is with great disappointment that I note the persistent oversight of the non-micropsychiatric applications of Thiotimoline, an area of research that deserves proper recognition.</p>

<p>Thiotimoline has generated considerable interest within the scientific community due to its unique temporal properties and hypothetical solubility characteristics.</p>

<p>Contrary to popular belief, Thiotimoline's potential extends far beyond the realm of micropsychiatry. Researchers have explored various hypothetical applications in multiple disciplines, and it is disheartening to witness Nature's omission of these intriguing possibilities. Allow me to shed some light on the non-micropsychiatric uses of Thiotimoline that merit attention:</p>

<ul>
<li><p>Time-Dependent Chemical Reactions: Thiotimoline's purported ability to dissolve before it comes into contact with water presents fascinating prospects for studying time-dependent chemical reactions. By altering reaction kinetics and introducing temporal dimensions into experimental setups, Thiotimoline could revolutionize our understanding of reaction mechanisms and provide insights into complex chemical processes <sup id="fnref:1"><a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fn:1" class="footnote-ref" title="Hypothetical Research, Journal of Speculative Chemistry, vol. 123, no. 4, pp. 567-578, 20XX." role="doc-noteref">0</a></sup>.</p></li>
<li><p>Temporal Pharmacokinetics: Thiotimoline's hypothetical solubility properties and unique temporal characteristics offer a potential breakthrough in drug delivery systems. Controlled-release formulations utilizing Thiotimoline could provide precise temporal dosing, ensuring optimal drug concentrations at critical intervals and improving therapeutic efficacy <sup id="fnref:2"><a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fn:2" class="footnote-ref" title="Imaginary Drug Delivery Systems, Journal of Fictional Pharmacology, vol. 45, no. 2, pp. 211-223, 20XX." role="doc-noteref">1</a></sup>.</p></li>
<li><p>Time-Sensitive Analytical Chemistry: Thiotimoline's temporal properties have captivated analytical chemists, inspiring innovative methodologies in time-sensitive analysis. Researchers propose the use of Thiotimoline as a temporal indicator, enabling real-time monitoring of chemical reactions and facilitating rapid data acquisition in various analytical techniques <sup id="fnref:3"><a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fn:3" class="footnote-ref" title="Exploring Time-Sensitive Analytical Techniques, Fictional Analytical Chemistry Review, vol. 67, no. 3, pp. 354-365, 20XX." role="doc-noteref">2</a></sup>.</p></li>
</ul>

<p>While the studies mentioned above are speculative, they demonstrate the conceptual potential of Thiotimoline as a catalyst for groundbreaking scientific exploration. By embracing the imaginative aspects of scientific inquiry, we can encourage innovative thinking and uncover unexpected insights that may guide future advancements.</p>

<p>I implore Nature to devote some attention to these non-micropsychiatric uses of Thiotimoline. By acknowledging the imaginative scientific spirit that drives our quest for knowledge, the journal can foster interdisciplinary collaboration and inspire researchers to explore uncharted territories.</p>

<p>Thank you for considering my concerns. I sincerely hope that Nature will continue to lead the scientific community by embracing the full spectrum of scientific endeavors.</p>

<p>Yours faithfully,

</p>

<div id="footnotes" role="doc-endnotes">
<hr aria-label="Footnotes">
<ol start="0">

<li id="fn:1">
<p>Hypothetical Research, Journal of Speculative Chemistry, vol. 123, no. 4, pp. 567-578, 20XX.&nbsp;<a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

<li id="fn:2">
<p>Imaginary Drug Delivery Systems, Journal of Fictional Pharmacology, vol. 45, no. 2, pp. 211-223, 20XX.&nbsp;<a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

<li id="fn:3">
<p>Exploring Time-Sensitive Analytical Techniques, Fictional Analytical Chemistry Review, vol. 67, no. 3, pp. 354-365, 20XX.&nbsp;<a href="https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=46126&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/06/addressing-the-overlooked-non-micropsychiatric-uses-for-thiotimoline/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[LinkedIn supports Schema‎.org metadata]]></title>
		<link>https://shkspr.mobi/blog/2023/06/linkedin-supports-schema-org-metadata/</link>
					<comments>https://shkspr.mobi/blog/2023/06/linkedin-supports-schema-org-metadata/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 23 Jun 2023 11:34:09 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[linked data]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=46089</guid>

					<description><![CDATA[I&#039;m a big fan of machine-readable metadata. It&#039;s useful for programs which need to extract information from messy and complicated websites. It&#039;s always surprising where it turns up.  For example, take this post of mine on LinkedIn. If you view the source, you&#039;ll see this scrap of linked data:  &#38;lt;script type=&#38;quot;application/ld+json&#38;quot;&#38;gt; {   &#38;quot;@context&#38;quot;:…]]></description>
										<content:encoded><![CDATA[<p>I'm a big fan of machine-readable metadata. It's useful for programs which need to extract information from messy and complicated websites. It's always surprising where it turns up.</p>

<p>For example, take <a href="https://www.linkedin.com/posts/terenceeden_did-you-know-that-every-post-you-make-on-activity-7075043149462556672-fxiw?utm_source=share&amp;utm_medium=member_desktop">this post of mine on LinkedIn</a>. If you view the source, you'll see this scrap of linked data:</p>

<pre><code class="language-html">&amp;lt;script type=&amp;quot;application/ld+json&amp;quot;&amp;gt;
{
  &amp;quot;@context&amp;quot;: &amp;quot;http://schema.org&amp;quot;,
  &amp;quot;@type&amp;quot;: &amp;quot;SocialMediaPosting&amp;quot;,
  &amp;quot;@id&amp;quot;: &amp;quot;https://www.linkedin.com/posts/terenceeden_did-you-know-that-every-post-you-make-on-activity-7075043149462556672-fxiw&amp;quot;,
  &amp;quot;author&amp;quot;: {
    &amp;quot;name&amp;quot;: &amp;quot;Terence Eden&amp;quot;,
    &amp;quot;image&amp;quot;: {
      &amp;quot;url&amp;quot;: &amp;quot;https://media.licdn.com/dms/image/C4E03AQEX11qBnAo43A/profile-displayphoto-shrink_400_400/0/1517677542848?e=1692230400&amp;amp;v=beta&amp;amp;t=-AHOoj__Ehm_p24dQ6McPbqNj9gQ2UsjvzOCIU16IGs&amp;quot;,
      &amp;quot;@type&amp;quot;: &amp;quot;ImageObject&amp;quot;
    },
    &amp;quot;url&amp;quot;: &amp;quot;https://uk.linkedin.com/in/terenceeden&amp;quot;,
    &amp;quot;@type&amp;quot;: &amp;quot;Person&amp;quot;
  },
  &amp;quot;datePublished&amp;quot;: &amp;quot;2023-06-15T09:35:34.752Z&amp;quot;,
  &amp;quot;articleBody&amp;quot;: &amp;quot;Did you know that every post you make on LinkedIn has SchemaOrg metadata embedded in it?\n(This post mostly to test which fields are supported.)&amp;quot;,
  &amp;quot;isAccessibleForFree&amp;quot;: false,
  &amp;quot;hasPart&amp;quot;: {
    &amp;quot;@type&amp;quot;: &amp;quot;WebPageElement&amp;quot;,
    &amp;quot;isAccessibleForFree&amp;quot;: false,
    &amp;quot;cssSelector&amp;quot;: &amp;quot;.details&amp;quot;
  }
}
&amp;lt;/script&amp;gt;
</code></pre>

<p>If you share a link in your post, the markup is slightly different:</p>

<pre><code class="language-html">&amp;lt;script type=&amp;quot;application/ld+json&amp;quot;&amp;gt;
{
  &amp;quot;@context&amp;quot;: &amp;quot;http://schema.org&amp;quot;,
  &amp;quot;@type&amp;quot;: &amp;quot;SocialMediaPosting&amp;quot;,
  &amp;quot;@id&amp;quot;: &amp;quot;https://www.linkedin.com/posts/terenceeden_why-im-using-mx-as-a-title-activity-7074702026084884480-jO0C&amp;quot;,
  &amp;quot;author&amp;quot;: {
    &amp;quot;name&amp;quot;: &amp;quot;Terence Eden&amp;quot;,
    &amp;quot;image&amp;quot;: {
      &amp;quot;url&amp;quot;: &amp;quot;https://media.licdn.com/dms/image/C4E03AQEX11qBnAo43A/profile-displayphoto-shrink_400_400/0/1517677542848?e=1692230400&amp;amp;v=beta&amp;amp;t=-AHOoj__Ehm_p24dQ6McPbqNj9gQ2UsjvzOCIU16IGs&amp;quot;,
      &amp;quot;@type&amp;quot;: &amp;quot;ImageObject&amp;quot;
    },
    &amp;quot;url&amp;quot;: &amp;quot;https://uk.linkedin.com/in/terenceeden&amp;quot;,
    &amp;quot;@type&amp;quot;: &amp;quot;Person&amp;quot;
  },
  &amp;quot;datePublished&amp;quot;: &amp;quot;2023-06-14T11:00:04.600Z&amp;quot;,
  &amp;quot;image&amp;quot;: {
    &amp;quot;url&amp;quot;: &amp;quot;https://media.licdn.com/dms/image/sync/D5627AQHWF4nuGqlfzQ/articleshare-shrink_800/0/1686397225711?e=1687428000&amp;amp;v=beta&amp;amp;t=SsQ_1b8M3xAGXnhUvID0976rpItlTLdC2Gz9RG3sXwI&amp;quot;,
    &amp;quot;@type&amp;quot;: &amp;quot;ImageObject&amp;quot;
  },
  &amp;quot;sharedContent&amp;quot;: {
    &amp;quot;@type&amp;quot;: &amp;quot;WebPage&amp;quot;,
    &amp;quot;headline&amp;quot;: &amp;quot;Why I&amp;#039;m using \&amp;quot;Mx\&amp;quot; as a title&amp;quot;,
    &amp;quot;url&amp;quot;: &amp;quot;https://shkspr.mobi/blog/2023/06/why-im-using-mx-as-a-title/&amp;quot;
  },
  &amp;quot;articleBody&amp;quot;: &amp;quot;What title do you use when filling in forms? Mr? Mrs? Ms? Or something newer and more incluside?\n\nWhy do companies want to know my title? What are they going to do with my data?\n\nHere&amp;#039;s why I&amp;#039;m using \&amp;quot;Mx\&amp;quot; as my title.\nhttps://lnkd.in/eCNH5sqp&amp;quot;,
  &amp;quot;isAccessibleForFree&amp;quot;: false,
  &amp;quot;hasPart&amp;quot;: {
    &amp;quot;@type&amp;quot;: &amp;quot;WebPageElement&amp;quot;,
    &amp;quot;isAccessibleForFree&amp;quot;: false,
    &amp;quot;cssSelector&amp;quot;: &amp;quot;.details&amp;quot;
  }
}
&amp;lt;/script&amp;gt;
</code></pre>

<p>Interestingly, this doesn't seem to be exposed in the API. It's available to any user-agent which requests a public LinkedIn post. I don't recommend you train any LLMs on the data though - it would be unbearably smug.</p>

<p>It would be incredibly useful if other social media platforms like Mastodon used this.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=46089&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/06/linkedin-supports-schema-org-metadata/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Does AI mean we don't need the Semantic Web?]]></title>
		<link>https://shkspr.mobi/blog/2023/05/does-ai-mean-we-dont-need-the-semantic-web/</link>
					<comments>https://shkspr.mobi/blog/2023/05/does-ai-mean-we-dont-need-the-semantic-web/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 20 May 2023 11:34:47 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=45827</guid>

					<description><![CDATA[If you hang around with computerists long enough, they start talking about the Semantic Web. If you can represent human knowledge in a way that&#039;s easy for computers to understand it will be transformative for information processing.  But computers, traditionally, haven&#039;t been very good at parsing ambiguous human text.  Suppose you saw this text written for a human:  Our opening hours are:…]]></description>
										<content:encoded><![CDATA[<p>If you hang around with computerists long enough, they start talking about the Semantic Web. If you can represent human knowledge in a way that's easy for computers to understand it will be transformative for information processing.</p>

<p>But computers, traditionally, haven't been very good at parsing ambiguous human text.</p>

<p>Suppose you saw this text written for a human:</p>

<blockquote><p>Our opening hours are: Weekdays 10 until 7. Weekend 10 until 10 (Early closing 9 o'clock Sunday).</p></blockquote>

<p>Not the most straightforward sentence, but pretty easy for a human to parse.</p>

<p>Until recently, the best way to represent that for a computer was something like:</p>

<pre><code class="language-html">&lt;meta itemprop="openingHours" content="Mo-Fr 10:00-19:00"&gt;
&lt;meta itemprop="openingHours" content="Sa 10:00-22:00"&gt;
&lt;meta itemprop="openingHours" content="Su 10:00-21:00"&gt;
</code></pre>

<p>or</p>

<pre><code class="language-html">&lt;script type="application/ld+json"&gt;
{
   "@context": "https://schema.org",
   "openingHours":["Mo-Fr 10:00-19:00", "Sa 10:00-22:00", "Su 10:00-21:00"]
}
&lt;/script&gt;
</code></pre>

<p>A tightly constrained vocabulary which can be precisely parsed by a simple state-machine. Easy to ingest, interpret, and query. Easy for machines, that is. As much as I love the semantic web, it is <em>hard</em> for humans to write, update, and maintain.</p>

<p>But we have AI now.  So do we need to mark up documents specifically for machines?</p>

<p>I fed the text into OpenAI's ChatGPT.  Here's what it said:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/05/ChatGPT-opening-hours.png" alt="User: Read the following sentence: " our="" opening="" hours="" are:="" weekdays="" 10="" until="" 7.="" weekend="" (early="" closing="" 9="" o'clock="" sunday)."="" chatgpt:="" the="" given="" sentence="" states="" of="" a="" certain="" establishment.="" here="" is="" breakdown="" mentioned:="" weekdays:="" establishment="" open="" from="" in="" morning="" 7="" evening.="" weekend:="" on="" weekends,="" at="" night.="" early="" sunday:="" sundays,="" closes="" earlier="" than="" usual,="" please="" note="" that="" this="" information="" based="" solely="" provided="" sentence,="" and="" specific="" or="" its="" type="" not="" mentioned.="" user:="" 2130="" sunday?="" has="" sunday,="" with="" time="" set="" therefore,="" would="" be="" 21:30="" (or="" 9:30="" pm)="" sunday."="" width="1024" height="868" class="aligncenter size-full wp-image-45828">

It isn't just capable of parroting back data - it can perform moderately complex reasoning:

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/05/0830.png" alt="User: It is 0830 Wednesday. How long until the establishment is open? ChatGPT: Based on the information provided, the establishment's opening hours on weekdays start at 10 in the morning. If it is currently 8:30 on a Wednesday, you would need to wait 1 hour and 30 minutes until the establishment opens at 10:00 AM." width="1024" height="277" class="aligncenter size-full wp-image-45831">

<p>Do we need to write for computers any more?  One of the demands of the Semantic Web was that we should use HTML elements like <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address"><code>&lt;address&gt;</code> to clearly mark up a contact address</a> and we should wrap dates and times in the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time"><code>&lt;time&gt;</code> element</a>.</p>

<p>Is that now redundant?</p>

<p>We still need to write clearly and unambiguously. But do we need separate "machine-readable" HTML if machines can now read and interpret text designed for humans?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=45827&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/05/does-ai-mean-we-dont-need-the-semantic-web/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Adding restaurant review metadata to WordPress]]></title>
		<link>https://shkspr.mobi/blog/2023/01/restaurant-review-metadata/</link>
					<comments>https://shkspr.mobi/blog/2023/01/restaurant-review-metadata/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 22 Jan 2023 12:34:46 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=44545</guid>

					<description><![CDATA[I&#039;ve started adding Restaurant Reviews to this blog - with delicious semantic metadata.  Previously I&#039;d been posting all my reviews to HappyCow.  It&#039;s a great site for finding veggie-friendly food around the worlds, but I wanted to experiment more with the IndieWeb idea of POSSE.  So now I can Post on my Own Site and Syndicate Elsewhere.  The Schema.org representation of a Restaurant is pretty…]]></description>
										<content:encoded><![CDATA[<p>I've started adding <a href="https://shkspr.mobi/blog/tag/restaurant-review/">Restaurant Reviews to this blog</a> - with <em>delicious</em> semantic metadata.  Previously I'd been posting <a href="https://www.happycow.net/members/profile/Edent">all my reviews to HappyCow</a>.  It's a great site for finding veggie-friendly food around the worlds, but I wanted to experiment more with the <a href="https://indieweb.org/POSSE">IndieWeb idea of POSSE</a>.  So now I can <strong>P</strong>ost on my <strong>O</strong>wn <strong>S</strong>ite and <strong>S</strong>yndicate <strong>E</strong>lsewhere.</p>

<p>The Schema.org representation of a Restaurant is pretty simple:</p>

<pre><code class="language-json">"itemReviewed": {
    "@type": "Restaurant",
    "name": "Example Bistro",
    "address": "42 Wallaby Way, Sydney",
    "hasMenu": "https://example.com/menu",
    "servesCuisine": "Vegetarian",
    "sameAs": "https://www.example.com/restaurant"
}
</code></pre>

<p>There are <a href="https://schema.org/Restaurant">many more metadata items</a> which could be added - but that's enough for my purposes.</p>

<p>I've written my own <a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/">WordPress theme to add Semantic Reviews</a>. It gives me a little UI box to add in all the essential data.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/01/review-UI-fs8.png" alt="Screenshot of a user interface which allows the entry of data." width="501" height="498" class="aligncenter size-full wp-image-44564">

<p>Once all that's fed in, it's converted to JSON+LD which looks like this:</p>

<pre><code class="language-json">{
    "@context": "https:\/\/schema.org",
    "@type": "Review",
    "author": {
        "@type": "Person",
        "name": "Terence Eden",
        "sameAs": [""]
    },
    "url": "https:\/\/shkspr.mobi\/blog\/?p=44547",
    "datePublished": "2023-01-20T12:34:10+00:00",
    "publisher": {
        "@type": "Organization",
        "name": "Terence Eden\u2019s Blog",
        "sameAs": "https:\/\/shkspr.mobi\/blog"
    },
    "description": "If you've visiting Batu Caves in Kuala Lumpur, I have two tips for you. Firstly, get there as early as possible in order to avoid the heat and other tourists. Secondly, after climbing a mountain of ",
    "inLanguage": "en-GB",
    "itemReviewed": {
        "@type": "Restaurant",
        "name": "Rani Vilas Restaurant Batu Caves",
        "address": "Jalan Batu Caves, Batu Caves, Malaysia, 68100",
        "sameAs": "http:\/\/www.facebook.com\/RaniVilasRestaurantBatuCaves",
        "hasMenu": "https:\/\/www.foodpanda.my\/restaurant\/w1rb\/rani-vilas-restaurant-shop",
        "servesCuisine": "Vegetarian Indian",
        "image": "https:\/\/shkspr.mobi\/blog\/wp-content\/uploads\/2023\/01\/rani.jpg",
        "aggregateRating": {
            "@type": "AggregateRating",
            "ratingValue": "5",
            "reviewCount": "1",
            "worstRating": 0,
            "bestRating": 5
        }
    },
    "reviewRating": {
        "@type": "Rating",
        "worstRating": 0,
        "bestRating": 5,
        "ratingValue": "5"
    },
    "thumbnailUrl": "https:\/\/shkspr.mobi\/blog\/wp-content\/uploads\/2023\/01\/rani.jpg"
}
</code></pre>

<p>The somewhat messy <a href="https://gitlab.com/edent/blog-theme/">code is available on my GitLab</a>. If there's any interest, I might turn it into a separate WordPress plugin.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=44545&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/01/restaurant-review-metadata/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Semantic Comments for WordPress]]></title>
		<link>https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/</link>
					<comments>https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 28 Apr 2022 11:34:13 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=42412</guid>

					<description><![CDATA[As regular readers will know, I love adding Semantic things to my blog.  The standard WordPress comments HTML isn&#039;t very semantic - so I thought I&#039;d change that. Here&#039;s some code which you can add to your blog&#039;s theme - an an explanation of how it works.  The aim is to end up with some HTML which looks like this (edited for brevity):  &#60;li itemscope itemtype=&#34;https://schema.org/Comment&#34;…]]></description>
										<content:encoded><![CDATA[<p>As regular readers will know, I love <a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/">adding Semantic things to my blog</a>.</p>

<p>The standard WordPress comments HTML isn't very semantic - so I thought I'd change that. Here's some code which you can add to your blog's theme - an an explanation of how it works.</p>

<p>The aim is to end up with some HTML which looks like this (edited for brevity):</p>

<pre><code class="language-HTML5">&lt;li itemscope itemtype="https://schema.org/Comment" itemid="#246827"&gt;
    &lt;article&gt;
        &lt;time datetime="2022-04-12T10:22:32+01:00" itemprop="dateCreated"&gt;
            &lt;a href="https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/#comment-246827" itemprop='url'&gt;22-04-12 10:22&lt;/a&gt;
        &lt;/time&gt;
        &lt;div itemprop="https://schema.org/author" itemscope itemtype="https://schema.org/Person"&gt;
            &lt;img itemprop="image" alt='' src='logo.jpg' height='64' width='64'/&gt;
            &lt;span itemprop="name"&gt;
                &lt;a itemprop="url" href="https://twitter.com/example"&gt;Commenter's Name&lt;/a&gt;&lt;/span&gt; says:
        &lt;/div&gt;
        &lt;div itemprop="text"&gt;This is the text of my comment&lt;/code&gt;&lt;/div&gt;
    &lt;/article&gt;
&lt;/li&gt;
</code></pre>

<p>Which will be interpreted as:
<img src="https://shkspr.mobi/blog/wp-content/uploads/2022/04/Schema-Markup-validator.png" alt="A schema tree showing all the properties." width="916" height="310" class="aligncenter size-full wp-image-42415"></p>

<p>This adds <code>&lt;time&gt;</code> elements as well as Schema.org microdata.</p>

<h2 id="howto"><a href="https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/#howto">Howto</a></h2>

<p>In <code>comments.php</code> you'll see something like this:</p>

<pre><code class="language-php">&lt;ol class="comment-list"&gt;
    &lt;?php
        wp_list_comments( array(
            'style'       =&gt; 'ol',
            'short_ping'  =&gt; true,
            'avatar_size' =&gt; 64,
        ) );
    ?&gt;
&lt;/ol&gt;
</code></pre>

<p>You need to add a new <code>callback</code>. In this case, I've called it <code>my_comments_walker</code>:</p>

<pre><code class="language-php">&lt;ol class="comment-list"&gt;
    &lt;?php
        wp_list_comments( array(
            'style'       =&gt; 'ol',
            'short_ping'  =&gt; true,
            'avatar_size' =&gt; 64,
            'callback' =&gt; 'my_comments_walker',
        ) );
    ?&gt;
&lt;/ol&gt;
</code></pre>

<p>You can read more about <a href="https://developer.wordpress.org/reference/classes/walker/">WordPress Walkers on their documentation page</a>.</p>

<p>Now that's done, you need to create a function in your <code>functions.php</code> file.  I added this to the end of my file:</p>

<pre><code class="language-php">function my_comments_walker() {

    //  Basic comment data
    $comment_id          = get_comment_id();
    $comment             = get_comment( $comment_id );

    //  Date the comment was submitted
    $comment_date        = get_comment_date( "c" );
    //  In slightly more human-readable format
    $comment_date_human  = get_comment_date( "y-m-d H:i" );

    //  Author Details
    $comment_author      = get_comment_author();

    //  Author's URl if they've added one
    $comment_author_url  = get_comment_author_url();

    //  If there's an Author URl, link it
    if ($comment_author_url != null) {
        $comment_author_name = "&lt;a itemprop='url' href='{$comment_author_url}' rel='external nofollow ugc' class='url'&gt;{$comment_author}&lt;/a&gt;";
    } else {
        $comment_author_name = "{$comment_author}";
    }

    //  Provide a link to the comment anchor
    $comment_url_link = "&lt;a href="https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/#comment-$comment_id" itemprop='url'&gt;{$comment_date_human}&lt;/a&gt;";

    //  Author's Avatar based on ID
    //  As per https://developer.wordpress.org/reference/functions/get_avatar/ both alt &amp; default must be set
    $gravatar            = get_avatar( $comment, 64, "", "", array('extra_attr' =&gt; 'itemprop="image"') );

    //  Comment needs newlines and links added
    $comment_text        = apply_filters( 'comment_text', get_comment_text(), $comment);


    //  The comment may have various classes. They are stored as an array
    $comment_classes     = get_comment_class();
    $comment_classes_text = "";
    foreach( $comment_classes as $class ) {
        $comment_classes_text .= $class . " ";
    }
    $comment_classes_text = trim($comment_classes_text);

    //  Link to open the reply box
    $comment_reply_link = get_comment_reply_link( [
                    'depth'     =&gt; 20,
                    'max_depth' =&gt; 100,
                    'before'    =&gt; '&lt;div class="reply"&gt;',
                    'after'     =&gt; '&lt;/div&gt;'
            ] );

    //  Write the comment HTML. No need for a closing &lt;/li&gt; as WP handles that.
    echo &lt;&lt;&lt; EOT
    &lt;li id="comment-$comment_id" itemscope itemtype="https://schema.org/Comment" itemid="#comment-$comment_id" class="$comment_classes_text"&gt;
        &lt;article class="comment-body" id="div-comment-$comment_id"&gt;
            &lt;time datetime="$comment_date" class="comment-meta commentmetadata" itemprop="dateCreated"&gt;
                $comment_url_link
            &lt;/time&gt;
            &lt;div class="comment-author vcard" itemprop="https://schema.org/author" itemscope itemtype="https://schema.org/Person"&gt;
                $gravatar
                &lt;span class="fn" itemprop="name"&gt;$comment_author_name&lt;/span&gt; &lt;span class="says"&gt;says:&lt;/span&gt;
            &lt;/div&gt;
            &lt;div itemprop="text" class="comment-text"&gt;$comment_text&lt;/div&gt;
            $comment_reply_link
        &lt;/article&gt;
    EOT;
}
</code></pre>

<p>There are a few extra classes and spans which I use. You can remove them if you like.</p>

<p>And that's it. All your comments will have individual semantic metadata. If you think anything else should be included, please let me know.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=42412&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2022/04/semantic-comments-for-wordpress/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[How to add ISSN metadata to a web page]]></title>
		<link>https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/</link>
					<comments>https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 17 Sep 2021 11:09:05 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=40341</guid>

					<description><![CDATA[Inspired by John Hoare at the Dirty Feed blog - I&#039;ve asked the British Library to assign my blog an International Standard Serial Number (ISSN).  An ISSN is an 8-digit code used to identify newspapers, journals, magazines and periodicals of all kinds and on all media–print and electronic.    Why?  Shut up.  OK. It turns out that lots of people cite my blog in academic papers - so I wanted to make …]]></description>
										<content:encoded><![CDATA[<p>Inspired by John Hoare at the <a href="https://www.dirtyfeed.org/">Dirty Feed blog</a> - I've asked the British Library to assign my blog an <a href="https://www.issn.org/understanding-the-issn/what-is-an-issn/">International Standard Serial Number</a> (ISSN).</p>

<blockquote><p>An ISSN is an 8-digit code used to identify newspapers, journals, magazines and periodicals of all kinds and on all media–print and electronic.</p></blockquote>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2021/09/Screenshot-2021-09-07-at-10-21-40-Application-for-an-ISSN-terence-eden-shkspr-mobi-Shkspr-mobi-Mail.png" alt="creenshot of an email from the British Library. Dear Terence Eden INTERNATIONAL STANDARD SERIAL NUMBER (ISSN) Thank you for your recent enquiry, we have assigned ISSN to the following publication(s): Terence Eden’s blog ISSN 2753-1570 ." width="867" height="310" class="aligncenter size-full wp-image-40345">

<h2 id="why"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#why">Why?</a></h2>

<p>Shut up.</p>

<p>OK. It turns out that lots of people <a href="https://shkspr.mobi/blog/citations">cite my blog in academic papers</a> - so I wanted to make it slightly easier for scholars of the future to use metadata to trace my vast influence on Human civilisation.</p>

<h2 id="how"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#how">How?</a></h2>

<p>I filled in <a href="https://www.bl.uk/help/get-an-isbn-or-issn-for-your-publication">a form on the British Library website</a>. Didn't cost me a penny. Was pretty quick!</p>

<h2 id="metadata"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#metadata">Metadata</a></h2>

<p>I can stick a bit of text at the bottom of each page with the ISSN - but that doesn't make it easily discoverable by automated tools. How can I make an ISSN machine readable?  There are a few ways.</p>

<h3 id="meta-elements"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#meta-elements">Meta Elements</a></h3>

<p>There are <a href="https://html.spec.whatwg.org/multipage/semantics.html#standard-metadata-names">a limited list of official <code>&lt;meta&gt;</code> names</a>. These are extensible, and <a href="https://scholar.google.com/intl/en/scholar/inclusion.html#indexing">Google Scholar recommends <code>citation_issn</code></a>. Which is as simple as adding the following to your page's <code>&lt;head&gt;</code>:</p>

<pre><code class="language-html">&lt;meta name="citation_issn" content="1234-5678"&gt;
</code></pre>

<p>There alternatives though.</p>

<h3 id="schema-org"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#schema-org">Schema.org</a></h3>

<p>In recent years, <a href="https://schema.org/">Schema.org</a> has become the dominant form for representing metadata on the web. There are two ways you can implement it:</p>

<h4 id="json-ld"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#json-ld">JSON-LD</a></h4>

<p>JSON Linked Data involves adding a scrap of JavaScript to your HTML, like this:</p>

<pre><code class="language-HTML">&lt;script type="application/ld+json"&gt;
{
  "@context": "https://schema.org",
  "@type": "Blog",
  "issn": "1234-5678"
}
&lt;/script&gt;
</code></pre>

<p>If you don't want to add a separate script, you can add the data inline using...</p>

<h4 id="microdata"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#microdata">Microdata</a></h4>

<p>The <a href="https://html.spec.whatwg.org/multipage/microdata.html">microdata specification</a> uses the exact same data as Schema.org - but allows you to add the data directly into the web page like this:</p>

<pre><code class="language-_">&lt;body itemscope itemtype="https://schema.org/Blog"&gt;
   ...
   ISSN &lt;span itemprop="issn"&gt;1234-5678&lt;/span&gt;
</code></pre>

<p>That's probably the <em>easiest</em> way to do it.</p>

<h3 id="links"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#links">Links</a></h3>

<p>The ISSN registry allows you to look up any ISSN with a simple URL. Mine is at <a href="https://portal.issn.org/resource/ISSN/2753-1570"></a><a href="https://portal.issn.org/resource/ISSN/2753-1570">https://portal.issn.org/resource/ISSN/2753-1570</a>.</p>

<h2 id="belt-and-braces"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#belt-and-braces">Belt and braces</a></h2>

<p>So, this is what I've ended up doing - cramming everything in all at once.</p>

<pre><code class="language-html">&lt;head&gt;
   ...
   &lt;meta name="citation_issn" content="1234-5678"&gt;
&lt;/head&gt;
&lt;body itemscope itemtype="https://schema.org/Blog"&gt;
   ...
   ISSN &lt;a href="https://portal.issn.org/resource/ISSN/1234-5678"&gt;&lt;span itemprop="issn"&gt;1234-5678&lt;/span&gt;&lt;/a&gt;
</code></pre>

<h2 id="any-other-ways"><a href="https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/#any-other-ways">Any other ways?</a></h2>

<p>What am I missing? Can someone smarter than I tell me that there's an easier / better / more interoperable way to do this?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=40341&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2021/09/how-to-add-issn-metadata-to-a-web-page/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Introducing DOI2HT.ML - the simple semantic citation server]]></title>
		<link>https://shkspr.mobi/blog/2020/11/introducing-doi2ht-ml-the-simple-semantic-citation-server/</link>
					<comments>https://shkspr.mobi/blog/2020/11/introducing-doi2ht-ml-the-simple-semantic-citation-server/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 13 Nov 2020 12:51:22 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[NaBloPoMo]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[semantic web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=37114</guid>

					<description><![CDATA[Academic citations are hard. One of the joys of the Digital Object Identifier System (DOI) is that every academic paper gets a unique reference - like: 10.34053/artivate.8.2.2.  As well as always leading you to a URl of the paper, a DOI also provides lots of metadata. Things like author, publisher, ORCID, year of publication etc.  I&#039;ve built a simple website that turns any DOI into a semantic…]]></description>
										<content:encoded><![CDATA[<p>Academic citations are <em>hard</em>. One of the joys of the Digital Object Identifier System (DOI) is that every academic paper gets a unique reference - like: <code>10.34053/artivate.8.2.2</code>.</p>

<p>As well as always leading you to a URl of the paper, a DOI also provides lots of metadata. Things like author, publisher, ORCID, year of publication etc.</p>

<p>I've built a simple website that turns any DOI into a semantic HTML reference - get started at <a href="https://web.archive.org/web/20221025144116/https://doi2ht.ml/">DOI2HT.ML</a>.</p>

<p>Here's what it looks like:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/11/doi2html-fs8.png" alt="Website Screenshot." width="1247" height="779" class="aligncenter size-full wp-image-37116">

<p>Pop a DOI in the box and hit the button. You'll receive an HTML5 citation which has embedded schema.org microdata data.  It makes a human-readable citation <em>and</em> a robot-readable way for search engines to understand your citation.</p>

<p>It uses <a href="https://citation.crosscite.org/docs.html#sec-4">content negotiation</a> to get the canonical citation, then it renders it into standards compliant HTML + microdata.</p>

<p>There's no tracking, no cookies, no selling your data. Just a plain HTML site - the way the web should be.</p>

<p>Enjoy!</p>

<p><a href="https://web.archive.org/web/20221025144116/https://doi2ht.ml/">DOI2HT.ML</a></p>

<p>This is a "scratch my own itch" product. I run a <a href="https://shkspr.mobi/blog/citations">citations page</a> where I track whenever I'm mentioned in academia. Feedback very welcome.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=37114&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/11/introducing-doi2ht-ml-the-simple-semantic-citation-server/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Adding Semantic Reviews / Rich Snippets to your WordPress Site]]></title>
		<link>https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/</link>
					<comments>https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 12 Jul 2020 11:50:01 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=35586</guid>

					<description><![CDATA[This is a real &#34;scratch my own itch&#34; post. I want to add Schema.org semantic metadata to the book reviews I write on my blog. This will enable &#34;rich snippets&#34; in search engines.  There are loads of WordPress plugins which do this. But where&#039;s the fun in that?! So here&#039;s how I quickly built it into my open source blog theme.  Screen options  First, let&#039;s add some screen options to the WordPress…]]></description>
										<content:encoded><![CDATA[<p>This is a real "scratch my own itch" post. I want to add <a href="https://schema.org/Review">Schema.org semantic metadata</a> to the book reviews I write on my blog. This will enable "rich snippets" in search engines.</p>

<p>There are <em>loads</em> of WordPress plugins which do this. But where's the fun in that?! So here's how I quickly built it into my <a href="https://gitlab.com/edent/blog-theme">open source blog theme</a>.</p>

<h2 id="screen-options"><a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/#screen-options">Screen options</a></h2>

<p>First, let's add some <a href="https://make.wordpress.org/support/user-manual/getting-to-know-wordpress/screen-options/">screen options</a> to the WordPress editor screen.</p>

<p>This is what it will look like when done:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/06/Screenshot_2020-06-29-Edit-Post-‹-Terence-Eden’s-Blog-—-WordPress-fs8.png" alt="Simple interface for adding details." width="513" height="428" class="aligncenter size-full wp-image-35589">

<p>This is how to add a <a href="https://developer.wordpress.org/plugins/metadata/custom-meta-boxes/#adding-meta-boxes">custom metabox</a> to the editor screen:</p>

<pre><code class="language-php">//  Place this in functions.php
//  Display the box
function edent_add_review_custom_box()
{
   $screens = ['post'];
   foreach ($screens as $screen) {
      add_meta_box(
         'edent_review_box_id', // Unique ID
         'Book Review Metadata',    // Box title
         'edent_review_box_html',// Content callback, must be of type callable
         $screen                 // Post type
       );
   }
}
add_action('add_meta_boxes', 'edent_add_review_custom_box');
</code></pre>

<p>The contents of the box are bog standard HTML</p>

<pre><code class="language-php">//  Place this in functions.php
//  HTML for the box
function edent_review_box_html($post)
{
    $review_data = get_post_meta(get_the_ID(), "_edent_book_review_meta_key", true);
    echo "&lt;table&gt;";

    $checked = "";
    if ($review_data["review"] == "true") {
        $checked = "checked";
    }
    echo "&lt;tr&gt;&lt;td&gt;&lt;label for='edent_book_review'&gt;Embed Book Review:&lt;/label&gt;&lt;/td&gt;&lt;td&gt;&lt;input type=checkbox id=edent_book_review name=edent_book_review[review] value=true {$checked}&gt;&lt;/tr&gt;";

    echo "&lt;tr&gt;&lt;td&gt;&lt;label for='edent_rating'&gt;Rating:&lt;/label&gt;&lt;/td&gt;&lt;td&gt;&lt;input type=range id=edent_rating name=edent_book_review[rating] min=0 max=5 step=0.5 value='". esc_html($review_data["rating"]) ."'&gt;&lt;/tr&gt;";

    echo "&lt;tr&gt;&lt;td&gt;&lt;label for=edent_isbn &gt;ISBN:&lt;/label&gt;&lt;/td&gt;&lt;td&gt;&lt;input name=edent_book_review[isbn]  id=edent_isbn type=text value='" . esc_html($review_data["isbn"]) . "' autocomplete=off&gt;&lt;/tr&gt;";

    echo "&lt;/table&gt;";
}
</code></pre>

<p>Done! We now have a box for metadata. That data will be <code>POST</code>ed every time the blogpost is saved. But where do the data go?</p>

<h2 id="saving-data"><a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/#saving-data">Saving data</a></h2>

<p>This function is added every time the blogpost is saved. If the checkbox has been ticked, the metadata are saved to the database. If the checkbox is unticked, the metadata are deleted.</p>

<pre><code class="language-php">//  Place this in functions.php
//  Save the box
function edent_review_save_postdata($post_id)
{
   if (array_key_exists('edent_book_review', $_POST)) {
        if ($_POST['edent_book_review']["review"] == "true") {
            update_post_meta(
                $post_id,
                '_edent_book_review_meta_key',
                $_POST['edent_book_review']
            );
        } else {
            delete_post_meta(
                $post_id,
                '_edent_book_review_meta_key'
            );
        }
    }
}
add_action('save_post', 'edent_review_save_postdata');
</code></pre>

<p>Nice! But how do we get the data back out again?</p>

<h2 id="retrieving-the-data"><a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/#retrieving-the-data">Retrieving the data</a></h2>

<p>We can use the <a href="https://developer.wordpress.org/reference/functions/get_post_meta/"><code>get_post_meta()</code> function</a> to get all the metadata associated with a blog entry.  We can then turn it into a Schema.org structured metadata entry.</p>

<pre><code class="language-php">function edent_book_review_display($post_id){
    // https://developer.wordpress.org/reference/functions/the_meta/
    $review_data = get_post_meta($post_id, "_edent_book_review_meta_key", true);
    if ($review_data["review"] == "true")
    {
        $blog_author_data = get_the_author_meta();

        $schema_review = array (
            '@context' =&gt; 'https://schema.org',
            '@type'    =&gt; 'Review',
            'author' =&gt;
            array (
                '@type' =&gt; 'Person',
                'name'  =&gt; get_the_author_meta("user_firstname") . " " . get_the_author_meta("user_lastname"),
                'sameAs' =&gt;
                array (
                    0 =&gt; get_the_author_meta("user_url"),
                ),
            ),
            'url' =&gt; get_permalink(),
            'datePublished' =&gt; get_the_date('c'),
            'publisher' =&gt;
            array (
                '@type'  =&gt; 'Organization',
                'name'   =&gt; get_bloginfo("name"),
                'sameAs' =&gt; get_bloginfo("url"),
            ),
            'description' =&gt; mb_substr(get_the_excerpt(), 0, 198),
            'inLanguage'  =&gt; get_bloginfo("language"),
            'itemReviewed' =&gt;
            array (
                '@type'  =&gt; 'Book',
                'name'   =&gt; $review_data["title"],
                'isbn'   =&gt; $review_data["isbn"],
                'sameAs' =&gt; $review_data["book_url"],
                'author' =&gt;
                array (
                    '@type'  =&gt; 'Person',
                    'name'   =&gt; $review_data["author"],
                    'sameAs' =&gt; $review_data["author_url"],
                ),
            'datePublished' =&gt; $review_data["book_date"],
            ),
            'reviewRating' =&gt;
            array (
                '@type' =&gt; 'Rating',
                'worstRating' =&gt; 0,
                'bestRating'  =&gt; 5,
                'ratingValue' =&gt; $review_data["rating"],
            ),
            'thumbnailUrl' =&gt; get_the_post_thumbnail_url(),
        );
        echo '&lt;script type="application/ld+json"&gt;' . json_encode($schema_review) . '&lt;/script&gt;';

        echo "&lt;div class='edent-review' style='clear:both;'&gt;";
        if (isset($review_data["rating"])) {
            echo "&lt;span class='edent-rating-stars' style='font-size:2em;color:yellow;background-color:#13131380;'&gt;";
            $full = floor($review_data["rating"]);
            $half = 0;
            if ($review_data["rating"] - $full == 0.5)
            {
                $half = 1;
            }

            $empty = 5 - $half - $full;

            for ($i=0; $i &lt; $full ; $i++) {
                echo "★";
            }
            if ($half == 1)
            {
                echo "⯪";
            }
            for ($i=0; $i &lt; $empty ; $i++) {
                echo "☆";
            }
            echo "&lt;/span&gt;";
        }
        echo "&lt;ul&gt;";
        if ($review_data["amazon_url"] != "") {
            echo "&lt;li&gt;&lt;a href='{$review_data["amazon_url"]}'&gt;Buy it on Amazon&lt;/a&gt;&lt;/li&gt;";
        }
        if ($review_data["author_url"] != "") {
            echo "&lt;li&gt;&lt;a href='{$review_data["author_url"]}'&gt;Author's homepage&lt;/a&gt;&lt;/li&gt;";
        }
        if ($review_data["book_url"] != "") {
            echo "&lt;li&gt;&lt;a href='{$review_data["book_url"]}'&gt;Publisher's details&lt;/a&gt;&lt;/li&gt;";
        }
        echo "&lt;/ul&gt;";
    }
    echo "&lt;/div&gt;";
}
</code></pre>

<p>In <code>index.php</code>, after <code>the_content();</code> add:</p>

<pre><code class="language-php">edent_book_review_display(get_the_ID());
</code></pre>

<p>Then, on the website, it will look something like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/06/Screenshot_2020-06-29-Review-The-House-of-Shattered-Wings-–-Aliette-de-Bodard-fs8.png" alt="Star rating and links displayed under a book cover." width="451" height="446" class="aligncenter size-full wp-image-35588">

<p>Note the use of the <a href="http://www.righto.com/2016/10/inspired-by-hn-comment-four-half-star.html">Unicode Half Star</a> for the ratings.</p>

<p>The source code of the site shows the output of the JSON LD:
<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/06/Screenshot-from-2020-06-29-08-49-36-fs8.png" alt="Screenshot of JSON code in a web page." width="598" height="513" class="aligncenter size-full wp-image-35590"></p>

<p>When run through a <a href="https://search.google.com/structured-data/testing-tool/u/0/">Structured Data Testing Tool</a>, it shows as a valid review:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/06/Screenshot_2020-06-29-Structured-Data-Testing-Tool-fs8.png" alt="Results of a Structured Data Test" width="884" height="944" class="aligncenter size-full wp-image-35587">

<p>And this means, when search engines access your blog, they will display rich snippets based on the semantic metadata.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/07/Screenshot_2020-07-12-house-of-shattered-wings-shkspr-Google-Search.png" alt="Rich result from Google showing the star rating." width="773" height="170" class="aligncenter size-full wp-image-35923">

<p>You can <a href="https://shkspr.mobi/blog/2020/06/review-the-house-of-shattered-wings-aliette-de-bodard/">see the final blog post</a> to see how it works.</p>

<h2 id="todo"><a href="https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/#todo">ToDo</a></h2>

<p>My code is horrible and hasn't been tested, validated, or sanitised. It's only for my own blog, and I'm unlikely to hack myself, but that needs fixing.</p>

<p>I want to add review metadata for movies, games, and gadgets. That will either require multiple boxes, or a clever way to only show the necessary fields.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=35586&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/07/adding-semantic-reviews-rich-snippets-to-your-wordpress-site/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[The future of the web, isn't the web]]></title>
		<link>https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/</link>
					<comments>https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 22 Dec 2019 12:24:46 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[web]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=33424</guid>

					<description><![CDATA[My friends, and former employers, at the Government Digital Service have written a spectacularly good blog post &#34;Making GOV.UK more than a website&#34;.  In it, they describe how adding Schema.org markup to their website has allowed search engines to extract semantic content and display it to a user. For example, the &#34;Learn to drive&#34; page has content which can appear directly in a search engine:  …]]></description>
										<content:encoded><![CDATA[<p>My friends, and former employers, at the Government Digital Service have written a spectacularly good blog post "<a href="https://gds.blog.gov.uk/2019/12/19/making-gov-uk-more-than-a-website/">Making GOV.UK more than a website</a>".</p>

<p>In it, they describe how adding Schema.org markup to their website has allowed search engines to extract semantic content and display it to a user. For example, the "Learn to drive" page has content which can appear directly in a search engine:
<img src="https://gds.blog.gov.uk/wp-content/uploads/sites/60/2019/12/3_step-by-steps-620x618.png" width="620" height="618" alt="two screenshots of search results on mobile showing results for 'learn to drive step by step'." class="alignnone size-medium"></p>

<p>Even better, if you ask Siri / Google / Alexa for something, it can give an answer from an authoritative source:
<img src="https://gds.blog.gov.uk/wp-content/uploads/sites/60/2019/12/5_Alexa-620x618.png" width="620" height="618" alt="Amazon Alexa answers the query ‘When’s the next bank holiday’." class="alignnone size-medium"></p>

<p>This is the death of the web. Long live the web!</p>

<h2 id="why-this-is-really-important"><a href="https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/#why-this-is-really-important">Why this is <em>really</em> important</a></h2>

<p>Your information has to be where your users want to access it. Not where you want to display it.  I remember sitting in a housing benefits office, watching someone playing on their PlayStation Portable - or so I thought. On closer inspection, she was browsing the GOV.UK web pages to see what the process was for claiming benefits.  Web browsers are <em>everywhere!</em></p>

<p>But the future is <em>not</em> a browser. It is a User-Agent.  It could be your search engine, smart watch, voice assistant, or something yet to be invented.</p>

<h2 id="history"><a href="https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/#history">History</a></h2>

<p>The web is great. But its real power was in separating content from design.</p>

<ul>
<li>HTML for your words.</li>
<li>CSS for your layout.</li>
</ul>

<p>That's a good start. But we can go one deeper. Because content isn't HTML.</p>

<p>Your content probably lives in a database. Whether you're running a personal blog, or an ecommerce platform, the content is actually data. You render it as HTML because that's what's easiest for humans to read on a screen.</p>

<p>But... not everyone is able to read a screen. Nor do they always want to.</p>

<p>Do we need to write custom CSS just in case our data is rendered on a smartwatch? Or a TV? Or an Internet Connected Fridge? No! The User-Agent should be able to grab the data and render it appropriately.</p>

<p>At the moment, we're mostly stuck in this paradigm:</p>

<p>Data ➡ HTML ➡ CSS ➡ Browser ➡ 👀</p>

<p>But because our content is just data in a database, we're not restricted to that. It can just as easily be:</p>

<p>Data ➡ Speech Synthesis Markup Language ➡ Alexa ➡ 👂</p>

<h2 id="too-many-apis"><a href="https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/#too-many-apis">Too many APIs</a></h2>

<p>And that is what I love about HTML + microdata / Schema.  No one is going to use your API - unless you are a megacorp. But if the data is <em>already</em> in your web pages, they don't have to do anything fancy.</p>

<p>No one is ever going to use my blog's API. But your Kindle could come across my web page, and see <a href="https://shkspr.mobi/blog/2019/12/book-review-this-is-how-you-lose-the-time-war-amal-el-mohtar-max-gladstone/">this recent review</a> - embedded in it is this data:</p>

<pre><code class="language-json">{
    "@context": "http:\/\/schema.org",
    "@type": "Review",
    "author": {
        "@type": "Person",
        "name": "@edent",
    },
    "itemReviewed": {
        "@type": "Book",
        "name": "This Is How You Lose the Time War",
        "isbn": "9781534431003",
        "author": {
            "@type": "Person",
            "name": "Amal El-Mohtar",
            "sameAs": "https:\/\/www.goodreads.com\/book\/author\/Amal+El-Mohtar"
        },
    },
    "reviewRating": {
        "@type": "Rating",
        "worstRating": 1,
        "bestRating": 5,
        "ratingValue": 5
    }
}
</code></pre>

<p>And - hey presto! - it can find the book via ISBN, show you books by the same author, and display the rating I gave the book. All without needing any fancy AI or Natural Language Processing.</p>

<p>Your smart-fridge can find a recipe and display the steps you need to take in order to prepare the perfect moussaka.  You don't need to build an app for Samsung fridges, and another one for Smeg fridges. Just build a website and embed your data in the pages!</p>

<h2 id="the-future"><a href="https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/#the-future">The future</a></h2>

<p>So, I <em>hope</em> that the future is more data-in-the-web &amp; more diverse User Agents.</p>

<p>You will have many, many User Agents - your car, your speaker, your microwave - all of them grabbing data on your behalf, rendering it, processing it, giving you information in the format which works best for you.</p>

<p>It will all be powered by the web, but won't be accessed by what you think of as a traditional web browser.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=33424&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2019/12/the-future-of-the-web-isnt-the-web/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Add review to Goodreads from Schema markup]]></title>
		<link>https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/</link>
					<comments>https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Tue, 10 Dec 2019 19:40:23 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[goodreads]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=33209</guid>

					<description><![CDATA[I write book reviews on my blog. I also want to syndicate them to Goodreads.  Sadly, Goodreads doesn&#039;t natively read the Schema.org markup I so carefully craft.  So here&#039;s the scrap of code I use to syndicate my reviews.  Goodreads API Keys  Get your Keys from https://www.goodreads.com/api/keys  You will also need to get OAuth tokens  For this documentation, I&#039;ll use the example keys - please…]]></description>
										<content:encoded><![CDATA[<p>I write book reviews on my blog. I also want to syndicate them to Goodreads.</p>

<p>Sadly, Goodreads doesn't natively read the Schema.org markup I so carefully craft.  So here's the scrap of code I use to syndicate my reviews.</p>

<h2 id="goodreads-api-keys"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#goodreads-api-keys">Goodreads API Keys</a></h2>

<p>Get your Keys from <a href="https://www.goodreads.com/api/keys"></a><a href="https://www.goodreads.com/api/keys">https://www.goodreads.com/api/keys</a></p>

<p>You will also need to <a href="https://www.goodreads.com/api/oauth_example#python">get OAuth tokens</a></p>

<p>For this documentation, I'll use the example keys - please substitute them with your own keys.</p>

<pre><code class="language-python">from rauth.service import OAuth1Service, OAuth1Session

# Get a real consumer key &amp; secret from: https://www.goodreads.com/api/keys
API_KEY    = 'ABC123'
API_SECRET = 'XYZ789'

goodreads = OAuth1Service(
    consumer_key    = API_KEY,
    consumer_secret = API_SECRET,
    name='goodreads',
    request_token_url = 'https://www.goodreads.com/oauth/request_token',
    authorize_url     = 'https://www.goodreads.com/oauth/authorize',
    access_token_url  = 'https://www.goodreads.com/oauth/access_token',
    base_url          = 'https://www.goodreads.com/'
)

OAUTH_TOKEN, OAUTH_SECRET = goodreads.get_request_token(header_auth=True)
authorize_url = goodreads.get_authorize_url(request_token)
print(authorize_url)
</code></pre>

<p>Visit the URL printed out, and authorise the app.  Then run this to get the access tokens you need:</p>

<pre><code class="language-python">session = goodreads.get_auth_session(OAUTH_TOKEN, OAUTH_SECRET)
ACCESS_TOKEN = session.access_token
ACCESS_TOKEN_SECRET = session.access_token_secret
</code></pre>

<p>Save those tokens, we'll need them later!</p>

<h2 id="get-json-ld-from-html-page"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#get-json-ld-from-html-page">Get JSON-LD from HTML page</a></h2>

<p>This uses <a href="https://docs.python-requests.org/en/latest/index.html">Requests</a> and <a href="https://pypi.org/project/beautifulsoup4/">BeautifulSoup</a>.</p>

<pre><code class="language-python">import requests
from bs4 import BeautifulSoup
import json
import re

review_url = 'https://shkspr.mobi/blog/2019/11/review-because-internet-by-gretchen-mcculloch/'
r = requests.get(review_url)
soup = BeautifulSoup(r.text)
pattern = re.compile(r"\"@type\":\"Review\"")
script = soup.find("script", text=pattern)
review = script.text
review_json = json.loads(review)

isbn        = review_json["itemReviewed"]["isbn"]
rating      = review_json["reviewRating"]["ratingValue"]
date        = review_json["datePublished"]:date[0:10]
description = review_json["description"] + " " + review_url

</code></pre>

<h2 id="isbn-to-goodreads-id"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#isbn-to-goodreads-id">ISBN to Goodreads ID</a></h2>

<pre><code class="language-python">goodreads_id = requests.get("https://www.goodreads.com/book/isbn_to_id/" + isbn + "?key=" + API_KEY).text
</code></pre>

<p>This will return a number - the Goodreads ID.</p>

<h2 id="post-a-review"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#post-a-review">Post a review</a></h2>

<p>The <a href="https://www.goodreads.com/api/index#review.create">documentation for posting Goodreads reviews</a> is a bit sparse.</p>

<pre><code class="language-python">goodreads_api = OAuth1Session(
    consumer_key        = API_KEY,
    consumer_secret     = API_SECRET,
    access_token        = ACCESS_TOKEN,
    access_token_secret = ACCESS_TOKEN_SECRET,
)

#   Post the review to the API
#   https://www.goodreads.com/api/index#review.create

review_data = {"book_id": goodreads_id, "review[review]":description, "review[rating]":rating, "review[read_at]":date}

response = goodreads_api.post('https://www.goodreads.com/review.xml', review_data)

print(response.text)
</code></pre>

<h2 id="setting-the-date"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#setting-the-date">Setting the date</a></h2>

<p>The Goodreads API is... crap. <a href="https://www.goodreads.com/topic/show/20997772-review-read-at-doesn-t-work">Posting the review doesn't actually add a date to the review</a>. So you need to edit the review to post it <em>again</em>.  To start with, we need to get the review's ID:</p>

<pre><code class="language-python">import xml.etree.ElementTree as ET
tree = ET.fromstring(response.text)
review_id = tree.find("id").text
review_data = {"review[read_at]":date[0:10]}
response = goodreads_api.post('https://www.goodreads.com/review/'+review_id+'.xml', review_data)
print(response.text)
</code></pre>

<h2 id="get-the-code"><a href="https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/#get-the-code">Get the code</a></h2>

<p><a href="https://gitlab.com/edent/schema-to-goodreads/tree/master">The Python code is available on my GitLab</a>.</p>

<p>But... The Goodreads API is a bit picky. ISBN lookup doesn't work very well, and bits of the API are flaky. So while this code <em>mostly</em> works, I don't run it that often.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=33209&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2019/12/add-review-to-goodreads-from-schema-markup/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Convert DOI to a HTML5 / Schema citation]]></title>
		<link>https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/</link>
					<comments>https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 07 Dec 2019 12:51:27 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[citation]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[schema.org]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=33323</guid>

					<description><![CDATA[This is a quick and dirty way to turn a DOI (Digital Object Identifiers for academic papers) into an HTML &#38; Microdata citation.  I use this to power my Citations page.  Schema.org is a Microdata standard which allows machines to read your HTML and create semantic relations between documents.  Here&#039;s a minimum viable citation:  &#60;blockquote itemprop=&#34;citation&#34; itemscope…]]></description>
										<content:encoded><![CDATA[<p>This is a quick and dirty way to turn a DOI (<a href="https://www.doi.org/">Digital Object Identifiers</a> for academic papers) into an HTML &amp; Microdata citation.  I use this to power my <a href="https://shkspr.mobi/blog/citations/">Citations page</a>.</p>

<p>Schema.org is a Microdata standard which allows machines to read your HTML and create semantic relations between documents.</p>

<p>Here's a minimum viable citation:</p>

<pre><code class="language-html">&lt;blockquote itemprop="citation" itemscope itemtype="http://schema.org/ScholarlyArticle"&gt;
    &lt;span itemprop="author" itemscope itemtype="http://schema.org/Person"&gt;
        &lt;span itemprop="name"&gt;
            Terence Eden
        &lt;/span&gt;
    &lt;/span&gt; 
    &lt;cite itemprop="headline"&gt;
        Proof that P ≠ NP
    &lt;/cite&gt;
    (&lt;span itemprop="datePublished"&gt;2025&lt;/span&gt;)
    &lt;a itemprop="url" href="https://ex.doi.org/99.9999/1234"&gt;
        https://ex.doi.org/99.9999/1234
    &lt;/a&gt;
    &lt;span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"&gt;
        &lt;span itemprop="name"&gt;
            Journal of Impossible Research
        &lt;/span&gt;
    &lt;/span&gt;
&lt;/blockquote&gt;
</code></pre>

<p>That says: This citation is a scholarly article which has a headline, date, and URl. It has an author who is a person with a name. It has a publisher which is an organisation with a name.</p>

<p>Here's a more full example, including ORCID, page numbers, etc:</p>

<pre><code class="language-html">&lt;blockquote itemscope itemtype="http://schema.org/ScholarlyArticle"&gt;
    &lt;span itemprop="citation"&gt;
        &lt;span itemprop="author" itemscope itemtype="http://schema.org/Person"&gt;
            &lt;link itemprop="url" href="http://orcid.org/0000-0003-4542-8599"/&gt;
            &lt;span itemprop="name"&gt;
                &lt;span itemprop="familyName"&gt;Losavio&lt;/span&gt;, &lt;span itemprop="givenName"&gt;Michael M.&lt;/span&gt;
            &lt;/span&gt;
        &lt;/span&gt;,
        &lt;cite itemprop="headline"&gt;The Internet of Things and the Smart City: Legal challenges with digital forensics, privacy, and security&lt;/cite&gt;
        (&lt;time itemprop="datePublished" datetime="2018-04-27T03:13:15Z"&gt;2018&lt;/time&gt;)
        Page: &lt;span itemprop="pagination"&gt;e23&lt;/span&gt;.
        &lt;span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"&gt;
            &lt;span itemprop="name"&gt;Wiley&lt;/span&gt;
        &lt;/span&gt;
        &lt;span itemprop="publication"&gt;Security and Privacy&lt;/span&gt;
        &lt;a itemprop="url" href="https://doi.org/10.1002/spy2.23"&gt;https://doi.org/10.1002/spy2.23&lt;/a&gt;
    &lt;/span&gt;
&lt;/blockquote&gt;
</code></pre>

<h2 id="apis"><a href="https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/#apis">APIs</a></h2>

<p>Sadly, <a href="https://citation.crosscite.org/docs.html">CrossRef doesn't do Schema.org</a>, so we have to use their API to get some JSON and convert it to JSON+LD.</p>

<p>Here's how to install their official Python library:</p>

<pre><code class="language-bash">pip3 install --user crossref-commons
</code></pre>

<h2 id="the-code"><a href="https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/#the-code">The Code</a></h2>

<pre><code class="language-python">import crossref_commons.retrieval
import os
import re

# Set a friendly header
os.environ['CR_API_MAILTO'] = 'yourEmail@example.com'

reference = input("Enter a DOI: ")

# Check DOI is valid
# https://www.crossref.org/blog/dois-and-matching-regular-expressions/
regex = r"^10.\d{4,9}/[-._;()/:A-Z0-9]+$"
matches = re.search(regex, reference, re.IGNORECASE)

if matches:
    # Call the API
    data = crossref_commons.retrieval.get_publication_as_json(reference)

    # Start the citation
    citation_html = '&lt;span itemscope itemtype="http://schema.org/ScholarlyArticle"&gt;&lt;span itemprop="citation"&gt;'

    # Get all the authors
    authors = []
    for a in data["author"]:
        author_html = '&lt;span itemprop="author" itemscope itemtype="http://schema.org/Person"&gt;'

        if "ORCID" in a:
            author_html += '&lt;link itemprop="url" href="' + a["ORCID"] + '"/&gt;'

        author_html += '&lt;span itemprop="name"&gt;&lt;span itemprop="familyName"&gt;' + a["family"] +'&lt;/span&gt;, &lt;span itemprop="givenName"&gt;' + a["given"] + '&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;'

        authors.extend({author_html})

    # Add the authors to the citation
    for author in authors:
        citation_html += author
        citation_html += " &amp; "
    # Remove the last &amp;
    citation_html = citation_html.rstrip(' &amp;')

    # Title and any language information
    if "title" in data:
        headline  = data["title"][0]

        if "language" in data:
            lang = data["language"]
            citation_html += ' &lt;q&gt;&lt;cite itemprop="headline" lang="'+lang+'"&gt;&lt;span itemprop="inLanguage" content="'+lang+'"&gt;'+headline+'&lt;/span&gt;&lt;/cite&gt;&lt;/q&gt; '
        else:
            citation_html += ' &lt;q&gt;&lt;cite itemprop="headline"&gt;'+headline+'&lt;/cite&gt;&lt;/q&gt; '

    # Add the date
    if "published-print" in data:
        year = data["published-print"]["date-parts"][0][0]
        citation_html += '(&lt;time itemprop="datePublished" datetime="'+str(year)+'"&gt;' + str(year) + '&lt;/time&gt;) '
    elif "issued" in data:
        year = data["issued"]["date-parts"][0][0]
        citation_html += '(&lt;time itemprop="datePublished" datetime="'+str(year)+'"&gt;' + str(year) + '&lt;/time&gt;) '
    elif "created" in data:
        datetime = data["created"]["date-time"]
        year     = data["created"]["date-parts"][0][0]
        citation_html += '(&lt;time itemprop="datePublished" datetime="'+datetime+'"&gt;' + str(year) + '&lt;/time&gt;) '
    elif "deposited" in data:
        datetime = data["deposited"]["date-time"]
        year     = data["deposited"]["date-parts"][0][0]
        citation_html += '(&lt;time itemprop="datePublished" datetime="'+datetime+'"&gt;' + str(year) + '&lt;/time&gt;) '

    # Page number information
    if "page" in data:
        citation_html += ' page: &lt;span itemprop="pagination"&gt;' + data["page"] + '&lt;/span&gt;. '

    # Publisher
    if "publisher" in data:
        citation_html += '&lt;span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"&gt;&lt;span itemprop="name"&gt;'+data["publisher"]+'&lt;/span&gt;&lt;/span&gt;. '

    # Publication
    if "container-title" in data:
        citation_html += '&lt;span itemprop="publication"&gt;'+data["container-title"][0]+'&lt;/span&gt;. '

    # DOI link
    if "DOI" in data:
        doi = data["DOI"]
        doi_url = "https://doi.org/" + doi
        citation_html += '&lt;a itemprop="url" href="'+doi_url+'"&gt;'+doi_url+'&lt;/a&gt;'

    # End the citation
    citation_html += '&lt;/span&gt;&lt;/span&gt;'

    print(citation_html)
</code></pre>

<h2 id="opinions-about-citations"><a href="https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/#opinions-about-citations">Opinions about citations</a></h2>

<p>There are too many citation styles. And most of them suck. I used to hate seeing "Smith (1991)" as the only reference.  Theoretically, a DOI is the only citation you need - but I discovered that some were missing from major resolvers.  And, it is probably helpful to have some human readable information to aid discoverability.</p>

<p>I've tried to keep to author name(s), title, year, publisher, publication, page, DOI.  That's more-or-less MLA.  But, because of the microdata, a machine can understand the citation and you can convert to your preferred style.</p>

<p>Or, if you wish, you can adapt this code to pump out a different citation style.</p>

<p><a href="https://gitlab.com/edent/doi-to-html5-schema-microdata-citation">Source code on GitLab</a>.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=33323&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2019/12/convert-doi-to-a-html5-schema-citation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Use-cases wanted! Adding dietary requirements to Schema.org/Person]]></title>
		<link>https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/</link>
					<comments>https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 02 Dec 2019 12:11:35 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[vegetarian]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=33114</guid>

					<description><![CDATA[I want Schema.org to add dietary requirements to the Person specification. And I need your help!  Background  Schema.org is a metadata standard. You can include it on webpages to create structured, machine-readable data.  Here&#039;s a sample way of representing a Person:  {   &#34;@context&#34;: &#34;https://schema.org/&#34;,   &#34;@type&#34;: &#34;Person&#34;,   &#34;name&#34;: &#34;Albert Einstein&#34;,   &#34;hasOccupation&#34;: [     {       &#34;@type&#34;: …]]></description>
										<content:encoded><![CDATA[<p>I want Schema.org to add dietary requirements to the <code>Person</code> specification. And I need your help!</p>

<h2 id="background"><a href="https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#background">Background</a></h2>

<p>Schema.org is a metadata standard. You can include it on webpages to create structured, machine-readable data.</p>

<p>Here's a sample way of representing a Person:</p>

<pre><code class="language-json">{
  "@context": "https://schema.org/",
  "@type": "Person",
  "name": "Albert Einstein",
  "hasOccupation": [
    {
      "@type": "Occupation",
      "name": "Professor of Physics",
      "occupationLocation": {
        "@type": "Country",
        "name": "USA",
        "sameAs": "https://www.wikidata.org/wiki/Q30"
      }
    }
  ]
}
</code></pre>

<p>Hopefully easy to follow. This is a <code>Person</code>, they have a <code>name</code> and an <code>occupation</code>. That <code>occupation</code> has a <code>name</code> and is located in a <code>country</code>. That <code>country</code> has some linked data.</p>

<p>There are all sorts of properties we can associate with a <code>Person</code> - birth and death dates, memberships, nationality, credentials, tax ID, and even weight! See <a href="https://Schema.org/Person">Schema.org/Person</a> for a full list.</p>

<p>One which I think would be useful is a person's diet.</p>

<h2 id="diet"><a href="https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#diet">Diet</a></h2>

<p>Schema already has the concept of a <a href="https://schema.org/RestrictedDiet"><code>RestrictedDiet</code> type</a>.  It lists things like Vegetarian, Halal, Kosher, Low Salt etc.</p>

<p><em>But</em> it only applies to <a href="https://schema.org/suitableForDiet"><code>MenuItem</code> and <code>Recipe</code> types</a>.  That is, I can mark up a restaurant's menu and say that this dish is Gluten Free, and that dish is Vegan friendly.</p>

<pre><code class="language-json">{
    "@context": "http://schema.org",
    "@type":"MenuItem",
    "name":"Potato Skins",
    "description":"Small serving of baked potato skins.",
    "offers":{
        "@type":"Offer",
        "price":"4.49",
        "priceCurrency":"GBP"
    },
    "suitableForDiet":[
        {
            "@type": "GlutenFreeDiet"
        },
        {
            "@type": "VeganDiet"
        }
    ]
}
</code></pre>

<h2 id="my-use-cases"><a href="https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#my-use-cases">My Use Cases</a></h2>

<p>I maintain a <a href="https://edent.tel/">personal contact site</a>. I tell people my name, address, occupation, etc. I also want to inform other people that I am vegetarian.</p>

<ul>
<li>On a social network, it might be nice to have an (optional) feature where people give their dietary preferences.</li>
<li>My Jewish and Muslim friends might want to automatically filter out the pork casserole recipes people post.</li>
<li>My address book might suggest a restaurant which caters for my guests' preferences.</li>
<li>An encyclopædia can show dietary restrictions of famous people.</li>
<li>An airline could - with permission - read your social profile to select your meal for a flight.</li>
</ul>

<h3 id="sample"><a href="https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#sample">Sample</a></h3>

<p>Here's how I think it could work:</p>

<pre><code class="language-json">{
    "@context": "https://schema.org/",
    "@type": "Person",
    "name": "Terence Eden",
    "restrictedDiet": "http://schema.org/VegetarianDiet"
}
</code></pre>

<p>That is, just add <code>restrictedDiet</code> as a valid property of <code>Person</code>.  I suppose it could be <code>hasDiet</code> or <code>dietaryPreference</code> or similar.</p>

<h2 id="your-use-cases"><a href="https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/#your-use-cases">Your Use Cases</a></h2>

<p>If you want to add your own use cases, or just think this is a good idea, please leave a comment on <a href="https://github.com/schemaorg/schemaorg/issues/1996">GitHub.com/schemaorg/schemaorg/issues/1996</a></p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=33114&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2019/12/use-cases-wanted-adding-dietary-requirements-to-schema-org-person/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
