Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Frontmatter Reader: Support summary card (OG. Twitter) #2321

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ shlex = "1.3.0"
tempfile = "3.4.0"
toml = "0.5.11" # Do not update, see https://github.com/rust-lang/mdBook/issues/2037
topological-sort = "0.2.2"
gray_matter = "0.2" #Fronmatter
serde_yaml = "0.9"


# Watch feature
notify = { version = "6.1.1", optional = true }
Expand Down
57 changes: 56 additions & 1 deletion src/renderer/html_handlebars/hbs_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ use once_cell::sync::Lazy;
use regex::{Captures, Regex};
use serde_json::json;

use gray_matter::engine::YAML;
use gray_matter::Matter;
use serde::Deserialize;

fn extract_frontmatter(content: &str) -> Option<&str> {
let start = content.find("---")? + 3; // Find the end of the first `---` + 3 to move past it
let end = content[start..].find("---")? + start; // Find the start of the closing `---`
Some(&content[start..end].trim())
}

#[derive(Deserialize, Debug)]
struct FrontMatter {
title: String,
description: String,
featured_image_url: String,
}

#[derive(Default)]
pub struct HtmlHandlebars;

Expand Down Expand Up @@ -54,7 +71,45 @@ impl HtmlHandlebars {
.insert("git_repository_edit_url".to_owned(), json!(edit_url));
}

let content = utils::render_markdown(&ch.content, ctx.html_config.curly_quotes);
// Parse frontmatter and prepare content
let matter = Matter::<YAML>::new();
let parsed = matter.parse(&ch.content);
let (content, new_content) = if let Some(data) = parsed.data {
debug!("Parsed frontmatter: {:?}", &data);
let yaml_str = extract_frontmatter(&ch.content).unwrap_or_default();
let front_matter_result: Result<FrontMatter, serde_yaml::Error> =
serde_yaml::from_str(yaml_str);
// let front_matter_result: Result<FrontMatter, serde_yaml::Error> = serde_yaml::from_str(&ch.content);
match front_matter_result {
Ok(front_matter) => {
ctx.data.insert("is_frontmatter".to_owned(), json!("true"));
ctx.data
.insert("og_title".to_owned(), json!(front_matter.title));
ctx.data
.insert("og_description".to_owned(), json!(front_matter.description));
ctx.data.insert(
"og_image_url".to_owned(),
json!(front_matter.featured_image_url),
);
}
Err(e) => {
eprintln!("Frontmatter: Deserialization error: {:?}", e);
}
}

// Prepare new content without frontmatter for rendering
let new_content = parsed.content.trim_start();
(
utils::render_markdown(&new_content, ctx.html_config.curly_quotes),
Some(new_content),
)
} else {
// No frontmatter, use original content
(
utils::render_markdown(&ch.content, ctx.html_config.curly_quotes),
None,
)
};

let fixed_content =
utils::render_markdown_with_path(&ch.content, ctx.html_config.curly_quotes, Some(path));
Expand Down
27 changes: 27 additions & 0 deletions src/theme/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">

<!-- Open Graph Meta Tags for Social Media Exposure -->
{{#if is_frontmatter}}
<meta name="title" property="og:title" content="{{ og_title }}">
<meta name="description" property="og:description" content="{{ og_description }}">
<meta name="twitter:title" content="{{ og_title }}"/>
<meta name="twitter:description" content="{{ og_description }}"/>
<!-- <meta property="og:url" content="{{ base_url}}"> -->
{{else}}
<meta name="title" property="og:title" content="mdBook Documentation">
<meta name="description" property="og:description" content="Create book from markdown files. Like Gitbook but implemented in Rust">
<!-- <meta property="og:url" content="https://www.dedp.online"> -->
<meta name="twitter:title" content="mdBook Documentation"/>
<meta name="twitter:description" content="Create book from markdown files. Like Gitbook but implemented in Rust"/>
{{/if}}
{{#if og_image_url}}
<meta property="og:image" content="{{ og_image_url }}">
<meta name="twitter:image" content="{{ og_image_url }}"/>
{{else}}
<meta property="og:image" content="https://rust-lang.github.io/mdBook/favicon.png">
<meta name="twitter:image" content="https://rust-lang.github.io/mdBook/favicon.png"/>
{{/if}}

<meta name="author" content="mdBook">
<meta property="og:type" content="book">
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:creator" content="@rustlang"/>

<!-- Custom theme stylesheets -->
{{#each additional_css}}
<link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
Expand Down
Loading