@@ -578,7 +578,12 @@ type internal DocContent
578
578
uri = model.Uri( root) }
579
579
| _ -> () |]
580
580
581
- member _.GetNavigationEntries ( input , docModels : ( string * bool * LiterateDocModel ) list ) =
581
+ member _.GetNavigationEntries
582
+ (
583
+ input ,
584
+ docModels : ( string * bool * LiterateDocModel ) list ,
585
+ currentPagePath : string option
586
+ ) =
582
587
let modelsForList =
583
588
[ for thing in docModels do
584
589
match thing with
@@ -587,12 +592,16 @@ type internal DocContent
587
592
&& model.OutputKind = OutputKind.Html
588
593
&& not ( Path.GetFileNameWithoutExtension( inputFileFullPath) = " index" )
589
594
->
590
- model
595
+ { model with
596
+ IsActive =
597
+ match currentPagePath with
598
+ | None -> false
599
+ | Some currentPagePath -> currentPagePath = inputFileFullPath }
591
600
| _ -> () ]
592
601
593
602
let modelsByCategory =
594
603
modelsForList
595
- |> List.groupBy ( fun model -> model.Category)
604
+ |> List.groupBy ( fun ( model ) -> model.Category)
596
605
|> List.sortBy ( fun ( _ , ms ) ->
597
606
match ms.[ 0 ]. CategoryIndex with
598
607
| Some s ->
@@ -602,19 +611,12 @@ type internal DocContent
602
611
Int32.MaxValue)
603
612
| None -> Int32.MaxValue)
604
613
605
- let orderList ( list : LiterateDocModel list ) =
614
+ let orderList ( list : ( LiterateDocModel ) list ) =
606
615
list
607
- |> List.sortBy ( fun model ->
608
- match model.Index with
609
- | Some s ->
610
- ( try
611
- int32 s
612
- with _ ->
613
- Int32.MaxValue)
614
- | None -> Int32.MaxValue)
616
+ |> List.sortBy ( fun model -> Option.defaultValue Int32.MaxValue model.Index)
615
617
616
618
if Menu.isTemplatingAvailable input then
617
- let createGroup ( header : string ) ( items : LiterateDocModel list ) : string =
619
+ let createGroup ( isCategoryActive : bool ) ( header : string ) ( items : LiterateDocModel list ) : string =
618
620
//convert items into menuitem list
619
621
let menuItems =
620
622
orderList items
@@ -623,18 +625,20 @@ type internal DocContent
623
625
let title = System.Web.HttpUtility.HtmlEncode model.Title
624
626
625
627
{ Menu.MenuItem.Link = link
626
- Menu.MenuItem.Content = title })
628
+ Menu.MenuItem.Content = title
629
+ Menu.MenuItem.IsActive = model.IsActive })
627
630
628
- Menu.createMenu input header menuItems
631
+ Menu.createMenu input isCategoryActive header menuItems
629
632
// No categories specified
630
633
if modelsByCategory.Length = 1 && ( fst modelsByCategory.[ 0 ]) = None then
631
634
let _ , items = modelsByCategory.[ 0 ]
632
- createGroup " Documentation" items
635
+ createGroup false " Documentation" items
633
636
else
634
637
modelsByCategory
635
638
|> List.map ( fun ( header , items ) ->
636
639
let header = Option.defaultValue " Other" header
637
- createGroup header items)
640
+ let isActive = items |> List.exists ( fun m -> m.IsActive)
641
+ createGroup isActive header items)
638
642
|> String.concat " \n "
639
643
else
640
644
[
@@ -644,22 +648,34 @@ type internal DocContent
644
648
645
649
for model in snd modelsByCategory.[ 0 ] do
646
650
let link = model.Uri( root)
651
+ let activeClass = if model.IsActive then " active" else " "
647
652
648
- li [ Class " nav-item" ] [ a [ Class " nav-link" ; ( Href link) ] [ encode model.Title ] ]
653
+ li
654
+ [ Class $" nav-item %s {activeClass}" ]
655
+ [ a [ Class " nav-link" ; ( Href link) ] [ encode model.Title ] ]
649
656
else
650
657
// At least one category has been specified. Sort each category by index and emit
651
658
// Use 'Other' as a header for uncategorised things
652
659
for ( cat, modelsInCategory) in modelsByCategory do
653
660
let modelsInCategory = orderList modelsInCategory
654
661
662
+ let categoryActiveClass =
663
+ if modelsInCategory |> List.exists ( fun m -> m.IsActive) then
664
+ " active"
665
+ else
666
+ " "
667
+
655
668
match cat with
656
- | Some c -> li [ Class " nav-header" ] [ !! c ]
657
- | None -> li [ Class " nav-header" ] [ !! " Other" ]
669
+ | Some c -> li [ Class $ " nav-header %s {categoryActiveClass} " ] [ !! c ]
670
+ | None -> li [ Class $ " nav-header %s {categoryActiveClass} " ] [ !! " Other" ]
658
671
659
672
for model in modelsInCategory do
660
673
let link = model.Uri( root)
674
+ let activeClass = if model.IsActive then " active" else " "
661
675
662
- li [ Class " nav-item" ] [ a [ Class " nav-link" ; ( Href link) ] [ encode model.Title ] ] ]
676
+ li
677
+ [ Class $" nav-item %s {activeClass}" ]
678
+ [ a [ Class " nav-link" ; ( Href link) ] [ encode model.Title ] ] ]
663
679
|> List.map ( fun html -> html.ToString())
664
680
|> String.concat " \n "
665
681
@@ -1675,12 +1691,9 @@ type CoreBuildOptions(watch) =
1675
1691
)
1676
1692
1677
1693
let docModels = docContent.Convert( this.input, defaultTemplate, extraInputs)
1678
-
1679
1694
let actualDocModels = docModels |> List.map fst |> List.choose id
1680
-
1681
1695
let extrasForSearchIndex = docContent.GetSearchIndexEntries( actualDocModels)
1682
-
1683
- let navEntries = docContent.GetNavigationEntries( this.input, actualDocModels)
1696
+ let navEntriesWithoutActivePage = docContent.GetNavigationEntries( this.input, actualDocModels, None)
1684
1697
1685
1698
let headTemplateContent =
1686
1699
let headTemplatePath = Path.Combine( this.input, " _head.html" )
@@ -1709,20 +1722,36 @@ type CoreBuildOptions(watch) =
1709
1722
latestDocContentSearchIndexEntries <- extrasForSearchIndex
1710
1723
1711
1724
latestDocContentGlobalParameters <-
1712
- [ ParamKeys.`` fsdocs-list-of-documents `` , navEntries
1725
+ [ ParamKeys.`` fsdocs-list-of-documents `` , navEntriesWithoutActivePage
1713
1726
ParamKeys.`` fsdocs-head-extra `` , headTemplateContent
1714
1727
ParamKeys.`` fsdocs-body-extra `` , bodyTemplateContent ]
1715
1728
1716
1729
latestDocContentPhase2 <-
1717
1730
( fun globals ->
1718
-
1719
1731
printfn " "
1720
1732
printfn " Write Content:"
1721
1733
1722
- for (_ thing, action) in docModels do
1723
- action globals
1724
-
1725
- ))
1734
+ for ( optDocModel, action) in docModels do
1735
+ let globals =
1736
+ match optDocModel with
1737
+ | None -> globals
1738
+ | Some( currentPagePath, _, _) ->
1739
+ // Update the nav entries with the current page doc model
1740
+ let navEntries =
1741
+ docContent.GetNavigationEntries(
1742
+ this.input,
1743
+ actualDocModels,
1744
+ Some currentPagePath
1745
+ )
1746
+
1747
+ globals
1748
+ |> List.map ( fun ( pk , v ) ->
1749
+ if pk <> ParamKeys.`` fsdocs-list-of-documents `` then
1750
+ pk, v
1751
+ else
1752
+ ParamKeys.`` fsdocs-list-of-documents `` , navEntries)
1753
+
1754
+ action globals))
1726
1755
1727
1756
let runDocContentPhase2 () =
1728
1757
protect " Content generation (phase 2)" ( fun () ->
0 commit comments