Redirect to translation index page in serve command

This commit is contained in:
Ruin0x11 2020-08-28 01:36:22 -07:00
parent 8869c2cf06
commit 85ab4d39cd
4 changed files with 100 additions and 72 deletions

1
Cargo.lock generated
View File

@ -789,6 +789,7 @@ dependencies = [
"futures-util",
"gitignore",
"handlebars",
"http",
"lazy_static",
"log",
"memchr",

View File

@ -21,6 +21,7 @@ chrono = "0.4"
clap = "2.24"
env_logger = "0.7.1"
handlebars = "4.0"
http = "0.2.4"
lazy_static = "1.0"
log = "0.4"
memchr = "2.0"

View File

@ -4,6 +4,7 @@ use crate::{get_book_dir, get_build_opts, open};
use clap::{App, Arg, ArgMatches, SubCommand};
use futures_util::sink::SinkExt;
use futures_util::StreamExt;
use http::Uri;
use mdbook::errors::*;
use mdbook::utils;
use mdbook::utils::fs::get_404_output_file;
@ -60,7 +61,7 @@ pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
pub fn execute(args: &ArgMatches) -> Result<()> {
let book_dir = get_book_dir(args);
let build_opts = get_build_opts(args);
let mut book = MDBook::load_with_build_opts(&book_dir, build_opts)?;
let mut book = MDBook::load_with_build_opts(&book_dir, build_opts.clone())?;
let port = args.value_of("port").unwrap();
let hostname = args.value_of("hostname").unwrap();
@ -82,6 +83,18 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
update_config(&mut book);
book.build()?;
let language: Option<String> = match build_opts.language_ident {
// index.html will be at the root directory.
Some(_) => None,
None => match book.config.language.default_language() {
// If book has translations, index.html will be under src/en/ or
// similar.
Some(lang_ident) => Some(lang_ident.clone()),
// If not, it will be at the root.
None => None,
}
};
let sockaddr: SocketAddr = address
.to_socket_addrs()?
.next()
@ -100,7 +113,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
let reload_tx = tx.clone();
let thread_handle = std::thread::spawn(move || {
serve(build_dir, sockaddr, reload_tx, &file_404);
serve(build_dir, sockaddr, reload_tx, &file_404, language);
});
let serving_url = format!("http://{}", address);
@ -140,6 +153,7 @@ async fn serve(
address: SocketAddr,
reload_tx: broadcast::Sender<Message>,
file_404: &str,
language: Option<String>,
) {
// A warp Filter which captures `reload_tx` and provides an `rx` copy to
// receive reload messages.
@ -166,7 +180,6 @@ async fn serve(
// The fallback route for 404 errors
let fallback_route = warp::fs::file(build_dir.join(file_404))
.map(|reply| warp::reply::with_status(reply, warp::http::StatusCode::NOT_FOUND));
let routes = livereload.or(book_route).or(fallback_route);
std::panic::set_hook(Box::new(move |panic_info| {
// exit if serve panics
@ -174,5 +187,16 @@ async fn serve(
std::process::exit(1);
}));
warp::serve(routes).run(address).await;
if let Some(lang_ident) = language {
// Redirect root to the default translation directory, if serving a localized book.
// BUG: This can't be `/{lang_ident}`, or the static assets won't get loaded.
let index_for_language = format!("/{}/index.html", lang_ident).parse::<Uri>().unwrap();
let redirect_to_index = warp::path::end().map(move || warp::redirect(index_for_language.clone()));
let routes = livereload.or(redirect_to_index).or(book_route).or(fallback_route);
warp::serve(routes).run(address).await;
}
else {
let routes = livereload.or(book_route).or(fallback_route);
warp::serve(routes).run(address).await;
};
}

View File

@ -428,81 +428,83 @@ function playground_text(playground) {
var languageToggleButton = document.getElementById('language-toggle');
var languagePopup = document.getElementById('language-list');
function showLanguages() {
languagePopup.style.display = 'block';
languageToggleButton.setAttribute('aria-expanded', true);
}
function hideLanguages() {
languagePopup.style.display = 'none';
languageToggleButton.setAttribute('aria-expanded', false);
languageToggleButton.focus();
}
function set_language(language) {
console.log("Set language " + language)
}
languageToggleButton.addEventListener('click', function () {
if (languagePopup.style.display === 'block') {
hideLanguages();
} else {
showLanguages();
if (languageToggleButton !== null) {
function showLanguages() {
languagePopup.style.display = 'block';
languageToggleButton.setAttribute('aria-expanded', true);
}
});
languagePopup.addEventListener('click', function (e) {
var language = e.target.id || e.target.parentElement.id;
set_language(language);
});
languagePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !languageToggleButton.contains(e.relatedTarget) && !languagePopup.contains(e.relatedTarget)) {
hideLanguages();
function hideLanguages() {
languagePopup.style.display = 'none';
languageToggleButton.setAttribute('aria-expanded', false);
languageToggleButton.focus();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (languagePopup.style.display === 'block' && !languageToggleButton.contains(e.target) && !languagePopup.contains(e.target)) {
hideLanguages();
function set_language(language) {
console.log("Set language " + language)
}
});
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!languagePopup.contains(e.target)) { return; }
switch (e.key) {
case 'Escape':
e.preventDefault();
languageToggleButton.addEventListener('click', function () {
if (languagePopup.style.display === 'block') {
hideLanguages();
break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
languagePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
languagePopup.querySelector('li:last-child button').focus();
break;
}
});
} else {
showLanguages();
}
});
languagePopup.addEventListener('click', function (e) {
var language = e.target.id || e.target.parentElement.id;
set_language(language);
});
languagePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !languageToggleButton.contains(e.relatedTarget) && !languagePopup.contains(e.relatedTarget)) {
hideLanguages();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (languagePopup.style.display === 'block' && !languageToggleButton.contains(e.target) && !languagePopup.contains(e.target)) {
hideLanguages();
}
});
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!languagePopup.contains(e.target)) { return; }
switch (e.key) {
case 'Escape':
e.preventDefault();
hideLanguages();
break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
languagePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
languagePopup.querySelector('li:last-child button').focus();
break;
}
});
}
})();
(function sidebar() {