Files
computer-playbook/roles/web-app-fediwall/templates/wall-config.json.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

33 lines
1.4 KiB
Django/Jinja

{# Per-wall config rendered for slug '{{ wall.slug }}'.
Every field is taken VERBATIM from
meta/services.yml.fediwall.walls[*].config — services.yml is the
single point of truth, no defaults are computed here. An empty
`servers` list renders as an empty array; the operator (or a
variant) declares the literal sibling domains they want polled. #}
{
"servers": {{ wall.config.servers | to_json }},
"tags": {{ wall.config.tags | to_json }},
"accounts": {{ wall.config.accounts | to_json }},
"loadPublic": {{ wall.config.loadPublic | to_json }},
"loadFederated": {{ wall.config.loadFederated | to_json }},
"loadTrends": {{ wall.config.loadTrends | to_json }},
"languages": {{ wall.config.languages | to_json }},
"badWords": {{ wall.config.badWords | to_json }},
"hideSensitive": {{ wall.config.hideSensitive | to_json }},
"hideBots": {{ wall.config.hideBots | to_json }},
"hideReplies": {{ wall.config.hideReplies | to_json }},
"hideBoosts": {{ wall.config.hideBoosts | to_json }},
"limit": {{ wall.config.limit | to_json }},
"interval": {{ wall.config.interval | to_json }},
"title": {{ wall.config.title | to_json }},
"theme": {{ wall.config.theme | to_json }},
"showInfobar": {{ wall.config.showInfobar | to_json }},
"showText": {{ wall.config.showText | to_json }},
"showMedia": {{ wall.config.showMedia | to_json }},
"playVideos": {{ wall.config.playVideos | to_json }}
}