From be38acdce7bd74b749929c4360c4099a80a774d7 Mon Sep 17 00:00:00 2001 From: bep Date: Sun, 31 May 2015 20:30:53 +0200 Subject: [PATCH] Add PreserveTaxonomyNames flag Before this commit, taxonomy names were hyphenated, lower-cased and normalized -- then fixed and titleized on the archive page. So what you entered in the front matter isn't necessarily what you got in the final site. To preserve backwards compability, `PreserveTaxonomyNames` is default `false`. Setting it to `true` will preserve what you type (the first characters is made toupper for titles), but normalized in URLs. This also means that, if you manually construct URLs to the archive pages, you will have to pass the Taxonomy names through the `urlize` func. Fixes #1180 --- commands/hugo.go | 11 ++++- hugolib/page.go | 14 ++++++- hugolib/site.go | 99 +++++++++++++++++++++++++-------------------- hugolib/taxonomy.go | 6 ++- 4 files changed, 80 insertions(+), 50 deletions(-) diff --git a/commands/hugo.go b/commands/hugo.go index ce38f1cbf..2b0250965 100644 --- a/commands/hugo.go +++ b/commands/hugo.go @@ -57,7 +57,7 @@ Complete documentation is available at http://gohugo.io`, var hugoCmdV *cobra.Command //Flags that are to be added to commands. -var BuildWatch, IgnoreCache, Draft, Future, UglyURLs, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, PluralizeListTitles, NoTimes bool +var BuildWatch, IgnoreCache, Draft, Future, UglyURLs, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, PluralizeListTitles, PreserveTaxonomyNames, NoTimes bool var Source, CacheDir, Destination, Theme, BaseURL, CfgFile, LogFile, Editor string //Execute adds all child commands to the root command HugoCmd and sets flags appropriately. @@ -102,6 +102,8 @@ func init() { HugoCmd.PersistentFlags().BoolVar(&VerboseLog, "verboseLog", false, "verbose logging") HugoCmd.PersistentFlags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program") HugoCmd.PersistentFlags().BoolVar(&PluralizeListTitles, "pluralizeListTitles", true, "Pluralize titles in lists using inflect") + HugoCmd.PersistentFlags().BoolVar(&PreserveTaxonomyNames, "preserveTaxonomyNames", false, `Preserve taxonomy names as written ("GĂ©rard Depardieu" vs "gerard-depardieu")`) + HugoCmd.Flags().BoolVarP(&BuildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") HugoCmd.Flags().BoolVarP(&NoTimes, "noTimes", "", false, "Don't sync modification time of files") hugoCmdV = HugoCmd @@ -147,6 +149,7 @@ func LoadDefaultSettings() { viper.SetDefault("PygmentsUseClasses", false) viper.SetDefault("DisableLiveReload", false) viper.SetDefault("PluralizeListTitles", true) + viper.SetDefault("PreserveTaxonomyNames", false) viper.SetDefault("FootnoteAnchorPrefix", "") viper.SetDefault("FootnoteReturnLinkContents", "") viper.SetDefault("NewContentEditor", "") @@ -189,7 +192,7 @@ func InitializeConfig() { if hugoCmdV.PersistentFlags().Lookup("disableSitemap").Changed { viper.Set("DisableSitemap", DisableSitemap) } - + if hugoCmdV.PersistentFlags().Lookup("verbose").Changed { viper.Set("Verbose", Verbose) } @@ -198,6 +201,10 @@ func InitializeConfig() { viper.Set("PluralizeListTitles", PluralizeListTitles) } + if hugoCmdV.PersistentFlags().Lookup("preserveTaxonomyNames").Changed { + viper.Set("PreserveTaxonomyNames", PreserveTaxonomyNames) + } + if hugoCmdV.PersistentFlags().Lookup("editor").Changed { viper.Set("NewContentEditor", Editor) } diff --git a/hugolib/page.go b/hugolib/page.go index 4abc09c58..1f895cdcc 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -539,6 +539,10 @@ func (p *Page) update(f interface{}) error { } func (p *Page) GetParam(key string) interface{} { + return p.getParam(key, true) +} + +func (p *Page) getParam(key string, stringToLower bool) interface{} { v := p.Params[strings.ToLower(key)] if v == nil { @@ -549,7 +553,10 @@ func (p *Page) GetParam(key string) interface{} { case bool: return cast.ToBool(v) case string: - return strings.ToLower(cast.ToString(v)) + if stringToLower { + return strings.ToLower(cast.ToString(v)) + } + return cast.ToString(v) case int64, int32, int16, int8, int: return cast.ToInt(v) case float64, float32: @@ -557,7 +564,10 @@ func (p *Page) GetParam(key string) interface{} { case time.Time: return cast.ToTime(v) case []string: - return helpers.SliceToLower(v.([]string)) + if stringToLower { + return helpers.SliceToLower(v.([]string)) + } + return v.([]string) case map[string]interface{}: // JSON and TOML return v case map[interface{}]interface{}: // YAML diff --git a/hugolib/site.go b/hugolib/site.go index a11b52de4..0a1e2090e 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -93,27 +93,28 @@ type targetList struct { } type SiteInfo struct { - BaseURL template.URL - Taxonomies TaxonomyList - Authors AuthorList - Social SiteSocial - Sections Taxonomy - Pages *Pages - Files []*source.File - Menus *Menus - Hugo *HugoInfo - Title string - Author map[string]interface{} - LanguageCode string - DisqusShortname string - Copyright string - LastChange time.Time - Permalinks PermalinkOverrides - Params map[string]interface{} - BuildDrafts bool - canonifyURLs bool - paginationPageCount uint64 - Data *map[string]interface{} + BaseURL template.URL + Taxonomies TaxonomyList + Authors AuthorList + Social SiteSocial + Sections Taxonomy + Pages *Pages + Files []*source.File + Menus *Menus + Hugo *HugoInfo + Title string + Author map[string]interface{} + LanguageCode string + DisqusShortname string + Copyright string + LastChange time.Time + Permalinks PermalinkOverrides + Params map[string]interface{} + BuildDrafts bool + canonifyURLs bool + preserveTaxonomyNames bool + paginationPageCount uint64 + Data *map[string]interface{} } // SiteSocial is a place to put social details on a site level. These are the @@ -465,19 +466,20 @@ func (s *Site) initializeSiteInfo() { } s.Info = SiteInfo{ - BaseURL: template.URL(helpers.SanitizeURLKeepTrailingSlash(viper.GetString("BaseURL"))), - Title: viper.GetString("Title"), - Author: viper.GetStringMap("author"), - LanguageCode: viper.GetString("languagecode"), - Copyright: viper.GetString("copyright"), - DisqusShortname: viper.GetString("DisqusShortname"), - BuildDrafts: viper.GetBool("BuildDrafts"), - canonifyURLs: viper.GetBool("CanonifyURLs"), - Pages: &s.Pages, - Menus: &s.Menus, - Params: params, - Permalinks: permalinks, - Data: &s.Data, + BaseURL: template.URL(helpers.SanitizeURLKeepTrailingSlash(viper.GetString("BaseURL"))), + Title: viper.GetString("Title"), + Author: viper.GetStringMap("author"), + LanguageCode: viper.GetString("languagecode"), + Copyright: viper.GetString("copyright"), + DisqusShortname: viper.GetString("DisqusShortname"), + BuildDrafts: viper.GetBool("BuildDrafts"), + canonifyURLs: viper.GetBool("CanonifyURLs"), + preserveTaxonomyNames: viper.GetBool("PreserveTaxonomyNames"), + Pages: &s.Pages, + Menus: &s.Menus, + Params: params, + Permalinks: permalinks, + Data: &s.Data, } } @@ -833,21 +835,20 @@ func (s *Site) assembleTaxonomies() { for _, plural := range taxonomies { s.Taxonomies[plural] = make(Taxonomy) for _, p := range s.Pages { - vals := p.GetParam(plural) + vals := p.getParam(plural, !s.Info.preserveTaxonomyNames) weight := p.GetParam(plural + "_weight") if weight == nil { weight = 0 } - if vals != nil { if v, ok := vals.([]string); ok { for _, idx := range v { x := WeightedPage{weight.(int), p} - s.Taxonomies[plural].Add(idx, x) + s.Taxonomies[plural].Add(idx, x, s.Info.preserveTaxonomyNames) } } else if v, ok := vals.(string); ok { x := WeightedPage{weight.(int), p} - s.Taxonomies[plural].Add(v, x) + s.Taxonomies[plural].Add(v, x, s.Info.preserveTaxonomyNames) } else { jww.ERROR.Printf("Invalid %s in %s\n", plural, p.File.Path()) } @@ -864,7 +865,7 @@ func (s *Site) assembleTaxonomies() { func (s *Site) assembleSections() { for i, p := range s.Pages { - s.Sections.Add(p.Section(), WeightedPage{s.Pages[i].Weight, s.Pages[i]}) + s.Sections.Add(p.Section(), WeightedPage{s.Pages[i].Weight, s.Pages[i]}, s.Info.preserveTaxonomyNames) } for k := range s.Sections { @@ -1058,9 +1059,16 @@ func (s *Site) RenderTaxonomiesLists() error { } func (s *Site) newTaxonomyNode(t taxRenderInfo) (*Node, string) { - base := t.plural + "/" + t.key + key := t.key n := s.NewNode() - n.Title = strings.Replace(strings.Title(t.key), "-", " ", -1) + if s.Info.preserveTaxonomyNames { + key = helpers.MakePathToLower(key) + // keep as is, just make sure the first char is upper + n.Title = helpers.FirstUpper(t.key) + } else { + n.Title = strings.Replace(strings.Title(t.key), "-", " ", -1) + } + base := t.plural + "/" + key s.setURLs(n, base) if len(t.pages) > 0 { n.Date = t.pages[0].Page.Date @@ -1179,16 +1187,19 @@ func (s *Site) newSectionListNode(sectionName, section string, data WeightedPage // RenderSectionLists renders a page for each section func (s *Site) RenderSectionLists() error { for section, data := range s.Sections { - - // section keys are lower case + // section keys can be lower case (depending on site.pathifyTaxonomyKeys) // extract the original casing from the first page to get sensible titles. sectionName := section - if len(data) > 0 { + if !s.Info.preserveTaxonomyNames && len(data) > 0 { sectionName = data[0].Page.Section() } layouts := s.appendThemeTemplates( []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}) + if s.Info.preserveTaxonomyNames { + section = helpers.MakePathToLower(section) + } + n := s.newSectionListNode(sectionName, section, data) if err := s.renderAndWritePage(fmt.Sprintf("section %s", section), section, n, s.appendThemeTemplates(layouts)...); err != nil { return err diff --git a/hugolib/taxonomy.go b/hugolib/taxonomy.go index 1cab1a1eb..22cdfbbb3 100644 --- a/hugolib/taxonomy.go +++ b/hugolib/taxonomy.go @@ -65,8 +65,10 @@ func kp(in string) string { func (i Taxonomy) Get(key string) WeightedPages { return i[kp(key)] } func (i Taxonomy) Count(key string) int { return len(i[kp(key)]) } -func (i Taxonomy) Add(key string, w WeightedPage) { - key = kp(key) +func (i Taxonomy) Add(key string, w WeightedPage, pretty bool) { + if !pretty { + key = kp(key) + } i[key] = append(i[key], w) }