Skip to content

Commit

Permalink
completed the sitemap generation code, examples and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
IndigoCurnick committed Jun 23, 2024
1 parent 6515792 commit 40392cd
Show file tree
Hide file tree
Showing 17 changed files with 308 additions and 220 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "blog-tools"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
authors = ["Indigo Curnick <indigocurnick@gmail.com>"]
description = "A collection of tools that helps make blogs in Rust"
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ next to a `blog.json`.

The JSON must conform to the following schema

```rust,ignore
```json,ignore
{
"title": String,
"date": ISO 8601 Date i.e. YYYY-MM-DD,
Expand All @@ -27,7 +27,9 @@ The JSON must conform to the following schema
"keywords": Optional<[String]>,
"canonical_link": Optional<String>,
"author_name": Optional<String>,
"author_webpage": Optional<String>
"author_webpage": Optional<String>,
"last_modified": Optional<Date>, (ISO 8601)
"priority": Optional<float>
}
```

Expand All @@ -36,7 +38,6 @@ The JSON must conform to the following schema
In `blog-tools` all slugs are /{date}/{sub-slug}.

Make sure the "slug" filed in the JSON is *just* the final sub-slug
- `blog-tools` will automatically handle the date for you

## How This Crate is Organised

Expand All @@ -56,7 +57,7 @@ the best way to do this is using a lazy static like so
```rust,ignore
lazy_static! {
pub static ref STATIC_BLOG_ENTRIES: HighBlog =
get_high_blog(PathBuf::from(BLOG_ROOT), None, None);
get_high_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::default());
}
```

Expand All @@ -66,7 +67,7 @@ blog posts themselves. These will need to be rendered when requested
```rust,ignore
lazy_static! {
pub static ref STATIC_BLOG_ENTRIES: MediumBlog =
get_medium_blog(PathBuf::from(BLOG_ROOT), None, None);
get_medium_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::default());
}
let this_blog = match all_blogs.hash.get(&complete_slug) {
Expand All @@ -88,6 +89,7 @@ everything at runtime.
let preview = preview_blogs(PathBuf::from_str(BLOG_ROOT).unwrap(), 2, None);
let tags = get_blog_tag_list(PathBuf::from_str(BLOG_ROOT).unwrap());
let blog_post = render_blog_post(PathBuf::from_str(BLOG_ROOT).unwrap(), date, slug, None).unwrap();
let sitemap = create_sitemap(BLOG_ROOT, URL, &SitemapOptions::default());
```

This method can have serious runtime performance implecations, but might be
Expand Down
31 changes: 26 additions & 5 deletions examples/low/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use blog_tools::low::{
get_blog_tag_list, preview_blogs, preview_blogs_tagged, render_blog_post, PreviewBlogEntry,
use blog_tools::{
low::{
get_blog_tag_list, preview_blogs, preview_blogs_tagged, render_blog_post, PreviewBlogEntry,
},
sitemap::{create_sitemap, SitemapOptions},
};
use rocket::{
fs::{relative, FileServer},
response::Redirect,
response::{content::RawXml, Redirect},
Request, Route,
};
use rocket_dyn_templates::Template;
use serde::{Deserialize, Serialize};
use std::{path::PathBuf, str::FromStr};
use std::{fs, path::PathBuf, str::FromStr};

pub static BLOG_ROOT: &str = "examples/blog";

Expand Down Expand Up @@ -82,6 +85,24 @@ fn tag_page(slug: String) -> Option<Template> {
Some(Template::render("tags", context.into_json()))
}

pub static URL: &str = "www.example.xyz";

#[get("/sitemap.xml")]
fn sitemap() -> RawXml<String> {
let base_sitemap = fs::read_to_string("examples/xml/sitemap.xml").unwrap();
let sitemap = create_sitemap(
BLOG_ROOT,
&URL.to_string(),
&SitemapOptions {
include_tags: true,
sitemap_base: Some(base_sitemap),
..Default::default()
},
);

return RawXml(sitemap.unwrap());
}

#[catch(404)]
async fn not_found(req: &Request<'_>) -> Redirect {
let mut context = rocket_dyn_templates::tera::Context::new();
Expand All @@ -97,5 +118,5 @@ async fn error(req: &Request<'_>) -> Redirect {
}

fn get_all_routes() -> Vec<Route> {
return routes![blog_index, blog_article, tag_page];
return routes![blog_index, blog_article, tag_page, sitemap];
}
3 changes: 2 additions & 1 deletion examples/medium/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{fs, path::PathBuf, str::FromStr};
use blog_tools::{
medium::{get_medium_blog, MediumBlog, MediumBlogEntry},
sitemap::SitemapOptions,
Blog,
};
use lazy_static::lazy_static;
use rocket::{
Expand Down Expand Up @@ -78,7 +79,7 @@ fn tag_page(slug: String) -> Option<Template> {
let mut these_blogs: Vec<&MediumBlogEntry> = vec![];

for blog in &all_blogs.entries {
if blog.tags.contains(&slug) {
if blog.get_tags().contains(&slug) {
these_blogs.push(&blog);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ pub fn get_json_data<T: AsRef<Path>>(blog: T) -> Result<BlogJson, BlogError> {

let file_name = match blog.file_name() {
Some(x) => x,
None => todo!(),
None => return Err(BlogError::FileNotFound),
};

let file_str = match file_name.to_str() {
Some(x) => x,
None => todo!(),
None => return Err(BlogError::FileNotFound),
};

let name_split: Vec<&str> = file_str.split(".").collect();

let n = match name_split.get(0) {
Some(&x) => x,
None => todo!(),
None => return Err(BlogError::ImproperFileName(file_str.to_string())),
};

let name = format!("{}.json", n);
Expand Down
6 changes: 4 additions & 2 deletions src/common/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct BlogJson {
pub author_name: Option<String>,
pub author_webpage: Option<String>,
pub last_modified: Option<NaiveDate>, // For sitemap, if not present uses `date`
pub priority: Option<f64>, // For sitemap, if not present uses the default
pub priority: Option<f64>, // For sitemap, if not present uses the default
}

#[derive(Debug)]
Expand All @@ -27,6 +27,7 @@ pub enum BlogError {
FileNotFound, // TODO: It would be nice to include the file not found here but that would rely on converting a Path to a String - which involves TWO unwraps!
/// Include the date as found as a string
ImproperDate(String),
ImproperFileName(String),
}

impl Error for BlogError {}
Expand All @@ -37,7 +38,8 @@ impl Display for BlogError {
BlogError::File(a) => write!(f, "File read error caused by: {}", a),
BlogError::Markdown(b) => write!(f, "Markdown rendering error caused by: {}", b),
BlogError::FileNotFound => write!(f, "File not found"),
BlogError::ImproperDate(c) => write!(f, "Found date `{}` which appears to be improper - dates should be in the yyyy-mm-dd format", c)
BlogError::ImproperDate(c) => write!(f, "Found date `{}` which appears to be improper - dates should be in the yyyy-mm-dd format", c),
BlogError::ImproperFileName(d) => write!(f, "Found file name `{}` which appears to be improper", d),
}
}
}
2 changes: 0 additions & 2 deletions src/high/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ pub fn get_high_blog<T: AsRef<Path>>(
);
}

// TODO: I will make a new function which will handle getting the list of blogs and tags, and I should use that here
// TODO: I also wonder if using the `Blog` trait I can abstract this code even more for Medium and Low?
fn get_blog_entries<T: AsRef<Path>>(
base: T,
toc_generation_func: Option<&dyn Fn(&Node) -> String>,
Expand Down
19 changes: 2 additions & 17 deletions src/high/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,7 @@ impl Blog for HighBlogEntry {

let toc = toc(&markdown, toc_generation_func)?;

return Ok(HighBlogEntry {
title: json.title,
date: json.date,
desc: json.desc,
html: html,
slug: json.slug,
tags: json.tags,
toc: toc,
keywords: json.keywords,
canonical_link: json.canonical_link,
author_name: json.author_name,
author_webpage: json.author_webpage,
preview,
last_modified: json.last_modified,
priority: json.priority,
});
return Ok(HighBlogEntry::new(json, html, toc, preview));
}

fn get_title(&self) -> String {
Expand Down Expand Up @@ -193,7 +178,7 @@ impl HighBlogEntry {
date: json.date,
desc: json.desc,
html: html,
slug: format!("{}/{}", json.date, json.slug),
slug: json.slug,
tags: json.tags,
toc: toc,
keywords: json.keywords,
Expand Down
29 changes: 19 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
//! "keywords": Optional<[String]>,
//! "canonical_link": Optional<String>,
//! "author_name": Optional<String>,
//! "author_webpage": Optional<String>
//! "author_webpage": Optional<String>,
//! "last_modified": Optional<Date>, (ISO 8601)
//! "priority": Optional<float>
//! }
//! ```
//!
Expand All @@ -36,7 +38,6 @@
//! In `blog-tools` all slugs are /{date}/{sub-slug}.
//!
//! Make sure the "slug" filed in the JSON is *just* the final sub-slug
//! - `blog-tools` will automatically handle the date for you
//!
//! ## How This Crate is Organised
//!
Expand All @@ -55,18 +56,18 @@
//!
//! ```rust,ignore
//! lazy_static! {
//! pub static ref STATIC_BLOG_ENTRIES: HighBlog =
//! get_high_blog(PathBuf::from(BLOG_ROOT), None, None);
//! }
//! pub static ref STATIC_BLOG_ENTRIES: HighBlog =
//! get_high_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::default());
//! }
//! ```
//!
//! `medium` stores the majority of the blog, but not the rendered HTML of the
//! blog posts themselves. These will need to be rendered when requested
//!
//! ```rust,ignore
//! lazy_static! {
//! pub static ref STATIC_BLOG_ENTRIES: MediumBlog =
//! get_medium_blog(PathBuf::from(BLOG_ROOT), None, None);
//! pub static ref STATIC_BLOG_ENTRIES: MediumBlog =
//! get_medium_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::default());
//! }
//!
//! let this_blog = match all_blogs.hash.get(&complete_slug) {
Expand All @@ -88,6 +89,7 @@
//! let preview = preview_blogs(PathBuf::from_str(BLOG_ROOT).unwrap(), 2, None);
//! let tags = get_blog_tag_list(PathBuf::from_str(BLOG_ROOT).unwrap());
//! let blog_post = render_blog_post(PathBuf::from_str(BLOG_ROOT).unwrap(), date, slug, None).unwrap();
//! let sitemap = create_sitemap(BLOG_ROOT, URL, &SitemapOptions::default());
//! ```
//!
//! This method can have serious runtime performance implecations, but might be
Expand Down Expand Up @@ -115,6 +117,12 @@ mod types;

pub use types::Blog;

/// Sitemap related utilities can be found here. If you use `high` or `medium`
/// then the only thing you need from here is `SitemapOptions` to configure
/// how a sitemap is generated.
///
/// If you use `low` then the function `create_sitemap` can be used to
/// generate the sitemap
pub mod sitemap;

/// `high` refers to high RAM usage - using this module you will be effectively
Expand All @@ -124,8 +132,8 @@ pub mod sitemap;
/// ```rust,ignore
/// lazy_static! {
/// pub static ref STATIC_BLOG_ENTRIES: HighBlog =
/// get_high_blog(PathBuf::from(BLOG_ROOT), None, None);
/// }
/// get_high_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::default());
/// }
/// ```
pub mod high;

Expand All @@ -139,6 +147,7 @@ pub mod high;
/// let preview = preview_blogs(PathBuf::from_str(BLOG_ROOT).unwrap(), 2, None);
/// let tags = get_blog_tag_list(PathBuf::from_str(BLOG_ROOT).unwrap());
/// let blog_post = render_blog_post(PathBuf::from_str(BLOG_ROOT).unwrap(), date, slug, None).unwrap();
/// let sitemap = create_sitemap(BLOG_ROOT, URL, &SitemapOptions::default());
/// ```
pub mod low;

Expand All @@ -149,7 +158,7 @@ pub mod low;
/// ```rust,ignore
/// lazy_static! {
/// pub static ref STATIC_BLOG_ENTRIES: MediumBlog =
/// get_medium_blog(PathBuf::from(BLOG_ROOT), None, None);
/// get_medium_blog(PathBuf::from(BLOG_ROOT), None, None, URL, &SitemapOptions::Default());
/// }
///
/// let this_blog = match all_blogs.hash.get(&complete_slug) {
Expand Down
Loading

0 comments on commit 40392cd

Please sign in to comment.