# CMS Implementation Guide ## Quick Start This guide shows you how to implement the Content Management System for static pages. ## What Was Implemented ✅ **Database Model**: `models/database/content_page.py` ✅ **Service Layer**: `app/services/content_page_service.py` ✅ **Admin API**: `app/api/v1/admin/content_pages.py` ✅ **Store API**: `app/api/v1/store/content_pages.py` ✅ **Storefront API**: `app/api/v1/storefront/content_pages.py` ✅ **Documentation**: Full CMS documentation in `docs/features/content-management-system.md` ## Next Steps to Activate ### 1. Create Database Migration ```bash # Create Alembic migration alembic revision --autogenerate -m "Add content_pages table" # Review the generated migration in alembic/versions/ # Run migration alembic upgrade head ``` ### 2. Add Relationship to Store Model Edit `models/database/store.py` and add this relationship: ```python # Add this import from sqlalchemy.orm import relationship # Add this relationship to Store class content_pages = relationship("ContentPage", back_populates="store", cascade="all, delete-orphan") ``` ### 3. Register API Routers Edit the appropriate router files to include the new endpoints: **Admin Router** (`app/api/v1/admin/__init__.py`): ```python from app.api.v1.admin import content_pages api_router.include_router( content_pages.router, prefix="/content-pages", tags=["admin-content-pages"] ) ``` **Store Router** (`app/api/v1/store/__init__.py`): ```python from app.api.v1.store import content_pages api_router.include_router( content_pages.router, prefix="/{store_code}/content-pages", tags=["store-content-pages"] ) ``` **Storefront Router** (`app/api/v1/storefront/__init__.py` or create if doesn't exist): ```python from app.api.v1.storefront import content_pages api_router.include_router( content_pages.router, prefix="/content-pages", tags=["storefront-content-pages"] ) ``` ### 4. Update Storefront Routes to Use CMS Edit `app/routes/storefront_pages.py` to add a generic content page handler: ```python from app.services.content_page_service import content_page_service @router.get("/{slug}", response_class=HTMLResponse, include_in_schema=False) async def generic_content_page( slug: str, request: Request, db: Session = Depends(get_db) ): """ Generic content page handler. Handles: /about, /faq, /contact, /shipping, /returns, /privacy, /terms, etc. """ store = getattr(request.state, 'store', None) store_id = store.id if store else None page = content_page_service.get_page_for_store( db, slug=slug, store_id=store_id, include_unpublished=False ) if not page: raise HTTPException(status_code=404, detail=f"Page not found: {slug}") return templates.TemplateResponse( "storefront/content-page.html", get_storefront_context(request, page=page) ) ``` ### 5. Create Generic Content Page Template Create `app/templates/storefront/content-page.html`: ```jinja2 {# app/templates/storefront/content-page.html #} {% extends "storefront/base.html" %} {% block title %}{{ page.title }}{% endblock %} {% block meta_description %} {{ page.meta_description or page.title }} {% endblock %} {% block content %}
We connect quality stores with customers worldwide.
Our mission is to provide a seamless shopping experience...
""", is_published=True, show_in_footer=True, display_order=1 ) # Shipping Information content_page_service.create_page( db, slug="shipping", title="Shipping Information", content="""We offer fast and reliable shipping...
""", is_published=True, show_in_footer=True, display_order=2 ) # Returns content_page_service.create_page( db, slug="returns", title="Returns & Refunds", content="""30-day return policy on all items...
""", is_published=True, show_in_footer=True, display_order=3 ) # Privacy Policy content_page_service.create_page( db, slug="privacy", title="Privacy Policy", content="""Your privacy is important to us...
""", is_published=True, show_in_footer=True, display_order=4 ) # Terms of Service content_page_service.create_page( db, slug="terms", title="Terms of Service", content="""By using our platform, you agree to...
""", is_published=True, show_in_footer=True, display_order=5 ) # Contact content_page_service.create_page( db, slug="contact", title="Contact Us", content="""Have questions? We'd love to hear from you!
Email: support@example.com
""", is_published=True, show_in_footer=True, display_order=6 ) # FAQ content_page_service.create_page( db, slug="faq", title="Frequently Asked Questions", content="""Simply browse our products...
""", is_published=True, show_in_footer=True, display_order=7 ) print("✅ Created default content pages successfully") except Exception as e: print(f"❌ Error: {e}") db.rollback() finally: db.close() if __name__ == "__main__": create_defaults() ``` Run it: ```bash python scripts/seed/create_default_content_pages.py ``` ## Testing ### 1. Test Platform Defaults ```bash # Create platform default curl -X POST http://localhost:8000/api/v1/admin/content-pages/platform \ -H "Authorization: BearerPlatform default content
", "is_published": true, "show_in_footer": true }' # View in storefront curl http://localhost:8000/store/orion/about ``` ### 2. Test Store Override ```bash # Create store override curl -X POST http://localhost:8000/api/v1/store/orion/content-pages/ \ -H "Authorization: BearerCustom store content
", "is_published": true }' # View in storefront (should show store content) curl http://localhost:8000/store/orion/about ``` ### 3. Test Fallback ```bash # Delete store override curl -X DELETE http://localhost:8000/api/v1/store/orion/content-pages/{id} \ -H "Authorization: Bearer