2015-12-07 13:57:01 -05:00
// Copyright 2015 The Hugo Authors. All rights reserved.
2014-01-09 17:33:20 -05:00
//
2015-11-23 22:16:36 -05:00
// Licensed under the Apache License, Version 2.0 (the "License");
2014-01-09 17:33:20 -05:00
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
2015-11-23 22:16:36 -05:00
// http://www.apache.org/licenses/LICENSE-2.0
2014-01-09 17:33:20 -05:00
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2014-11-20 12:32:21 -05:00
package tpl
2014-01-09 17:33:20 -05:00
type Tmpl struct {
2014-01-29 17:50:31 -05:00
Name string
Data string
2014-01-09 17:33:20 -05:00
}
2015-03-11 13:34:57 -04:00
func ( t * GoHTMLTemplate ) EmbedShortcodes ( ) {
Provide (relative) reference funcs & shortcodes.
- `.Ref` and `.RelRef` take a reference (the logical filename for a
page, including extension and/or a document fragment ID) and return
a permalink (or relative permalink) to the referenced document.
- If the reference is a page name (such as `about.md`), the page
will be discovered and the permalink will be returned: `/about/`
- If the reference is a page name with a fragment (such as
`about.md#who`), the page will be discovered and used to add the
`page.UniqueID()` to the resulting fragment and permalink:
`/about/#who:deadbeef`.
- If the reference is a fragment and `.*Ref` has been called from
a `Node` or `SiteInfo`, it will be returned as is: `#who`.
- If the reference is a fragment and `.*Ref` has been called from
a `Page`, it will be returned with the page’s unique ID:
`#who:deadbeef`.
- `.*Ref` can be called from either `Node`, `SiteInfo` (e.g.,
`Node.Site`), `Page` objects, or `ShortcodeWithPage` objects in
templates.
- `.*Ref` cannot be used in content, so two shortcodes have been
created to provide the functionality to content: `ref` and `relref`.
These are intended to be used within markup, like `[Who]({{% ref
about.md#who %}})` or `<a href="{{% ref about.md#who %}}">Who</a>`.
- There are also `ref` and `relref` template functions (used to create
the shortcodes) that expect a `Page` or `Node` object and the
reference string (e.g., `{{ relref . "about.md" }}` or `{{
"about.md" | ref . }}`). It actually looks for `.*Ref` as defined on
`Node` or `Page` objects.
- Shortcode handling had to use a *differently unique* wrapper in
`createShortcodePlaceholder` because of the way that the `ref` and
`relref` are intended to be used in content.
2014-11-24 01:15:34 -05:00
t . AddInternalShortcode ( "ref.html" , ` {{ .Get 0 | ref .Page }} ` )
t . AddInternalShortcode ( "relref.html" , ` {{ .Get 0 | relref .Page }} ` )
2015-04-15 20:20:15 -04:00
t . AddInternalShortcode ( "highlight.html" , ` {{ if len .Params | eq 2 }} {{ highlight .Inner ( .Get 0 ) ( .Get 1 ) }} {{ else }} {{ highlight .Inner ( .Get 0 ) "" }} {{ end }} ` )
2014-02-25 23:57:31 -05:00
t . AddInternalShortcode ( "test.html" , ` This is a simple Test ` )
t . AddInternalShortcode ( "figure.html" , ` < ! -- image -- >
< figure { { with . Get "class" } } class = "{{.}}" { { end } } >
{ { with . Get "link" } } < a href = "{{.}}" > { { end } }
2014-10-30 11:37:00 -04:00
< img src = "{{ .Get " src " }}" { { if or ( . Get "alt" ) ( . Get "caption" ) } } alt = "{{ with .Get " alt "}}{{.}}{{else}}{{ .Get " caption " }}{{ end }}" { { end } } { { with . Get "width" } } width = "{{.}}" { { end } } / >
2014-02-25 23:57:31 -05:00
{ { if . Get "link" } } < / a > { { end } }
{ { if or ( or ( . Get "title" ) ( . Get "caption" ) ) ( . Get "attr" ) } }
2014-01-09 17:33:20 -05:00
< figcaption > { { if isset . Params "title" } }
2014-02-25 23:57:31 -05:00
< h4 > { { . Get "title" } } < / h4 > { { end } }
{ { if or ( . Get "caption" ) ( . Get "attr" ) } } < p >
{ { . Get "caption" } }
{ { with . Get "attrlink" } } < a href = "{{.}}" > { { end } }
{ { . Get "attr" } }
{ { if . Get "attrlink" } } < / a > { { end } }
2014-01-09 17:33:20 -05:00
< / p > { { end } }
< / figcaption >
{ { end } }
< / figure >
< ! -- image -- > ` )
2015-11-23 13:32:03 -05:00
t . AddInternalShortcode ( "speakerdeck.html" , "<script async class='speakerdeck-embed' data-id='{{ index .Params 0 }}' data-ratio='1.33333333333333' src='//speakerdeck.com/assets/embed.js'></script>" )
t . AddInternalShortcode ( "youtube.html" , ` { { if . IsNamedParams } }
< div { { if . Get "class" } } class = "{{ .Get " class " }}" { { else } } style = "position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;" { { end } } >
2016-09-18 13:10:11 -04:00
< iframe src = "//www.youtube.com/embed/{{ .Get " id " }}?{{ with .Get " autoplay " }}{{ if eq . " true " }}autoplay=1{{ end }}{{ end }}"
2016-01-16 12:49:18 -05:00
{ { if not ( . Get "class" ) } } style = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;" { { end } } allowfullscreen frameborder = "0" > < / iframe >
2015-11-23 13:32:03 -05:00
< / div > { { else } }
< div { { if len . Params | eq 2 } } class = "{{ .Get 1 }}" { { else } } style = "position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;" { { end } } >
< iframe src = "//www.youtube.com/embed/{{ .Get 0 }}" { { if len . Params | eq 1 } } style = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;" { { end } } allowfullscreen frameborder = "0" > < / iframe >
< / div >
{ { end } } ` )
t . AddInternalShortcode ( "vimeo.html" , ` { { if . IsNamedParams } } < div { { if . Get "class" } } class = "{{ .Get " class " }}" { { else } } style = "position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;" { { end } } >
< iframe src = "//player.vimeo.com/video/{{ .Get " id " }}" { { if not ( . Get "class" ) } } style = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;" { { end } } webkitallowfullscreen mozallowfullscreen allowfullscreen > < / iframe >
< / div > { { else } }
< div { { if len . Params | eq 2 } } class = "{{ .Get 1 }}" { { else } } style = "position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;" { { end } } >
< iframe src = "//player.vimeo.com/video/{{ .Get 0 }}" { { if len . Params | eq 1 } } style = "position: absolute; top: 0; left: 0; width: 100%; height: 100%;" { { end } } webkitallowfullscreen mozallowfullscreen allowfullscreen > < / iframe >
< / div >
{ { end } } ` )
2016-03-11 09:02:57 -05:00
t . AddInternalShortcode ( "gist.html" , ` <script src="//gist.github.com/ {{ index .Params 0 }} / {{ index .Params 1 }} .js {{ if len .Params | eq 3 }} ?file= {{ index .Params 2 }} {{ end }} "></script> ` )
2015-11-23 13:32:03 -05:00
t . AddInternalShortcode ( "tweet.html" , ` {{ ( getJSON "https://api.twitter.com/1/statuses/oembed.json?id=" ( index .Params 0 ) ) .html | safeHTML }} ` )
2014-01-09 17:33:20 -05:00
}
2014-04-09 17:45:34 -04:00
2015-03-11 13:34:57 -04:00
func ( t * GoHTMLTemplate ) EmbedTemplates ( ) {
2014-04-09 17:45:34 -04:00
t . AddInternalTemplate ( "_default" , "rss.xml" , ` < rss version = "2.0" xmlns : atom = "http://www.w3.org/2005/Atom" >
< channel >
2016-11-20 06:54:17 -05:00
< title > { { if eq . Title . Site . Title } } { { . Site . Title } } { { else } } { { with . Title } } { { . } } on { { end } } { { . Site . Title } } { { end } } < / title >
2014-04-09 17:45:34 -04:00
< link > { { . Permalink } } < / link >
2016-11-20 06:54:17 -05:00
< description > Recent content { { if ne . Title . Site . Title } } { { with . Title } } in { { . } } { { end } } { { end } } on { { . Site . Title } } < / description >
2015-01-30 08:24:44 -05:00
< generator > Hugo -- gohugo . io < / generator > { { with . Site . LanguageCode } }
2016-09-18 13:10:11 -04:00
< language > { { . } } < / language > { { end } } { { with . Site . Author . email } }
< managingEditor > { { . } } { { with $ . Site . Author . name } } ( { { . } } ) { { end } } < / managingEditor > { { end } } { { with . Site . Author . email } }
< webMaster > { { . } } { { with $ . Site . Author . name } } ( { { . } } ) { { end } } < / webMaster > { { end } } { { with . Site . Copyright } }
2015-01-30 08:24:44 -05:00
< copyright > { { . } } < / copyright > { { end } } { { if not . Date . IsZero } }
2015-03-18 01:16:54 -04:00
< lastBuildDate > { { . Date . Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML } } < / lastBuildDate > { { end } }
2016-08-08 07:55:18 -04:00
< atom : link href = "{{.Permalink}}" rel = "self" type = "application/rss+xml" / >
2014-04-09 17:45:34 -04:00
{ { range first 15 . Data . Pages } }
< item >
< title > { { . Title } } < / title >
< link > { { . Permalink } } < / link >
2015-03-18 01:16:54 -04:00
< pubDate > { { . Date . Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML } } < / pubDate >
2016-09-18 13:10:11 -04:00
{ { with . Site . Author . email } } < author > { { . } } { { with $ . Site . Author . name } } ( { { . } } ) { { end } } < / author > { { end } }
2014-04-09 17:45:34 -04:00
< guid > { { . Permalink } } < / guid >
< description > { { . Content | html } } < / description >
< / item >
{ { end } }
< / channel >
< / rss > ` )
2014-05-06 06:50:23 -04:00
t . AddInternalTemplate ( "_default" , "sitemap.xml" , ` < urlset xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9" >
{ { range . Data . Pages } }
< url >
2015-05-14 17:58:14 -04:00
< loc > { { . Permalink } } < / loc > { { if not . Lastmod . IsZero } }
< lastmod > { { safeHTML ( . Lastmod . Format "2006-01-02T15:04:05-07:00" ) } } < / lastmod > { { end } } { { with . Sitemap . ChangeFreq } }
2014-05-06 11:02:56 -04:00
< changefreq > { { . } } < / changefreq > { { end } } { { if ge . Sitemap . Priority 0.0 } }
< priority > { { . Sitemap . Priority } } < / priority > { { end } }
2014-05-06 06:50:23 -04:00
< / url >
{ { end } }
< / urlset > ` )
2016-08-04 16:12:19 -04:00
// For multilanguage sites
t . AddInternalTemplate ( "_default" , "sitemapindex.xml" , ` < sitemapindex xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9" >
{ { range . } }
< sitemap >
< loc > { { . SitemapAbsURL } } < / loc >
{ { if not . LastChange . IsZero } }
< lastmod > { { . LastChange . Format "2006-01-02T15:04:05-07:00" | safeHTML } } < / lastmod >
{ { end } }
< / sitemap >
{ { end } }
< / sitemapindex >
` )
2015-02-19 05:36:09 -05:00
t . AddInternalTemplate ( "" , "pagination.html" , ` { { $ pag := $ . Paginator } }
2015-01-26 07:34:12 -05:00
{ { if gt $ pag . TotalPages 1 } }
< ul class = "pagination" >
{ { with $ pag . First } }
< li >
2015-03-18 01:16:54 -04:00
< a href = "{{ .URL }}" aria - label = "First" > < span aria - hidden = "true" > & laquo ; & laquo ; < / span > < / a >
2015-01-26 07:34:12 -05:00
< / li >
{ { end } }
< li
{ { if not $ pag . HasPrev } } class = "disabled" { { end } } >
2015-03-18 01:16:54 -04:00
< a href = "{{ if $pag.HasPrev }}{{ $pag.Prev.URL }}{{ end }}" aria - label = "Previous" > < span aria - hidden = "true" > & laquo ; < / span > < / a >
2015-01-26 07:34:12 -05:00
< / li >
{ { range $ pag . Pagers } }
< li
2015-03-18 01:16:54 -04:00
{ { if eq . $ pag } } class = "active" { { end } } > < a href = "{{ .URL }}" > { { . PageNumber } } < / a > < / li >
2015-01-26 07:34:12 -05:00
{ { end } }
< li
{ { if not $ pag . HasNext } } class = "disabled" { { end } } >
2015-03-18 01:16:54 -04:00
< a href = "{{ if $pag.HasNext }}{{ $pag.Next.URL }}{{ end }}" aria - label = "Next" > < span aria - hidden = "true" > & raquo ; < / span > < / a >
2015-01-26 07:34:12 -05:00
< / li >
{ { with $ pag . Last } }
< li >
2015-03-18 01:16:54 -04:00
< a href = "{{ .URL }}" aria - label = "Last" > < span aria - hidden = "true" > & raquo ; & raquo ; < / span > < / a >
2015-01-26 07:34:12 -05:00
< / li >
{ { end } }
< / ul >
{ { end } } ` )
2014-04-23 02:52:01 -04:00
t . AddInternalTemplate ( "" , "disqus.html" , ` { { if . Site . DisqusShortname } } < div id = "disqus_thread" > < / div >
< script type = "text/javascript" >
var disqus_shortname = ' { { . Site . DisqusShortname } } ' ;
var disqus_identifier = ' { { with . GetParam "disqus_identifier" } } { { . } } { { else } } { { . Permalink } } { { end } } ' ;
var disqus_title = ' { { with . GetParam "disqus_title" } } { { . } } { { else } } { { . Title } } { { end } } ' ;
var disqus_url = ' { { with . GetParam "disqus_url" } } { { . | html } } { { else } } { { . Permalink } } { { end } } ' ;
( function ( ) {
var dsq = document . createElement ( ' script ' ) ; dsq . type = ' text / javascript ' ; dsq . async = true ;
dsq . src = ' //' + disqus_shortname + '.disqus.com/embed.js';
( document . getElementsByTagName ( ' head ' ) [ 0 ] || document . getElementsByTagName ( ' body ' ) [ 0 ] ) . appendChild ( dsq ) ;
} ) ( ) ;
< / script >
< noscript > Please enable JavaScript to view the < a href = "http://disqus.com/?ref_noscript" > comments powered by Disqus . < / a > < / noscript >
< a href = "http://disqus.com" class = "dsq-brlink" > comments powered by < span class = "logo-disqus" > Disqus < / span > < / a > { { end } } ` )
2014-12-09 13:33:55 -05:00
// Add SEO & Social metadata
2015-01-30 15:58:18 -05:00
t . AddInternalTemplate ( "" , "opengraph.html" , ` < meta property = "og:title" content = "{{ .Title }}" / >
2015-02-01 13:56:21 -05:00
< meta property = "og:description" content = "{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" / >
2014-12-09 13:33:55 -05:00
< meta property = "og:type" content = "{{ if .IsPage }}article{{ else }}website{{ end }}" / >
< meta property = "og:url" content = "{{ .Permalink }}" / >
{ { with . Params . images } } { { range first 6 . } }
2015-11-02 14:49:15 -05:00
< meta property = "og:image" content = "{{ . | absURL }}" / >
2014-12-09 13:33:55 -05:00
{ { end } } { { end } }
2015-03-18 01:16:54 -04:00
{ { if not . Date . IsZero } } < meta property = "og:updated_time" content = "{{ .Date.Format " 2006 - 01 - 02 T15 : 04 : 05 - 07 : 00 " | safeHTML }}" / > { { end } } { { with . Params . audio } }
2014-12-09 13:33:55 -05:00
< meta property = "og:audio" content = "{{ . }}" / > { { end } } { { with . Params . locale } }
< meta property = "og:locale" content = "{{ . }}" / > { { end } } { { with . Site . Params . title } }
< meta property = "og:site_name" content = "{{ . }}" / > { { end } } { { with . Params . videos } }
{ { range . Params . videos } }
2015-11-02 14:49:15 -05:00
< meta property = "og:video" content = "{{ . | absURL }}" / >
2015-01-20 04:43:42 -05:00
{ { end } } { { end } }
2014-12-09 13:33:55 -05:00
< ! -- If it is part of a series , link to related articles -- >
{ { $ permalink := . Permalink } }
{ { $ siteSeries := . Site . Taxonomies . series } } { { with . Params . series } }
{ { range $ name := . } }
{ { $ series := index $ siteSeries $ name } }
{ { range $ page := first 6 $ series . Pages } }
{ { if ne $ page . Permalink $ permalink } } < meta property = "og:see_also" content = "{{ $page.Permalink }}" / > { { end } }
{ { end } }
{ { end } } { { end } }
{ { if . IsPage } }
{ { range . Site . Authors } } { { with . Social . facebook } }
< meta property = "article:author" content = "https://www.facebook.com/{{ . }}" / > { { end } } { { with . Site . Social . facebook } }
< meta property = "article:publisher" content = "https://www.facebook.com/{{ . }}" / > { { end } }
< meta property = "article:published_time" content = "{{ .PublishDate }}" / >
< meta property = "article:modified_time" content = "{{ .Date }}" / >
< meta property = "article:section" content = "{{ .Section }}" / >
{ { with . Params . tags } } { { range first 6 . } }
< meta property = "article:tag" content = "{{ . }}" / > { { end } } { { end } }
2015-01-20 04:43:42 -05:00
{ { end } } { { end } }
2014-12-09 13:33:55 -05:00
< ! -- Facebook Page Admin ID for Domain Insights -- >
{ { with . Site . Social . facebook_admin } } < meta property = "fb:admins" content = "{{ . }}" / > { { end } } ` )
2015-01-30 15:58:18 -05:00
t . AddInternalTemplate ( "" , "twitter_cards.html" , ` { { if . IsPage } }
2014-12-09 13:33:55 -05:00
{ { with . Params . images } }
< ! -- Twitter summary card with large image must be at least 280 x150px -- >
< meta name = "twitter:card" content = "summary_large_image" / >
2015-11-02 14:49:15 -05:00
< meta name = "twitter:image:src" content = "{{ index . 0 | absURL }}" / >
2014-12-09 13:33:55 -05:00
{ { else } }
< meta name = "twitter:card" content = "summary" / >
{ { end } }
< ! -- Twitter Card data -- >
< meta name = "twitter:title" content = "{{ .Title }}" / >
2015-02-01 13:56:21 -05:00
< meta name = "twitter:description" content = "{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" / >
2014-12-09 13:33:55 -05:00
{ { with . Site . Social . twitter } } < meta name = "twitter:site" content = "@{{ . }}" / > { { end } }
{ { with . Site . Social . twitter_domain } } < meta name = "twitter:domain" content = "{{ . }}" / > { { end } }
{ { range . Site . Authors } }
{ { with . twitter } } < meta name = "twitter:creator" content = "@{{ . }}" / > { { end } }
{ { end } } { { end } } ` )
2015-01-30 15:58:18 -05:00
t . AddInternalTemplate ( "" , "google_news.html" , ` { { if . IsPage } } { { with . Params . news_keywords } }
2014-12-09 13:33:55 -05:00
< meta name = "news_keywords" content = "{{ range $i, $kw := first 10 . }}{{ if $i }},{{ end }}{{ $kw }}{{ end }}" / >
{ { end } } { { end } } ` )
2015-01-30 15:58:18 -05:00
t . AddInternalTemplate ( "" , "schema.html" , ` { { with . Site . Social . GooglePlus } } < link rel = "publisher" href = "{{ . }}" / > { { end } }
2014-12-09 13:33:55 -05:00
< meta itemprop = "name" content = "{{ .Title }}" >
2015-02-01 13:56:21 -05:00
< meta itemprop = "description" content = "{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" >
2014-12-09 13:33:55 -05:00
2015-01-30 08:24:44 -05:00
{ { if . IsPage } } { { $ ISO8601 := "2006-01-02T15:04:05-07:00" } } { { if not . PublishDate . IsZero } }
2015-03-18 01:16:54 -04:00
< meta itemprop = "datePublished" content = "{{ .PublishDate.Format $ISO8601 | safeHTML }}" / > { { end } }
{ { if not . Date . IsZero } } < meta itemprop = "dateModified" content = "{{ .Date.Format $ISO8601 | safeHTML }}" / > { { end } }
2014-12-09 13:33:55 -05:00
< meta itemprop = "wordCount" content = "{{ .WordCount }}" >
{ { with . Params . images } } { { range first 6 . } }
2015-11-02 14:49:15 -05:00
< meta itemprop = "image" content = "{{ . | absURL }}" >
2014-12-09 13:33:55 -05:00
{ { end } } { { end } }
< ! -- Output all taxonomies as schema . org keywords -- >
< meta itemprop = "keywords" content = "{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf " % s , " $term }}{{ end }}{{ end }}" / >
2015-10-19 07:31:03 -04:00
{ { end } } ` )
t . AddInternalTemplate ( "" , "google_analytics.html" , ` { { with . Site . GoogleAnalytics } }
< script >
( function ( i , s , o , g , r , a , m ) { i [ ' GoogleAnalyticsObject ' ] = r ; i [ r ] = i [ r ] || function ( ) {
( i [ r ] . q = i [ r ] . q || [ ] ) . push ( arguments ) } , i [ r ] . l = 1 * new Date ( ) ; a = s . createElement ( o ) ,
m = s . getElementsByTagName ( o ) [ 0 ] ; a . async = 1 ; a . src = g ; m . parentNode . insertBefore ( a , m )
} ) ( window , document , ' script ',' //www.google-analytics.com/analytics.js','ga');
ga ( ' create ' , ' { { . } } ' , ' auto ' ) ;
ga ( ' send ' , ' pageview ' ) ;
< / script >
2015-12-17 00:56:16 -05:00
{ { end } } ` )
t . AddInternalTemplate ( "" , "google_analytics_async.html" , ` { { with . Site . GoogleAnalytics } }
< script >
window . ga = window . ga || function ( ) { ( ga . q = ga . q || [ ] ) . push ( arguments ) } ; ga . l = + new Date ;
ga ( ' create ' , ' { { . } } ' , ' auto ' ) ;
ga ( ' send ' , ' pageview ' ) ;
< / script >
< script async src = ' //www.google-analytics.com/analytics.js'></script>
2015-01-20 04:43:42 -05:00
{ { end } } ` )
2015-12-08 16:13:09 -05:00
t . AddInternalTemplate ( "_default" , "robots.txt" , "User-agent: *" )
2014-04-09 17:45:34 -04:00
}