002f5b3a

Archive
Tree [002f5b3a] [>]
commit
002f5b3a27087253378d17b7fae0f227b890ce95
parent
author
Christopher K. Schmitt <me@shmish.dev>
date
2026-07-29
committer
Christopher K. Schmitt <me@shmish.dev>
date
2026-07-29
changes
15
insertions
58
deletions
0
Add favicon support with file override and embedded fallback
Msrc/cli.rs
~    /// All generated URLs will be prefixed with this value.~    #[arg(long)]~    pub base_url: Option<String>,++    /// Path to a custom favicon file (SVG or ICO). Overrides the default+    /// commit-icon favicon.+    #[arg(long)]+    pub favicon: Option<PathBuf>,~}
Msrc/main.rs
~/// Base URL path prefix for reverse proxy support, set once from `--base-url`.~static BASE_URL: OnceLock<String> = OnceLock::new();~+/// Favicon bytes, loaded at startup from the default or a custom path.+static FAVICON: OnceLock<Vec<u8>> = OnceLock::new();+~/// Returns the configured hostname, or `"index"` if none was provided.~pub fn hostname() -> &'static str {~    HOSTNAME.get().map_or("index", |s| s.as_str())
~/// provided.~pub fn base_url() -> &'static str {~    BASE_URL.get().map_or("", |s| s.as_str())+}++/// Returns the favicon bytes loaded at startup.+pub fn favicon() -> &'static [u8] {+    FAVICON.get().map_or(&[], |v| v.as_slice())~}~~#[tokio::main]
~    if let Some(base_url) = args.base_url {~        let _ = BASE_URL.set(base_url);~    }++    let favicon_data = match args.favicon {+        Some(path) => std::fs::read(&path).unwrap_or_default(),+        None => include_bytes!("../static/favicon.svg").to_vec(),+    };+    let _ = FAVICON.set(favicon_data);~~    // Concatenate base styles, markdown styles, and theme variables into a~    // single stylesheet served at /style.css.
Msrc/routes.rs
~    )~}~+/// Serves the favicon (SVG or ICO bytes loaded at startup).+async fn favicon() -> impl IntoResponse {+    (+        [(header::CONTENT_TYPE, "image/svg+xml")],+        crate::favicon(),+    )+}+~/// Builds the application router with all routes and shared state attached.~pub fn router(state: AppState) -> Router {~    Router::new()+        .route("/favicon.ico", get(favicon))~        .route("/style.css", get(style))~        .route("/", get(repo::list))~        .route("/{repo}", get(repo::detail))
Mtemplates/base.html
~    <meta name="viewport" content="width=device-width, initial-scale=1.0">~    <title>{% block title %}{% endblock %}</title>~    <link rel="stylesheet" href="{{ crate::base_url() }}/style.css">+    <link rel="icon" type="image/svg+xml" href="{{ crate::base_url() }}/favicon.ico">+    <meta property="og:site_name" content="git browse">+    <meta property="og:type" content="website">+    <meta property="og:title" content="{% block og_title %}{% endblock %}">+    <meta property="og:description" content="{% block og_description %}{% endblock %}">~</head>~<body>~{% include "sprites.svg" %}
Mtemplates/blame.html
~{% extends "base.html" %}~~{% block title %}blame {{ path }} - {{ repo }}{% endblock %}+{% block og_title %}blame {{ path }} - {{ repo }}{% endblock %}+{% block og_description %}annotated view of {{ path }} in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/branch_detail.html
~{% extends "base.html" %}~~{% block title %}{{ branch }} - {{ repo }}{% endblock %}+{% block og_title %}{{ branch }} - {{ repo }}{% endblock %}+{% block og_description %}branch {{ branch }} in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/branch_list.html
~{% extends "base.html" %}~~{% block title %}branches - {{ repo }}{% endblock %}+{% block og_title %}branches - {{ repo }}{% endblock %}+{% block og_description %}branches in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/commit.html
~{% extends "base.html" %}~~{% block title %}{{ sha[..8] }} - {{ repo }}{% endblock %}+{% block og_title %}{{ sha[..8] }} - {{ repo }}{% endblock %}+{% block og_description %}{{ message }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/commit_list.html
~{% extends "base.html" %}~~{% block title %}commits - {{ repo }}{% endblock %}+{% block og_title %}commits - {{ repo }}{% endblock %}+{% block og_description %}commit history for {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/repo.html
~{% block title %}~{{ name }}~{% endblock %}+{% block og_title %}{{ name }}{% endblock %}+{% block og_description %}{% if let Some(desc) = description %}{{ desc }}{% endif %}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/repo_list.html
~{% extends "base.html" %}~~{% block title %}repos{% endblock %}+{% block og_title %}repos{% endblock %}+{% block og_description %}git repository browser{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/tag_detail.html
~{% extends "base.html" %}~~{% block title %}{{ tag }} - {{ repo }}{% endblock %}+{% block og_title %}{{ tag }} - {{ repo }}{% endblock %}+{% block og_description %}tag {{ tag }} in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/tag_list.html
~{% extends "base.html" %}~~{% block title %}tags - {{ repo }}{% endblock %}+{% block og_title %}tags - {{ repo }}{% endblock %}+{% block og_description %}tags in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Mtemplates/tree.html
~{% extends "base.html" %}~~{% block title %}{{ repo }}/{{ path }}{% endblock %}+{% block og_title %}{{ repo }}/{{ path }}{% endblock %}+{% block og_description %}browsing {{ path }} in {{ repo }}{% endblock %}~~{% block breadcrumbs %}~<ul>
Astatic/favicon.svg
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#4fc1ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">+  <circle cx="12" cy="12" r="3"/>+  <line x1="3" x2="9" y1="12" y2="12"/>+  <line x1="15" x2="21" y1="12" y2="12"/>+</svg>