from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import json
import os
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from contextlib import asynccontextmanager
from markdown_render import render_markdown_with_jinja
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
# Context manager for app lifespan
@asynccontextmanager
async def lifespan(app: FastAPI):
print("App startup: Processing Markdown files...")
process_markdown_files("./data", "./data") # Process all Markdown files
print("Markdown processing complete!")
yield # Allow the app to start
print("App shutdown: Cleanup complete.")
app = FastAPI(lifespan=lifespan)
app.mount("/data", StaticFiles(directory="data"), name="data")
# Mount static files
app.mount("/static", StaticFiles(directory="static"), name="static")
# Templates directory
templates = Jinja2Templates(directory="templates")
# Load JSON data
with open("mock_data.json") as file:
data = json.load(file)
@app.get("/test", response_class=HTMLResponse)
async def home_test():
# Load the Markdown content from a file
with open("templates/example.md", "r") as f:
markdown_content = f.read()
# Render Markdown first, then inject Jinja2 components
rendered_html = render_markdown_with_jinja(markdown_content)
# Wrap in a base HTML layout
html_template = f"""
Markdown + Jinja2
{rendered_html}
"""
return HTMLResponse(content=html_template)
def process_markdown_files(input_dir: str, output_dir: str):
"""
Recursively process all Markdown files in the input directory,
render them to HTML, and save them in the output directory.
"""
for root, _, files in os.walk(input_dir):
for file in files:
if file.endswith(".md"):
input_file_path = os.path.join(root, file)
# Determine output file path (convert .md to .html)
relative_path = os.path.relpath(input_file_path, input_dir)
output_file_path = os.path.join(output_dir, os.path.splitext(relative_path)[0] + ".html")
# Ensure the output directory exists
os.makedirs(os.path.dirname(output_file_path), exist_ok=True)
# Read Markdown content
with open(input_file_path, "r", encoding="utf-8") as md_file:
markdown_content = md_file.read()
# Render Markdown with Jinja2
print(f"Processing: {input_file_path} -> {output_file_path}")
rendered_html = render_markdown_with_jinja(markdown_content)
# Write the rendered HTML to the output file
with open(output_file_path, "w", encoding="utf-8") as html_file:
html_file.write(rendered_html)
# Index route
@app.get("/", response_class=HTMLResponse)
async def get_index(request: Request):
return templates.TemplateResponse(
"index.html",
{"request": request, "data": data, "page_title": "Forside", "author": "Henrik"}
)
@app.get("/sitemap", response_class=HTMLResponse)
async def sitemap():
"""Simple home page listing available HTML files."""
links = []
for root, _, files in os.walk("./data"):
for file in files:
if file.endswith(".html"):
relative_path = os.path.relpath(os.path.join(root, file), "./data")
link = f"{relative_path}"
links.append(link)
links_html = "
".join(links)
return HTMLResponse(content=f"Available Pages
{links_html}")
# Category route
@app.get("/category/{category_name}", response_class=HTMLResponse)
async def get_category(request: Request, category_name: str):
# Find den korrekte kategori
category = next((cat for cat in data["categories"] if cat["path"] == category_name), None)
if category:
category_file = f"data/{category_name}/index.html"
if os.path.exists(category_file):
with open(category_file) as file:
category_content = file.read()
return templates.TemplateResponse(
"category.html",
{
"request": request,
"data": data,
"page_title": category["name"],
"author": category["author"],
"content": category_content
},
)
return HTMLResponse("Kategori ikke fundet", status_code=404)