feat: verwendete Prompts im Archiv ausklappbar anzeigen
Speichert OpenRouter- und SDXL-Prompts pro Archiv-Eintrag und zeigt sie auf der Übersichtsseite in aufklappbaren Details an. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -255,6 +255,7 @@ def render_template(name: str, context: dict) -> str:
|
|||||||
def build_archiv_entries(archive: list[dict]) -> list[dict]:
|
def build_archiv_entries(archive: list[dict]) -> list[dict]:
|
||||||
entries = []
|
entries = []
|
||||||
for item in sorted(archive, key=lambda e: e["date"], reverse=True):
|
for item in sorted(archive, key=lambda e: e["date"], reverse=True):
|
||||||
|
prompts = item.get("prompts")
|
||||||
entries.append(
|
entries.append(
|
||||||
{
|
{
|
||||||
"date": item["date"],
|
"date": item["date"],
|
||||||
@@ -264,6 +265,7 @@ def build_archiv_entries(archive: list[dict]) -> list[dict]:
|
|||||||
"url": f"/archiv/{item['date']}.html",
|
"url": f"/archiv/{item['date']}.html",
|
||||||
"image": f"/img/{item['date']}.jpg" if item.get("has_image") else None,
|
"image": f"/img/{item['date']}.jpg" if item.get("has_image") else None,
|
||||||
"topics": item.get("topics", []),
|
"topics": item.get("topics", []),
|
||||||
|
"prompts": prompts if isinstance(prompts, dict) else None,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return entries
|
return entries
|
||||||
@@ -343,6 +345,12 @@ def main() -> int:
|
|||||||
"theme": theme,
|
"theme": theme,
|
||||||
"topics": [topic["name"] for topic in selected_topics],
|
"topics": [topic["name"] for topic in selected_topics],
|
||||||
"has_image": hero_image is not None,
|
"has_image": hero_image is not None,
|
||||||
|
"prompts": {
|
||||||
|
"content_system": build_system_prompt(),
|
||||||
|
"content_user": build_user_prompt(selected_topics),
|
||||||
|
"image_prompt": llm_json["image_prompt"],
|
||||||
|
"image_negative_prompt": llm_json["image_negative_prompt"],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
archive = [entry for entry in archive if entry.get("date") != date_iso]
|
archive = [entry for entry in archive if entry.get("date") != date_iso]
|
||||||
archive.append(archive_entry)
|
archive.append(archive_entry)
|
||||||
|
|||||||
@@ -114,12 +114,19 @@
|
|||||||
transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
|
transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-card:hover {
|
.entry-card:has(.entry-link:hover) {
|
||||||
border-color: #4a4a60;
|
border-color: #4a4a60;
|
||||||
transform: translateY(-3px);
|
transform: translateY(-3px);
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entry-link {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.entry-thumb {
|
.entry-thumb {
|
||||||
aspect-ratio: 16 / 9;
|
aspect-ratio: 16 / 9;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -177,6 +184,80 @@
|
|||||||
border: 1px solid #3a3a50;
|
border: 1px solid #3a3a50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entry-prompts {
|
||||||
|
border-top: 1px solid #2a2a38;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-prompts > summary {
|
||||||
|
padding: 0.75rem 1.25rem;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #8888a0;
|
||||||
|
font-weight: 600;
|
||||||
|
list-style: none;
|
||||||
|
user-select: none;
|
||||||
|
transition: color 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-prompts > summary::-webkit-details-marker { display: none; }
|
||||||
|
|
||||||
|
.entry-prompts > summary::before {
|
||||||
|
content: "▸ ";
|
||||||
|
display: inline-block;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-prompts[open] > summary::before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-prompts > summary:hover {
|
||||||
|
color: #c8c8d8;
|
||||||
|
background: #222230;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-panel {
|
||||||
|
padding: 0 1.25rem 1.25rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-block h3 {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
color: #686880;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-text {
|
||||||
|
font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, monospace;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #b8b8cc;
|
||||||
|
background: #111118;
|
||||||
|
border: 1px solid #2a2a38;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.75rem;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
max-height: 14rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
color: #585870;
|
||||||
|
margin: 0.6rem 0 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-label:first-child { margin-top: 0; }
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
.footer {
|
.footer {
|
||||||
border-top: 1px solid #2a2a38;
|
border-top: 1px solid #2a2a38;
|
||||||
@@ -229,7 +310,8 @@
|
|||||||
{% if entries %}
|
{% if entries %}
|
||||||
<div class="archive-grid">
|
<div class="archive-grid">
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<a href="{{ entry.url }}" class="entry-card">
|
<article class="entry-card">
|
||||||
|
<a href="{{ entry.url }}" class="entry-link">
|
||||||
<div class="entry-thumb">
|
<div class="entry-thumb">
|
||||||
{% if entry.image %}
|
{% if entry.image %}
|
||||||
<img src="{{ entry.image }}" alt="{{ entry.backronym }}" width="360" height="203" loading="lazy">
|
<img src="{{ entry.image }}" alt="{{ entry.backronym }}" width="360" height="203" loading="lazy">
|
||||||
@@ -248,6 +330,36 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
{% if entry.prompts %}
|
||||||
|
<details class="entry-prompts">
|
||||||
|
<summary>Prompts anzeigen</summary>
|
||||||
|
<div class="prompt-panel">
|
||||||
|
<div class="prompt-block">
|
||||||
|
<h3>Seiteninhalt (OpenRouter)</h3>
|
||||||
|
{% if entry.prompts.content_system %}
|
||||||
|
<p class="prompt-label">System</p>
|
||||||
|
<pre class="prompt-text">{{ entry.prompts.content_system }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
{% if entry.prompts.content_user %}
|
||||||
|
<p class="prompt-label">User</p>
|
||||||
|
<pre class="prompt-text">{{ entry.prompts.content_user }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="prompt-block">
|
||||||
|
<h3>Bildgenerierung (SDXL)</h3>
|
||||||
|
{% if entry.prompts.image_prompt %}
|
||||||
|
<p class="prompt-label">Prompt</p>
|
||||||
|
<pre class="prompt-text">{{ entry.prompts.image_prompt }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
{% if entry.prompts.image_negative_prompt %}
|
||||||
|
<p class="prompt-label">Negative Prompt</p>
|
||||||
|
<pre class="prompt-text">{{ entry.prompts.image_negative_prompt }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
Reference in New Issue
Block a user