feat: import 48 new recipes from weitere Rezepte with images and dynamic TOC pagination
@@ -400,9 +400,28 @@ async def cookbook_view(
|
|||||||
|
|
||||||
# --- Seitenzahlen & Inhaltsverzeichnis (TOC) berechnen ---
|
# --- Seitenzahlen & Inhaltsverzeichnis (TOC) berechnen ---
|
||||||
# Seite 1: Cover
|
# Seite 1: Cover
|
||||||
# TOC: Bei einzeiligem Inhaltsverzeichnis (1 Spalte) passen ca. 26 Rezepte + Kapitelheader ideal auf 1 Seite
|
# TOC: Bei einzeiligem Inhaltsverzeichnis (1 Spalte) passen ca. 24-28 Einträge (Rezepte + Kapitelheader) ideal auf 1 A4-Seite
|
||||||
total_display_recipes = len(all_recipes)
|
active_chapters = [c for c in chapters_to_display if recipes_by_chapter.get(c["number"])]
|
||||||
toc_page_count = 2 if total_display_recipes > 26 else (1 if total_display_recipes > 0 else 0)
|
toc_pages_raw = []
|
||||||
|
cur_toc = []
|
||||||
|
cur_w = 0
|
||||||
|
MAX_TOC_PAGE_WEIGHT = 26
|
||||||
|
|
||||||
|
for c in active_chapters:
|
||||||
|
c_recs = recipes_by_chapter.get(c["number"], [])
|
||||||
|
item_w = len(c_recs) + 2
|
||||||
|
if cur_w + item_w > MAX_TOC_PAGE_WEIGHT and cur_toc:
|
||||||
|
toc_pages_raw.append(cur_toc)
|
||||||
|
cur_toc = [c]
|
||||||
|
cur_w = item_w
|
||||||
|
else:
|
||||||
|
cur_toc.append(c)
|
||||||
|
cur_w += item_w
|
||||||
|
|
||||||
|
if cur_toc:
|
||||||
|
toc_pages_raw.append(cur_toc)
|
||||||
|
|
||||||
|
toc_page_count = len(toc_pages_raw)
|
||||||
current_page = 1 + toc_page_count + 1
|
current_page = 1 + toc_page_count + 1
|
||||||
|
|
||||||
display_chapters_data = []
|
display_chapters_data = []
|
||||||
@@ -423,25 +442,18 @@ async def cookbook_view(
|
|||||||
chap_copy["recipes"] = chap_recipes
|
chap_copy["recipes"] = chap_recipes
|
||||||
display_chapters_data.append(chap_copy)
|
display_chapters_data.append(chap_copy)
|
||||||
|
|
||||||
# Inhaltsverzeichnis aufteilen (falls 2 Seiten: gleichmäßige 50/50 Balance)
|
# Inhaltsverzeichnis Seiten mit vollständigen Kapitel- & Rezeptdaten
|
||||||
active_chapters = [c for c in display_chapters_data if recipes_by_chapter.get(c["number"], [])]
|
display_by_number = {c["number"]: c for c in display_chapters_data}
|
||||||
total_weight = sum(len(recipes_by_chapter.get(c["number"], [])) + 2 for c in active_chapters)
|
toc_pages = []
|
||||||
half_weight = total_weight / 2
|
for p_idx, p_chaps in enumerate(toc_pages_raw):
|
||||||
|
toc_pages.append({
|
||||||
|
"page_index": p_idx + 1,
|
||||||
|
"book_page": p_idx + 2,
|
||||||
|
"chapters": [display_by_number[c["number"]] for c in p_chaps if c["number"] in display_by_number]
|
||||||
|
})
|
||||||
|
|
||||||
toc_p1 = []
|
toc_p1 = toc_pages[0]["chapters"] if toc_pages else []
|
||||||
toc_p2 = []
|
toc_p2 = toc_pages[1]["chapters"] if len(toc_pages) > 1 else []
|
||||||
if toc_page_count == 2:
|
|
||||||
accum = 0
|
|
||||||
for c in active_chapters:
|
|
||||||
c_recs = recipes_by_chapter.get(c["number"], [])
|
|
||||||
item_weight = len(c_recs) + 2
|
|
||||||
if accum < half_weight or not toc_p1:
|
|
||||||
toc_p1.append(c)
|
|
||||||
accum += item_weight
|
|
||||||
else:
|
|
||||||
toc_p2.append(c)
|
|
||||||
else:
|
|
||||||
toc_p1 = active_chapters
|
|
||||||
|
|
||||||
# User Agent Check für Apple iOS
|
# User Agent Check für Apple iOS
|
||||||
user_agent = request.headers.get("user-agent", "").lower()
|
user_agent = request.headers.get("user-agent", "").lower()
|
||||||
@@ -457,6 +469,7 @@ async def cookbook_view(
|
|||||||
"recipes_by_chapter": recipes_by_chapter,
|
"recipes_by_chapter": recipes_by_chapter,
|
||||||
"recipe_counts": recipe_counts,
|
"recipe_counts": recipe_counts,
|
||||||
"total_recipes": len(all_recipes),
|
"total_recipes": len(all_recipes),
|
||||||
|
"toc_pages": toc_pages,
|
||||||
"toc_page_count": toc_page_count,
|
"toc_page_count": toc_page_count,
|
||||||
"toc_p1": toc_p1,
|
"toc_p1": toc_p1,
|
||||||
"toc_p2": toc_p2,
|
"toc_p2": toc_p2,
|
||||||
|
|||||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 632 KiB |
|
After Width: | Height: | Size: 447 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 323 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 777 KiB |
|
After Width: | Height: | Size: 163 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 174 KiB |
@@ -614,17 +614,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- INHALTSVERZEICHNIS (TOC) -->
|
<!-- INHALTSVERZEICHNIS (TOC) -->
|
||||||
{% if total_recipes > 0 %}
|
{% if total_recipes > 0 and toc_pages %}
|
||||||
<!-- TOC SEITE 1 (Seite 2 des Buchs) -->
|
{% for toc_page in toc_pages %}
|
||||||
<div class="page toc-page" id="page-toc-1">
|
<div class="page toc-page" id="page-toc-{{ toc_page.page_index }}">
|
||||||
<header class="toc-header">
|
<header class="toc-header">
|
||||||
<div class="toc-subhead">Übersicht aller Gerichte</div>
|
<div class="toc-subhead">Übersicht aller Gerichte</div>
|
||||||
<h2 class="toc-title">Inhaltsverzeichnis{% if toc_page_count > 1 %} <span style="font-size: 1.3rem; font-weight: normal; color: var(--gold);">(Teil 1)</span>{% endif %}</h2>
|
<h2 class="toc-title">Inhaltsverzeichnis{% if toc_pages|length > 1 %} <span style="font-size: 1.3rem; font-weight: normal; color: var(--gold);">(Teil {{ toc_page.page_index }})</span>{% endif %}</h2>
|
||||||
<div class="toc-divider-ornament">✦ ✦ ✦</div>
|
<div class="toc-divider-ornament">✦ ✦ ✦</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="toc-columns">
|
<div class="toc-columns">
|
||||||
{% for chap in toc_p1 %}
|
{% for chap in toc_page.chapters %}
|
||||||
<div class="toc-chapter-group" data-chapter="{{ chap.number }}">
|
<div class="toc-chapter-group" data-chapter="{{ chap.number }}">
|
||||||
<div class="toc-chapter-header">
|
<div class="toc-chapter-header">
|
||||||
<span class="toc-chap-icon">{{ chap.icon }}</span>
|
<span class="toc-chap-icon">{{ chap.icon }}</span>
|
||||||
@@ -647,49 +647,11 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="page-footer page-even">
|
<footer class="page-footer {% if toc_page.book_page % 2 == 0 %}page-even{% else %}page-odd{% endif %}">
|
||||||
<span class="page-number">2</span>
|
<span class="page-number">{{ toc_page.book_page }}</span>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
<!-- TOC SEITE 2 (Seite 3 des Buchs, falls > 55 Rezepte) -->
|
|
||||||
{% if toc_page_count > 1 %}
|
|
||||||
<div class="page toc-page" id="page-toc-2">
|
|
||||||
<header class="toc-header">
|
|
||||||
<div class="toc-subhead">Übersicht aller Gerichte</div>
|
|
||||||
<h2 class="toc-title">Inhaltsverzeichnis <span style="font-size: 1.3rem; font-weight: normal; color: var(--gold);">(Teil 2)</span></h2>
|
|
||||||
<div class="toc-divider-ornament">✦ ✦ ✦</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="toc-columns">
|
|
||||||
{% for chap in toc_p2 %}
|
|
||||||
<div class="toc-chapter-group" data-chapter="{{ chap.number }}">
|
|
||||||
<div class="toc-chapter-header">
|
|
||||||
<span class="toc-chap-icon">{{ chap.icon }}</span>
|
|
||||||
<span class="toc-chap-title">Kapitel {{ chap.number }}: {{ chap.title }}</span>
|
|
||||||
<span class="toc-dots"></span>
|
|
||||||
<span class="toc-page-num" data-page-ref="kapitel-{{ chap.number }}">{{ chap.page_number }}</span>
|
|
||||||
</div>
|
|
||||||
<ul class="toc-recipe-list">
|
|
||||||
{% for r in chap.recipes %}
|
|
||||||
<li class="toc-recipe-item" data-recipe-id="{{ r.id }}">
|
|
||||||
<a href="#rezept-{{ r.id }}" class="toc-recipe-link">
|
|
||||||
<span class="toc-rec-title">{{ r.title }}</span>
|
|
||||||
<span class="toc-dots"></span>
|
|
||||||
<span class="toc-page-num" data-page-ref="rezept-{{ r.id }}">{{ r.page_number }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="page-footer page-odd">
|
|
||||||
<span class="page-number">3</span>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||