Files
computer-playbook/roles/web-app-fediwall/templates/index.html.j2
kevinveenbirkenbachandClaude Opus 4.7 c6f4b7fb4b feat(web-app-fediwall): integrate Fediwall as multi-wall public timeline aggregator
New Ansible role rendering one Fediwall instance with one or more
configurable walls under https://fediwall.<DOMAIN_PRIMARY>/<slug>/. Each
wall's `wall-config.json` is forwarded VERBATIM from
meta/services.yml.fediwall.walls[*].config — the YAML there is the
single source of truth, the role's template applies no defaults. Two
matrix-deploy variants ship: variant 0 inherits the services.yml
default (one wall, polls all active Mastodon-API-compatible siblings via
the new `lookup('fediwall_active', ...)` plugin); variant 1 overrides
with two explicitly configured walls (default + mastodon-only) so the
per-wall server scoping is observable end-to-end.

End-to-end Playwright spec drives biber's first OIDC login on Mastodon
and ldapauth-mediated form login on Friendica through the same web UI a
human would use — biber's local accounts come into existence lazily on
first SSO login, exactly as in production. The cross-Fediverse test is
data-driven against each wall's `wall-config.json.servers`: a sibling's
post is visible iff its host is listed there.

Cross-cutting fixes that surfaced during the iteration ship alongside:

- utils/cache + utils/templating: type-preserving render path for
  single-Jinja-expression scalars in `lookup('config', ...)`.
  `_templar_render_best_effort` always coerced its output to `str`, so a
  list-returning lookup like `{{ lookup('fediwall_active', 'domains') }}`
  collapsed to its Python repr. `_render_scalar` now detects the
  `{{ ... }}`-only shape and routes it through the new
  `_templar_render_preserve_type` helper, which returns templar's
  native value (list/dict/etc.) instead of stringifying.

- web-app-friendica/tasks/04_addons.yml: force a `disable` + `enable`
  cycle for enabled addons. Friendica's `addon enable` only fires the
  `_install` hooks on the disabled→enabled transition, so an
  already-enabled-but-broken state (the addon shows up in `list
  enabled` but its `_install`-registered hooks are missing from the
  `hook` DB table) silently rejected every ldapauth login at runtime.
  Cycling through disable+enable reliably re-registers the hooks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:50:05 +02:00

41 lines
1.6 KiB
Django/Jinja

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% if FEDIWALL_WALLS | length == 1 %}
<meta http-equiv="refresh" content="0; url=./{{ FEDIWALL_WALLS[0].slug }}/">
<link rel="canonical" href="./{{ FEDIWALL_WALLS[0].slug }}/">
<title>Redirecting to {{ FEDIWALL_WALLS[0].config.title }}…</title>
</head>
<body>
<p><a href="./{{ FEDIWALL_WALLS[0].slug }}/">Open {{ FEDIWALL_WALLS[0].config.title }}</a></p>
</body>
{% else %}
<title>Fediwalls on {{ DOMAIN_PRIMARY }}</title>
<link rel="shortcut icon" type="image/png" href="./favicon.png">
<style>
body { font: 16px/1.5 system-ui, sans-serif; margin: 2rem auto; max-width: 40rem; padding: 0 1rem; color: #222; background: #fafafa; }
h1 { font-size: 1.5rem; margin-bottom: 1.5rem; }
ul { list-style: none; padding: 0; }
li { margin: 0.5rem 0; }
a { color: #1a73e8; text-decoration: none; padding: 0.5rem 0.75rem; border: 1px solid #ddd; border-radius: 0.375rem; display: inline-block; background: #fff; }
a:hover { background: #f0f4ff; border-color: #1a73e8; }
@media (prefers-color-scheme: dark) {
body { color: #eee; background: #121212; }
a { color: #82b1ff; background: #1e1e1e; border-color: #333; }
a:hover { background: #1f2a44; border-color: #82b1ff; }
}
</style>
</head>
<body>
<h1>Fediwalls on {{ DOMAIN_PRIMARY }}</h1>
<ul>
{% for wall in FEDIWALL_WALLS %}
<li><a href="./{{ wall.slug }}/">{{ wall.config.title }}</a></li>
{% endfor %}
</ul>
</body>
{% endif %}
</html>