header template hinzugefügt
This commit is contained in:
1 parent
fac4f10062
commit
92f8e00fb5
6 files changed
+51
-20
No files matched your search
@@ -31,7 +31,8 @@ for d in (MD_DIR, TPL_DIR, CSS_DIR, OUT_DIR):
|
||||
|
||||
SLUG_RE = re.compile(r"^[a-z0-9][a-z0-9_-]*$", re.IGNORECASE)
|
||||
START_PAGE = "startseite"
|
||||
FOOTER_PAGE = "footer" # Baustein: wird in jede Seite eingefuegt, nicht eigenstaendig exportiert
|
||||
HEADER_PAGE = "header" # Baustein: wird ueber den Inhalt jeder Seite gesetzt
|
||||
FOOTER_PAGE = "footer" # Baustein: wird unter den Inhalt jeder Seite gesetzt
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- markdown
|
||||
@@ -174,7 +175,7 @@ def md_path(slug):
|
||||
def list_pages():
|
||||
pages = []
|
||||
for f in sorted(os.listdir(MD_DIR)):
|
||||
if f.endswith(".md") and f[:-3] != FOOTER_PAGE:
|
||||
if f.endswith(".md") and f[:-3] not in (HEADER_PAGE, FOOTER_PAGE):
|
||||
pages.append(f[:-3])
|
||||
return pages
|
||||
|
||||
@@ -197,12 +198,26 @@ def delete_page(slug):
|
||||
|
||||
# ------------------------------------------------------------------ export
|
||||
|
||||
def render_page(raw, template, footer_html=""):
|
||||
def block_html(slug):
|
||||
"""Rendert einen Baustein (header/footer) als HTML, leer wenn nicht vorhanden."""
|
||||
if os.path.exists(md_path(slug)):
|
||||
_, body = parse_md(load_page(slug))
|
||||
return md_to_html(body)
|
||||
return ""
|
||||
|
||||
|
||||
def render_page(raw, template, header_html="", footer_html=""):
|
||||
meta, body = parse_md(raw)
|
||||
html = md_to_html(body)
|
||||
page = (template
|
||||
.replace("{{titel}}", _escape(meta.get("titel", "")))
|
||||
.replace("{{inhalt}}", html))
|
||||
if "{{header}}" in template:
|
||||
page = page.replace("{{header}}", header_html)
|
||||
elif header_html and "<body>" in page:
|
||||
# Template ohne {{header}}-Platzhalter: Baustein automatisch setzen
|
||||
idx = page.index("<body>") + len("<body>")
|
||||
page = page[:idx] + "\n<header>\n" + header_html + "\n</header>\n" + page[idx:]
|
||||
if "{{footer}}" in template:
|
||||
page = page.replace("{{footer}}", footer_html)
|
||||
elif footer_html and "</body>" in page:
|
||||
@@ -232,14 +247,12 @@ def export_site():
|
||||
if f.endswith(".css"):
|
||||
shutil.copy2(os.path.join(CSS_DIR, f), os.path.join(OUT_DIR, "css", f))
|
||||
|
||||
footer_html = ""
|
||||
if os.path.exists(md_path(FOOTER_PAGE)):
|
||||
_, fbody = parse_md(load_page(FOOTER_PAGE))
|
||||
footer_html = md_to_html(fbody)
|
||||
footer_html = block_html(FOOTER_PAGE)
|
||||
header_html = block_html(HEADER_PAGE)
|
||||
|
||||
exported = []
|
||||
for slug in list_pages():
|
||||
page, _ = render_page(load_page(slug), template, footer_html)
|
||||
page, _ = render_page(load_page(slug), template, header_html, footer_html)
|
||||
# startseite.md wird zur index.html
|
||||
out_name = "index.html" if slug == START_PAGE else slug + ".html"
|
||||
with open(os.path.join(OUT_DIR, out_name), "w", encoding="utf-8") as fh:
|
||||
@@ -276,10 +289,11 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self._send(200, ADMIN_HTML, "text/html; charset=utf-8")
|
||||
elif path == "/api/pages":
|
||||
self._json({"pages": list_pages(), "start": START_PAGE,
|
||||
"header": os.path.exists(md_path(HEADER_PAGE)),
|
||||
"footer": os.path.exists(md_path(FOOTER_PAGE))})
|
||||
elif path.startswith("/api/page/"):
|
||||
slug = unquote(path[len("/api/page/"):])
|
||||
if slug == FOOTER_PAGE or slug in list_pages():
|
||||
if slug in (HEADER_PAGE, FOOTER_PAGE) or slug in list_pages():
|
||||
self._json({"slug": slug, "raw": load_page(slug)})
|
||||
else:
|
||||
self._json({"error": "Seite nicht gefunden"}, 404)
|
||||
@@ -304,10 +318,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self._json({"ok": True, "slug": slug})
|
||||
elif path == "/api/delete":
|
||||
slug = data.get("slug", "")
|
||||
if slug != FOOTER_PAGE and slug not in list_pages():
|
||||
if slug not in (HEADER_PAGE, FOOTER_PAGE) and slug not in list_pages():
|
||||
return self._json({"error": "Seite nicht gefunden"}, 404)
|
||||
if slug in (START_PAGE, FOOTER_PAGE):
|
||||
return self._json({"error": "Startseite und Footer-Baustein koennen nicht geloescht werden."}, 400)
|
||||
if slug in (START_PAGE, HEADER_PAGE, FOOTER_PAGE):
|
||||
return self._json({"error": "Startseite und Bausteine koennen nicht geloescht werden."}, 400)
|
||||
delete_page(slug)
|
||||
self._json({"ok": True})
|
||||
elif path == "/api/preview":
|
||||
@@ -384,12 +398,14 @@ async function loadPages() {
|
||||
if (p === current) a.className = "active";
|
||||
$("pages").appendChild(a);
|
||||
}
|
||||
if (d.footer) {
|
||||
const a = document.createElement("a");
|
||||
a.textContent = "footer (Baustein)";
|
||||
a.onclick = () => openPage("footer");
|
||||
if (current === "footer") a.className = "active";
|
||||
$("pages").appendChild(a);
|
||||
for (const b of [["header", d.header], ["footer", d.footer]]) {
|
||||
if (b[1]) {
|
||||
const a = document.createElement("a");
|
||||
a.textContent = b[0] + " (Baustein)";
|
||||
a.onclick = () => openPage(b[0]);
|
||||
if (current === b[0]) a.className = "active";
|
||||
$("pages").appendChild(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,9 @@
|
||||
---
|
||||
titel: Header
|
||||
---
|
||||
|
||||
# Meine Website
|
||||
|
||||
Dieser Header-Baustein wird automatisch ueber den Inhalt **aller** Seiten gesetzt.
|
||||
|
||||
- [Startseite](index.html)
|
||||
+6
-1
@@ -8,9 +8,14 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>startseite</h1>
|
||||
<h1>Meine Website</h1>
|
||||
<p>Dieser Header-Baustein wird automatisch ueber den Inhalt <strong>aller</strong> Seiten gesetzt.</p>
|
||||
<ul>
|
||||
<li><a href="index.html">Startseite</a></li>
|
||||
</ul>
|
||||
</header>
|
||||
<main>
|
||||
<h1>startseite</h1>
|
||||
<p>Neue Seite. hier kommen alle inhalte hin.</p>
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>{{titel}}</h1>
|
||||
{{header}}
|
||||
</header>
|
||||
<main>
|
||||
<h1>{{titel}}</h1>
|
||||
{{inhalt}}
|
||||
</main>
|
||||
<footer>
|
||||
|
||||
Reference in new issue
Block a user