//! This crate generates HTML templates for crates.rs //! //! Most template require their own type of struct that does //! some lightweight conversion from data model/APIs, //! because the template engine Ructe doesn't support //! complex expressions in the templates. mod author_page; mod cat_page; mod crate_page; mod download_graph; mod home_page; mod install_page; mod iter; mod not_found_page; mod reverse_dependencies; mod search_page; mod urler; pub use crate::not_found_page::*; pub use crate::search_page::*; use futures::future::try_join_all; use crate::author_page::*; use crate::crate_page::*; use crate::urler::Urler; use categories::Category; use chrono::prelude::*; use failure; use failure::ResultExt; use kitchen_sink::Compat; use kitchen_sink::RichAuthor; use kitchen_sink::KitchenSink; use kitchen_sink::{stopped, KitchenSinkErr}; use render_readme::Links; use render_readme::Markup; use render_readme::Renderer; use rich_crate::RichCrate; use rich_crate::RichCrateVersion; use semver::Version as SemVer; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::io::Write; use url::Url; include!(concat!(env!("OUT_DIR"), "/templates.rs")); /// Metadata used in the base template, mostly for `` #[derive(Default)] pub struct Page { title: String, description: Option, item_name: Option, item_description: Option, keywords: Option, created: Option, alternate: Option, alternate_type: Option<&'static str>, canonical: Option, noindex: bool, search_meta: bool, critical_css_data: Option<&'static str>, critical_css_dev_url: Option<&'static str>, local_css_data: Option<&'static str>, } impl Page { pub fn site_twitter_handle(&self) -> &str { "@CratesRS" } pub fn critical_css(&self) -> templates::Html<&'static str> { #[cfg(debug_assertions)] { if let Some(url) = self.critical_css_dev_url { // it's super ugly hack, but just for dev return templates::Html(Box::leak(format!("