middleware fix for path-based vendor url
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
# middleware/theme_context.py
|
||||
"""
|
||||
Theme Context Middleware
|
||||
Injects vendor-specific theme into request context
|
||||
Theme Context Middleware (Class-Based)
|
||||
|
||||
Injects vendor-specific theme into request context.
|
||||
|
||||
Class-based middleware provides:
|
||||
- Better state management
|
||||
- Easier testing
|
||||
- Standard ASGI pattern
|
||||
"""
|
||||
|
||||
import logging
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from fastapi import Request
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -31,7 +39,7 @@ class ThemeContextManager:
|
||||
return theme.to_dict()
|
||||
|
||||
# Return default theme
|
||||
return get_default_theme()
|
||||
return ThemeContextManager.get_default_theme()
|
||||
|
||||
@staticmethod
|
||||
def get_default_theme() -> dict:
|
||||
@@ -76,40 +84,68 @@ class ThemeContextManager:
|
||||
}
|
||||
|
||||
|
||||
async def theme_context_middleware(request: Request, call_next):
|
||||
class ThemeContextMiddleware(BaseHTTPMiddleware):
|
||||
"""
|
||||
Middleware to inject theme context into request state.
|
||||
|
||||
This runs AFTER vendor_context_middleware has set request.state.vendor
|
||||
Class-based middleware provides:
|
||||
- Better state management
|
||||
- Easier testing
|
||||
- Standard ASGI pattern
|
||||
|
||||
Runs LAST in middleware chain (after vendor_context_middleware and context_middleware).
|
||||
Depends on:
|
||||
request.state.vendor (set by vendor_context_middleware)
|
||||
|
||||
Sets:
|
||||
request.state.theme: Theme dictionary
|
||||
"""
|
||||
# Only inject theme for shop pages (not admin or API)
|
||||
if hasattr(request.state, 'vendor') and request.state.vendor:
|
||||
vendor = request.state.vendor
|
||||
|
||||
# Get database session
|
||||
db_gen = get_db()
|
||||
db = next(db_gen)
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
"""
|
||||
Load and inject theme context.
|
||||
"""
|
||||
# Only inject theme for shop pages (not admin or API)
|
||||
if hasattr(request.state, 'vendor') and request.state.vendor:
|
||||
vendor = request.state.vendor
|
||||
|
||||
try:
|
||||
# Get vendor theme
|
||||
theme = ThemeContextManager.get_vendor_theme(db, vendor.id)
|
||||
request.state.theme = theme
|
||||
# Get database session
|
||||
db_gen = get_db()
|
||||
db = next(db_gen)
|
||||
|
||||
logger.debug(
|
||||
f"Theme loaded for vendor {vendor.name}: {theme['theme_name']}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load theme for vendor {vendor.id}: {e}")
|
||||
# Fallback to default theme
|
||||
try:
|
||||
# Get vendor theme
|
||||
theme = ThemeContextManager.get_vendor_theme(db, vendor.id)
|
||||
request.state.theme = theme
|
||||
|
||||
logger.debug(
|
||||
f"[THEME] Theme loaded for vendor",
|
||||
extra={
|
||||
"vendor_id": vendor.id,
|
||||
"vendor_name": vendor.name,
|
||||
"theme_name": theme.get('theme_name', 'default'),
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"[THEME] Failed to load theme for vendor {vendor.id}: {e}",
|
||||
exc_info=True
|
||||
)
|
||||
# Fallback to default theme
|
||||
request.state.theme = ThemeContextManager.get_default_theme()
|
||||
finally:
|
||||
db.close()
|
||||
else:
|
||||
# No vendor context, use default theme
|
||||
request.state.theme = ThemeContextManager.get_default_theme()
|
||||
finally:
|
||||
db.close()
|
||||
else:
|
||||
# No vendor context, use default theme
|
||||
request.state.theme = ThemeContextManager.get_default_theme()
|
||||
logger.debug(
|
||||
"[THEME] No vendor context, using default theme",
|
||||
extra={"has_vendor": False}
|
||||
)
|
||||
|
||||
response = await call_next(request)
|
||||
return response
|
||||
# Continue processing
|
||||
response = await call_next(request)
|
||||
return response
|
||||
|
||||
|
||||
def get_current_theme(request: Request) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user