mirror of
				https://github.com/gohugoio/hugo.git
				synced 2024-05-11 05:54:58 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:spf13/hugo
This commit is contained in:
		@@ -358,7 +358,7 @@ func NewWatcher(port int) error {
 | 
				
			|||||||
						continue
 | 
											continue
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					isstatic := strings.HasPrefix(ev.Name, helpers.AbsPathify(viper.GetString("StaticDir"))) || strings.HasPrefix(ev.Name, helpers.AbsPathify("themes/"+viper.GetString("theme"))+"/static/")
 | 
										isstatic := strings.HasPrefix(ev.Name, helpers.GetStaticDirPath()) || strings.HasPrefix(ev.Name, helpers.GetThemesDirPath())
 | 
				
			||||||
					static_changed = static_changed || isstatic
 | 
										static_changed = static_changed || isstatic
 | 
				
			||||||
					dynamic_changed = dynamic_changed || !isstatic
 | 
										dynamic_changed = dynamic_changed || !isstatic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,9 +174,17 @@ func AbsPathify(inPath string) string {
 | 
				
			|||||||
	return filepath.Clean(filepath.Join(viper.GetString("WorkingDir"), inPath))
 | 
						return filepath.Clean(filepath.Join(viper.GetString("WorkingDir"), inPath))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetStaticDirPath() string {
 | 
				
			||||||
 | 
						return AbsPathify(viper.GetString("StaticDir"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetThemesDirPath() string {
 | 
				
			||||||
 | 
						return AbsPathify(filepath.Join("themes", viper.GetString("theme"), "static"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func MakeStaticPathRelative(inPath string) (string, error) {
 | 
					func MakeStaticPathRelative(inPath string) (string, error) {
 | 
				
			||||||
	staticDir := AbsPathify(viper.GetString("StaticDir"))
 | 
						staticDir := GetStaticDirPath()
 | 
				
			||||||
	themeStaticDir := AbsPathify("themes/"+viper.GetString("theme")) + "/static/"
 | 
						themeStaticDir := GetThemesDirPath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return MakePathRelative(inPath, staticDir, themeStaticDir)
 | 
						return MakePathRelative(inPath, staticDir, themeStaticDir)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,7 +60,7 @@ func (h markdownHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
 | 
				
			|||||||
	tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
 | 
						tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(p.contentShortCodes) > 0 {
 | 
						if len(p.contentShortCodes) > 0 {
 | 
				
			||||||
		tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, -1, true, p.contentShortCodes)
 | 
							tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, true, p.contentShortCodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
 | 
								jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
 | 
				
			||||||
@@ -113,7 +113,7 @@ func (h rstHandler) PageConvert(p *Page, t tpl.Template) HandledResult {
 | 
				
			|||||||
	tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
 | 
						tmpContent, tmpTableOfContents := helpers.ExtractTOC(p.renderContent(helpers.RemoveSummaryDivider(p.rawContent)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(p.contentShortCodes) > 0 {
 | 
						if len(p.contentShortCodes) > 0 {
 | 
				
			||||||
		tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, -1, true, p.contentShortCodes)
 | 
							tmpContentWithTokensReplaced, err := replaceShortcodeTokens(tmpContent, shortcodePlaceholderPrefix, true, p.contentShortCodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
 | 
								jww.FATAL.Printf("Fail to replace short code tokens in %s:\n%s", p.BaseFileName(), err.Error())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -163,10 +163,9 @@ func (p *Page) setSummary() {
 | 
				
			|||||||
		p.Truncated = true // by definition
 | 
							p.Truncated = true // by definition
 | 
				
			||||||
		header := bytes.Split(p.rawContent, helpers.SummaryDivider)[0]
 | 
							header := bytes.Split(p.rawContent, helpers.SummaryDivider)[0]
 | 
				
			||||||
		renderedHeader := p.renderBytes(header)
 | 
							renderedHeader := p.renderBytes(header)
 | 
				
			||||||
		numShortcodesInHeader := bytes.Count(header, []byte(shortcodePlaceholderPrefix))
 | 
					 | 
				
			||||||
		if len(p.contentShortCodes) > 0 {
 | 
							if len(p.contentShortCodes) > 0 {
 | 
				
			||||||
			tmpContentWithTokensReplaced, err :=
 | 
								tmpContentWithTokensReplaced, err :=
 | 
				
			||||||
				replaceShortcodeTokens(renderedHeader, shortcodePlaceholderPrefix, numShortcodesInHeader, true, p.contentShortCodes)
 | 
									replaceShortcodeTokens(renderedHeader, shortcodePlaceholderPrefix, true, p.contentShortCodes)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				jww.FATAL.Printf("Failed to replace short code tokens in Summary for %s:\n%s", p.BaseFileName(), err.Error())
 | 
									jww.FATAL.Printf("Failed to replace short code tokens in Summary for %s:\n%s", p.BaseFileName(), err.Error())
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,6 @@ import (
 | 
				
			|||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,7 +132,7 @@ func ShortcodesHandle(stringToParse string, page *Page, t tpl.Template) string {
 | 
				
			|||||||
	tmpContent, tmpShortcodes := extractAndRenderShortcodes(stringToParse, page, t)
 | 
						tmpContent, tmpShortcodes := extractAndRenderShortcodes(stringToParse, page, t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(tmpShortcodes) > 0 {
 | 
						if len(tmpShortcodes) > 0 {
 | 
				
			||||||
		tmpContentWithTokensReplaced, err := replaceShortcodeTokens([]byte(tmpContent), shortcodePlaceholderPrefix, -1, true, tmpShortcodes)
 | 
							tmpContentWithTokensReplaced, err := replaceShortcodeTokens([]byte(tmpContent), shortcodePlaceholderPrefix, true, tmpShortcodes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			jww.ERROR.Printf("Fail to replace short code tokens in %s:\n%s", page.BaseFileName(), err.Error())
 | 
								jww.ERROR.Printf("Fail to replace short code tokens in %s:\n%s", page.BaseFileName(), err.Error())
 | 
				
			||||||
@@ -432,60 +431,44 @@ Loop:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Replace prefixed shortcode tokens (HUGOSHORTCODE-1, HUGOSHORTCODE-2) with the real content.
 | 
					// Replace prefixed shortcode tokens (HUGOSHORTCODE-1, HUGOSHORTCODE-2) with the real content.
 | 
				
			||||||
// This assumes that all tokens exist in the input string and that they are in order.
 | 
					 | 
				
			||||||
// numReplacements = -1 will do len(replacements), and it will always start from the beginning (1)
 | 
					 | 
				
			||||||
// wrapped = true means that the token has been wrapped in {@{@/@}@}
 | 
					// wrapped = true means that the token has been wrapped in {@{@/@}@}
 | 
				
			||||||
func replaceShortcodeTokens(source []byte, prefix string, numReplacements int, wrapped bool, replacements map[string]string) ([]byte, error) {
 | 
					func replaceShortcodeTokens(source []byte, prefix string, wrapped bool, replacements map[string]string) (b []byte, err error) {
 | 
				
			||||||
 | 
						var re *regexp.Regexp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if numReplacements < 0 {
 | 
						if wrapped {
 | 
				
			||||||
		numReplacements = len(replacements)
 | 
							re, err = regexp.Compile(`\{@\{@` + regexp.QuoteMeta(prefix) + `-\d+@\}@\}`)
 | 
				
			||||||
	}
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
	if numReplacements == 0 {
 | 
							}
 | 
				
			||||||
		return source, nil
 | 
						} else {
 | 
				
			||||||
	}
 | 
							re, err = regexp.Compile(regexp.QuoteMeta(prefix) + `-(\d+)`)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
	newLen := len(source)
 | 
								return nil, err
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := 1; i <= numReplacements; i++ {
 | 
					 | 
				
			||||||
		key := prefix + "-" + strconv.Itoa(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if wrapped {
 | 
					 | 
				
			||||||
			key = "{@{@" + key + "@}@}"
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		val := []byte(replacements[key])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		newLen += (len(val) - len(key))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buff := make([]byte, newLen)
 | 
						// use panic/recover for reporting if an unknown
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
	width := 0
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
	start := 0
 | 
								var ok bool
 | 
				
			||||||
 | 
								b = nil
 | 
				
			||||||
	for i := 0; i < numReplacements; i++ {
 | 
								err, ok = r.(error)
 | 
				
			||||||
		tokenNum := i + 1
 | 
								if !ok {
 | 
				
			||||||
		oldVal := prefix + "-" + strconv.Itoa(tokenNum)
 | 
									err = fmt.Errorf("unexpected panic during replaceShortcodeTokens: %v", r)
 | 
				
			||||||
		if wrapped {
 | 
								}
 | 
				
			||||||
			oldVal = "{@{@" + oldVal + "@}@}"
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		newVal := []byte(replacements[oldVal])
 | 
						}()
 | 
				
			||||||
		j := start
 | 
						b = re.ReplaceAllFunc(source, func(m []byte) []byte {
 | 
				
			||||||
 | 
							key := string(m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		k := bytes.Index(source[start:], []byte(oldVal))
 | 
							if val, ok := replacements[key]; ok {
 | 
				
			||||||
 | 
								return []byte(val)
 | 
				
			||||||
		if k < 0 {
 | 
							} else {
 | 
				
			||||||
			// this should never happen, but let the caller decide to panic or not
 | 
								panic(fmt.Errorf("unknown shortcode token %q", key))
 | 
				
			||||||
			return nil, fmt.Errorf("illegal state in content; shortcode token #%d is missing or out of order (%q)", tokenNum, source)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		j += k
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		width += copy(buff[width:], source[start:j])
 | 
						return b, err
 | 
				
			||||||
		width += copy(buff[width:], newVal)
 | 
					 | 
				
			||||||
		start = j + len(oldVal)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	width += copy(buff[width:], source[start:])
 | 
					 | 
				
			||||||
	return buff[0:width], nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetTemplate(name string, t tpl.Template) *template.Template {
 | 
					func GetTemplate(name string, t tpl.Template) *template.Template {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -281,23 +281,24 @@ func collectAndShortShortcodes(shortcodes map[string]shortcode) []string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestReplaceShortcodeTokens(t *testing.T) {
 | 
					func TestReplaceShortcodeTokens(t *testing.T) {
 | 
				
			||||||
	for i, this := range []struct {
 | 
						for i, this := range []struct {
 | 
				
			||||||
		input           []byte
 | 
							input        string
 | 
				
			||||||
		prefix          string
 | 
							prefix       string
 | 
				
			||||||
		replacements    map[string]string
 | 
							replacements map[string]string
 | 
				
			||||||
		numReplacements int
 | 
							wrappedInDiv bool
 | 
				
			||||||
		wrappedInDiv    bool
 | 
							expect       interface{}
 | 
				
			||||||
		expect          interface{}
 | 
					 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{[]byte("Hello PREFIX-1."), "PREFIX", map[string]string{"PREFIX-1": "World"}, -1, false, []byte("Hello World.")},
 | 
							{"Hello PREFIX-1.", "PREFIX", map[string]string{"PREFIX-1": "World"}, false, "Hello World."},
 | 
				
			||||||
		{[]byte("A {@{@A-1@}@} asdf {@{@A-2@}@}."), "A", map[string]string{"{@{@A-1@}@}": "v1", "{@{@A-2@}@}": "v2"}, -1, true, []byte("A v1 asdf v2.")},
 | 
							{"A {@{@A-1@}@} asdf {@{@A-2@}@}.", "A", map[string]string{"{@{@A-1@}@}": "v1", "{@{@A-2@}@}": "v2"}, true, "A v1 asdf v2."},
 | 
				
			||||||
		{[]byte("Hello PREFIX2-1. Go PREFIX2-2, Go, Go PREFIX2-3 Go Go!."), "PREFIX2", map[string]string{"PREFIX2-1": "Europe", "PREFIX2-2": "Jonny", "PREFIX2-3": "Johnny"}, -1, false, []byte("Hello Europe. Go Jonny, Go, Go Johnny Go Go!.")},
 | 
							{"Hello PREFIX2-1. Go PREFIX2-2, Go, Go PREFIX2-3 Go Go!.", "PREFIX2", map[string]string{"PREFIX2-1": "Europe", "PREFIX2-2": "Jonny", "PREFIX2-3": "Johnny"}, false, "Hello Europe. Go Jonny, Go, Go Johnny Go Go!."},
 | 
				
			||||||
		{[]byte("A PREFIX-2 PREFIX-1."), "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, -1, false, false},
 | 
							{"A PREFIX-2 PREFIX-1.", "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, false, "A B A."},
 | 
				
			||||||
		{[]byte("A PREFIX-1 PREFIX-2"), "PREFIX", map[string]string{"PREFIX-1": "A"}, -1, false, []byte("A A PREFIX-2")},
 | 
							{"A PREFIX-1 PREFIX-2", "PREFIX", map[string]string{"PREFIX-1": "A"}, false, false},
 | 
				
			||||||
		{[]byte("A PREFIX-1 but not the second."), "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, -1, false, false},
 | 
							{"A PREFIX-1 but not the second.", "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, false, "A A but not the second."},
 | 
				
			||||||
		{[]byte("An PREFIX-1."), "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, 1, false, []byte("An A.")},
 | 
							{"An PREFIX-1.", "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, false, "An A."},
 | 
				
			||||||
		{[]byte("An PREFIX-1 PREFIX-2."), "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, 1, false, []byte("An A PREFIX-2.")},
 | 
							{"An PREFIX-1 PREFIX-2.", "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B"}, false, "An A B."},
 | 
				
			||||||
 | 
							{"A PREFIX-1 PREFIX-2 PREFIX-3 PREFIX-1 PREFIX-3.", "PREFIX", map[string]string{"PREFIX-1": "A", "PREFIX-2": "B", "PREFIX-3": "C"}, false, "A A B C A C."},
 | 
				
			||||||
 | 
							{"A {@{@PREFIX-1@}@} {@{@PREFIX-2@}@} {@{@PREFIX-3@}@} {@{@PREFIX-1@}@} {@{@PREFIX-3@}@}.", "PREFIX", map[string]string{"{@{@PREFIX-1@}@}": "A", "{@{@PREFIX-2@}@}": "B", "{@{@PREFIX-3@}@}": "C"}, true, "A A B C A C."},
 | 
				
			||||||
	} {
 | 
						} {
 | 
				
			||||||
		results, err := replaceShortcodeTokens(this.input, this.prefix, this.numReplacements, this.wrappedInDiv, this.replacements)
 | 
							results, err := replaceShortcodeTokens([]byte(this.input), this.prefix, this.wrappedInDiv, this.replacements)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if b, ok := this.expect.(bool); ok && !b {
 | 
							if b, ok := this.expect.(bool); ok && !b {
 | 
				
			||||||
			if err == nil {
 | 
								if err == nil {
 | 
				
			||||||
@@ -308,7 +309,7 @@ func TestReplaceShortcodeTokens(t *testing.T) {
 | 
				
			|||||||
				t.Errorf("[%d] failed: %s", i, err)
 | 
									t.Errorf("[%d] failed: %s", i, err)
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if !reflect.DeepEqual(results, this.expect) {
 | 
								if !reflect.DeepEqual(results, []byte(this.expect.(string))) {
 | 
				
			||||||
				t.Errorf("[%d] replaceShortcodeTokens, got %q but expected %q", i, results, this.expect)
 | 
									t.Errorf("[%d] replaceShortcodeTokens, got %q but expected %q", i, results, this.expect)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ package livereload
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gorilla/websocket"
 | 
						"github.com/gorilla/websocket"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -44,7 +45,8 @@ func ForceRefresh() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func RefreshPath(s string) {
 | 
					func RefreshPath(s string) {
 | 
				
			||||||
	// Tell livereload a file has changed - will force a hard refresh if not CSS or an image
 | 
						// Tell livereload a file has changed - will force a hard refresh if not CSS or an image
 | 
				
			||||||
	wsHub.broadcast <- []byte(`{"command":"reload","path":"` + s + "\"" + `,"originalPath":"","liveCSS":true,"liveImg":true}`)
 | 
						urlPath := strings.Replace(s, "\\", "/", -1) // If path has backslashes on Windows, make path work for URL
 | 
				
			||||||
 | 
						wsHub.broadcast <- []byte(`{"command":"reload","path":"` + urlPath + "\"" + `,"originalPath":"","liveCSS":true,"liveImg":true}`)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ServeJS(w http.ResponseWriter, r *http.Request) {
 | 
					func ServeJS(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,18 +50,18 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
    <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
 | 
					    <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
 | 
				
			||||||
    <link>{{ .Permalink }}</link>
 | 
					    <link>{{ .Permalink }}</link>
 | 
				
			||||||
    <description>Recent content {{ with .Title }}in {{.}} {{ end }}on {{ .Site.Title }}</description>
 | 
					    <description>Recent content {{ with .Title }}in {{.}} {{ end }}on {{ .Site.Title }}</description>
 | 
				
			||||||
    <generator>Hugo -- gohugo.io</generator>
 | 
					    <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
 | 
				
			||||||
    {{ with .Site.LanguageCode }}<language>{{.}}</language>{{end}}
 | 
					    <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
 | 
				
			||||||
    {{ with .Site.Author.email }}<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}
 | 
					    <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
 | 
				
			||||||
    {{ with .Site.Author.email }}<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}
 | 
					    <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
 | 
				
			||||||
    {{ with .Site.Copyright }}<copyright>{{.}}</copyright>{{end}}
 | 
					    <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
 | 
				
			||||||
    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</lastBuildDate>
 | 
					    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHtml }}</lastBuildDate>{{ end }}
 | 
				
			||||||
    <atom:link href="{{.Url}}" rel="self" type="application/rss+xml" />
 | 
					    <atom:link href="{{.Url}}" rel="self" type="application/rss+xml" />
 | 
				
			||||||
    {{ range first 15 .Data.Pages }}
 | 
					    {{ range first 15 .Data.Pages }}
 | 
				
			||||||
    <item>
 | 
					    <item>
 | 
				
			||||||
      <title>{{ .Title }}</title>
 | 
					      <title>{{ .Title }}</title>
 | 
				
			||||||
      <link>{{ .Permalink }}</link>
 | 
					      <link>{{ .Permalink }}</link>
 | 
				
			||||||
      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</pubDate>
 | 
					      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHtml }}</pubDate>
 | 
				
			||||||
      {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
 | 
					      {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
 | 
				
			||||||
      <guid>{{ .Permalink }}</guid>
 | 
					      <guid>{{ .Permalink }}</guid>
 | 
				
			||||||
      <description>{{ .Content | html }}</description>
 | 
					      <description>{{ .Content | html }}</description>
 | 
				
			||||||
@@ -73,8 +73,8 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
	t.AddInternalTemplate("_default", "sitemap.xml", `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
 | 
						t.AddInternalTemplate("_default", "sitemap.xml", `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
 | 
				
			||||||
  {{ range .Data.Pages }}
 | 
					  {{ range .Data.Pages }}
 | 
				
			||||||
  <url>
 | 
					  <url>
 | 
				
			||||||
    <loc>{{ .Permalink }}</loc>
 | 
					    <loc>{{ .Permalink }}</loc>{{ if not .Date.IsZero }}
 | 
				
			||||||
    <lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ with .Sitemap.ChangeFreq }}
 | 
					    <lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
 | 
				
			||||||
    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
 | 
					    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
 | 
				
			||||||
    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
 | 
					    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
 | 
				
			||||||
  </url>
 | 
					  </url>
 | 
				
			||||||
@@ -126,7 +126,7 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>{{end}}`)
 | 
					<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>{{end}}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add SEO & Social metadata
 | 
						// Add SEO & Social metadata
 | 
				
			||||||
	t.AddInternalTemplate("_default", "opengraph.html", `<meta property="og:title" content="{{ .Title }}" />
 | 
						t.AddInternalTemplate("", "opengraph.html", `<meta property="og:title" content="{{ .Title }}" />
 | 
				
			||||||
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}" />
 | 
					<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}" />
 | 
				
			||||||
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
 | 
					<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
 | 
				
			||||||
<meta property="og:url" content="{{ .Permalink }}" />
 | 
					<meta property="og:url" content="{{ .Permalink }}" />
 | 
				
			||||||
@@ -134,7 +134,7 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
  <meta property="og:image" content="{{ . }}" />
 | 
					  <meta property="og:image" content="{{ . }}" />
 | 
				
			||||||
{{ end }}{{ end }}
 | 
					{{ end }}{{ end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<meta property="og:updated_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" }}"/>{{ with .Params.audio }}
 | 
					{{ if not .Date.IsZero }}<meta property="og:updated_time" content="{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHtml }}"/>{{ end }}{{ with .Params.audio }}
 | 
				
			||||||
<meta property="og:audio" content="{{ . }}" />{{ end }}{{ with .Params.locale }}
 | 
					<meta property="og:audio" content="{{ . }}" />{{ end }}{{ with .Params.locale }}
 | 
				
			||||||
<meta property="og:locale" content="{{ . }}" />{{ end }}{{ with .Site.Params.title }}
 | 
					<meta property="og:locale" content="{{ . }}" />{{ end }}{{ with .Site.Params.title }}
 | 
				
			||||||
<meta property="og:site_name" content="{{ . }}" />{{ end }}{{ with .Params.videos }}
 | 
					<meta property="og:site_name" content="{{ . }}" />{{ end }}{{ with .Params.videos }}
 | 
				
			||||||
@@ -166,7 +166,7 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
<!-- Facebook Page Admin ID for Domain Insights -->
 | 
					<!-- Facebook Page Admin ID for Domain Insights -->
 | 
				
			||||||
{{ with .Site.Social.facebook_admin }}<meta property="fb:admins" content="{{ . }}" />{{ end }}`)
 | 
					{{ with .Site.Social.facebook_admin }}<meta property="fb:admins" content="{{ . }}" />{{ end }}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.AddInternalTemplate("_default", "twitter_cards.html", `{{ if .IsPage }}
 | 
						t.AddInternalTemplate("", "twitter_cards.html", `{{ if .IsPage }}
 | 
				
			||||||
{{ with .Params.images }}
 | 
					{{ with .Params.images }}
 | 
				
			||||||
<!-- Twitter summary card with large image must be at least 280x150px -->
 | 
					<!-- Twitter summary card with large image must be at least 280x150px -->
 | 
				
			||||||
  <meta name="twitter:card" content="summary_large_image"/>
 | 
					  <meta name="twitter:card" content="summary_large_image"/>
 | 
				
			||||||
@@ -184,17 +184,17 @@ func (t *GoHtmlTemplate) EmbedTemplates() {
 | 
				
			|||||||
  {{ with .twitter }}<meta name="twitter:creator" content="@{{ . }}"/>{{ end }}
 | 
					  {{ with .twitter }}<meta name="twitter:creator" content="@{{ . }}"/>{{ end }}
 | 
				
			||||||
{{ end }}{{ end }}`)
 | 
					{{ end }}{{ end }}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.AddInternalTemplate("_default", "google_news.html", `{{ if .IsPage }}{{ with .Params.news_keywords }}
 | 
						t.AddInternalTemplate("", "google_news.html", `{{ if .IsPage }}{{ with .Params.news_keywords }}
 | 
				
			||||||
  <meta name="news_keywords" content="{{ range $i, $kw := first 10 . }}{{ if $i }},{{ end }}{{ $kw }}{{ end }}" />
 | 
					  <meta name="news_keywords" content="{{ range $i, $kw := first 10 . }}{{ if $i }},{{ end }}{{ $kw }}{{ end }}" />
 | 
				
			||||||
{{ end }}{{ end }}`)
 | 
					{{ end }}{{ end }}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.AddInternalTemplate("_default", "schema.html", `{{ with .Site.Social.GooglePlus }}<link rel="publisher" href="{{ . }}"/>{{ end }}
 | 
						t.AddInternalTemplate("", "schema.html", `{{ with .Site.Social.GooglePlus }}<link rel="publisher" href="{{ . }}"/>{{ end }}
 | 
				
			||||||
<meta itemprop="name" content="{{ .Title }}">
 | 
					<meta itemprop="name" content="{{ .Title }}">
 | 
				
			||||||
<meta itemprop="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}">
 | 
					<meta itemprop="description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ end }}{{ end }}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{if .IsPage}}{{ $ISO8601 := "2006-01-02T15:04:05-07:00" }}{{ if ne (.PublishDate.Format $ISO8601) "0001-01-01T00:00:00+00:00" }}
 | 
					{{if .IsPage}}{{ $ISO8601 := "2006-01-02T15:04:05-07:00" }}{{ if not .PublishDate.IsZero }}
 | 
				
			||||||
<meta itemprop="datePublished" content="{{ .PublishDate.Format $ISO8601 }}" />{{ end }}
 | 
					<meta itemprop="datePublished" content="{{ .PublishDate.Format $ISO8601 | safeHtml }}" />{{ end }}
 | 
				
			||||||
<meta itemprop="dateModified" content="{{ .Date.Format $ISO8601 }}" />
 | 
					{{ if not .Date.IsZero }}<meta itemprop="dateModified" content="{{ .Date.Format $ISO8601 | safeHtml }}" />{{ end }}
 | 
				
			||||||
<meta itemprop="wordCount" content="{{ .WordCount }}">
 | 
					<meta itemprop="wordCount" content="{{ .WordCount }}">
 | 
				
			||||||
{{ with .Params.images }}{{ range first 6 . }}
 | 
					{{ with .Params.images }}{{ range first 6 . }}
 | 
				
			||||||
  <meta itemprop="image" content="{{ . }}">
 | 
					  <meta itemprop="image" content="{{ . }}">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user