Hugo 0.18 introduced the imageConfig function which allows you to
access the height and width of images, which makes bots consuming
the structured data happy.
.Site.LastChange is the date of the last modification on the entire
site, not necessarily on the node we're currently showing, such as
a taxonomy list.
I'm not sure if it really matters to bots who will parse this (it's
much more important on content pages of course), but using .Date on
nodes like the homepage and taxonomy terms pages will set the date
to be that of the latest post in that range—to me this does indeed
seem to be "time when the object was last updated"[0].
[0] https://developers.facebook.com/docs/reference/opengraph/object-type/website/
Hugo's current handling of dates in the opengraph partial needs
nome work to be more correct—for example: the usage of published
and updated times. This comes verbatim from the Hugo source tree.
See: tpl/template_embedded.go
Allowing users to select specific icons they want to show makes the
configuration and logic a bit tricky. A user brought up the case of
disabling sharing icons on certain pages/posts, and it was actaully
not possible without adding lots of extra logic, not to mention the
pain of having to test all possible configurations.
Instead, it is much simpler to just allow sharing icons to be either
on or off as desired in the site config or page/post frontmatter:
sharingicons = false
Otherwise, sharing icons default to being enabled, as this is most
in line with what would be expected on a "blog".
This replaces the metadata that Hugo's own schema.html template had
been providing, but does so in JSON-LD notation rather than via the
use of <meta> tags (this is Google's currently recommended form of
specifying this markup). There are a few exceptions where I did not
follow the conventions used in Hugo's template, for example the use
of up to six images from a post's frontmatter, because Google's tool
only recognizes one image, as well as different logic for a post's
publish and modified dates (using enableGitInfo = true).
Using this new markup, Google's Structured Data Testing Tool is now
able to understand site metadata much better (before it was reading
none).
The implementation here is a mix of the elements and types from the
official Schema.org types—for example, Blog and BlogPosting—as well
as from Google's search documentation. Note that Google's docs are
geared towards AMP, where some metadata is required, while for non-
AMP pages the metadata is just recommended.
We will have to re-evaluate this in the future, for example to add
height and width information to image metadata.
See: https://schema.org/Blog
See: https://schema.org/BlogPosting
See: https://developers.google.com/search/docs/data-types/data-type-selector
See: https://search.google.com/structured-data/testing-tool
As of Hugo 0.18 .Site.Pages now returns all pages, including pages,
home, taxonomies, etc, and you are expected to filter them by their
"kind". There is a new variable .Site.RegularPages which returns a
range of "regular" pages like in pre-0.18 Hugo.
In this instance we are limiting the range to pages with the type
"post", so our current behavior works, but I'd rather be consistent
with other ranges we're using, like on the homepage and taxonomy
list pages.
See: https://github.com/spf13/hugo/releases/tag/v0.18
If the user's config doesn't have [params.sidebar] defined they get
errors when trying to build the site. It's better if we just check
that this config block is defined before trying to use it, and then
add something to the docs telling people that the site looks really
bad without this defined.
Bring the Disqus comments inside the <article> tag. The article has
a sizeable bottom margin seprating it from the blog footer, and if
Disqus comments are active they appear after this margin, and this
looks ugly.
Semantically, I think the comments should actually be inside the
article tag anyways (since they are directly related), as well as
further wrapped in article tags, but we don't control the code that
Disqus injects so we'll have to make do with this.
See: https://www.w3.org/TR/html5/sections.html#the-article-element
Prepending the site's URL to relative links was a hack but at the
time I couldn't understand why href="#" didn't take us to the top
of the page. It turns out that this was because of the <base> tag
that I have now removed.
It was screwing up relative links like the ones in footnotes. I'm
not sure why I added it in the first place, actually, as the docs
specifically say "specifies the base URL to use for all relative
URLs contained within a document".
See: https://developer.mozilla.org/en/docs/Web/HTML/Element/base
* Add Vim modeline comments to all relevent template files.
* Add Vim modeline comments to a few other files.
* Move modeline comments inside the template definitions in list and single.
For some odd reason, putting them outside breaks the page generation.
* Use template comments for modeline comments in templates.
* Fix form 2 modelines.
Set the cookie_consent_info_url parameter in your site's config to
display a message about cookie usage to your users. See the config
in `exampleSite/config.toml` for more info.
We are explicitly using the site's RSS feed, but after reading the
Hugo RSS docs I think it's better if we use the contextual version
of the RSSlink. This will make the RSS plumbing show a feed for the
current category, tag, section, etc. The example code also adds a
bit of markup to help browsers find the content more easily.
See: https://gohugo.io/templates/rss/
Instead of writing my own logic for metadata and Twitter cards, I
should be using Hugo's own. This makes my theme code cleaner, but
means I have to adjust some of the configuration conventions that
I have been using. An added bonus is that my theme will work with
more sites now, as long as they are using Hugo's config conventions.
Sites only need to add their Google Analytics tracking ID to their
config:
googleAnalytics = "UA-123-45"
This uses the async version of the Google Analytics code.
I had added Google Webmaster verify support but it got lost when I
was re-organizing the head meta stuff. I'm adding it back now plus
support for Bing and Yandex.
In a multilingual context a post's title could be "Title" in English
but «Title» in Bulgarian, and if we apply the Markdown filter to the
title tag, then the language's Black Friday configuration is used,
in this example it would be for the angled quotes.
We already do this everywhere else we can in the post's content, so
let's match it in the page title.
Hugo's own pagination stuff works just as well and probably covers
even more corner cases. Also, this is one less config variable to
have to check because you can just use Paginate (Default: 10).
Add categories/tags to front matter and they will be displayed on
summary and post pages, with links to taxonomy pages. Example:
+++
date = "2016-09-24T21:28:31+03:00"
title = "Post title"
categories = ["Nature"]
tags = ["Wetland", "Oasis"]
+++
For some reason if you add tags singularly, like:
categories = "Nature"
you get index errors from Hugo. Not sure if I need to parse the
tags differently or just add more logic to test if the terms are
singular or not.
Check if the params.sidebar is defined before checking to see if
params.sidebar.hide is true or false. New sites might not have
their config set up properly, so this avoids an error in the case
that params.sidebar isn't defined yet.
Advertises the XML sitemap and allows all user agents, but is only
enabled if the site sets this property in their config:
enableRobotsTXT = true
See: https://gohugo.io/extras/robots-txt/
By default they are on, but you can disable them by adding the
following configuration value:
[params.sharingicons]
hide = true
If this parameter is undefined (or "false") then the icons will be
shown. Furthermore, you can disable specific icons by setting their
value to "false", ie:
[params.sharingicons]
facebook = false
Any icons not named will be shown. Currently there a four icons
configureg: facebook, googleplus, linkedin, and twitter.
Uses basic data like title, description, author, and date that we
are using with existing vanilla meta tags, but extends them to OG
and Twitter Card tags. See [0] and [1].
For the Twitter summary cards specifically, you can optionally add
attribution for your username by adding something like this to your
configuration:
[params.social]
twitter_username = "@mralanorth"
... and for posts with images, you can specify an "image" in the
post's front matter like so:
image = "/2016/09/IMG_20160916_174409.jpg"
And then the theme will opt to use Twitter's "large" summary card.
[0] http://ogp.me/
[1] https://dev.twitter.com/cards/getting-started
Still need to figure out how to determine which page we're on so we
can set the "active" class accordingly (for Home we have the IsHome
variable the we can check).
Both work effectively the same for my use case, but the "type" is
more obvious when looking at the code. See the documentation for
Hugo's page variables for more info[0].
[0] http://gohugo.io/templates/variables/#page-variables
Use the post's author from frontmatter, or else use the author from
the site's config. You MUST have one of these set or else you will
get an error during site generation. I think it's better to force
the user to define an author tag rather than only printing it if
it is defined because it is a good practice to help bots understand
content.
Use the post's meta description if it exists, otherwise use the
one from the site's config. Set them using the "description" key
in frontmatter or site config.
Note: this means there is no way to NOT have a description. You
must have *at least* a site-wide description and *optionally* a
description for each page/post's front matter.
The W3C's HTML5 documentation says that header strength (h1–h6) is
only important per section, but their validator[0] recommends only
using one h1.
[0] https://validator.w3.org/
By default it shows the latest five posts, but you can set this
property in your config to override it:
[params.sidebar]
num_recent_posts = 7
Still no way to disable it, as I don't understand golang's HTML
templating stuff yet. The Hugo docs are a bit confusing, but it
seems like conditionals are a bit tricky because both false and
0 return a boolean false... hmm.
See: https://gohugo.io/templates/go-templates/
Add something like the following to your config to enable the about
block in the sidebar:
[params.sidebar]
about = "*My site* is really cool. Adios!"
Can be formatted in Markdown.
I need to figure out how to generate a list of posts grouped by
month, ie "August 2016", as well as a list template to show the
posts for each month for when the user clicks the link.
The HTML5 aside tag is for content that is tangentially related to
the content around the aside tag, but is considered separate from
that content. Section tags are semantic HTML5 elements that inform
computers about content structure, as opposed to div tags which
can be used for structure OR style.
See: http://diveinto.html5doctor.com/semantics.html
Headers are a semantic element that help computers understand the
content. In general, header tags should follow rank order, but the
most important is that the first header inside a section will serve
as the title in a table of contents, etc, but since article sections
stand alone as independent documents, I like the idea of explicitly
starting with H1 tags.
See: http://diveinto.html5doctor.com/semantics.html
The HTML5 <article> tag represents a complete, or self-contained,
composition in a document. Headers are a semantic HTML5 element
that helps computers understand the content.
Partials are nice, but blocks are a better base construct. Right
now there is basically only layouts/_default/baseof.html that is
doing most of the work.
See: https://gohugo.io/templates/blocks
I think this should be an H1 since it's in a standalone article tag
but for some reason WordPress' latest themes use an H2, so I'll use
one too until I go read the W3C docs.