Hacking on microformats and Gutenberg at IndieWebCamp East Online 2020, day 2

Today is day 2 of IndieWebCamp East Online 2020, a general hack/create day.

I’m hacking on microformats and implementing them in Gutenberg, which means I’m thinking in blocks.

Main personal inspirations for this include:

  • I write a frequent week’s end series that is composed mostly of individual thoughts or notes. I can imagine a future where someone (me) could link or reply directly to a thought rather than the entire thing. Doing this means that each unique thought likely deserves to be its own h-entry.
  • I want to reply to others’ posts via webmentions. Having a block or pattern dedicated to this would be nice.
  • Yesterday’s conversation during the IndieWebCamp session gave me some initial sparks into how this may all work in the future.

As I somewhat mentioned in yesterday’s wrap-up post, a default pattern for WordPress themes has been to do something like this:

<article <?php post_class(); ?>>
    // header info

    <div class="entry-content">
        <?php the_content(); ?>

The post_class() function outputs a handful of classes for the article wrapper. WordPress includes hentry with this by default, a property of the first microformats version that indicates a general container for the content of an entry.

The block editor allows for a much greater level of content flexibility, which makes specific markup like this less likely to be appropriate.

I decided my initial workaround would generally be this:

if ( has_block( 'mfblocks/h-entry' ) ) {
	$has_h_entry = true;
} else {
	$has_h_entry = false;

<?php if ( $has_entry ) : ?>
    <div class="entries-content-wrapper">
<?php else: ?>
    <article <?php post_class(); ?>>
<?php endif; ?>

If my h-entry block is detected, I can assume that the post content itself will take care of describing entries with microformats. If not, then markup the page as normal. I’ll of course screw something up with my CSS here, but I’ll get to it at some point. I’m going to use the same logic to determine if an entry header should be output in a single template.

And! In reality, I’ll create a content-has-h-entry.php or something that I’ll use for this markup rather than having a bunch of if clauses making it all annoying to work with. 🙂

Okay, my theme is now wired up to handle what I want to do. Now, for some blocks!

My initial impression as I’m starting to plan this out is that WYSIWG is fun in theory, but it’s also nice to have an awareness of the structure of the document.

Gutenberg has a list view that shows you the outline of the current document. I’d kind of like this in a static place so that I don’t lose track of my nested nested group blocks. I imagine this will become an experience problem that is more and more obvious as we get closer to full site editing.

Having some contextual awareness during editing—which group is this block a part of?—will become more important in the future.

I started off the day with a couple custom blocks that implemented h-entry and e-content as wrapping containers of Gutenberg’s <InnerBlocks> component. I figured I could create block patterns that started with those groups and allowed someone to fill in the blanks.

Two problems:

  • Discoverability. Adding one of my patterns means taking the mouse up to the + icon, clicking, clicking, clicking to find the right category and pattern that I want to use. It would be so great if I could insert a block pattern with the / command like I do with blocks.
  • I could spend so much time trying to setup placeholder content that has the right microformat class names, but there’s nothing built into the pattern to keep that structure strict. An accidental keystroke removes the e-content section and then I have to start over.

So, I switched strategies and started building out a custom h-entry block that dictated the structure. This ends up being more opinionated, but we do have a general spec to follow.

Fast-forward as I started hacking away and stopped keeping notes. 🙂

I now have a repository setup for Microformat Blocks, a plugin for WordPress that provides an h-entry block along with a structure that supports a handful of other microformat properties:

  • p-name
  • p-summary
  • e-content
  • dt-published

I’m really close on having author implemented, hopefully in the next few days. I’ll also find an initial way of handling in-reply-to. And I’ll also get it up on the WordPress plugin repo.

But! The day is over and I’m really hungry.

Gutenberg aside: I want to implement in-reply-to on specific anchor tags rather than create a whole custom input control for it. Another case where it would be nice to register custom inline blocks.

Some leftover notes:

  • Trying to think through the concept of authorship on a page of thoughts/notes. Will a microformat compatible reader infer authorship from a page level h-card or does u-author need to be included with each distinct entry?
  • I wonder if I can implement indie-auth comments in a way where someone can write a comment or annotation on my site and have it published back to their site?
  • How does the current WP webmention implementation handle my new block configuration?
  • Once I have dt-published actually setup for multiple entries on my site, it would be cool to sort h-entries in a thought post by date, ASC or DESC

That’s that. I had an excellent time this weekend geeking out on IndieWeb. Big thanks to Chris Aldrich and David Shanske for organizing!

Notes on IndieWebCamp East Online 2020, day 1

I woke up at 5am—on a Saturday—to participate in my first IndieWebCamp, IndieWebCamp 2020 East, which also happened to be my first online conference ever. As much as it’s fun to joke about getting up so early on a weekend, the schedule worked out really nice. I was able to eat a good breakfast, get the coffee going, and enjoy a full day of tech before the WSU game at 4pm.

Many of the notes here were written during sessions. I’ve now parsed through them a couple times to editorialize, likely mangle direct quotes I don’t remember, and build out some other thoughts I think I had at the time. I’ve allowed myself full editorial rights throughout, so there’s a chance some of it is my brain talking and not even what happened in the session.

Hopefully I haven’t mangled intent!

If you’d like to see the sessions, they’ll be posted on the IndieWebCamp site in the near future.

Intro and lightning keynotes

First up was an intro session and a couple of lightning keynotes. The conference as a whole is BarCamp style, so much of the agenda is created on the fly once everyone has had a chance to discuss what they want to talk about. Everyone who attends is also encouraged to propose a session.

During the intro, Chris mentioned that “getting something out of the camp means putting something into it”, a statement so undeniably accurate that it finally prodded me into proposing a session myself. I’ll expand on that further down.

I’m not sure what this is in reference to, or who said it, but I like the idea:

One objective of IndieWeb is to “bring the bar of connectability down to make it easier for people to own their own place on the web.”

That’s a mission I can get behind!

David Dylan Thomas

The first lightning keynote was from David Dylan Thomas, the author of Design for Cognitive Bias, which I happen to have on my desk right now. After watching the talk, I’m looking even more forward to reading his book.

I captured a handful of thoughts/quotes during his talk and in the discussion afterward:

  • If something gets easier to read, we generally think it’s true.
  • If something rhymes, we generally think it’s true.
  • “plain language, pictogram-based intervention” can help communicate a message (hello, could have been pandemic response!) more than dense material.
  • Our jobs (as designers, developers, etc…) are harder than we think. It’s not just “design cool shit”. The things we do have impact on others.
  • I want this Twitter/Facebook feature without knowing why they built it in the first place. Think: Why should you try to reproduce it? Why not do something entirely different.
  • When we assume that human beings are horrible and that if we were to gather them all in a room there will be fighting, “we discount how much design will inform discussion”. Design spaces for communication / conversation.
  • Medium says to “publish” rather than comment. What would it be like to replace “commenting” with a different word? Converse / conversation? I’ve chatted about this somewhere else recently, but I’m not recalling.
  • Gender equality by design” – talk by Iris Bohnet, also in book form.
  • “Curate a culture of curiosity and challenge your own assumptions”.
  • The (dangerous, flawed) concept of “Internalized capitalism” – if you’re not doing anything right now, then you’re not worth anything.
  • David has a proposed SXSW session titled “Content strategy hacks to save civil discourse“.

And then! David shared a fantastic list of resources on designing with cognitive bias that I’ll have to parse through at another time.

One of David’s slides included a quote from Martin Luther King Jr. that stood out as prescient enough to call out in more detail:

“We must rapidly begin—we must rapidly begin the shift from a thing-oriented society to a person-oriented society. When machines and computers, profit motives and property rights are considered more important than people, the giant triplets of racism, extreme materialism and militarism are incapable of being conquered.”

Martin Luther King Jr., in his Beyond Vietnam speech, April 4, 1967

Sarah Hibner

The second lightning keynote was from Sarah Hibner, who gave a great Intro to Variable Fonts. The slides from the presentation make for an excellent sheet to share with others and link off to a series of codepens that show variable fonts in actions. I took many fewer notes because I was busy playing with the codepens during the talk! I also like the outer-outer.space domain.

Lightning intros

Everybody says things! We went around the Zoom room doing introductions and showing off personal sites or projects. I forgot to show off my personal site, but that’s okay. 🙂

Creative Blocks in WordPress

I’ve been thinking quite a bit about elements of IndieWeb can be used at the block level rather than the full page view level and figured that this weekend would be a good time to explore that a bit more. I proposed a brainstorming session of sorts.

Overall the session was fun and there was a lot of good discussion. In hindsight, I might have proposed a slightly broader session topic as I still have a lot of catch-up to do in the current support for IndieWeb concepts in WordPress and the existing road blocks.

I will also admit in hindsight that I should not have chosen the first time slot as a first time facilitator. I was much more familiar with the ins and outs of a collaborative video chat discussion at the end of the day and would have probably been better prepared. Next time!


The future of WordPress is built on the new block editor, Gutenberg, and an entirely different editing experience than the one we’ve used for years. The next several releases will continue to introduce changes, including some form of full site editing through blocks. What are some creative ways the block editor can be used to create an indie web presence?

My editorialized discussion notes and takeaways

Most of our time was spent talking about microformats and the general lack of support or mis-support in WordPress. Many legacy themes use microformat version 1 properties and it is difficult to find general support for microformats 2.

In general, a question seems to be: How do microformat properties work with how WordPress outputs markup?

This may be an easier problem to solve as time goes on in the block editor. Themes of the future (this is me editorializing) are ideally less likely to include as much markup as they are required to now. Instead, the majority of the markup will be managed by the block editor itself. Microformat friendly blocks can be created to control the output.

One major issue now is the way a theme must assume everything output with a post or page is “content” and must be wrapped in a content section. What do we expect, when it is literally output with the_content(). 😁

The block editor makes it much easier to add a bunch of non-traditionally-recognized-as-content data to a page or a post. One way to approach this is through the grouping of content in the block editor. Unfortunately, the UI for this is a bit clunky, but it is possible to group the majority of your post with a content group and then add additional data in another group below. This would semantically communicate the content to readers.

There is likely an opportunity to create a series of custom blocks that apply the proper microformat properties. It may be that block patterns can be used to post various types of content, something that is handled now through things like the Post Kinds plugin, which uses a custom taxonomy to separate types of content.

I have ideas to work on!

Personal Data Warehouse

Simon Willison gave a demo of Dogsheep, a tool to track and query basically everything about you that has been collected through a number of online services and stored in a SQLite database. Simon was inspired to build Dogsheep by a Stephen Wolfram essay.

  • How to democratize something like Dogsheep to make it more approachable for anyone to fire up their own instance.
  • A previous talk and write-up by Simon. I kind of like this as a nice way to import a bunch of data locally and may give a shot in the near term
  • Gyuri Lajos gave an overview of Fission, which is described as “Next-gen serverless apps with user controlled data & great DX”.
  • Some conversation around IPFS as a data store for something built with Fission and the possibilities around searching the IPFS. IPFS Search was mentioned, and I was surprised to see it in my browser history because this is all way above my head right now.
  • Topic 3 is about the “why” of personal data storage.
  • Simon – it’s a bit of a super power.
  • People don’t necessarily want to store everything they’ve done in their head. Having a log ensures that it’s out of their head and opens up what they can do. Via BBC research – Ian Forrester
  • Tantek Çelik mentioned memories that you may not be ready for. Eric Meyer’s (very excellent) book, Design for Real Life.
  • Angelo Gladding gave an example of a (Maybe Aaron’s?) site when sending a comment with a sad emoji, the profile changes to display an avatar with a more somber face rather than the happy avatar. Very interesting idea.

Domain of One’s Own LMS

  • Chris – we went from slowly putting educational resources online over 20 years to all of a sudden putting everything online.
  • Odd ethical things happening in education space
  • DS106
  • An LMS in the indie web may mean using your own website as a lifelong learner’s LMS

Chris walked through an open course he had been involved with that was able to use things like webmentions to mark things as read and to comment or annotate them. Question posed at the beginning of the class: what do you want to get out of this, what do you want to learn? Maybe use a unique hashtag to create a feed of public stuff from the class.

If Moodle had a webmention endpoint, it may be able to exist as a platform but with some IndieWeb building blocks it becomes a hub where everyone can read the conversation in one spot. It could send webmentions back.

Internal wondering by me: Could a “private” webmention be sent with WordPress? Less discoverable permalink to serve a private post from WordPress. Similar to Public Post Preview.

Start a class by outlining the syllabus or the chapters of the textbook. Professors who decide to write their text books as they go with the students. Publish the result as OER. It’d be fun to see some examples of that.

h0p3: peer to peer sharing – resiliosync, hyper, ipfs – students create objects of knowledge on their own devices and transferring to a teacher. Sits on their own hard drives from the beginning, not on a central server somewhere.

I shared Commons in a Box and my general perspective that faculty are often creatively finding ways around the centrally dictated LMS. Jake’s HYPER Lab is a good example of a show your work textbook in progress, but I forgot to bring it up.

Chris brings up a good point that even with centralized open source systems, there are ways where the university can remove content or otherwise censor it. Tenure works most ways, but maybe not all ways.

Drupal’s OpenScholar came up, which I hadn’t seen before.

Note: My notes are getting sparser as the day went on! 😂

Discovery: A Trek Through the Indieweb

Now that we have social readers, how can we discover new sites and feeds to subscriber to in our readers?

  • Bring back blogrolls? How do we give blogroll concept more life? – David
  • Angelo – one failure with blogrolls was that it wasn’t descriptive enough.
  • Example of formatted OPML: http://petermolnar.net/subscriptions.opml
  • Categorized following lists – A friend maintains a list, I follow that, so I follow everyone that is on the list. When they update the list, I now follow everyone on that list.
  • How do we create public parks on the web to gather?
  • There are probably some opportunities via aggregator or “temporarily centralized” area which accepts contributions from a certain group of people.
  • Micro.blog mini communities via emoji / discovery as an organic community.
  • How do you provide value signals within a discovery system? – Chris

“As soon as you try to make it global rather than local, it becomes an attack mechanism” – Kevin Marks, discussing starting with something that seems like a social network at first, but then introduces trending topics, algorithms to feed content to people. Good indicator that local (smaller) communities are better? Split at certain points?

What is “local”? Curated community. Local to a topic can work, but armies of people can take system over. Brigading rather than spam now. Physical proximity is another option for “local”.

Chris mentioned the term “tummeling”, which I hadn’t heard of: “the art of creating active social spaces“.

Whew. I can tell from my notes that my brain was getting a bit overloaded with fun ideas. I may come back and clean some of this up some more in the future.

Topics to explore

A general list of things that I need to look into, among others:

Things to work on for day 2 / hack day

I’m wrapping this post up as part of my hack/create day work on Sunday morning. These are the things I think I’m going to be working on:

  • Wrapping up a day 1 blog post
  • Thinking about having an actual home page instead of an archive of posts
  • Taking a look at some theme markup, how it aligns (or doesn’t) with block editor markup
  • Start poking at some ideas for block specific web mentions

Of course, now that I’ve finished the first item on the list, my brain is already wandering to other unfinished projects, so we’ll see. Time to dive in!

Working through displaying Webmentions

Now that this site supports Webmentions, I’ve been having some fun digging into how I’d like them to be presented.

The theme I’m using is very bare-bones. I created it using Underscores a couple years ago when I decided I had lost touch with the code I was using and for some reason wanted to get back in touch? I don’t know, but I like it.

I created a plugin specifically for my adjustments to the IndieWeb, Webmention, and Semantic Linkbacks plugins. There are a couple scripts and styles I decided I didn’t need as well as a custom comment walker I decided to remove.

At the same time, I created another plugin specifically for adjustments to WordPress. I removed all default emoji handling to see if things would display better in feed readers and adjusted some of the markup output by default—sorry, Windows Live Writer.

Back to comments.

Before I started, the theme’s comment template output everything stored in the comments table as if it was a comment. This makes sense because WordPress doesn’t have a complete idea of “custom comment types”, so it treats them all the same.

The first thing I did was break the query for all comments into comment types so that I could display them in separate sections. WordPress has a function that should do this, separate_comments(), but it is hard coded to support only comment, trackback, pingback, and pings. I have my eye on proposing a filter there, but I’m guessing there are wider concerns with comment types that need to be addressed at the same time.

I’ll revisit that code in the near future. I was just winging it today and never actually went back to review some of those decisions. 🙂

I’m starting with a section for “Likes”, a section for “Mentions”, and a section for “Replies”. Once I get more familiar with other actions and how I see them being used, I’ll likely mix things up a little more.

For Likes and Mentions, I decided to keep things simple and display the avatar, name, action, and date. This displays a bit more than a facepile, but less than a full comment.

It’s been interesting seeing what data actually comes along with a Like or a Mention—sometimes it’s the full post—and it’d be fun to figure out the right way to display that in the future. I could see manually editing some mentions and displaying them differently so that the context is displayed. I envision something like the first 100 characters before and after the actual mention itself.

I removed support for comment navigation, as it’s something I don’t want to deal with right now and I have the option to paginate comments turned off in WordPress.

I was low-key annoyed that wp_list_comments() only supported a style of ol or li, but then went further to the comment walker and saw div was also a supported option. I created a new trac ticket for that and tagged it as a good first bug for anyone who may want to contribute.

My next annoyance is that comment author names are wrapped with <b> and so here I am deciding that of course I should add a custom walker. Exciting!

Of course now I’ve screwed this all up somehow and the reply links aren’t working.

Ahhh, I see! I tried to shrink the amount of markup used around each comment, but the default reply script used in WordPress expects a bit more structure. Added that back for now.

I’ve temporarily adjusted the “Reply” text below each comment to “Reply to {comment author name}”. I think I’d like to adjust this even more so that on nested comments, it includes everyone’s name. Something like “Reply to Jeremy Felt, Alice, and Bob” on a thread in which all have participated would be cool. Part of me wants to shorten that to first names only, though that starts to make assumptions.

One quirk now that I have this all in place is that I’ve replied to “mentions” in the past, which are now displayed in their own area of the page. These replies are now displayed outside of that context. I’m guessing this won’t be an issue in the future, though if I ever do want to reply to a mention, it’d be cool if there was a way to convert the mention into a reply for purposes of display. I’ll think some more on that.

Almost there. Time for another bad decision.

It looks like some multi-paragraph Webmentions are coming in or being stored without paragraph tags. Rather than dive into really testing that, I took the lazy way out and replaced single line breaks with double line breaks so that wpautop() can add paragraphs as intended. This seems to have worked, but I’m sure I’ll run into an edge case at some point.

Okay! Theme deployed. Deployments setup for the new plugins. All is right.

Version 0.0.2 of a new vibe for Webmentions is live on the site. 🕺🏻

Now supporting Webmention

I think? If you know how to send a Webmention, please do so that I know it works! 😂

I’ve installed the IndieWeb plugin as well as its companions, Webmention and Semantic-Linkbacks.

The IndieWeb plugin adds a few semantic things to the user profile in WordPress and acts as a launch platform for installing a bunch of other IndieWeb related plugins.

The Webmention plugin adds support for, imagine this, the Webmention protocol. This should enable support for sending and receiving mentions.

The Semantic-Linkbacks plugin treats Webmentions and other linkbacks as proper comments and formats things in a nice rich way.

I have added all of these, but I haven’t tested any of them yet. So this post should play the role of general announcement and playground.

Trying out Micro.blog

Services like Micro.blog should spend more time telling everyone about features like “oh, by the way, we have a dedicated discovery page for posts about pizza“. 🍕

That kind of pitch and I would have signed up for an account 2 years ago.

Here I am discovering new things though.

I got here because of a series of articles. I started reading “Twitter to decentralize… something” after having it open in a tab for a few days. And while I nodded along to that quite a bit, there was a link to another post titled “Open gardens” that I really nodded along to.

The issue isn’t that Twitter doesn’t care. It’s instead a design flaw in the platform. Because tweets don’t exist outside of Twitter, when you’re banned from Twitter, you need to start over with a new format or on a new social network. For this reason, and because their business depends on a large user base, Twitter is hesitant to throw anyone off their service. They’re unwilling to tend the garden for fear of pulling too many weeds.

– Manton Reece, Open gardens

That paragraph had me hooked, but it still wasn’t until the middle of the post when the author mentioned the Micro.blog Kickstarter that I connected the dots to whom I was reading. Paragraphs like those are the gotchas when you’ve heard about a service but haven’t paid enough attention and now you know you really should check it out.

It’s not over.

At the end of that article was a link to yet another, “The way out“, linked to as “the way forward“, an exceptional play on title and URL that caused me to open the link twice because I wasn’t sure I had clicked the right thing.

This one talks more about Micro.blog in the context of content ownership and hones in on a good difference between it and things like Mastadon: (emphasis mine)

Mastodon helps by encouraging smaller social networks, distributing the task of moderation, but doesn’t prioritize content ownership. An account on an instance like Mastodon.social has no more ownership of its content than an account on Twitter. Both let you export your data but both live at someone else’s domain name.

– Manton Reece, “The way out

A link then drops to “Starting a new photo blog“. At this point I’m thinking to myself how excellent of a series of perfectly placed links this has been because here I am on blog post four and I’ve read every post and often when this happens those tabs sit unread for weeks!

That post is great and it was cool to see how easy it is to import past Instagram posts into Micro.blog using the MacOS app. There’s also a nice looking Sunlit app for iOS that I won’t be able to use, but I’m definitely interested in giving this all a shot.

When I left Instagram, one of the final triggering events was my discovery of the open-source and hosted service pixelfed. I setup an account and immediately declared it was the replacement I would use. I posted a few photos, followed a couple people, added the site as a home screen bookmark so that it would be app like, and then…

Forgot to login after a few days.

The browser cookies expired and I had to login again, and I had that ownership question poking in my brain—If I start adding photos here, how long will it be before I have to move them somewhere else.

Still a little upset about URL shorteners in general and especially 2009, the year I used tr.im for everything 😞

Me, on Twitter a few weeks ago

Of course there’s more history.

Way way back in 2009, Posterous (post.ly) was a thing. A year before Instagram came around, a lot of people had photo blogs and Posterous made it easy to post via email or web. In 2012, the team was acquired by Twitter, and in 2013 the service was shut down.

A custom domain at Posterous made it easy for me to move to self hosted with working post.ly 301 redirects. Happy for that. Own your stuff.

Me, on Twitter almost 7 years ago

Luckily, Posterous was cool in that you could point a domain of your own to your account so that jeremys.posterous.com was really posterous.jeremyfelt.com. When they shut down, I was able to export all of my data and have control over the redirects. I imported everything into WordPress, setup redirects to posts and now I can still go back and see how absolutely horrid a Blackberry Pearl’s camera was 10 years ago.

Here we are several years later.

Even though I’ve seen how these cycles go, I’ve published a whole bunch of content so that if I move it somewhere else, I break every reference to it.

Instagram was never web friendly anyway, so there are barely any references—you couldn’t even link to photos within the app.

Twitter, on the other hand—even though it’s perfectly fine to treat it as an ephemeral stream and just delete it all—has also been a log of work, feelings, annoyances, experiences, and all kinds of junk that becomes fun to look back at every once and a while.

That’s going to suck when Twitter shuts down or everyone stops using it.

So. I should learn that lesson a bit here while also being open to trying new hosted services that seem to be driven by good people. I setup a Micro.blog account and pointed a sub-domain at it. Thanks to my HSTS configuration on this root domain (jeremyfelt.com), I need to wait just a bit… 🛌

Ok. I’m back to finish the post, and only two weeks later!

It was getting late and I had to request an HTTPS certificate for micro.jeremyfelt.com from the Micro.blog team. Manton actually replied early the next morning and had the cert and domain all configured for me. I also received a very welcoming set of replies to my first post from the Micro.blog community. All great touches!

I then got busy with not being busy for the holiday and left all these tabs and this post open with the intention of finishing every day since.

I’m going to figure out the right way to incorporate this into my flow now. I think I’ll start by trying to import my Instagram archive. Then I’ll need to work out a mobile solution and determine how this may all fit as a separate piece from my main site.

In an ideal world, if this all works out, most of my tweets will originate at micro.jeremyfelt.com and then syndicate out to Twitter according to some criteria. Or I’ll find some entirely new use for it that takes me away from Twitter for good. Let’s see what happens!