Skip to content

Commit 714bc30

Browse files
authored
refactoring sidebar highlighting and allowing collapsed subsecti… (jupyter-book#412)
refactoring sidebar highlighting and allowing collapsed subsections
2 parents 51b61f1 + d41485f commit 714bc30

File tree

6 files changed

+147
-111
lines changed

6 files changed

+147
-111
lines changed

jupyter_book/book_template/Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ GEM
4343
formatador (0.2.5)
4444
forwardable-extended (2.6.0)
4545
gemoji (3.0.1)
46-
github-pages (201)
46+
github-pages (202)
4747
activesupport (= 4.2.11.1)
4848
github-pages-health-check (= 1.16.1)
4949
jekyll (= 3.8.5)
@@ -244,7 +244,7 @@ GEM
244244
jekyll (~> 3.5)
245245
jekyll-feed (~> 0.9)
246246
jekyll-seo-tag (~> 2.1)
247-
minitest (5.12.2)
247+
minitest (5.13.0)
248248
multi_json (1.14.1)
249249
multipart-post (2.1.1)
250250
namae (1.0.1)

jupyter_book/book_template/_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ footer_text : This page was created by <a href="https://github.com
3535
# Sidebar settings
3636
show_sidebar : true # Show the sidebar. Only set to false if your only wish to host a single page.
3737
collapse_inactive_chapters: true # Whether to collapse the inactive chapters in the sidebar
38+
collapse_inactive_sections: true # Whether to collapse the sub-sections within a non-active section in the sidebar
3839
textbook_logo : images/logo/logo.png # A logo to be displayed at the top of your textbook sidebar. Should be square
3940
textbook_logo_link : https://jupyterbook.org/intro.html # A link for the logo.
4041
sidebar_footer_text : 'Powered by <a href="https://jupyterbook.org">Jupyter Book</a>'

jupyter_book/book_template/_data/toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- url: /guide/02_create
2929
- url: /guide/03_build
3030
- url: /guide/04_publish
31+
expand_subsections: false
3132
subsections:
3233
- url: /guide/publish/book-html
3334
not_numbered: true

jupyter_book/book_template/_includes/sidebar.html

Lines changed: 87 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -42,130 +42,111 @@ <h2 class="c-sidebar__title">{{ site.title }}</h2>
4242
{%- endfor %}
4343
{% if chapter.external == true %}{% assign chapter_title = chapter.title %}{% endif %}
4444

45-
{% comment %}
46-
If the entry is the current page, assign a CSS class to highlight it.
47-
{% endcomment %}
48-
{% if page.url contains chapter.url %}
49-
{% assign active_class = "c-sidebar__entry--active" %}
50-
{% else %}
51-
{% assign active_class = "" %}
52-
{% endif %}
53-
5445
{% assign topUrl = chapter.url | relative_url %}
5546
{% unless chapter.external == true %}
5647
{% assign topUrl = topUrl | append: '.html' %}
5748
{% endunless %}
58-
<li class="c-sidebar__chapter">
59-
<a class="c-sidebar__entry {{ active_class }}"
49+
<li class="c-sidebar__chapter" data-url="{{ chapter.url }}">
50+
<a class="c-sidebar__entry"
6051
href="{{ topUrl }}"
6152
>
6253
{% unless chapter.not_numbered or site.number_toc_chapters != true %}
6354
{{ chapter_num }}.
6455
{% endunless %}
6556
{{ chapter_title }}
6657
</a>
58+
</li>
59+
60+
{% comment %}
61+
Flags for whether we hide all inactive sections or sub-sections
62+
{% endcomment %}
63+
{% if site.collapse_inactive_chapters == true %}
64+
{% assign sectionsHideClass = " u-hidden-visually" %}
65+
{% else %}
66+
{% assign sectionsHideClass = "" %}
67+
{% endif %}
68+
69+
{% if site.collapse_inactive_sections == true %}
70+
{% assign subSectionsHideClass = " u-hidden-visually" %}
71+
{% else %}
72+
{% assign subSectionsHideClass = "" %}
73+
{% endif %}
6774

68-
{% if chapter.sections %}
75+
{% comment %}Per-chapter overrides from TOC data{% endcomment %}
76+
{% if chapter.expand_sections == true %}
77+
{% assign sectionsHideClass = "" %}
78+
{% endif %}
79+
80+
{% if chapter.sections %}
81+
{% comment %}
82+
By default, all sections are hidden. We show a chapter's sections
83+
if the chapter or any of its sections are the current page.
84+
{% endcomment %}
6985

70-
{% comment %}
71-
By default, all sections are hidden. We show a chapter's sections
72-
if the chapter or any of its sections are the current page.
73-
{% endcomment %}
74-
{% assign any_section_active = 0 %}
86+
{% assign section_num = 1 %}
87+
88+
<ul class="c-sidebar__sections{{ sectionsHideClass }}">
7589
{% for section in chapter.sections %}
76-
{% if page.url contains section.url or chapter.expand_sections %}
77-
{% assign any_section_active = 1 %}
78-
{% elsif section.subsections %}
90+
{% comment %}Per-section overrides from TOC data{% endcomment %}
91+
{% if section.expand_subsections == true %}
92+
{% assign subSectionsHideClass = "" %}
93+
{% endif %}
94+
95+
{% comment %}
96+
Find the title for this chapter
97+
{% endcomment %}
98+
{% assign section_url_html = section.url | append: '.html' %}
99+
{% for build_page in site.build %}
100+
{% if build_page.url == section_url_html %}
101+
{% assign section_title = build_page.title %}
102+
{% endif %}
103+
{%- endfor %}
104+
{% if section.external == true %}{% assign section_title = section.title %}{% endif %}
105+
106+
<li class="c-sidebar__section" data-url="{{ section.url }}">
107+
<a class="c-sidebar__entry"
108+
href="{{ section.url | relative_url | append: '.html'}}"
109+
>
110+
{% unless chapter.not_numbered or section.not_numbered or site.number_toc_chapters != true %}
111+
{{ chapter_num }}.{{ section_num }}
112+
{% endunless %}
113+
{{ section_title }}
114+
</a>
115+
</li>
116+
{% if section.subsections %}
117+
{% assign subsection_num = 1 %}
118+
<ul class='c-sidebar__subsections{{ subSectionsHideClass }}'>
79119
{% for subsection in section.subsections %}
80-
{% if page.url contains subsection.url %}
81-
{% assign any_section_active = 1 %}
82-
{% endif %}
120+
{% comment %}
121+
Find the title for this sub-section
122+
{% endcomment %}
123+
{% assign subsection_url_html = subsection.url | append: '.html' %}
124+
{% for build_page in site.build %}
125+
{% if build_page.url == subsection_url_html %}
126+
{% assign subsection_title = build_page.title %}
127+
{% endif %}
128+
{%- endfor %}
129+
{% if subsection.external == true %}{% assign subsection_title = subsection.title %}{% endif %}
130+
<li class="c-sidebar__subsection" data-url="{{ subsection.url }}">
131+
<a class="c-sidebar__entry"
132+
href="{{ subsection.url | relative_url | append: '.html'}}"
133+
>
134+
{% unless chapter.not_numbered or section.not_numbered or subsection.not_numbered or site.number_toc_chapters != true %}
135+
{{ chapter_num }}.{{ section_num }}.{{ subsection_num }}
136+
{% assign subsection_num = subsection_num | plus: 1 %}
137+
{% endunless %}
138+
{{ subsection_title }}
139+
</a>
140+
</li>
83141
{% endfor %}
84-
{% elsif page.url contains chapter.url %}
85-
{% assign any_section_active = 1 %}
142+
</ul>
86143
{% endif %}
144+
{% unless chapter.not_numbered or section.not_numbered %}
145+
{% assign section_num = section_num | plus: 1 %}
146+
{% endunless %}
87147
{% endfor %}
88-
{% if any_section_active > 0 or site.collapse_inactive_chapters == false %}
89-
{% assign hide_section_class = "" %}
90-
{% else %}
91-
{% assign hide_section_class = "u-hidden-visually" %}
92-
{% endif %}
93-
94-
{% assign section_num = 1 %}
95-
96-
<ul class="c-sidebar__sections {{ hide_section_class }}">
97-
{% for section in chapter.sections %}
98-
{% comment %}
99-
If the entry is the current page, assign a CSS class to highlight
100-
it.
101-
{% endcomment %}
102-
{% if page.url contains section.url %}
103-
{% assign active_class = "c-sidebar__entry--active" %}
104-
{% else %}
105-
{% assign active_class = "" %}
106-
{% endif %}
107-
108-
{% comment %}
109-
Find the title for this section
110-
{% endcomment %}
111-
{% assign section_url_html = section.url | append: '.html' %}
112-
{% for build_page in site.build %}
113-
{% if build_page.url == section_url_html %}
114-
{% assign section_title = build_page.title %}
115-
{% endif %}
116-
{%- endfor %}
117-
{% if section.external == true %}{% assign section_title = section.title %}{% endif %}
118-
<li class="c-sidebar__section">
119-
<a class="c-sidebar__entry {{ active_class }}"
120-
href="{{ section.url | relative_url | append: '.html'}}"
121-
>
122-
{% unless chapter.not_numbered or section.not_numbered or site.number_toc_chapters != true %}
123-
{{ chapter_num }}.{{ section_num }}
124-
{% endunless %}
125-
{{ section_title }}
126-
</a>
127-
128-
{% assign subsection_num = 1 %}
129-
{% for subsection in section.subsections %}
130-
{% comment %}
131-
Now add sub-sections. These will always be shown if they exist.
132-
{% endcomment %}
133-
{% if page.url contains subsection.url %}
134-
{% assign active_class = "c-sidebar__entry--active" %}
135-
{% else %}
136-
{% assign active_class = "" %}
137-
{% endif %}
138-
139-
{% comment %}
140-
Find the title for this sub-section
141-
{% endcomment %}
142-
{% assign subsection_url_html = subsection.url | append: '.html' %}
143-
{% for build_page in site.build %}
144-
{% if build_page.url == subsection_url_html %}
145-
{% assign subsection_title = build_page.title %}
146-
{% endif %}
147-
{%- endfor %}
148-
{% if subsection.external == true %}{% assign subsection_title = subsection.title %}{% endif %}
149-
<li class="c-sidebar__subsection">
150-
<a class="c-sidebar__entry {{ active_class }}"
151-
href="{{ subsection.url | relative_url | append: '.html'}}"
152-
>
153-
{% unless chapter.not_numbered or section.not_numbered or subsection.not_numbered or site.number_toc_chapters != true %}
154-
{{ chapter_num }}.{{ section_num }}.{{ subsection_num }}
155-
{% assign subsection_num = subsection_num | plus: 1 %}
156-
{% endunless %}
157-
{{ subsection_title }}
158-
</a>
159-
{% endfor %}
160-
161-
</li>
162-
{% unless chapter.not_numbered or section.not_numbered %}
163-
{% assign section_num = section_num | plus: 1 %}
164-
{% endunless %}
165-
{% endfor %}
166-
</ul>
167-
{% endif %}
168-
</li>
148+
</ul>
149+
{% endif %}
169150

170151
{% unless chapter.not_numbered %}
171152
{% assign chapter_num = chapter_num | plus: 1 %}

jupyter_book/book_template/_sass/components/_components.page__onthispage.scss

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,16 @@ li.c-sidebar__chapter > a {
4242
}
4343

4444
/* [1] */
45-
.c-sidebar__sections {
45+
.c-sidebar__sections, .c-sidebar__subsections {
4646
list-style: none;
47-
margin-left: $spacing-unit-small;
4847
margin-bottom: 0;
4948
}
5049

51-
li.c-sidebar__subsection {
50+
.c-sidebar__sections {
51+
margin-left: $spacing-unit-small;
52+
}
53+
54+
.c-sidebar__subsections {
5255
margin-left: 20px;
5356
}
5457

jupyter_book/book_template/assets/js/scripts.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,53 @@ initScrollFunc = function() {
188188
}
189189

190190
initFunction(initScrollFunc);
191+
192+
193+
/**
194+
* [6] Left sidebar highlight
195+
* Loop through the left sidebar links and show / highlight the relevant ones
196+
*/
197+
198+
var updateSidebar = () => {
199+
var currentUrl = window.location.href;
200+
var chapters = document.querySelector('ul.c-sidebar__chapters')
201+
chapters.querySelectorAll('li.c-sidebar__chapter').forEach((chapter, index) => {
202+
var sections = chapter.nextElementSibling;
203+
if (currentUrl.endsWith(chapter.dataset.url + '.html')) {
204+
chapter.querySelector('a').classList.add('c-sidebar__entry--active')
205+
if (sections.classList.contains('c-sidebar__sections')) {
206+
sections.classList.remove('u-hidden-visually');
207+
}
208+
}
209+
210+
// Loop through sections to highlight as needed
211+
if (sections) {
212+
sections.querySelectorAll('li.c-sidebar__section').forEach((section, ix_section) => {
213+
var subsections = section.nextElementSibling;
214+
215+
// If we're in a top-level section page, show the section
216+
if (currentUrl.endsWith(section.dataset.url + '.html')) {
217+
section.querySelector('a').classList.add('c-sidebar__entry--active');
218+
sections.classList.remove('u-hidden-visually');
219+
220+
// If we have subsections, show them if we've clicked the parent section
221+
if (subsections.classList.contains('c-sidebar__subsections')) {
222+
subsections.classList.remove('u-hidden-visually');
223+
}
224+
}
225+
226+
// Loop through subections to highlight if needed
227+
if (subsections) {
228+
subsections.querySelectorAll('li.c-sidebar__subsection').forEach((subsection, ix_subsection) => {
229+
if (currentUrl.endsWith(subsection.dataset.url + '.html')) {
230+
subsection.querySelector('a').classList.add('c-sidebar__entry--active');
231+
sections.classList.remove('u-hidden-visually');
232+
subsections.classList.remove('u-hidden-visually');
233+
}
234+
})
235+
}
236+
})
237+
}
238+
});
239+
}
240+
initFunction(updateSidebar);

0 commit comments

Comments
 (0)