The below filters can be added to a theme’s functions.php, but you have to make sure that your theme uses the post, body, and comment class functions, and that it doesn’t style hfeed or hentry. Also, hfeed is often added to the theme, and should be removed to avoid duplication.
/**
* Adds custom classes to the array of body classes.
*
* @param array $classes Classes for the body element.
* @return array
*/
function body_classes( $classes ) {
// Adds a class of hfeed to non-singular pages.
if ( ! is_singular() ) {
$classes[] = 'hfeed';
$classes[] = 'h-feed';
} else {
if ( 'page' !== get_post_type() ) {
$classes[] = 'hentry';
$classes[] = 'h-entry';
}
}
return $classes;
}
add_filter( 'body_class', 'body_classes' );
/**
* Adds custom classes to the array of post classes.
*
* @param array $classes Classes for the body element.
* @return array
*/
function post_classes( $classes ) {
$classes = array_diff( $classes, array( 'hentry' ) );
if ( ! is_singular() ) {
if ( 'page' !== get_post_type() ) {
// Adds a class for microformats v2
$classes[] = 'h-entry';
// add hentry to the same tag as h-entry
$classes[] = 'hentry';
}
}
return $classes;
}
add_filter( 'post_class', 'post_classes' );
Now the below adds microformats 2 classes to the avatar photo and to comments.
/**
* Adds mf2 to avatar
*
* @param array $args Arguments passed to get_avatar_data(), after processing.
* @param int|string|object $id_or_email A user ID, email address, or comment object
* @return array $args
*/
function get_avatar_data($args, $id_or_email) {
if ( ! isset( $args['class'] ) ) {
$args['class'] = array( 'u-photo' );
} else {
$args['class'][] = 'u-photo';
}
return $args;
}
add_filter( 'get_avatar_data', 'get_avatar_data', 11, 2 );
/**
* Adds custom classes to the array of comment classes.
*/
function comment_classes( $classes ) {
$classes[] = 'u-comment';
$classes[] = 'h-cite';
return array_unique( $classes );
}
add_filter( 'comment_class', 'comment_classes', 11 );
This allows for the simplest conversion of themes to the basic Microformats 2 structure. In the second part, we start moving into other more invasive modifications of the theme.
David, This is some excellent code for adding some microformats to @WordPress. Thanks @dshanske! https://david.shanske.com/2016/06/22/converting-wordpress-themes-microformats-2-part-1
For those with less technical expertise, could I pose a few questions which you may or may not cover in part 2?
If I recall, there’s microformats version 1 and a more recent, updated microformats2. Most of what you’re adding here is the mf2 spec and not backwards compatible mf1 mark up, right?
When you say that a theme shouldn’t “style” hfeed or hentry, you mean that the CSS shouldn’t include these classes as they’re used only for semantic mark up and not meant to be used for CSS at all?
If hfeed is already added into a theme, do you recommend removing it from the theme code directly with search and replace (particularly if it wasn’t added in the correct place) and then adding it with the snippet you provided, or is it best to leave it in the theme and remove it from the code? If we remove it from the code you provided, which line(s) should we omit? What happens if it is duplicated (ie, what will the output look like, or what happens to parsers that read the code)?
What exactly are the post, body and comment class functions? What do they look like and where would one find them in a particular theme?
How is the code you’ve provided different from what the WordPress plugin uf2 does? Is it more or less extensive?
In the end, this is also just a stop-gap measure to quickly add a small, but high level subset of microformats to current themes that don’t support it? Ideally we would hope more modern themes will add a more full version of microformats natively?
This Article was mentioned on stationaryjourney.com
For those interested in more and who know a bit of code, David’s also got a “master class” on adding microformats to modern themes in his commit trail for updating/upgrading the TwentySixteen theme to be more IndieWeb friendly: https://github.com/dshanske/twentysixteen-indieweb/commits/master
While it isn’t comprehensive and may not cover every eventuality for every theme, following along with his commits here will get you a long way towards better understanding microformats v2 use with WordPress. I think I’ve learned more about WordPress themes and microformats by following his changes here than anything else I’ve tried.
Sad, that TwentySixteen is the only microformat2 WordPress theme I could find. And TwentySixteen is ugly. I may be going back to less microformats friends but more attractive them suitable for a website that has a lot of photographic posts.
Alan Levine has pushed out another HTML conversion that reminds me a bit of Adobe Spark Pages. I think that I like it even more than the Big Picture theme that I used as a ‘home page’. The question I am left wondering about starting from scratch (or a basic starting block) is how hard it would be to bake in microformats or maybe the plugin is enough?
Also on:
Learning Log and Learning Radar Update: Tracking Daily Progress
I’ve been actually keeping up with my learning updates! I’ve been using my Hugo notebook subdomain to take quick notes and then revisit and craft into a post for my main site. On Tuesday I also added a learning radar to my notebook where I track topics that are, well, on my radar. This has been a great workflow and it encourages me to both document and to continue learning new things.
This post will include summaries of both Tuesday’s learning radar and today’s learning log. Let’s start with the radar. But first, some jump links:
Click to teleport to learning radar section.
Click to teleport to learning log section.
Things On My Radar
First, a quick distinction. The radar posts are collections of notes for technology, concepts, or other things I want to learn more about. Basically they are a way for me to actively take notes while discovering things, but before embarking on learning.
If the learning logs are the reflection phase, this represents the discovery phase.
Alright, here’s some new trends and tools that I’ve been encountering lately and want to dive into.
Hugo Build Tools and Peripheral Things
Netlify
I’ve now seen this mentioned in nearly every single Hugo boilerplate out there. Don’t think I need it for my current workflow, but this is something I’ve been encountering regularly with regard to Hugo. Will check this out.
Hugulp
There have been many Hugo boilerplate/build tools created recently. I read a bit about this one tonight and I’m intrigued by this workflow. I think Gulp brings a lot to the table for asset management, one area that I couldn’t quite get a handle on when I first was using Hugo.
Atlas
Another Hugo boilerplate setup. Seems like these are definitely worth checking out. Not sure which is best for my needs.
Forestry
CMS for Hugo/Jekyll with version control support. Investigate as something to recommend to newer learners who may not be comfortable with the level of hacking that Hugo still requires?
JavaScript and Peripheral Things
Headless CMS
Headless CMS overview and resource link: relates to JAMstack, Netlify, and Hugo.
Next.JS 3.0 and Headless WordPress…
Details on pairing React (NextJS) with headless WordPress via WP REST API. This post outlines the pros/cons of this as well as experiences taking this setup to production.
GraphQL Essential Training with Emmanuel Henri – Lynda course
GraphQL has popped up several times recently and I’ve added this to my list of Lynda courses to watch/take. Relatively short (1h54min) and created by a course author that creates high quality content.
WordPress Workflow
I need to fix the microformats2 markup on my site. My h-card is broken (leaking spans) and my entire page is showing up in an h-feed instead of just the post content. This is breaking brid.gy and causing lots of other issues.
One thing that’s been at the top of my to-do list for two months is to setup a WordPress workflow (develop locally -> push to production) that is similar to my Hugo workflow. I haven’t done this yet and this is even more timely now.
I love the WordPress backend. I’m somewhat leaning toward a headless CMS model at this point, but need to do more research.
Here’s what I know:
I need to fix either my IndieWeb supported theme, the IndieWeb plugin, the PHP template, or all of the above
I’ve had the microformats on my site break 3 times in 4 months.
Too many moving pieces -> things break when something updates
This is tricky to do without a local development environment
I enjoy the workflow I have for Hugo. My notebook -> refinement workflow has resulted in much more content being published
I need to reconcile all of these points and come up with a solution that increases my productivity.
Relevant resource: Converting WordPress Themes for Microformats 2 – Part 1 – David Shanske
Bookmarked David’s post and will use as reference when I start digging into these issues.
Other Interesting Things
Mozilla: Project Things
Goal to create a “decentralized ‘Internet of Things.’” Moving away from silo services for IoT platforms and to make a connected devices infrastructure more similar to the decentralized, open web.
This is pretty interesting. Going to do a bit more research on this… Lots of potential!
Visual Studio Code vs. Atom
Visual Studio Code: the editor I didn’t think I needed
Been hearing a lot of praise lately for VSCode. Checking out the pros/cons and why people seem to like it so much recently. Performance seems to be a pretty big reason.
Learning Log: Tracking Daily Progress
And now onto the learning log! It’s been nice to view these side by side because I’m able to see how well I pursue things that appear on my radar.
I’ve managed to track this all pretty well so far! In doing this, I realized that there are some days where I’m not dedicating enough time to discovering/learning new things, so there won’t necessarily be an entry for every day.
I also added a new type of post: Learning Radar. If the learning logs are the reflection phase, this represents the discovery phase.
Anyway, here’s a quick entry about things I’ve learned/am learning. Instead of being sorted by media type (blog/article or video/course), I’m going to lump this under the content topic.
JAMstack and the Headless CMS
On Tuesday’s learning radar/log entries I mentioned that I’ve become intrigued by Netlify, JAMstack, and headless CMSes. I started doing a bit of research about this and am going to share my current understanding/notes.
I’m in the process of watching two videos about JAMstack and a new trend in CMSes/web development. I’m still working through these and making observations/learning, but wanted to share the two videos I’m watching so far:
The Rise of the JAMstack CMS – Matt Biilmann
JAMstack Tutorial – Full site using Netlify & Hugo
The first is a conference presentation by Matt Biilman, the founder of Netlify and the second is an introduction about how to integrate Hugo and Netlify by using Netlify’s Hugo Boilerplate, Victor Hugo. I’m interested in exploring this as I’ve often wondered about the potential integration of a CMS style platform into Hugo as a way to make it more beginner friendly for users who expect/need/want a CMS experience.
WordPress security issues this week have made me think about all the reasons why I was against having my personal site run on WP. I originally had my reasons for switching – mostly IndieWeb related. I’m still evaluating the pros/cons of this decision.
WordPress Version Control
One of my ongoing goals has been to implement version control for my WordPress site. I decided that IF I keep using WordPress – and honestly, I’m still unsure at this point – that I need to implement a better workflow using version control with Git/GitHub.
I still need to set up the actual development -> production workflow, but I did manage to implement version control for my content. This was something I’ve been thinking about for a the last week, mostly because I wanted to find a way to version all of our content at DHF. My goal is to have all of our WP content living in the DHF organization on GitHub and figure out how to version all of the posts/lessons/etc. in repos, especially since we have more content creators on staff. This is also because I want to determine some best practices for scale, so that was motivating me to find some solutions.
I found two: VersionPress and WordPress GitHub Sync. First, I ended up installing the latter on my site and after fixing a few config mistakes, have it up and running. I exported all my existing posts to a repo. Each post is a separate Markdown file with Yaml frontmatter containing post meta-data, such as publication date. I’m happy with this for now but need to do further testing. I believe that it hooks into save_post in WordPress, so I want to play around more with this since the only thing I’ve done so far is export all my current content.
Also on:
Also on:
This Article was mentioned on indieweb.org
This Article was mentioned on indieweb.org
WordPress Themes are a simple way to quickly change the look and feel of a WordPress website primarily by use of CSS.
Okay, so four years after I wrote how to start Converting Your WordPress Theme for Microformats 2, I’m back with Part 2.
First, four years later, we need to recap, update, and expand what we discussed last time.
Before you start, you need to clean up two very simple things.
Don’t style any Microformats Classes. WordPress commonly supports classic microformats. WordPress actually adds hentry, the predecessor to h-entry, into every single post in the post_class filter. So, you want to be able to supplement, replace, or fix Microformats classes without changing the look of your theme. So if you are updating a theme that already does this, add a styling class and change your CSS to do that. For example, I add entry alongside hentry and rewrite all the CSS to style entry, then I can take hentry out where it shouldn’t be.
Someone years ago decided to add hfeed to the header file of their theme and everyone copied it. hfeed indicates a page is a feed…which means it contains multiple entries(date archive, author archive, main posts page, etc). This should therefore not appear on a single page…so if it does, take it out.
Where do you start?
Add h-entry and h-feed in the proper places. See Part 1 for some sample code on how to do that using the body_class and post_class filters. You could also add it manually by surrounding your post,
class="h-entry", and surrounding all the posts in an archive/feed page with an element that hasclass="h-feed"Congratulations, you’ve now marked up your posts as posts and your feeds as feeds.Now that we’ve marked up feeds and posts, we want to get down deeper…namely, inside your posts. We want to mark up things like author, publish date, etc.
In most themes, time is already marked up, something like this, with an HTML5 time element. The full time is present in ISO8601 format, with the timezone offset for your site, and inside the tag is the human readable one.
<time datetime=”2016-06-22T23:52:09-04:00″>June 22, 2016</time>
You get two times per post..the published time and the updated time. Many themes have the updated time visually hidden, but available for parsing. If you do not have a fully formatted timestamp in datetime, you should do so. Positively, since WordPress 5.3, the offset is properly set based on your site settings, where previously you had to edit the theme to get this. The displayed time is up to you.
Add
class="dt-published"to the publish time of the post, andclass="dt-updated"to the updated/modified time of the post.We also, most importantly, want to make sure the author is marked up correctly. That should include, at minimum, the author’s name, if not URL and photo. All author properties should be surrounded by an element that has
class="p-author h-card". The photo should haveclass="u-photo", indicating it is a representative photo of the element it is inside…the h-card. H-cards represent people, organizations, or places. By adding the p-author, we indicate that this person is the author of the piece. The p- tells the parser that whatever text is inside here is the value of the author property. You can also add a url for the author website, marking itclass="u-url"which states it is the URL that represents the containing element…the h-card/author property.Here is a simplified example of what this might look like…
<div class=”h-entry”>
<time class=”dt-published” datetime=”2016-06-22T23:52:09-04:00″>June 22, 2016</time>
<span class=”p-author h-card”><a class=”u-url” href=”https://joebloggs.com”>Joe Bloggs</a><img class=”u-photo” src=”https://joebloggs.com/avatar.jpg” /></span>
</div>
So, if we run the new file through a Microformats parser(I like php.microformats.io), we’d get a nice output…
{
“type”: [
“h-entry”
],
“properties”: {
“url”: [
“https://joebloggs.com”
],
“published”: [
“2016-06-22T23:52:09-04:00”
],
“author”: [
{
“type”: [
“h-card”
],
“properties”: {
“photo”: [
“https://joebloggs.com/avatar.jpg”
],
“name”: [
“Joe Bloggs”
]
},
“value”: “Joe Bloggs”
}
]
}
}
Looks pretty good…except no content… Content is a bit more complicated, because WordPress stores content in the database, but when outputting it, puts it through a filter called “the_content”, which many plugins use to add things that aren’t content to the post.
Content is supposed to be wrapped in an element with the
class="e-content". If we wrap the output of the_content, we might incorporate things from other plugins.While it is by no means the most reliable way, my solution is to use the same content filter, but at the first priority, wrapping what original came out of post_content before all the other items.
You can do the same with the summary, if it exists, wrapping it in p-summary.
function add_econtent( $content ) {
// Do Not Add this is it is a Feed.
if ( is_feed() ) {
return $content;
}
$wrap = ‘<div class=”e-content”>’;
// If there is no content, do not bother.
if ( empty( $content ) ) {
return $content;
}
return $wrap . $content . ‘</div>’;
}
add_filter( ‘the_content’, ‘add_econtent’, 1 );
function add_psummary( $excerpt ) {
// Do Not Add this is it is a Feed.
if ( is_feed() ) {
return $excerpt;
}
$wrap = ‘<div class=”p-summary”>’;
// If there is no excerpt, do not bother.
if ( empty( $excerpt ) ) {
return $excerpt;
}
return $wrap . $excerpt . ‘</div>’;
}
add_filter( ‘the_excerpt’, ‘add_psummary’, 1 );
In the next part, we’ll dive even more into the weeds, talking about other classic microformats and rel-values and what to do with them. Probably before 2024.