shithub: hugo

Download patch

ref: bec839e652838a1804bf0dfa3879d69fa9c1f130
parent: be0cbeee7fb9b6e8af12745971ff80e86e0d3d32
author: bep <[email protected]>
date: Mon May 11 09:59:06 EDT 2015

Add relURL template func

Fixes #1126

--- a/helpers/url.go
+++ b/helpers/url.go
@@ -151,7 +151,36 @@
 	if strings.HasPrefix(path, "http") || strings.HasPrefix(path, "//") {
 		return path
 	}
-	return MakePermalink(string(viper.GetString("BaseURL")), path).String()
+	return MakePermalink(viper.GetString("BaseURL"), path).String()
+}
+
+// RelURL creates a URL relative to the BaseURL root.
+// Note: The result URL will not include the context root if canonifyURLs is enabled.
+func RelURL(path string) string {
+	baseURL := viper.GetString("BaseURL")
+	canonifyURLs := viper.GetBool("canonifyURLs")
+	if (!strings.HasPrefix(path, baseURL) && strings.HasPrefix(path, "http")) || strings.HasPrefix(path, "//") {
+		return path
+	}
+
+	u := path
+
+	if strings.HasPrefix(path, baseURL) {
+		u = strings.TrimPrefix(u, baseURL)
+	}
+
+	if !canonifyURLs {
+		u = AddContextRoot(baseURL, u)
+	}
+	if path == "" && !strings.HasSuffix(u, "/") && strings.HasSuffix(baseURL, "/") {
+		u += "/"
+	}
+
+	if !strings.HasPrefix(u, "/") {
+		u = "/" + u
+	}
+
+	return u
 }
 
 // AddContextRoot adds the context root to an URL if it's not already set.
--- a/helpers/url_test.go
+++ b/helpers/url_test.go
@@ -49,6 +49,37 @@
 	}
 }
 
+func TestRelURL(t *testing.T) {
+	defer viper.Set("canonifyURLs", viper.GetBool("canonifyURLs"))
+	tests := []struct {
+		input    string
+		baseURL  string
+		canonify bool
+		expected string
+	}{
+		{"/test/foo", "http://base/", false, "/test/foo"},
+		{"test.css", "http://base/sub", false, "/sub/test.css"},
+		{"test.css", "http://base/sub", true, "/test.css"},
+		{"/test/", "http://base/", false, "/test/"},
+		{"/test/", "http://base/sub/", false, "/sub/test/"},
+		{"/test/", "http://base/sub/", true, "/test/"},
+		{"", "http://base/ace/", false, "/ace/"},
+		{"", "http://base/ace", false, "/ace"},
+		{"http://abs", "http://base/", false, "http://abs"},
+		{"//schemaless", "http://base/", false, "//schemaless"},
+	}
+
+	for i, test := range tests {
+		viper.Set("BaseURL", test.baseURL)
+		viper.Set("canonifyURLs", test.canonify)
+
+		output := RelURL(test.input)
+		if output != test.expected {
+			t.Errorf("[%d][%t] Expected %#v, got %#v\n", i, test.canonify, test.expected, output)
+		}
+	}
+}
+
 func TestSanitizeURL(t *testing.T) {
 	tests := []struct {
 		input    string
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -1197,6 +1197,7 @@
 		"safeCSS":     SafeCSS,
 		"safeURL":     SafeURL,
 		"absURL":      func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) },
+		"relURL":      func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
 		"markdownify": Markdownify,
 		"first":       First,
 		"where":       Where,