Compare commits

..

26 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
1fb0a762ff added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 29s
2024-12-10 22:41:26 +01:00
31f0f49dec added middelware
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
2024-12-10 22:41:10 +01:00
669098e568 [main] Static folder
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-10 21:57:31 +01:00
3c8d51c758 added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 31s
2024-12-10 21:49:15 +01:00
0936adae7d added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 37s
2024-12-10 21:48:34 +01:00
d9001d2758 added middelware
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
2024-12-10 21:48:10 +01:00
1faff0fbc2 added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-10 21:42:33 +01:00
a8aa012c2a added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-10 21:22:15 +01:00
16578726fe added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-10 21:21:36 +01:00
97e77d8b75 [main] requirements.txt update
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Failing after 4m49s
2024-12-10 21:15:58 +01:00
1175d40710 added middelware
Some checks failed
Build, Push, and Deploy to Nomad / docker-nomad (push) Has been cancelled
2024-12-10 21:13:58 +01:00
1b56d7fef1 added middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 37s
2024-12-10 21:09:48 +01:00
b8f1414a58 Removed middelware
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 31s
2024-12-10 20:50:39 +01:00
Henrik Jess
d78efed30b https enforcement
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 33s
2024-12-10 17:42:24 +01:00
Henrik Jess
3c6004a7b1 https enforcement
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 35s
2024-12-10 17:30:58 +01:00
Henrik Jess
4230987b3f Loads of boiler plating
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 38s
2024-12-10 17:25:29 +01:00
Henrik Jess
191b21f275 Loads of boiler plating
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 36s
2024-12-10 17:20:44 +01:00
Henrik Jess
85db7fd1b3 Inspiration til filer
All checks were successful
Build, Push, and Deploy to Nomad / docker-nomad (push) Successful in 49s
2024-12-10 17:16:00 +01:00
19 changed files with 2782 additions and 1827 deletions

View File

@@ -17,4 +17,4 @@ COPY . .
EXPOSE 9210
# Command to run the FastAPI application
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "9210", "--workers", "1"]
CMD ["uvicorn", "app:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "9210", "--workers", "1"]

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

100
app.py
View File

@@ -1,15 +1,35 @@
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 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")
app = FastAPI()
# Mount static files
app.mount("/static", StaticFiles(directory="static"), name="static")
# Templates directory
templates = Jinja2Templates(directory="templates")
@@ -17,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):
@@ -25,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):

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

@@ -1,4 +1,23 @@
fastapi==0.110.0 # Latest FastAPI version
uvicorn[standard]==0.27.1 # ASGI server to run FastAPI
annotated-types==0.7.0
anyio==4.7.0
click==8.1.7
fastapi==0.115.6
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
python-dotenv==1.0.1 # Manage environment variables
pydantic_core==2.16.3
python-dotenv==1.0.1
PyYAML==6.0.2
sniffio==1.3.1
starlette==0.41.3
typing_extensions==4.12.2
uvicorn==0.32.1
uvloop==0.21.0
watchfiles==1.0.0
websockets==14.1

File diff suppressed because it is too large Load Diff

1
static/css/main.css.map Normal file

File diff suppressed because one or more lines are too long

View File

@@ -9,20 +9,20 @@
body, input, select, textarea {
color: _palette(fg);
font-family: _font(family);
font-size: 13pt;
font-size: 16pt;
font-weight: _font(weight);
line-height: 1.65;
@include breakpoint('<=xlarge') {
font-size: 11pt;
font-size: 13pt;
}
@include breakpoint('<=large') {
font-size: 10pt;
font-size: 11pt;
}
@include breakpoint('<=xxsmall') {
font-size: 9pt;
font-size: 10pt;
}
}

View File

@@ -4,7 +4,8 @@
<title>{% block title %}PortugalFAQ{% endblock %}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="{{ url_for('static', path='css/main.css') }}" />
<!-- <link rel="stylesheet" href="{{ url_for('static', path='css/main.css') }}"> -->
<link rel="stylesheet" href="/static/css/main.css">
</head>
<body class="is-preload">
<!-- Wrapper -->
@@ -39,10 +40,10 @@
</div>
<!-- Scripts -->
<script src="{{ url_for('static', path='js/jquery.min.js') }}"></script>
<script src="{{ url_for('static', path='js/browser.min.js') }}"></script>
<script src="{{ url_for('static', path='js/breakpoints.min.js') }}"></script>
<script src="{{ url_for('static', path='js/util.js') }}"></script>
<script src="{{ url_for('static', path='js/main.js') }}"></script>
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/browser.min.js"></script>
<script src="/static/js/breakpoints.min.js"></script>
<script src="/static/js/util.js"></script>
<script src="/static/js/main.js"></script>
</body>
</html>

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)