DEV Community

Cover image for Annotating my pages with microformats2 and h-entry
Minh Nguyen (he/him)
Minh Nguyen (he/him)

Posted on • Originally published at mnguyen.io

Annotating my pages with microformats2 and h-entry

h-entry is an open microformat for datestamped content on the web. I was looking at ways to make my site a bit more open to syndication, and also as an alternative to RSS/Atom feeds. I haven’t seen major browsers pick up on these formats, but the main focus are IndieWeb readers, and I’m all for them.

Now, please note that this post isn’t much of a guide to implementing h-entry or other parts of the microformats2 spec on your site, as it is a summary of I went about implementing it for this website.

What it looks like

{
  "items": [
    {
      "type": [
        "h-entry"
      ],
      "properties": {
        "name": [
          "My blog post"
        ],
        "author": [
          {
            "value": "John Smith"
          }
        ],
        "published": [
          "2020-01-01 12:00:00"
        ],
        "summary": [
          "A short summary of my blog post, and what you can do."
        ],
        "content": [
          {
            "value": "Starting paragraph of my blog post.",
            "html": "<p>Starting paragraph of my blog post.</p>"
          }
        ]
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

In short, there’s basically all of the information about the post, in a JSON object that could be easily be used as part of a different app. With that in mind, how does a parser go about doing this?

Elements of h-entry

h-entry itself is a what is known as a root class name. We can use it to define a h-entry, and it has a series of properties that the parser will determine, based on knowing that. Other root class names include:

  • h-adr
  • h-event
  • h-geo
  • h-item
  • h-product
  • h-recipe

You can find a more detailed list of these on the microformats2 page, along with examples and detailed descriptions.

Back to h-entry, we can establish this simply by naming it as a class:

<article class="h-entry">
...
</article>
Enter fullscreen mode Exit fullscreen mode

and that’s it, our article is now parseable as it is, though it might not be very useful by itself. This is where we add some core h-entry properties!

h-entry properties

There’s quite an amount of these, so I’ll only go with the properties that I used for this site.

p-name

This represents the entry name or title. For the title, we just need to add this class to the element that contains it:

<h1 class="p-name">{post.frontmatter.title}</h1>
Enter fullscreen mode Exit fullscreen mode

e-content

The full content of the entry in question i.e. the full body of the blog post:

<section class="e-content">...</section>
Enter fullscreen mode Exit fullscreen mode

dt-published

The datestamp of when the entry was published:

<time class="dt-published" datetime="2020-09-29">29 September, 2020</time>
Enter fullscreen mode Exit fullscreen mode

Implementing h-entry within a Gatsby content type

Let’s get topical! For this, I’m using Gatsby as my site generator, so in order to get this working for my blog post, I need to modify the template for the blog post’s render function (located in /src/templates/blog-post.js), which returns JSX as follows:

export default ({data}) => {
  const post = data.markdownRemark
  return (
    <Layout>
      <SEO title={post.frontmatter.title} description={post.excerpt} />
      <section className="h-entry">
        <h1 style={{marginBottom: `0.5rem`}} className="p-name">{post.frontmatter.title}</h1>
        { post.frontmatter.draft ? (
          `Draft`
        ) : (
          <time className="dt-published" dateTime={post.frontmatter.htmldate}>{post.frontmatter.date}</time>
        )}
        <section className="e-content" dangerouslySetInnerHTML={{ __html: post.html }} />
      </section>
    </Layout>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can see that the 2 section, the h1, and the time elements are updated as above to have the microformat2 elements defined via the className attribute. While I was able to get it working on these generic HTML elements, I wasn’t able to get it working for the time element, which was previously a separate element called <DateTime>. I couldn’t figure it out, so I reverted to using the base element that it represented.

Further reading

Implementing a microformat isn’t difficult, and can provide new ways for people to access your content. Give it a go!

Discussion (0)