Repository: gohugoio/hugo (language: go)

Issue:
Add a "none" config option for titleCaseStyle
The [`title`](https://gohugo.io/functions/title/) is great for people who always hesitate about how to capitalize English titles.

However, it only proposes English-style capitalizations. Some languages (as French) don't have such conventions and write titles without capitalizations.

If `title` is used in a theme, it will result in titles being wrongly capitalized in such languages.

Adding a setting that makes `title` a no-op function seems to be the easiest way to address this issue: when the proposed settings don't match the conventions of the language, the webmaster can choose the "none" setting and manually capitalize the titles.

Reference for `titleCaseStyle`: https://gohugo.io/getting-started/configuration/#configure-title-case


Discussion / hints:
Yes, that is a great idea.

I suggest we use `none`.

Maybe it would also be good to have a very simple `firstupper` style as well, which I suspect would make sense at least in Norwegian (my native language).


Fix patch:
diff --git a/docs/content/en/getting-started/configuration.md b/docs/content/en/getting-started/configuration.md
index 05465967ae6..477edc1c488 100644
--- a/docs/content/en/getting-started/configuration.md
+++ b/docs/content/en/getting-started/configuration.md
@@ -623,7 +623,13 @@ status = 404
 
 Set `titleCaseStyle` to specify the title style used by the [title](/functions/title/) template function and the automatic section titles in Hugo. 
 
-By default, Hugo adheres to the capitalization rules in the [Associated Press (AP) Stylebook]. Set `titleCaseStyle` to `chicago` if you would prefer to follow the [Chicago Manual of Style], or set if to `go` to use Go's convention of capitalizing every word.
+Can be one of:
+
+* `ap` (default),  the capitalization rules in the [Associated Press (AP) Stylebook]
+* `chicago`, the [Chicago Manual of Style]
+* `go`, Go's convention of capitalizing every word.
+* `firstupper`, capitalize the first letter of the first word.
+* `none`, no capitalization.
 
 [Associated Press (AP) Stylebook]: https://www.apstylebook.com/
 [Chicago Manual of Style]: https://www.chicagomanualofstyle.org/home.html
diff --git a/helpers/general.go b/helpers/general.go
index d476b912563..f8f273397dd 100644
--- a/helpers/general.go
+++ b/helpers/general.go
@@ -205,6 +205,8 @@ func ReaderContains(r io.Reader, subslice []byte) bool {
 // - "Go" (strings.Title)
 // - "AP" (see https://www.apstylebook.com/)
 // - "Chicago" (see http://www.chicagomanualofstyle.org/home.html)
+// - "FirstUpper" (only the first character is upper case)
+// - "None" (no transformation)
 //
 // If an unknown or empty style is provided, AP style is what you get.
 func GetTitleFunc(style string) func(s string) string {
@@ -214,6 +216,10 @@ func GetTitleFunc(style string) func(s string) string {
 	case "chicago":
 		tc := transform.NewTitleConverter(transform.ChicagoStyle)
 		return tc.Title
+	case "none":
+		return func(s string) string { return s }
+	case "firstupper":
+		return FirstUpper
 	default:
 		tc := transform.NewTitleConverter(transform.APStyle)
 		return tc.Title


Test patch:
diff --git a/helpers/general_test.go b/helpers/general_test.go
index 82741102724..1463458fa4f 100644
--- a/helpers/general_test.go
+++ b/helpers/general_test.go
@@ -203,7 +203,7 @@ func TestReaderContains(t *testing.T) {
 }
 
 func TestGetTitleFunc(t *testing.T) {
-	title := "somewhere over the rainbow"
+	title := "somewhere over the Rainbow"
 	c := qt.New(t)
 
 	c.Assert(helpers.GetTitleFunc("go")(title), qt.Equals, "Somewhere Over The Rainbow")
@@ -213,6 +213,8 @@ func TestGetTitleFunc(t *testing.T) {
 	c.Assert(helpers.GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
 	c.Assert(helpers.GetTitleFunc("")(title), qt.Equals, "Somewhere Over the Rainbow")
 	c.Assert(helpers.GetTitleFunc("unknown")(title), qt.Equals, "Somewhere Over the Rainbow")
+	c.Assert(helpers.GetTitleFunc("none")(title), qt.Equals, title)
+	c.Assert(helpers.GetTitleFunc("firstupper")(title), qt.Equals, "Somewhere over the Rainbow")
 }
 
 func BenchmarkReaderContains(b *testing.B) {