Marty McGuire

Archive for March 2023

Fri Mar 31

Have you had enough during eternal Caturday?

Thu Mar 30

Are you saying it with your eyes during eternal Caturday?

Tue Mar 28
πŸ” Reposted https://ciechanow.ski/bicycle/

Are you giving it your all during eternal Caturday?

Mon Mar 27

Are you ready with a look during eternal Caturday?

Sun Mar 26

Are you having a huddle during eternal Caturday?

Sat Mar 25

New community members, upcoming social web events, and digesting digests. It’s your < 10min update on the #IndieWeb community!

This Week in the IndieWeb audio edition for March 18th - 24th, 2023. https://martymcgui.re/2023/03/25/this-week-in-the-indieweb-audio-edition--march-18th---24th-2023/

This Week in the IndieWeb Audio Edition β€’ March 18th - 24th, 2023

Show/Hide Transcript

New community members, upcoming social web events, and digesting digests. It’s the audio edition for This Week in the IndieWeb for March 18th - 24th, 2023.

You can find all of my audio editions and subscribe with your favorite podcast app here: martymcgui.re/podcasts/indieweb/.

Music from Aaron Parecki’s 100DaysOfMusic project: Day 85 - Suit, Day 48 - Glitch, Day 49 - Floating, Day 9, and Day 11

Thanks to everyone in the IndieWeb chat for their feedback and suggestions. Please drop me a note if there are any changes you’d like to see for this audio edition!

Are you keeping up with the latest technology during eternal Caturday?

Fri Mar 24

Are your feet on the, uh, ground during eternal Caturday?

Thu Mar 23

Are you making it fashion during eternal Caturday?

Wed Mar 22

Are you at your posts during eternal Caturday?

Tue Mar 21

Are you looking for the action during eternal Caturday?

Mon Mar 20

Are you doing a double take during eternal Caturday?

Sun Mar 19

Go Time

This is one of those posts about a tech issue comes up from time to time for me that I find difficult to search for. Sorry (not sorry) if it is not helpful to anyone else!

Too much context about my site building process

My site is built with Hugo, a static site generator known for being quite fast, and with a powerful (and challenging) templating system.

I use my site for lots of stuff, which sometimes means showing content from other sites in my posts. For example:

In either case, my site's build process includes a step where it finds new links that need this context - to be displayed as a preview or displayed as a like/comment/etc., and it fetches that stuff. To do this, my site fetches the link content, then parses it using a handy library called aaronpk/XRay, then saving it in a place where Hugo can find it at build time.

For example, the RSVP post I mentioned gets a little chunk of data like this:

{
  "fetched_at": "2019-10-02T23:29:15-04:00",
  "xray": {
    "data": {
      "type": "entry",
      "published": "2019-10-02 19:53-0700",
      "url": "https://tantek.com/2019/275/t1/indiewebcamp-new-york-city",
      "content": {
        "text": "going to #IndieWebCamp NYC this weekend ...",
...

I’ve cut out a lot of stuff here and highlighted the two things relevant for my particular time issue.

In my templates for previews and responses I try to show the published time from the post itself. If XRay wasn't able to find a value for published or (spoiler) Hugo can't parse that value as a time, the template will give up and omit the published time.

What is Web Time?

This is such a ridiculously fraught question that I refuse to answer it properly. Suffice to say:

What is (Hu)go Time?

Okay, finally, the point of this post has been found. To archive this lil' set of facts for my future frustrations.

From an unrelated Hugo date parsing issue, I learned about the list of time formats that Hugo tries when you ask it to parse something as a time, last updated August 2022:

var (
  timeFormats = []timeFormat{
    {time.RFC3339, timeFormatNumericTimezone},
    {"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
    {time.RFC1123Z, timeFormatNumericTimezone},
    {time.RFC1123, timeFormatNamedTimezone},
    {time.RFC822Z, timeFormatNumericTimezone},
    {time.RFC822, timeFormatNamedTimezone},
    {time.RFC850, timeFormatNamedTimezone},
    {"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
    {"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
    {"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
    {"2006-01-02 15:04:05", timeFormatNoTimezone},
    {time.ANSIC, timeFormatNoTimezone},
    {time.UnixDate, timeFormatNamedTimezone},
    {time.RubyDate, timeFormatNumericTimezone},
    {"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
    {"2006-01-02", timeFormatNoTimezone},
    {"02 Jan 2006", timeFormatNoTimezone},
    {"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
    {"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
    {time.Kitchen, timeFormatTimeOnly},
    {time.Stamp, timeFormatTimeOnly},
    {time.StampMilli, timeFormatTimeOnly},
    {time.StampMicro, timeFormatTimeOnly},
    {time.StampNano, timeFormatTimeOnly},
  }
)

There's a lot of time.Whatever constants in that list. These are part of the Go language's time package :

const (
  Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
  ANSIC = "Mon Jan _2 15:04:05 2006"
  UnixDate = "Mon Jan _2 15:04:05 MST 2006"
  RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
  RFC822 = "02 Jan 06 15:04 MST"
  RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
  RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
  RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
  RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
  RFC3339 = "2006-01-02T15:04:05Z07:00"
  RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
  Kitchen = "3:04PM"
  // Handy time stamps.
  Stamp = "Jan _2 15:04:05"
  StampMilli = "Jan _2 15:04:05.000"
  StampMicro = "Jan _2 15:04:05.000000"
  StampNano = "Jan _2 15:04:05.000000000"
  DateTime = "2006-01-02 15:04:05"
  DateOnly = "2006-01-02"
  TimeOnly = "15:04:05"
)

If your brain just can't help but puzzle-solve, you may have noticed that the published time from the example above:

"2019-10-02 19:53-0700"

Is close to but does not match either the time.RFC3339 or time.DateTime formats.

The issue? Neither Hugo nor Go fully support ISO 8601 time, instead supporting very close time formats which do not allow omitting the seconds value. There are definitely other formats they don't support, which I've seen commonly, like "January 2, 2006".

Workaround (Deprecated)

When I first built out the Hugo templates for my site (2018, so back in the 0.4x or 0.5x days, maybe?), if you asked Hugo to parse a time, and it couldn't, it would give you back a string instead with an error message beginning "unable to parse date: ...". This was gnarly, but I could code around it by asking Hugo to convert a value to a time and checking if the result starts with "unable to parse". Something like:

{{ $safe_published := (time $item_published) -}}
{{ if not (hasPrefix $safe_start "unable to parse") -}}
  {{/* ... it parsed, hooray, use it */}}
{{ else -}}
  {{/* failed to parse so do a fallback or ignore it or whatever */}}
{{ end -}}

Time passes and Hugo has since changed this behavior. Now, if you ask it to convert a value to a time, and it cannot parse it with one of the known format strings, Hugo bails and the entire build fails. It throws an error something like:

ERROR 2023/03/19 13:02:05 render of "page" failed:
  "/home/schmarty/me/martymcgui.re/themes/mmgre-2015/layouts/_default/single.html:3:7":
  execute of template failed: template: _default/single.html:3:7:
  executing "main" at <partial "post/post.html" (...)>:
  error calling partial: "/home/schmarty/me/martymcgui.re/themes/mmgre-2015/layouts/partials/post/post.html:20:36":
  execute of template failed: template: partials/post/post.html:20:36:
  executing "partials/post/post.html" at <partial "link-preview/link-preview.html" (...)>:
  error calling partial: "/home/schmarty/me/martymcgui.re/themes/mmgre-2015/layouts/partials/link-preview/link-preview.html:26:9":
  execute of template failed: template: partials/link-preview/link-preview.html:26:9:
  executing "partials/link-preview/link-preview.html" at <partial (printf "link-preview/%s.html" "xray") (...)>:
  error calling partial: "/home/schmarty/me/martymcgui.re/themes/mmgre-2015/layouts/partials/link-preview/xray.html:30:28":
  execute of template failed: template: partials/link-preview/xray.html:30:28:
  executing "partials/link-preview/xray.html" at <partial "util/safe-time.html" $item.published>:
  error calling partial: "/home/schmarty/me/martymcgui.re/themes/mmgre-2015/layouts/partials/util/safe-time.html:1:4":
  execute of template failed: template: partials/util/safe-time.html:1:4:
  executing "partials/util/safe-time.html" at <time .>:
   error calling time: unable to parse date: 2019-10-02 19:53-0700

Believe it or not I actually cleaned up that error a lot, removed duplicates, and highlighted the key issue in bold.

I hate this.

Workaround (Derogatory)

For now I check my site's build logs from time to time looking for build errors like the one above. I'll then:

  1. Use a tool like grep to search my saved reply context data for the problematic time string (in this case "2019-10-02 19:53-0700").
  2. Find the file it's in, and "fix" it so Hugo can parse it. In this case, "2019-10-02 19:53:00-0700".
  3. With the "fix" in place, I'll rebuild the site.

Either it builds successfully (hooray!) or I find the next time parsing failure and repeat.

I seriously dislike this.

A Future Fix

What I actually need to do here is update my build system to sanitize the value of published if it exists.

Like Hugo's list, I'll need to decide what date string formats I want to support, have the build system try them all on that published value, and store a sanitized version for Hugo.

Okay! Now I have this post to refer to in the future when I get next get cranky about this.

Are you practicing your plank during eternal Caturday?

Sat Mar 18

IndieWebCamp DΓΌsseldorf planning, A People’s History of Twitter, and an AI’s history of James. It’s your < 5min update on the #IndieWeb community!

This Week in the IndieWeb audio edition for March 11th - 17th, 2023. https://martymcgui.re/2023/03/18/this-week-in-the-indieweb-audio-edition--march-11th---17th-2023/

This Week in the IndieWeb Audio Edition β€’ March 11th - 17th, 2023

Show/Hide Transcript

IndieWebCamp DΓΌsseldorf planning, A People’s History of Twitter, and an AI’s history of James. It’s the audio edition for This Week in the IndieWeb for March 11th - 17th, 2023.

You can find all of my audio editions and subscribe with your favorite podcast app here: martymcgui.re/podcasts/indieweb/.

Music from Aaron Parecki’s 100DaysOfMusic project: Day 85 - Suit, Day 48 - Glitch, Day 49 - Floating, Day 9, and Day 11

Thanks to everyone in the IndieWeb chat for their feedback and suggestions. Please drop me a note if there are any changes you’d like to see for this audio edition!

How are your dance moves during eternal Caturday?

Fri Mar 17

Are you a critic of the arts during eternal Caturday?

Thu Mar 16

Are you part of the Lie Flat Crew during eternal Caturday?

Wed Mar 15

Are you finding it easier to lie flat during eternal Caturday?

Tue Mar 14

Do you have a spring in your, uh, mouth during eternal Caturday?

Mon Mar 13

Are you seated upon your tuffet during eternal Caturday?

Sun Mar 12

Are you letting your limbs hang loose during eternal Caturday?

Sat Mar 11

IndieWebCamp DΓΌsseldorf planning, federated formatting, and BlueSky’s beta is brewing. It’s your < 10min update on the #IndieWeb community!

This Week in the IndieWeb audio edition for March 4th - 10th, 2023. https://martymcgui.re/2023/03/11/this-week-in-the-indieweb-audio-edition--march-4th---10th-2023/

This Week in the IndieWeb Audio Edition β€’ March 4th - 10th, 2023

Show/Hide Transcript

IndieWebCamp DΓΌsseldorf planning, federated formatting, and BlueSky’s beta is brewing. It’s the audio edition for This Week in the IndieWeb for March 4th - 10th, 2023.

You can find all of my audio editions and subscribe with your favorite podcast app here: martymcgui.re/podcasts/indieweb/.

Music from Aaron Parecki’s 100DaysOfMusic project: Day 85 - Suit, Day 48 - Glitch, Day 49 - Floating, Day 9, and Day 11

Thanks to everyone in the IndieWeb chat for their feedback and suggestions. Please drop me a note if there are any changes you’d like to see for this audio edition!

Are you dedicated to sanitation during eternal Caturday?

Fri Mar 10

Do you seek vengeance during eternal Caturday?

Thu Mar 9

Did you forget to call dibs during eternal Caturday?

Wed Mar 8

Do you have the element of surprise during eternal Caturday?

πŸ“— Want to read The Once and Future Sex: Going Medieval on Women&amp;apos;s Roles in Society by Eleanor Janega ISBN: 9780393867817
πŸ“— Want to read Emergent Strategy: Shaping Change, Changing Worlds by Adrienne Maree Brown ISBN: 9781849352604
πŸ“— Want to read The Blade Itself (The First Law, #1) by Joe Abercrombie ISBN: 9780575079793
Tue Mar 7
πŸ”– Bookmarked 2022’s best reads – Hi, I'm Heather Burns http://webdevlaw.uk/2023/01/10/2022s-best-reads/
πŸ”– Bookmarked Adactio: Journalβ€”Books I read in 2022 https://adactio.com/journal/19786

Yes I (still) collect other folks’ reading lists in my reading list.

How is the view from above during eternal Caturday?

Mon Mar 6

Are you making your way up in the world during eternal Caturday?

Sun Mar 5

Is it your turn to be mysterious during eternal Caturday?

Sat Mar 4

Wiki spring cleaning, a false Fediverse, and how do you hashtag? It’s your < 10min update on the IndieWeb community!

This Week in the IndieWeb audio edition for February 25th - March 3rd, 2023. https://martymcgui.re/2023/03/04/this-week-in-the-indieweb-audio-edition--february-25th---march-3rd-2023/

This Week in the IndieWeb Audio Edition β€’ February 25th - March 3rd, 2023

Show/Hide Transcript

Wiki spring cleaning, a false Fediverse, and how do you hashtag? It’s the audio edition for This Week in the IndieWeb for February 25th - March 3rd, 2023.

You can find all of my audio editions and subscribe with your favorite podcast app here: martymcgui.re/podcasts/indieweb/.

Music from Aaron Parecki’s 100DaysOfMusic project: Day 85 - Suit, Day 48 - Glitch, Day 49 - Floating, Day 9, and Day 11

Thanks to everyone in the IndieWeb chat for their feedback and suggestions. Please drop me a note if there are any changes you’d like to see for this audio edition!

Can you solve the mystery during eternal Caturday?

Fri Mar 3

Do you have a sound to let out during eternal Caturday?

Thu Mar 2

Are you a lovely loaf during eternal Caturday?

Wed Mar 1

Are you cleaning house during eternal Caturday?