Compare commits

...

8 Commits

Author SHA1 Message Date
fa359f095d Lets test 2024-12-11 20:45:52 +01:00
67f0096f7f Lets test
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 32s
2024-12-11 20:39:22 +01:00
5afecf4d11 Lets test
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-11 20:37:45 +01:00
d4a8e20817 [main] requirements
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 46s
2024-12-11 20:34:48 +01:00
c49fc5a0d5 markdown template
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
2024-12-11 20:34:33 +01:00
e728d5c14e markdown template
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
2024-12-11 20:34:20 +01:00
Henrik Jess
f3ae944edf Merge remote-tracking branch 'origin/main'
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Failing after 4m35s
# Conflicts:
#	app.py
2024-12-11 19:10:39 +01:00
Henrik Jess
27ee0516d9 https enforcement 2024-12-11 19:10:25 +01:00
13 changed files with 262 additions and 19 deletions

View File

@@ -0,0 +1,5 @@
# Overskrift
## underskrift

Binary file not shown.

Binary file not shown.

115
app.py
View File

@@ -1,19 +1,30 @@
import uvicorn
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import json
import os
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import HTMLResponse
from contextlib import asynccontextmanager
from markdown_render import render_markdown_with_jinja
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
# 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")
@@ -26,6 +37,69 @@ templates = Jinja2Templates(directory="templates")
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"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Markdown + Jinja2</title>
<style>
.img-left-overlay img {{ width: 300px; }}
.box {{ border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9; }}
.note {{ background-color: #e7f3fe; border-left: 4px solid #2196F3; padding: 10px; }}
.warning {{ background-color: #fff3cd; border-left: 4px solid #ffeb3b; padding: 10px; }}
</style>
</head>
<body>
<div class="content">
{rendered_html}
</div>
</body>
</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):
@@ -34,6 +108,19 @@ async def get_index(request: Request):
{"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"<a href='/data/{relative_path}'>{relative_path}</a>"
links.append(link)
links_html = "<br>".join(links)
return HTMLResponse(content=f"<h1>Available Pages</h1>{links_html}")
# Category route
@app.get("/category/{category_name}", response_class=HTMLResponse)
async def get_category(request: Request, category_name: str):
@@ -54,14 +141,4 @@ async def get_category(request: Request, category_name: str):
"content": category_content
},
)
return HTMLResponse("Kategori ikke fundet", status_code=404)
# Main entry point
def main():
"""Run the FastAPI app directly"""
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True, proxy_headers=True)
# Run main when executed directly
if __name__ == "__main__":
main()
return HTMLResponse("Kategori ikke fundet", status_code=404)

View File

@@ -0,0 +1,43 @@
import os
from markdown_render import render_markdown_with_jinja
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 to 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)
print("Markdown processing complete!")
if __name__ == "__main__":
# Input directory containing Markdown files
input_directory = "./data"
# Output directory where HTML files will be stored
output_directory = "./data"
# Start the processing
process_markdown_files(input_directory, output_directory)

View File

@@ -0,0 +1,7 @@
<h1>BoligBolig Bolig Bolig - Hvor skal sengen placeres</h1>
<p>Nu bliver det spænde!</p>
<p>
<div class="note">
<p>Dette er stadig en test side</p>
</div>
</p>

View File

@@ -0,0 +1,5 @@
# BoligBolig Bolig Bolig - Hvor skal sengen placeres
Nu bliver det spænde!
{{ note("Dette er stadig en test side") }}

View File

@@ -0,0 +1,7 @@
<h1>Lidt mere info om job</h1>
<p>Der skal langt mere tekst her</p>
<p>
<div class="note">
<p>Husk alpha side</p>
</div>
</p>

View File

@@ -0,0 +1,6 @@
# Lidt mere info om job
Der skal langt mere tekst her
{{ note("Husk alpha side") }}

59
markdown_render.py Normal file
View File

@@ -0,0 +1,59 @@
from jinja2 import Environment, FileSystemLoader
import markdown
def img_left_overlay(src):
"""Render an image with overlay."""
return f'''
<div class="img-left-overlay">
<img src="{src}" alt="Overlay Image">
<div class="overlay-text">Overlay Text</div>
</div>
'''
def box(title, content):
"""Render a box component."""
return f'''
<div class="box">
<strong>{title}</strong>
<p>{content}</p>
</div>
'''
def note(content):
"""Render a note component."""
return f'''
<div class="note">
<p>{content}</p>
</div>
'''
def warning(content):
"""Render a warning component."""
return f'''
<div class="warning">
⚠️ <p>{content}</p>
</div>
'''
def create_jinja_environment(template_dir="templates"):
"""Set up Jinja2 environment and register custom components."""
env = Environment(loader=FileSystemLoader(template_dir))
env.globals.update({
"img_left_overlay": img_left_overlay,
"box": box,
"note": note,
"warning": warning,
})
return env
def render_markdown_with_jinja(markdown_content, template_data=None):
"""Process Markdown first, then inject Jinja2 components."""
# Step 1: Convert Markdown to HTML
md_html = markdown.markdown(markdown_content, extensions=['extra', 'nl2br'])
# Step 2: Use Jinja2 to inject components into the already-rendered HTML
env = create_jinja_environment()
template = env.from_string(md_html)
rendered_html = template.render(template_data or {})
return rendered_html

View File

@@ -6,7 +6,10 @@ h11==0.14.0
httptools==0.6.4
idna==3.10
Jinja2==3.1.4
Markdown==3.7
markdown-it-py==3.0.0
MarkupSafe==3.0.2
mdurl==0.1.2
pydantic==2.6.3
pydantic_core==2.16.3
python-dotenv==1.0.1

13
templates/example.md Normal file
View File

@@ -0,0 +1,13 @@
# Welcome to My Page
Here is an image overlay:
{{ img_left_overlay("my-cat.png") }}
Here is a box:
{{ box("Important Notice", "This is a reusable box.") }}
Here is a note:
{{ note("This is a very important note for the user.") }}
Here is a warning:
{{ warning("Be cautious when proceeding!") }}

18
test_markdown_render.py Normal file
View File

@@ -0,0 +1,18 @@
from markdown_render import MarkdownRenderer
# Initialize MarkdownRenderer
renderer = MarkdownRenderer()
# Test Markdown input
markdown_content = """
{img-left-overlay: src=my-cat.png}
{box: title=Test Box, content=This is a test.}
{note: content=This is a note.}
{warning: content=Be careful!}
"""
# Render to HTML
print("Rendering Markdown...")
html_output = renderer.render(markdown_content)
print("Rendered HTML:")
print(html_output)