Domain-specific templates moved from shared/browser/templates/ to
each app's templates/ dir. 38 domain-free infrastructure templates
remain (root layout, macros, oob, mobile, social, sentinel).
Removed fragment fallbacks from root header.
Deleted _widgets/ (dead code since Phase 4-5).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Account nav links and page panels (tickets, bookings) now fetched
as HTML fragments from events app instead of using widget registry.
All three widget registration functions are now no-ops.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Templates now consume container_nav_html and card_widgets_html from
fragment fetches instead of iterating widgets.container_nav / container_cards.
OOB nav template renders entry/calendar links directly from data.
Calendar and market widget registrations removed (account widgets remain).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously only 'cart' was mapped — slugs like 'federation', 'market',
'events', 'account' incorrectly linked to blog_url(). Now all app
slugs resolve to their proper cross-app URLs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The shared _header.html template now checks for pre-fetched fragment
HTML (nav_tree_html, auth_menu_html, cart_mini_html) before falling
back to local includes. This lets consumer apps render cross-app
UI via the fragment composition system.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Avoids collision with app-level url_value_preprocessor that pops
"slug" for page-level routing. All url_for() calls for product
endpoints now use product_slug= instead of slug=.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Nav sign-in links point to account_url('/') instead of login_url()
- After-request hook clears old blog_session cookie on .rose-ash.com
(prevents collision with new per-app first-party cookies)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The logged-in user links in _full_user.html (desktop + mobile)
still used blog_url — now they use federation_url to match
the account page migration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Auth templates and widget nav links now point to
federation_url instead of blog_url, co-locating the
account UI with the auth system in the federation app.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Templates were incorrectly identified as dead code because individual
apps override them, but other apps still depend on the shared versions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Delete shared/models/domain_event.py (table dropped, model orphaned)
- Delete 39 shared templates that are overridden by app-local copies:
- 8 blog overrides (blog/_action_buttons, post/_meta, etc.)
- 27 events overrides (calendar/*, day/*, entry/*, post_entries/*)
- 4 market overrides (market/index, browse/_oob_elements, etc.)
These shared copies were never served — Quart loads app-level
templates first, so the app-local versions always win.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cart app has its own override with ticket support. The shared
copy was never used and would only cause confusion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The login URL is cross-origin (blog app), so hx-get can't load it
into the current page. Use a regular <a href> for cross-app navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds get_followers_paginated and get_actor_timeline to FederationService
protocol + SQL implementation + stubs. Includes accumulated federation
changes: models, DTOs, delivery handler, webfinger, inline publishing,
widget nav templates, and migration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Edit: placeholder "Page title..." vs "Post title..."
- Settings: slug placeholder, featured checkbox, custom template
all say "page" when is_page is true
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pages are container/landing pages, not blog posts. Hide the like
button, tags/authors bar, and excerpt when post.is_page is true.
Feature image and content still render for both.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the macro is imported without context ({% from ... import mini %}),
template variables like cart_count aren't visible. The new count param
allows callers to pass it explicitly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reserved tickets now flow through the cart and checkout pipeline:
- TicketDTO gains price, entry_id, order_id, calendar_container_id
- CartSummaryDTO gains ticket_count, ticket_total
- 6 new CalendarService methods for ticket lifecycle
- cart_summary includes tickets; login adoption migrates tickets
- New _ticket_items.html template for checkout return page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a widget system where domains register UI fragments into
named slots (container_nav, container_card, account_page, account_link).
Host apps iterate widgets generically without naming any domain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TicketDTO, user_tickets/user_bookings to CalendarService protocol
and SqlCalendarService implementation, plus nav links and panel
templates for the auth account sub-pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use top_slug/sub_slug directly instead of current_local_href for
active state detection. The previous approach compared full request
paths against short category-relative paths, which never matched.
This also avoids conflicting with current_local_href used by brand
filter URL construction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added app_name Jinja global and aria-selected to nav menu links.
Matches by first path segment (e.g. /market/... → "market") or by
app_name for cross-domain cases (e.g. cart app → "cart" menu item).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Minus button now floors at 0 instead of going negative. A trash button
with SweetAlert2 confirmation appears when cart_delete_url is defined
(cart app only). Items at quantity 0 remain visible for re-increment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cart_item macro now checks for cart_quantity_url (defined only in the cart app)
and uses it for same-origin quantity updates, falling back to market_product_url.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Templates were accessing entry.calendar.name/slug/post via ORM relationships,
but these entries are now CalendarEntryDTOs. Use flat fields instead
(calendar_name, calendar_slug, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The |qs filter returns "" when makeqs_factory is not set (events app),
causing |host to generate the events app root URL which has no route.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move 6 model files to shared/models/ (ghost_content, order, page_config,
market, market_place, calendars) so apps import from shared, not each other
- Fix auth templates: replace url_for('auth.*') with coop_url() for
cross-app compatibility
- Fix TYPE_CHECKING import in sumup.py to use shared.models.order
- Delete dead infrastructure/cart_loader.py (inverted dependency)
- Update models/__init__.py to export all new models
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The orders link navigates cross-domain (cart subdomain from coop) and
htmx 2.0 selfRequestsOnly blocks cross-origin requests. Explicitly
disable htmx on this link so the browser does a normal navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
url_for('auth.account') and url_for('auth.newsletters') only work in
the blog app. Other apps (cart) that render these shared templates
don't have an auth blueprint. Use coop_url() so links always resolve
to the blog subdomain regardless of which app renders the template.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The market menu item in the top bar should link to the blog page at
coop_url('/market/'), not to market_url('/') which goes to the market
subdomain. Reverts the incorrect 'market' addition to _app_slugs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
market_url('/product/...') was missing the /<page_slug>/<market_slug>/
prefix required by the market app's route structure. New helper
market_product_url() resolves the prefix from request context
(g.post_slug/g.market_slug in market app, g.page_slug + market_place
in cart app).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Accept optional page_config parameter to use per-page
SumUp merchant code and API key instead of global config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
_join_url_parts() only checked the first segment for a scheme, so
passing an already-absolute URL (e.g. from cart_url()) through the
|host filter would join route_prefix() + absolute URL, producing
"https://host/https://host/path/".
Now detects schemes in later segments and resets the base.
Also add missing 'market' entry to _nav.html _app_slugs to match
_nav_oob.html — without it the market menu item fell through to
coop_url('/market/') instead of market_url('/').
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The checkout form action used url_for('cart_global.checkout') which
only resolves inside the cart app. Replace with cart_url() and
page_cart_url() Jinja globals that work across all apps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Templates: item.post.X → item.X (MenuNode has label/slug/feature_image directly)
- factory.py: add glue.models to import loop + register_glue_handlers() at startup
- alembic env.py: add glue.models to import loop
- New migration: container_relations + menu_nodes tables with backfill from existing data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>