Question on Date and URL format in source

Hello - just wondering if someone could kindly take a look at this. I am not sure if this is expected or not.

Given a config.toml with:

+++
...
ISO8601 = "2006-01-02T15:04:05-07:00"
...
+++

And a partial template that is meant to render json-ld markup for a schema.org schema:

{{ "<!-- ENTERING partial seo-schema.html -->" | safeHTML }}
{{ if .IsPage }}
{{ if eq .Type "post" }}
<script type="application/ld+json">
{
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "articleSection" : "{{ .Section }}",
    "name" : "{{ .Title }}",
    "headline" : "{{ .Title }}",
    "description" : "{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}",
    "inLanguage" : "en-US",
    "author" : "{{ .Params.author }}",
    "creator" : "{{ .Params.author }}",
    "accountablePerson" : "{{ .Params.author }}",
    "copyrightHolder" : "{{ .Params.author }}",
    "copyrightYear" : "{{ .Date.Format "2006" }}",
    "dateCreated" : "{{ .Params.createdate }}",
    "datePublished": "{{ .PublishDate.Format $.Site.Params.ISO8601 }}",
    "dateUpdated" : "{{ .Date.Format $.Site.Params.ISO8601 }}",
    "url" : "{{ .Permalink }}",
    "wordCount" : "{{ .WordCount }}",
    "image" : [ {{ range $i, $e := .Params.images }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} ],
    "keywords" : [ {{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} ]
}
</script>
{{ end }}
{{ end }}
{{ "<!-- LEAVING partial seo-schema.html -->" | safeHTML }}

… then with yaml frontmatter like this:

---
author: Rick Cogley
authorlink: /about
authortwitter: https://twitter.com/rickcogley
banner: https://farm5.staticflickr.com/4059/5135448447_95b026227b_o.jpg
date: 2015-05-08T12:33:19+09:00
publishdate: 2015-05-08T12:33:19+09:00
createdate: 2015-05-08T12:33:19+09:00
description: The rsync that Apple provides in OS X Yosemite is out of date, but you can easily upgrade it using the homebrew package manager - a post by Rick Cogley.
draft: "false"
showauthor: "true"
showcomment: "true"
showdate: "true"
showpaging: "true"
showreadingtime: "true"
showsocialsharing: "true"
showtoc: "true"
showtotop: "true"
slug: upgrade-outdated-rsync-on-osx
subtitle: Homebrew to the rescue
tags:
- brew
- tap
- rsync
- homebrew
- upgrade
- osx
- mac
title: Old rsync on OS X?
topics:
- Tips
- SysAdmin
- Upgrades
news_keywords:
- brew
- tap
- rsync
- homebrew
- upgrade
- mac
- osx
images:
- /img/homebrew.png
- http://static.cogley.info/img/rick-cogley-avatar-900x900.jpg
---

… I get this as the result, in view source:

<script type="application/ld+json">
{
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "articleSection" : "post",
    "name" : "Old rsync on OS X?",
    "headline" : "Old rsync on OS X?",
    "description" : "The rsync that Apple provides in OS X Yosemite is out of date, but you can easily upgrade it using the homebrew package manager - a post by Rick Cogley.",
    "inLanguage" : "en-US",
    "author" : "Rick Cogley",
    "creator" : "Rick Cogley",
    "accountablePerson" : "Rick Cogley",
    "copyrightHolder" : "Rick Cogley",
    "copyrightYear" : "2015",
    "dateCreated" : "2015-05-08T12:33:19\x2b09:00",
    "datePublished": "2015-05-08T12:33:19\x2b09:00",
    "dateUpdated" : "2015-05-08T12:33:19\x2b09:00",
    "url" : "http:\/\/localhost:1313\/post\/upgrade-outdated-rsync-on-osx",
    "wordCount" : "214",
    "image" : [ "/img/homebrew.png", "http://static.cogley.info/img/rick-cogley-avatar-900x900.jpg" ],
    "keywords" : [ "brew", "tap", "rsync", "homebrew", "upgrade", "osx", "mac" ]
}
</script>

Finally, My Question

My question is about the url field and date fields.

The plus sign in +9:00 got converted to \x2b and the permalink URL is escaped.

Is this expected? Or is this a problem?

Thanks for your attention in advance!

Kind regards
Rick

Hugo version:
Hugo Static Site Generator v0.14-DEV BuildDate: 2015-05-08T11:10:47+09:00

Another thing I noticed with this, besides the formatting - when I reference .PublishDate, like this:

    "datePublished": "{{ .PublishDate.Format $.Site.Params.ISO8601 }}",

… but without setting it in YAML frontmatter, it is set to a date far in the past (sorry, can’t remember what exactly).

If that is a built-in, why would it not get the date correct? Or, am I missing something about how this is supposed to be used?

Yeah, pasting the json from the source here: http://json-ld.org/playground/ …, unless I enter a + for those \x2b codes, it does not parse correctly.

Question is, why is go or hugo replacing those and how can I prevent it?

Tried this too, to no avail:

    "test" : "{{ dateFormat $.Site.Params.ISO8601 .Date }}",

It outputs the same format with the + converted to the unicode hex code equivalent.
Is that command dateFormat analogous to doing .Date.Format?

dateFormat does to things:

  • converts the last arg into a time.Time. If it’s already a time.Time, it does nothing
  • calling t.Format(layout)

So, in your case, yes.

But date formatting in Go can be confusing, there is even a web page around about it.

1 Like

Thanks @bjornerik, your comment, and sleep, helped me figure out a few things. Now the page validates in Google’s Structured Data Testing Tool.

Here’s what I found out or did:

The format I had in config.toml had a + sign, but, since that is used to represent spaces in HTML, it’s ambiguous. Hence the auto-conversion into a hex entity, I think.

Since my server timezone is set to Japan (JST or, GMT +9), and since ISO 8601 dates support simply typing your tz in as a three-letter code, I changed the format to: ISO8601 = "2006-01-02T15:04:05JST", and used that.

When hugo parses those dates in the yaml frontmatter, which are automatically set by hugo new to be in a format like 2015-05-08T12:33:19+09:00 with a plus, doing something like:

"datePublished": "{{ .PublishDate.Format $.Site.Params.ISO8601 }}",

… in a template will result in:

"datePublished": "2015-05-08T12:33:19JST",

… in the source. That date validates fine in the json-ld validators I could find.

So long as all my dates are in JST, I’m good. I don’t need no stinkin’ zulu time.

Also, a couple more things:

  • dataUpdated that I entered above was a mistake. The correct term is dateModified. Mea culpa.
  • dateCreated is valid in schema.org BlogPosting context, but I don’t need that for my purposes, so I’l remove it (besides this, it’s not a date but a string, and I’d have to figure out how to deal with it). I’m just going to use two dates in frontmatter, date (meaning ‘latest’ date) and publishdate (meaning ‘original publish date’).

I’m including this info in case it helps someone and will summarize the “working” method below.

1 Like

The below is what is working for me.

Given a config.toml with:

+++
...
ISO8601 = "2006-01-02T15:04:05JST"
...
+++

… specifying my timezone JST (Japan time, noting that server is also set to this), and a partial template that is meant to render json-ld markup for a schema.org BlogPosting schema:

{{ "<!-- ENTERING partial seo-schema.html -->" | safeHTML }}
{{ if .IsPage }}
{{ if eq .Type "post" }}
<script type="application/ld+json">
{
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "articleSection" : "{{ .Section }}",
    "name" : "{{ .Title }}",
    "headline" : "{{ .Title }}",
    "description" : "{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}",
    "inLanguage" : "en-US",
    "author" : "{{ .Params.author }}",
    "creator" : "{{ .Params.author }}",
    "accountablePerson" : "{{ .Params.author }}",
    "copyrightHolder" : "{{ .Params.author }}",
    "copyrightYear" : "{{ .Date.Format "2006" }}",
    "datePublished": "{{ .PublishDate.Format $.Site.Params.ISO8601 }}",
    "dateModified" : "{{ .Date.Format $.Site.Params.ISO8601 }}",
    "url" : "{{ .Permalink }}",
    "wordCount" : "{{ .WordCount }}",
    "image" : [ {{ range $i, $e := .Params.images }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} ],
    "keywords" : [ {{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }} ]
}
</script>
{{ end }}
{{ end }}
{{ "<!-- LEAVING partial seo-schema.html -->" | safeHTML }}

… then, with yaml frontmatter like this:

---
author: Rick Cogley
authorlink: /about
authortwitter: https://twitter.com/rickcogley
banner: https://farm5.staticflickr.com/4059/5135448447_95b026227b_o.jpg
date: 2015-05-08T12:33:19+09:00
publishdate: 2015-05-08T12:33:19+09:00
description: The rsync that Apple provides in OS X Yosemite is out of date, but you can easily upgrade it using the homebrew package manager - a post by Rick Cogley.
draft: "false"
showauthor: "true"
showcomment: "true"
showdate: "true"
showpaging: "true"
showreadingtime: "true"
showsocialsharing: "true"
showtoc: "true"
showtotop: "true"
slug: upgrade-outdated-rsync-on-osx
subtitle: Homebrew to the rescue
tags:
- brew
- tap
- rsync
- homebrew
- upgrade
- osx
- mac
title: Old rsync on OS X?
topics:
- Tips
- SysAdmin
- Upgrades
news_keywords:
- brew
- tap
- rsync
- homebrew
- upgrade
- mac
- osx
images:
- /img/homebrew.png
- http://static.cogley.info/img/rick-cogley-avatar-900x900.jpg
---

… I get this as the result, in view source:

<script type="application/ld+json">
{
    "@context" : "http://schema.org",
    "@type" : "BlogPosting",
    "articleSection" : "post",
    "name" : "Old rsync on OS X?",
    "headline" : "Old rsync on OS X?",
    "description" : "The rsync that Apple provides in OS X Yosemite is out of date, but you can easily upgrade it using the homebrew package manager - a post by Rick Cogley.",
    "inLanguage" : "en-US",
    "author" : "Rick Cogley",
    "creator" : "Rick Cogley",
    "accountablePerson" : "Rick Cogley",
    "copyrightHolder" : "Rick Cogley",
    "copyrightYear" : "2015",
    "datePublished": "2015-05-08T12:33:19JST",
    "dateModified" : "2015-05-08T12:33:19JST",
    "url" : "http:\/\/localhost:1313\/post\/upgrade-outdated-rsync-on-osx",
    "wordCount" : "214",
    "image" : [ "/img/homebrew.png", "http://static.cogley.info/img/rick-cogley-avatar-900x900.jpg" ],
    "keywords" : [ "brew", "tap", "rsync", "homebrew", "upgrade", "osx", "mac" ]
}
</script>

Amongst other semantic formats, at least the above source validates in https://developers.google.com/structured-data/testing-tool/.

Hi i have a similar problem with json-ld - actually it is with the URL. I am using "@id": "{{ .Permalink }}" and output URL is not coming correct showing extra \/\/ can anyone help thanks in advance.

output URL "@id": "http:\/\/localhost:1313\/contact-us\/",

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{
    "@type": "ListItem",
    "position": 1,
    "item": {
      "@id": "http://www.example.com",
      "name": "Home"
    }
  },{
   "@type": "ListItem",
   "position": 2,
   "item": {
     "@id": "{{ .Permalink }}",
     "name": "{{ .Title }}"
   }
  }]
}
</script>

There should be a safeJS func you can pipe the value through.

Hey @Sarbjit_Singh, hope you’re still using Hugo, try:

"@id": {{ printf "%s" .Permalink }}, (also notice how the surrounding quotes have been omitted)