@@ -16,6 +16,7 @@ package hugolib
1616import (
1717 "errors"
1818 "fmt"
19+ "html/template"
1920 "os"
2021 "path"
2122 "strings"
@@ -198,6 +199,13 @@ func (h *HugoSites) Build(config BuildCfg) error {
198199
199200 t0 := time .Now ()
200201
202+ // TODO(bep) np init page collections
203+ for _ , s := range h .Sites {
204+ if s .PageCollections == nil {
205+ s .PageCollections = newPageCollections ()
206+ }
207+ }
208+
201209 if config .ResetState {
202210 h .reset ()
203211 }
@@ -220,7 +228,7 @@ func (h *HugoSites) Build(config BuildCfg) error {
220228 return err
221229 }
222230
223- h .setupTranslations ()
231+ h .setupTranslationsForRegularPages ()
224232
225233 if len (h .Sites ) > 1 {
226234 // Initialize the rest
@@ -244,8 +252,13 @@ func (h *HugoSites) Build(config BuildCfg) error {
244252 }
245253
246254 for _ , s := range h .Sites {
247- // Needed by all who use .Pages, .AllPages, .indexPages
255+ // TODO(bep) np Needed by all who use .Pages, .AllPages, .indexPages
248256 s .refreshPageCaches ()
257+ s .setupPrevNext ()
258+ }
259+
260+ if err := h .assignMissingTranslations (); err != nil {
261+ return err
249262 }
250263
251264 if err := h .preRender (config , whatChanged {source : true , other : true }); err != nil {
@@ -311,7 +324,7 @@ func (h *HugoSites) Rebuild(config BuildCfg, events ...fsnotify.Event) error {
311324 }
312325
313326 // Assign pages to sites per translation.
314- h .setupTranslations ()
327+ h .setupTranslationsForRegularPages ()
315328
316329 if changed .source {
317330 h .assembleGitInfo ()
@@ -324,6 +337,10 @@ func (h *HugoSites) Rebuild(config BuildCfg, events ...fsnotify.Event) error {
324337 if err := h .createMissingNodes (); err != nil {
325338 return err
326339 }
340+
341+ if err := h .assignMissingTranslations (); err != nil {
342+ return err
343+ }
327344 }
328345
329346 if err := h .preRender (config , changed ); err != nil {
@@ -389,95 +406,141 @@ func (h *HugoSites) render() error {
389406 return nil
390407}
391408
409+ func (h * HugoSites ) assignMissingTranslations () error {
410+ // This looks heavy, but it should be a small number of nodes by now.
411+ allNodes := h .findAllPagesByNodeTypeNotIn (NodePage )
412+ for _ , nodeType := range []NodeType {NodeHome , NodeSection , NodeTaxonomy , NodeTaxonomyTerms } {
413+ nodes := h .findPagesByNodeTypeIn (nodeType , allNodes )
414+
415+ // Assign translations
416+ for _ , t1 := range nodes {
417+ for _ , t2 := range nodes {
418+ if t2 .isTranslation (t1 ) {
419+ t1 .translations = append (t1 .translations , t2 )
420+ }
421+ }
422+ }
423+ }
424+ return nil
425+
426+ }
427+
392428// createMissingNodes creates home page, taxonomies etc. that isnt't created as an
393429// effect of having a content file.
394430func (h * HugoSites ) createMissingNodes () error {
395431 // TODO(bep) np revisit this on languages -- as this is currently run after the page language distribution (due to taxonomies)
396432 // TODO(bep) np re above, Pages vs.
397433 // TODO(bep) np check node title etc.
398- s := h .Sites [0 ]
399434
400- home := s .findPagesByNodeType (NodeHome )
401-
402- // home page
403- if len (home ) == 0 {
404- s .Nodes = append (s .Nodes , s .newHomePage ())
405- }
406-
407- // taxonomy list and terms pages
408- taxonomies := s .Language .GetStringMapString ("taxonomies" )
409- if len (taxonomies ) > 0 {
410- taxonomyPages := s .findPagesByNodeType (NodeTaxonomy )
411- taxonomyTermsPages := s .findPagesByNodeType (NodeTaxonomyTerms )
412- for _ , plural := range taxonomies {
413- tax := s .Taxonomies [plural ]
414- foundTaxonomyPage := false
415- foundTaxonomyTermsPage := false
416- for key , _ := range tax {
417- for _ , p := range taxonomyPages {
418- if p .sections [0 ] == plural && p .sections [1 ] == key {
419- foundTaxonomyPage = true
420- break
435+ var newNodes Pages
436+
437+ for _ , s := range h .Sites {
438+
439+ // home pages
440+ home := s .findPagesByNodeType (NodeHome )
441+ if len (home ) > 1 {
442+ panic ("Too many homes" )
443+ }
444+ if len (home ) == 0 {
445+ n := s .newHomePage ()
446+ s .Nodes = append (s .Nodes , n )
447+ newNodes = append (newNodes , n )
448+ }
449+
450+ // taxonomy list and terms pages
451+ taxonomies := s .Language .GetStringMapString ("taxonomies" )
452+ if len (taxonomies ) > 0 {
453+ taxonomyPages := s .findPagesByNodeType (NodeTaxonomy )
454+ taxonomyTermsPages := s .findPagesByNodeType (NodeTaxonomyTerms )
455+ for _ , plural := range taxonomies {
456+ tax := s .Taxonomies [plural ]
457+ foundTaxonomyPage := false
458+ foundTaxonomyTermsPage := false
459+ for key , _ := range tax {
460+ for _ , p := range taxonomyPages {
461+ if p .sections [0 ] == plural && p .sections [1 ] == key {
462+ foundTaxonomyPage = true
463+ break
464+ }
421465 }
422- }
423- for _ , p := range taxonomyTermsPages {
424- if p .sections [0 ] == plural {
425- foundTaxonomyTermsPage = true
426- break
466+ for _ , p := range taxonomyTermsPages {
467+ if p .sections [0 ] == plural {
468+ foundTaxonomyTermsPage = true
469+ break
470+ }
471+ }
472+ if ! foundTaxonomyPage {
473+ n := s .newTaxonomyPage (plural , key )
474+ s .Nodes = append (s .Nodes , n )
475+ newNodes = append (newNodes , n )
427476 }
428- }
429- if ! foundTaxonomyPage {
430- s .Nodes = append (s .Nodes , s .newTaxonomyPage (plural , key ))
431- }
432477
433- if ! foundTaxonomyTermsPage {
434- s .Nodes = append (s .Nodes , s .newTaxonomyTermsPage (plural ))
478+ if ! foundTaxonomyTermsPage {
479+ foundTaxonomyTermsPage = true
480+ n := s .newTaxonomyTermsPage (plural )
481+ s .Nodes = append (s .Nodes , n )
482+ newNodes = append (newNodes , n )
483+ }
435484 }
436485 }
437-
438486 }
439- }
440487
441- // sections
442- sectionPages := s .findPagesByNodeType (NodeSection )
443- if len (sectionPages ) < len (s .Sections ) {
444- for name , section := range s .Sections {
445- foundSection := false
446- for _ , sectionPage := range sectionPages {
447- if sectionPage .sections [0 ] == name {
448- foundSection = true
449- break
488+ sectionPages := s .findPagesByNodeType (NodeSection )
489+ if len (sectionPages ) < len (s .Sections ) {
490+ for name , section := range s .Sections {
491+ foundSection := false
492+ for _ , sectionPage := range sectionPages {
493+ if sectionPage .sections [0 ] == name {
494+ foundSection = true
495+ break
496+ }
497+ }
498+ if ! foundSection {
499+ n := s .newSectionPage (name , section )
500+ s .Nodes = append (s .Nodes , n )
501+ newNodes = append (newNodes , n )
450502 }
451- }
452- if ! foundSection {
453- s .Nodes = append (s .Nodes , s .newSectionPage (name , section ))
454503 }
455504 }
456505 }
457506
507+ if len (newNodes ) > 0 {
508+ first := h .Sites [0 ]
509+ first .AllNodes = append (first .AllNodes , newNodes ... )
510+ for i := 1 ; i < len (h .Sites ); i ++ {
511+ h .Sites [i ].AllNodes = first .AllNodes
512+ }
513+ }
458514 return nil
459515}
460516
461517// Move the new* methods after cleanup in site.go
462518func (s * Site ) newNodePage (typ NodeType ) * Page {
463- n := Node {
519+
520+ return & Page {Node : Node {
464521 NodeType : typ ,
465522 Data : make (map [string ]interface {}),
466523 Site : & s .Info ,
467524 language : s .Language ,
468- }
469-
470- return & Page {Node : n , site : s }
525+ }, site : s }
471526}
472527
473528func (s * Site ) newHomePage () * Page {
474529 p := s .newNodePage (NodeHome )
475530 p .Title = s .Info .Title
531+ p .Data ["Pages" ] = Pages {}
532+ s .setPageURLs (p , "/" )
476533 // TODO(bep) np check Data pages
477534 // TODO(bep) np check setURLs
478535 return p
479536}
480537
538+ func (s * Site ) setPageURLs (p * Page , in string ) {
539+ p .URLPath .URL = s .Info .pathSpec .URLizeAndPrep (in )
540+ p .URLPath .Permalink = s .Info .permalink (p .URLPath .URL )
541+ p .RSSLink = template .HTML (s .Info .permalink (in + ".xml" ))
542+ }
543+
481544func (s * Site ) newTaxonomyPage (plural , key string ) * Page {
482545
483546 p := s .newNodePage (NodeTaxonomy )
@@ -495,8 +558,7 @@ func (s *Site) newTaxonomyPage(plural, key string) *Page {
495558 p .Title = strings .Replace (strings .Title (key ), "-" , " " , - 1 )
496559 }
497560
498- // TODO(bep) np check set url
499- p .URLPath .URL = path .Join (plural , key )
561+ s .setPageURLs (p , path .Join (plural , key ))
500562
501563 return p
502564}
@@ -517,7 +579,7 @@ func (s *Site) newSectionPage(name string, section WeightedPages) *Page {
517579 } else {
518580 p .Title = sectionName
519581 }
520- p . URLPath . URL = name
582+ s . setPageURLs ( p , name )
521583 return p
522584}
523585
@@ -528,11 +590,13 @@ func (s *Site) newTaxonomyTermsPage(plural string) *Page {
528590 return p
529591}
530592
531- func (h * HugoSites ) setupTranslations () {
593+ func (h * HugoSites ) setupTranslationsForRegularPages () {
532594
533595 master := h .Sites [0 ]
534596
535- for _ , p := range master .rawAllPages {
597+ regularPages := master .rawAllPages // master.findRawAllPagesByNodeType(NodePage)
598+
599+ for _ , p := range regularPages {
536600 if p .Lang () == "" {
537601 panic ("Page language missing: " + p .Title )
538602 }
@@ -733,13 +797,24 @@ func (s *Site) updateBuildStats(page *Page) {
733797
734798// TODO(bep) np remove
735799func (h * HugoSites ) findAllPagesByNodeType (n NodeType ) Pages {
736- var pages Pages
737- for _ , p := range h .Sites [0 ].AllNodes {
738- if p .NodeType == n {
739- pages = append (pages , p )
740- }
741- }
742- return pages
800+ return h .Sites [0 ].findAllPagesByNodeType (n )
801+ }
802+
803+ func (h * HugoSites ) findPagesByNodeTypeNotIn (n NodeType , inPages Pages ) Pages {
804+ return h .Sites [0 ].findPagesByNodeTypeNotIn (n , inPages )
805+ }
806+
807+ func (h * HugoSites ) findPagesByNodeTypeIn (n NodeType , inPages Pages ) Pages {
808+ return h .Sites [0 ].findPagesByNodeTypeIn (n , inPages )
809+ }
810+
811+ func (h * HugoSites ) findAllPagesByNodeTypeNotIn (n NodeType ) Pages {
812+ return h .findPagesByNodeTypeNotIn (n , h .Sites [0 ].AllNodes )
813+ }
814+
815+ func (h * HugoSites ) findRawAllPagesByNodeType (n NodeType ) Pages {
816+ return h .Sites [0 ].findRawAllPagesByNodeType (n )
817+
743818}
744819
745820// Convenience func used in tests to build a single site/language excluding render phase.
0 commit comments