Schema.org Markup with JSON on Different Types of Pages

I want to use JSON to markup my pages with schema.org markup, but I have all kinds of pages (e.g. About, Contact, Tutorial and Category pages).

About page = schema.org/AboutPage

Contact page = schema.org/ContactPage

Category pages, sitemap.html, etc = schema.org/WebPage

Tutorial pages = schema.org/TechArticle

How can I create that?

I already created a site-schema.html file in the /layouts/partials/ folder - which looks like this:

    {{ if .IsHome -}}
<script type="application/ld+json">
{
  "@context":"http://schema.org",
  "@type":"WebSite",
  "name":"",
  "url":"",
  "description":"",
  "sameAs":[
	"",
	"",
	""
]}
</script>
{{- else if .IsPage -}}
<script type="application/ld+json">{
"@context":"http://schema.org",
"@type":"TechArticle",
"headline":"{{ .Title }}",
"description":"{{ .Description }}",
"image":"{{ range $i, $e := .Params.images }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}",
"datePublished":"{{.PublishDate}}"
},}
</script> 
{{- end }}

and in the header.html file I added the following code:

{{ partial "site-schema.html" . }}

But that will give the home page its correct schema markup, but will give all other pages the schema.org/TechArticle markup.

And on some pages I also have embedded YouTube videos:

<script type="application/ld+json">{
"@context":"http://schema.org",
"@graph":[{
"@type":"TechArticle",
"headline":"",
"description":"",
"image":"",
"datePublished":"2018-02-03"},{
"@type":"VideoObject",
"name":"",
"description":"",
"thumbnailUrl":"",
"uploadDate":"2018-02-03",
"embedUrl":""},{
"@type":"VideoObject",
"name":"",
"description":"",
"thumbnailUrl":"",
"uploadDate":"2018-02-03",
"embedUrl":""
}]}</script> 

So how can I do this?

One way would be to add the schema partial based on the kind of page, and having different partials for each kind.

For example: site-schema.html, page-schema.html, section-schema.html etc.

Take a look here and see if it helps: Variable in path string variable, printf?

Can you please give me 1 example for, lets say the about page? What do I place on the About page?and what do I place in the header.html file?

You could call the respective template like this:

{{ partial (printf "schema-%s.html" .Kind) . }}

And then you would have a partial for each kind: page, home, section, taxonomy, or taxonomyTerm.

For a page, the partial would be schema-page.html and so on.

Does this help?

Update: this can break if you don’t have a partial for each taxonomy term … not sure how to solve that :frowning:

In PHP I placed the following code in the header.php file:

<?php if (isset($schema)) {?>
<?php echo $schema ?>
<?php }?> 

And then placed the following code on every page:

$schema="<script type=\"application/ld+json\">{
\"@context\":\"http://schema.org\",
\"@type\":\"TechArticle\",
\"headline\":\"This is the title of the page\",
\"description\":\"This is the description of the page\",
\"image\":\"https://www.example.com/images/image-of-page.png\",
\"datePublished\":\"2018-02-02\"
},}</script>"; 

Is there a way to do the same in Hugo?

Yes, you check for the existence of .Params.schema and then use this in your template:

{{ .Params.schema | safeHtml }}

I’m sorry, but I don’t understand it. So what code do I place on the content page and where? and what do I place in the header.html file? And do I need to put something in the config.toml file?

UPDATE: Ok so I think it’s working now. Correct me if I’m wrong, but I placed the following lines in the content page between —:

schema: "<script type=\"application/ld+json\">{
\"@context\":\"http://schema.org\",
\"@type\":\"AboutPage\",
\"headline\":\"About DIYTechGuides\"
},}\</script>"

And then I placed the following lines in the header.html file:

{{ if isset .Params "schema" }}{{ .Params.schema | safeHTML }}{{ end }}

It looks like it’s working.

Is this the way you would do it?