Skip to content

Commit

Permalink
feat(generics): use config for generic content and some spas
Browse files Browse the repository at this point in the history
  • Loading branch information
fiji-flo committed Nov 22, 2024
1 parent 857d3f2 commit a717537
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 177 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion crates/rari-cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ struct BuildArgs {
#[arg(long)]
skip_spas: bool,
#[arg(long)]
skip_generics: bool,
#[arg(long)]
skip_sitemap: bool,
#[arg(long)]
templ_stats: bool,
Expand Down Expand Up @@ -280,9 +282,13 @@ fn main() -> Result<(), Error> {
if !args.skip_spas && args.files.is_empty() {
let start = std::time::Instant::now();
urls.extend(build_spas()?);
urls.extend(build_generic_pages()?);
println!("Took: {: >10.3?} to build spas", start.elapsed());
}
if !args.skip_generics && args.files.is_empty() {
let start = std::time::Instant::now();
urls.extend(build_generic_pages()?);
println!("Took: {: >10.3?} to build generics", start.elapsed());
}
if !args.skip_content {
let start = std::time::Instant::now();
urls.extend(build_docs(&docs)?);
Expand Down
2 changes: 0 additions & 2 deletions crates/rari-doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ strum = { version = "0.26", features = ["derive"] }
imagesize = "0.13"
svg_metadata = "0.5"
memoize = "0.4"
phf_macros = "0.11"
phf = "0.11"
unescaper = "0.1"


Expand Down
100 changes: 100 additions & 0 deletions crates/rari-doc/src/cached_readers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use rari_types::globals::{
use rari_types::locale::Locale;
use rari_utils::concat_strs;
use rari_utils::io::read_to_string;
use serde::{Deserialize, Serialize};
use tracing::error;

use crate::contributors::{WikiHistories, WikiHistory};
Expand Down Expand Up @@ -517,6 +518,77 @@ pub fn read_and_cache_doc_pages() -> Result<Vec<Page>, DocError> {
/// A type alias for a hashmap that maps URLs to pages.
pub type UrlToPageMap = HashMap<String, Page>;

/// Represents the configuration for generic pages.
///
/// # Fields
///
/// * `slug_prefix` - The prefix for the slug, defaults to None.
///
/// * `title_suffix` - A suffix to add to the page title.
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct GenericPagesConfig {
pub slug_prefix: Option<String>,
pub title_suffix: Option<String>,
}
/// Represents the configuration for all generic content.
///
/// # Fields
///
/// * `pages` - A `HashMap<String, GenericPagesConfig>` mapping pages sections to their
/// according `GenericPagesConfig`.
///
/// * `title_suffix` - A suffix to add to the page title.
#[derive(Debug, Clone, Deserialize, Default)]
pub struct GenericContentConfig {
pub pages: HashMap<String, GenericPagesConfig>,
pub spas: HashMap<String, BuildSPA>,
}

static GENERIC_CONTENT_CONFIG: OnceLock<GenericContentConfig> = OnceLock::new();

fn read_generic_content_config() -> Result<GenericContentConfig, DocError> {
if let Some(root) = generic_content_root() {
let json_str = read_to_string(root.join("config.json"))?;
let config: GenericContentConfig = serde_json::from_str(&json_str)?;
Ok(config)
} else {
Err(DocError::NoGenericContentConfig)
}
}

/// Provides access to the generic content configuration.
///
/// This function returns the generic content configuration, either from a
/// cached, lazily-initialized global value (`GENERIC_CONTENT_CONFIG`) or by
/// re-reading the configuration file, depending on the value of `cache_content()`.
///
/// - If `cache_content()` is true, the configuration is cached and re-used
/// across calls.
/// - If `cache_content()` is false, the configuration is re-read from the
/// `config.json` file on each call.
///
/// Any errors encountered during the reading or parsing of the configuration
/// are logged, and a default configuration is returned.
///
/// # Returns
/// A `Cow<'static, GenericContentConfig>` representing the configuration.
/// - If the configuration is cached, a borrowed reference is returned.
/// - If the configuration is re-read, an owned copy is returned.
pub fn generic_content_config() -> Cow<'static, GenericContentConfig> {
fn gather() -> GenericContentConfig {
read_generic_content_config().unwrap_or_else(|e| {
error!("{e}");
Default::default()
})
}
if cache_content() {
Cow::Borrowed(GENERIC_CONTENT_CONFIG.get_or_init(gather))
} else {
Cow::Owned(gather())
}
}

/// Retrieves all generic pages, using the cache if it is enabled.
///
/// This function returns a `Cow<'static, UrlToPageMap>` containing the generic pages.
Expand Down Expand Up @@ -666,3 +738,31 @@ pub fn wiki_histories() -> Cow<'static, WikiHistories> {
)
}
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BasicSPA {
pub only_follow: bool,
pub no_indexing: bool,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum SPAData {
BlogIndex,
HomePage,
NotFound,
#[serde(untagged)]
BasicSPA(BasicSPA),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BuildSPA {
pub slug: Cow<'static, str>,
pub page_title: Cow<'static, str>,
pub page_description: Option<Cow<'static, str>>,
pub trailing_slash: bool,
pub en_us_only: bool,
pub data: SPAData,
}
2 changes: 2 additions & 0 deletions crates/rari-doc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum DocError {
NoCurriculumRoot,
#[error("No generic content root set")]
NoGenericContentRoot,
#[error("No generic content config found")]
NoGenericContentConfig,
#[error("No H1 found")]
NoH1,
#[error(transparent)]
Expand Down
10 changes: 5 additions & 5 deletions crates/rari-doc/src/pages/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,11 @@ fn build_generic_page(page: &GenericPage) -> Result<BuiltPage, DocError> {
title: page.meta.title.clone(),
toc,
},
page_title: concat_strs!(
page.meta.title.as_str(),
" | ",
page.meta.title_suffix.as_str()
),
page_title: if let Some(suffix) = &page.meta.title_suffix {
concat_strs!(page.meta.title.as_str(), " | ", suffix)
} else {
page.meta.title.clone()
},
url: page.meta.url.clone(),
id: page.meta.page.clone(),
})))
Expand Down
58 changes: 28 additions & 30 deletions crates/rari-doc/src/pages/types/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rari_utils::concat_strs;
use rari_utils::io::read_to_string;
use serde::Deserialize;

use crate::cached_readers::generic_content_files;
use crate::cached_readers::{generic_content_config, generic_content_files, GenericPagesConfig};
use crate::error::DocError;
use crate::pages::page::{Page, PageLike, PageReader};
use crate::utils::split_fm;
Expand All @@ -27,7 +27,7 @@ pub struct GenericPageMeta {
pub url: String,
pub full_path: PathBuf,
pub path: PathBuf,
pub title_suffix: String,
pub title_suffix: Option<String>,
pub page: String,
}

Expand All @@ -38,7 +38,7 @@ impl GenericPageMeta {
path: PathBuf,
locale: Locale,
slug: String,
title_suffix: &str,
title_suffix: Option<String>,
page: String,
) -> Result<Self, DocError> {
let url = concat_strs!(
Expand All @@ -56,7 +56,7 @@ impl GenericPageMeta {
url,
path,
full_path,
title_suffix: title_suffix.to_string(),
title_suffix,
page,
})
}
Expand All @@ -70,30 +70,28 @@ impl PageReader for GenericPage {
let path = path.into();
let root = generic_content_root().ok_or(DocError::NoGenericContentRoot)?;
let without_root: &Path = path.strip_prefix(root)?;
let (slug_prefix, title_suffix, root) = if without_root.starts_with("plus/") {
(Some("plus/docs"), "MDN Plus", root.join("plus"))
} else if without_root.starts_with("community/") || without_root == Path::new("community") {
(None, "Contribute to MDN", root.join("community"))
} else if without_root.starts_with("observatory/") {
(
Some("observatory/docs"),
"HTTP Observatory",
root.join("observatory"),
)
} else {
return Err(DocError::PageNotFound(
path.to_string_lossy().to_string(),
crate::pages::page::PageCategory::GenericPage,
));
};
read_generic_page(
path,
locale.unwrap_or_default(),
slug_prefix,
title_suffix,
&root,
)
.map(|g| Page::GenericPage(Arc::new(g)))
if let Some(section) = without_root.iter().next() {
let config = generic_content_config();
let page_config = config.pages.get(section.to_string_lossy().as_ref());
if let Some(GenericPagesConfig {
slug_prefix,
title_suffix,
}) = page_config
{
return read_generic_page(
&path,
locale.unwrap_or_default(),
slug_prefix.as_deref(),
title_suffix.as_deref(),
&root.join(section),
)
.map(|g| Page::GenericPage(Arc::new(g)));
}
}
Err(DocError::PageNotFound(
path.to_string_lossy().to_string(),
crate::pages::page::PageCategory::GenericPage,
))
}
}
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -206,7 +204,7 @@ fn read_generic_page(
path: impl Into<PathBuf>,
locale: Locale,
slug_prefix: Option<&str>,
title_suffix: &str,
title_suffix: Option<&str>,
root: &Path,
) -> Result<GenericPage, DocError> {
let full_path: PathBuf = path.into();
Expand All @@ -230,7 +228,7 @@ fn read_generic_page(
path,
locale,
slug.to_string(),
title_suffix,
title_suffix.map(ToString::to_string),
page.to_string(),
)?,
raw,
Expand Down
Loading

0 comments on commit a717537

Please sign in to comment.