Utdrag på forsiden og forenklet favicon
Forsiden viser første avsnitt av hvert innlegg som ren tekst (nytt Jinja-filter `excerpt`, tilgjengelig for egne temaer). Favicon har færre og større former med tykkere streker så det holder seg ved 16 px. Siste to punkter fra UI-gjennomgangen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JcEy43fNYpwg6K6oTKakWR
This commit is contained in:
parent
ae3d6a4c0c
commit
50722bf7c2
8 changed files with 35 additions and 29 deletions
|
|
@ -107,7 +107,7 @@ cp soapbox/themes/green/static/style.css data/content/themes/skog/static/ # re
|
|||
Et tema kan være **delvis**: bare filene som finnes overstyrer det innebygde `green`-temaet.
|
||||
Vil du endre malene, legg `templates/base.html`, `index.html` eller `post.html` i temamappen.
|
||||
Malene får `site`, `posts`/`post`, `html`, `source_url` og `rel(sti)` (relativ lenke fra
|
||||
gjeldende side). `static/` havner under `/theme/`.
|
||||
gjeldende side), samt filtrene `date` og `excerpt(n)`. `static/` havner under `/theme/`.
|
||||
|
||||
## Lisens
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ def _env(cfg: Config) -> Environment:
|
|||
autoescape=select_autoescape(["html"]),
|
||||
)
|
||||
env.filters["date"] = lambda d, fmt="%d.%m.%Y": d.strftime(fmt)
|
||||
env.filters["excerpt"] = excerpt
|
||||
return env
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ interne lenker som forfatteren skriver (``/annet-innlegg/``) skrives om til
|
|||
from __future__ import annotations
|
||||
|
||||
import posixpath
|
||||
import re
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from markdown_it import MarkdownIt
|
||||
|
|
@ -69,5 +70,10 @@ def excerpt(text: str, limit: int = 300) -> str:
|
|||
para = para.strip()
|
||||
if para and not para.startswith(("#", "!", "```", "|")):
|
||||
plain = " ".join(para.split())
|
||||
# Fjern den vanligste inline-markeringen så utdraget leses som ren tekst
|
||||
plain = re.sub(r"!\[[^\]]*\]\([^)]*\)", "", plain) # bilder
|
||||
plain = re.sub(r"\[([^\]]+)\]\([^)]*\)", r"\1", plain) # lenker → tekst
|
||||
plain = re.sub(r"[*_`~]{1,3}", "", plain)
|
||||
plain = " ".join(plain.split()) # doble mellomrom etter fjernede bilder
|
||||
return plain if len(plain) <= limit else plain[:limit].rsplit(" ", 1)[0] + "…"
|
||||
return ""
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<!-- Såpeboks: en trekasse man kan stå på, med et såpestykke oppå. -->
|
||||
<!-- Kassen -->
|
||||
<rect x="8" y="34" width="48" height="24" rx="2" fill="#1f6b3a"/>
|
||||
<rect x="12" y="38" width="40" height="16" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<!-- Planker -->
|
||||
<line x1="12" y1="46" x2="52" y2="46" stroke="#7fd39a" stroke-width="2"/>
|
||||
<line x1="32" y1="38" x2="32" y2="54" stroke="#7fd39a" stroke-width="2"/>
|
||||
<!-- Såpestykke -->
|
||||
<rect x="17" y="21" width="30" height="13" rx="6" fill="#e8f5ec" stroke="#154d29" stroke-width="2"/>
|
||||
<ellipse cx="27" cy="26" rx="5" ry="2" fill="#fff" opacity=".8"/>
|
||||
<!-- Bobler -->
|
||||
<circle cx="48" cy="14" r="4" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<circle cx="40" cy="8" r="2.5" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<circle cx="54" cy="6" r="1.5" fill="#7fd39a"/>
|
||||
<!-- Såpeboks: en trekasse man kan stå på, med et såpestykke oppå.
|
||||
Få, store former og tykke streker så ikonet holder seg ved 16 px. -->
|
||||
<rect x="6" y="34" width="52" height="26" rx="3" fill="#1f6b3a"/>
|
||||
<line x1="6" y1="47" x2="58" y2="47" stroke="#7fd39a" stroke-width="3"/>
|
||||
<rect x="15" y="19" width="34" height="15" rx="7" fill="#e8f5ec" stroke="#154d29" stroke-width="3"/>
|
||||
<circle cx="50" cy="11" r="5" fill="none" stroke="#7fd39a" stroke-width="3"/>
|
||||
<circle cx="39" cy="7" r="2.5" fill="#7fd39a"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 919 B After Width: | Height: | Size: 597 B |
|
|
@ -1,16 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<!-- Såpeboks: en trekasse man kan stå på, med et såpestykke oppå. -->
|
||||
<!-- Kassen -->
|
||||
<rect x="8" y="34" width="48" height="24" rx="2" fill="#1f6b3a"/>
|
||||
<rect x="12" y="38" width="40" height="16" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<!-- Planker -->
|
||||
<line x1="12" y1="46" x2="52" y2="46" stroke="#7fd39a" stroke-width="2"/>
|
||||
<line x1="32" y1="38" x2="32" y2="54" stroke="#7fd39a" stroke-width="2"/>
|
||||
<!-- Såpestykke -->
|
||||
<rect x="17" y="21" width="30" height="13" rx="6" fill="#e8f5ec" stroke="#154d29" stroke-width="2"/>
|
||||
<ellipse cx="27" cy="26" rx="5" ry="2" fill="#fff" opacity=".8"/>
|
||||
<!-- Bobler -->
|
||||
<circle cx="48" cy="14" r="4" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<circle cx="40" cy="8" r="2.5" fill="none" stroke="#7fd39a" stroke-width="2"/>
|
||||
<circle cx="54" cy="6" r="1.5" fill="#7fd39a"/>
|
||||
<!-- Såpeboks: en trekasse man kan stå på, med et såpestykke oppå.
|
||||
Få, store former og tykke streker så ikonet holder seg ved 16 px. -->
|
||||
<rect x="6" y="34" width="52" height="26" rx="3" fill="#1f6b3a"/>
|
||||
<line x1="6" y1="47" x2="58" y2="47" stroke="#7fd39a" stroke-width="3"/>
|
||||
<rect x="15" y="19" width="34" height="15" rx="7" fill="#e8f5ec" stroke="#154d29" stroke-width="3"/>
|
||||
<circle cx="50" cy="11" r="5" fill="none" stroke="#7fd39a" stroke-width="3"/>
|
||||
<circle cx="39" cy="7" r="2.5" fill="#7fd39a"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 919 B After Width: | Height: | Size: 597 B |
|
|
@ -80,6 +80,7 @@ h2 { font-size: 1.4rem; line-height: 1.25; margin: 2rem 0 .5rem; }
|
|||
.summary h2 a { color: var(--accent-strong); text-decoration: none; }
|
||||
.summary h2 a:hover { text-decoration: underline; }
|
||||
.summary .meta { margin: 0; }
|
||||
.summary .excerpt { margin: .5rem 0 0; color: var(--fg); }
|
||||
.body p, .body ul, .body ol { margin: 0 0 1.1rem; }
|
||||
.body img { max-width: 100%; height: auto; display: block; margin: 1.5rem 0; border-radius: 4px; }
|
||||
.body pre { background: var(--code-bg); padding: 1rem; overflow-x: auto; border-radius: 4px; }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
<time datetime="{{ post.date.isoformat() }}">{{ post.date|date }}</time>
|
||||
{% if post.guest %} · <a href="{{ rel(post.guest ~ '/') }}">{{ post.author or post.guest }}</a>{% endif %}
|
||||
</p>
|
||||
{% set text = post.body|excerpt(220) %}{% if text %}<p class="excerpt">{{ text }}</p>{% endif %}
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -57,3 +57,14 @@ def test_password_hashing(tmp_path):
|
|||
assert db.authenticate(conn, "a", "feil") is None
|
||||
assert db.has_owner(conn)
|
||||
assert datetime.now(UTC) # sanity: UTC alias tilgjengelig
|
||||
|
||||
|
||||
def test_excerpt_plain_text():
|
||||
from soapbox.render import excerpt
|
||||
|
||||
assert (
|
||||
excerpt("Hei **verden**. Se [forsiden](/) og  _her_.")
|
||||
== "Hei verden. Se forsiden og her."
|
||||
)
|
||||
assert excerpt("# Overskrift\n\n```\nkode\n```\n\nTekst") == "Tekst"
|
||||
assert excerpt("x " * 200, 50).endswith("…")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue