Skip to content

Commit ff5e85a

Browse files
committed
Replace navigation helpers with objects
This replaces the `{{#previous}}` and `{{#next}}` handelbars helpers with simple objects that contain the previous and next values. These helpers have been a bit fussy to work with and have caused issues in the past. This drops a large amount of somewhat fragile code with something that is a bit simpler. Additionally, this switches the previous/next arrows to use an `{{#if}}` instead CSS trickery which may help with upcoming changes to font-awesome.
1 parent c1b631d commit ff5e85a

File tree

6 files changed

+72
-366
lines changed

6 files changed

+72
-366
lines changed

crates/mdbook-html/front-end/css/chrome.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,6 @@ html:not(.js) .left-buttons button {
186186
left: var(--page-padding);
187187
}
188188

189-
/* Use the correct buttons for RTL layouts*/
190-
[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
191-
[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
192-
193189
@media only screen and (max-width: 1080px) {
194190
.nav-wide-wrapper { display: none; }
195191
.nav-wrapper { display: block; }

crates/mdbook-html/front-end/templates/index.hbs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -221,35 +221,51 @@
221221

222222
<nav class="nav-wrapper" aria-label="Page navigation">
223223
<!-- Mobile navigation buttons -->
224-
{{#previous}}
225-
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
224+
{{#if previous}}
225+
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
226+
{{#if (eq ../text_direction "rtl")}}
227+
<i class="fa fa-angle-right"></i>
228+
{{else}}
226229
<i class="fa fa-angle-left"></i>
230+
{{/if}}
227231
</a>
228-
{{/previous}}
232+
{{/if}}
229233

230-
{{#next}}
231-
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
234+
{{#if next}}
235+
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
236+
{{#if (eq ../text_direction "rtl")}}
237+
<i class="fa fa-angle-left"></i>
238+
{{else}}
232239
<i class="fa fa-angle-right"></i>
240+
{{/if}}
233241
</a>
234-
{{/next}}
242+
{{/if}}
235243

236244
<div style="clear: both"></div>
237245
</nav>
238246
</div>
239247
</div>
240248

241249
<nav class="nav-wide-wrapper" aria-label="Page navigation">
242-
{{#previous}}
243-
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
250+
{{#if previous}}
251+
<a rel="prev" href="{{ path_to_root }}{{previous.link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
252+
{{#if (eq ../text_direction "rtl")}}
253+
<i class="fa fa-angle-right"></i>
254+
{{else}}
244255
<i class="fa fa-angle-left"></i>
256+
{{/if}}
245257
</a>
246-
{{/previous}}
258+
{{/if}}
247259

248-
{{#next}}
249-
<a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
260+
{{#if next}}
261+
<a rel="next prefetch" href="{{ path_to_root }}{{next.link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
262+
{{#if (eq text_direction "rtl")}}
263+
<i class="fa fa-angle-left"></i>
264+
{{else}}
250265
<i class="fa fa-angle-right"></i>
266+
{{/if}}
251267
</a>
252-
{{/next}}
268+
{{/if}}
253269
</nav>
254270

255271
</div>

crates/mdbook-html/src/html_handlebars/hbs_renderer.rs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::theme::Theme;
44
use anyhow::{Context, Result, bail};
55
use handlebars::Handlebars;
66
use log::{debug, info, trace, warn};
7-
use mdbook_core::book::{Book, BookItem};
7+
use mdbook_core::book::{Book, BookItem, Chapter};
88
use mdbook_core::config::{BookConfig, Code, Config, HtmlConfig, Playground, RustEdition};
99
use mdbook_core::utils;
1010
use mdbook_core::utils::fs::get_404_output_file;
@@ -30,18 +30,17 @@ impl HtmlHandlebars {
3030
HtmlHandlebars
3131
}
3232

33-
fn render_item(
33+
fn render_chapter(
3434
&self,
35-
item: &BookItem,
36-
mut ctx: RenderItemContext<'_>,
35+
ch: &Chapter,
36+
prev_ch: Option<&Chapter>,
37+
next_ch: Option<&Chapter>,
38+
mut ctx: RenderChapterContext<'_>,
3739
print_content: &mut String,
3840
) -> Result<()> {
3941
// FIXME: This should be made DRY-er and rely less on mutable state
4042

41-
let (ch, path) = match item {
42-
BookItem::Chapter(ch) if !ch.is_draft_chapter() => (ch, ch.path.as_ref().unwrap()),
43-
_ => return Ok(()),
44-
};
43+
let path = ch.path.as_ref().unwrap();
4544

4645
if let Some(ref edit_url_template) = ctx.html_config.edit_url_template {
4746
let full_path = ctx.book_config.src.to_str().unwrap_or_default().to_owned()
@@ -61,7 +60,7 @@ impl HtmlHandlebars {
6160

6261
let fixed_content =
6362
render_markdown_with_path(&ch.content, ctx.html_config.smart_punctuation, Some(path));
64-
if !ctx.is_index && ctx.html_config.print.page_break {
63+
if prev_ch.is_some() && ctx.html_config.print.page_break {
6564
// Add page break between chapters
6665
// See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before
6766
// Add both two CSS properties because of the compatibility issue
@@ -116,6 +115,25 @@ impl HtmlHandlebars {
116115
);
117116
}
118117

118+
let mut nav = |name: &str, ch: Option<&Chapter>| {
119+
let Some(ch) = ch else { return };
120+
let path = ch
121+
.path
122+
.as_ref()
123+
.unwrap()
124+
.with_extension("html")
125+
.to_str()
126+
.unwrap()
127+
.replace('\\', "//");
128+
let obj = json!( {
129+
"title": ch.name,
130+
"link": path,
131+
});
132+
ctx.data.insert(name.to_string(), obj);
133+
};
134+
nav("previous", prev_ch);
135+
nav("next", next_ch);
136+
119137
// Render the handlebars template with the data
120138
debug!("Render template");
121139
let rendered = ctx.handlebars.render("index", &ctx.data)?;
@@ -131,7 +149,7 @@ impl HtmlHandlebars {
131149
debug!("Creating {}", filepath.display());
132150
utils::fs::write_file(&ctx.destination, &filepath, rendered.as_bytes())?;
133151

134-
if ctx.is_index {
152+
if prev_ch.is_none() {
135153
ctx.data.insert("path".to_owned(), json!("index.md"));
136154
ctx.data.insert("path_to_root".to_owned(), json!(""));
137155
ctx.data.insert("is_index".to_owned(), json!(true));
@@ -253,8 +271,6 @@ impl HtmlHandlebars {
253271
no_section_label: html_config.no_section_label,
254272
}),
255273
);
256-
handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
257-
handlebars.register_helper("next", Box::new(helpers::navigation::next));
258274
// TODO: remove theme_option in 0.5, it is not needed.
259275
handlebars.register_helper("theme_option", Box::new(helpers::theme::theme_option));
260276
}
@@ -442,21 +458,26 @@ impl Renderer for HtmlHandlebars {
442458
utils::fs::write_file(destination, "CNAME", format!("{cname}\n").as_bytes())?;
443459
}
444460

445-
let mut is_index = true;
446-
for item in book.iter() {
447-
let ctx = RenderItemContext {
461+
let chapters: Vec<_> = book
462+
.iter()
463+
.filter_map(|item| match item {
464+
BookItem::Chapter(ch) if !ch.is_draft_chapter() => Some(ch),
465+
_ => None,
466+
})
467+
.collect();
468+
for (i, ch) in chapters.iter().enumerate() {
469+
let previous = (i != 0).then(|| chapters[i - 1]);
470+
let next = (i != chapters.len() - 1).then(|| chapters[i + 1]);
471+
let ctx = RenderChapterContext {
448472
handlebars: &handlebars,
449473
destination: destination.to_path_buf(),
450474
data: data.clone(),
451-
is_index,
452475
book_config: book_config.clone(),
453476
html_config: html_config.clone(),
454477
edition: ctx.config.rust.edition,
455478
chapter_titles: &ctx.chapter_titles,
456479
};
457-
self.render_item(item, ctx, &mut print_content)?;
458-
// Only the first non-draft chapter item should be treated as the "index"
459-
is_index &= !matches!(item, BookItem::Chapter(ch) if !ch.is_draft_chapter());
480+
self.render_chapter(ch, previous, next, ctx, &mut print_content)?;
460481
}
461482

462483
// Render 404 page
@@ -927,11 +948,10 @@ fn partition_source(s: &str) -> (String, String) {
927948
(before, after)
928949
}
929950

930-
struct RenderItemContext<'a> {
951+
struct RenderChapterContext<'a> {
931952
handlebars: &'a Handlebars<'a>,
932953
destination: PathBuf,
933954
data: serde_json::Map<String, serde_json::Value>,
934-
is_index: bool,
935955
book_config: BookConfig,
936956
html_config: HtmlConfig,
937957
edition: Option<RustEdition>,
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
pub(crate) mod navigation;
21
pub(crate) mod resources;
32
pub(crate) mod theme;
43
pub(crate) mod toc;

0 commit comments

Comments
 (0)