✨ sections
This commit is contained in:
42
app.py
42
app.py
@@ -7,9 +7,9 @@ from datetime import datetime
|
||||
from flask import Flask, render_template, abort, jsonify, request
|
||||
from comics_data import (
|
||||
COMICS, COMIC_NAME, SITE_URL, FULL_WIDTH_DEFAULT, PLAIN_DEFAULT, LOGO_IMAGE, LOGO_MODE,
|
||||
HEADER_IMAGE, FOOTER_IMAGE, COMPACT_FOOTER, ARCHIVE_FULL_WIDTH, USE_COMIC_NAV_ICONS,
|
||||
USE_HEADER_NAV_ICONS, USE_FOOTER_SOCIAL_ICONS, SOCIAL_INSTAGRAM, SOCIAL_YOUTUBE,
|
||||
SOCIAL_EMAIL, API_SPEC_LINK
|
||||
HEADER_IMAGE, FOOTER_IMAGE, COMPACT_FOOTER, ARCHIVE_FULL_WIDTH, SECTIONS_ENABLED,
|
||||
USE_COMIC_NAV_ICONS, USE_HEADER_NAV_ICONS, USE_FOOTER_SOCIAL_ICONS, SOCIAL_INSTAGRAM,
|
||||
SOCIAL_YOUTUBE, SOCIAL_EMAIL, API_SPEC_LINK
|
||||
)
|
||||
import markdown
|
||||
|
||||
@@ -31,6 +31,7 @@ def inject_global_settings():
|
||||
'footer_image': FOOTER_IMAGE,
|
||||
'compact_footer': COMPACT_FOOTER,
|
||||
'archive_full_width': ARCHIVE_FULL_WIDTH,
|
||||
'sections_enabled': SECTIONS_ENABLED,
|
||||
'use_comic_nav_icons': USE_COMIC_NAV_ICONS,
|
||||
'use_header_nav_icons': USE_HEADER_NAV_ICONS,
|
||||
'use_footer_social_icons': USE_FOOTER_SOCIAL_ICONS,
|
||||
@@ -141,13 +142,46 @@ def comic(comic_id):
|
||||
comic=comic, total_comics=len(COMICS))
|
||||
|
||||
|
||||
def group_comics_by_section(comics_list):
|
||||
"""Group comics by section. Returns list of (section_title, comics) tuples"""
|
||||
if not SECTIONS_ENABLED:
|
||||
return [(None, comics_list)]
|
||||
|
||||
sections = []
|
||||
current_section = None
|
||||
current_comics = []
|
||||
|
||||
for comic in comics_list:
|
||||
# Check if this comic starts a new section
|
||||
if 'section' in comic:
|
||||
# Save previous section if it has comics
|
||||
if current_comics:
|
||||
sections.append((current_section, current_comics))
|
||||
# Start new section
|
||||
current_section = comic['section']
|
||||
current_comics = [comic]
|
||||
else:
|
||||
# Add to current section
|
||||
current_comics.append(comic)
|
||||
|
||||
# Don't forget the last section
|
||||
if current_comics:
|
||||
sections.append((current_section, current_comics))
|
||||
|
||||
return sections
|
||||
|
||||
|
||||
@app.route('/archive')
|
||||
def archive():
|
||||
"""Archive page showing all comics"""
|
||||
# Reverse order to show newest first
|
||||
comics = [enrich_comic(comic) for comic in reversed(COMICS)]
|
||||
|
||||
# Group by section if enabled
|
||||
sections = group_comics_by_section(comics)
|
||||
|
||||
return render_template('archive.html', title='Archive',
|
||||
comics=comics)
|
||||
sections=sections)
|
||||
|
||||
|
||||
@app.route('/about')
|
||||
|
||||
@@ -48,6 +48,10 @@ COMPACT_FOOTER = False
|
||||
# Full-width archive shows square thumbnails with only dates, no titles
|
||||
ARCHIVE_FULL_WIDTH = True
|
||||
|
||||
# Global setting: Set to True to enable sections/chapters on the archive page
|
||||
# Add 'section': 'Chapter Title' to comics where a new section starts
|
||||
SECTIONS_ENABLED = True
|
||||
|
||||
# Global setting: Set to True to use icon images for comic navigation buttons
|
||||
# Icons should be in static/images/icons/ (first.png, previous.png, next.png, latest.png)
|
||||
USE_COMIC_NAV_ICONS = True
|
||||
@@ -80,6 +84,7 @@ COMICS = [
|
||||
'author_note': 'This is where your comic journey begins!',
|
||||
'full_width': True, # Optional: override FULL_WIDTH_DEFAULT for this comic
|
||||
'plain': True, # Optional: override PLAIN_DEFAULT for this comic
|
||||
'section': 'Chapter 1: The Beginning', # Optional: start a new section on archive page
|
||||
},
|
||||
{
|
||||
'number': 2,
|
||||
|
||||
@@ -468,6 +468,25 @@ main {
|
||||
margin-top: var(--space-md);
|
||||
}
|
||||
|
||||
/* Section Headers for Archive */
|
||||
.section-header {
|
||||
margin-top: var(--space-2xl);
|
||||
margin-bottom: var(--space-lg);
|
||||
padding-bottom: var(--space-sm);
|
||||
border-bottom: var(--border-width-thin) solid var(--border-color);
|
||||
}
|
||||
|
||||
.section-header:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.section-header h2 {
|
||||
color: var(--color-text);
|
||||
font-size: var(--font-size-xl);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: var(--letter-spacing-tight);
|
||||
}
|
||||
|
||||
.archive-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(var(--archive-grid-min), 1fr));
|
||||
|
||||
@@ -7,27 +7,35 @@
|
||||
|
||||
<div class="page-header{% if archive_full_width %} page-header-fullwidth{% endif %}">
|
||||
<h1>Comic Archive</h1>
|
||||
<p>Browse all {{ comics|length }} comics</p>
|
||||
<p>Browse all {% set total = namespace(count=0) %}{% for section_title, section_comics in sections %}{% set total.count = total.count + section_comics|length %}{% endfor %}{{ total.count }} comics</p>
|
||||
</div>
|
||||
|
||||
<section class="archive-content{% if archive_full_width %} archive-content-fullwidth{% endif %}">
|
||||
<div class="archive-grid{% if archive_full_width %} archive-grid-fullwidth{% endif %}">
|
||||
{% for comic in comics %}
|
||||
<div class="archive-item{% if archive_full_width %} archive-item-fullwidth{% endif %}">
|
||||
<a href="{{ url_for('comic', comic_id=comic.number) }}">
|
||||
<img src="{{ url_for('static', filename='images/thumbs/' + comic.filename) }}"
|
||||
onerror="this.onerror=null; this.src='{{ url_for('static', filename='images/thumbs/default.jpg') }}';"
|
||||
alt="{{ comic.title if comic.title else '#' ~ comic.number }}">
|
||||
<div class="archive-info">
|
||||
{% if not archive_full_width %}
|
||||
<h3>#{{ comic.number }}{% if comic.title %}: {{ comic.title }}{% endif %}</h3>
|
||||
{% endif %}
|
||||
<p class="archive-date">{{ comic.date }}</p>
|
||||
</div>
|
||||
</a>
|
||||
{% for section_title, section_comics in sections %}
|
||||
{% if section_title and sections_enabled %}
|
||||
<div class="section-header">
|
||||
<h2>{{ section_title }}</h2>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="archive-grid{% if archive_full_width %} archive-grid-fullwidth{% endif %}">
|
||||
{% for comic in section_comics %}
|
||||
<div class="archive-item{% if archive_full_width %} archive-item-fullwidth{% endif %}">
|
||||
<a href="{{ url_for('comic', comic_id=comic.number) }}">
|
||||
<img src="{{ url_for('static', filename='images/thumbs/' + comic.filename) }}"
|
||||
onerror="this.onerror=null; this.src='{{ url_for('static', filename='images/thumbs/default.jpg') }}';"
|
||||
alt="{{ comic.title if comic.title else '#' ~ comic.number }}">
|
||||
<div class="archive-info">
|
||||
{% if not archive_full_width %}
|
||||
<h3>#{{ comic.number }}{% if comic.title %}: {{ comic.title }}{% endif %}</h3>
|
||||
{% endif %}
|
||||
<p class="archive-date">{{ comic.date }}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</section>
|
||||
|
||||
{% if archive_full_width %}
|
||||
|
||||
Reference in New Issue
Block a user