diff --git a/.vscode/settings.json b/.vscode/settings.json index 013a244..96ccb8b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,16 @@ ".specify/scripts/bash/": true, ".specify/scripts/powershell/": true }, - "terminal.integrated.cwd": "${workspaceFolder}/src" + "terminal.integrated.cwd": "${workspaceFolder}/src", + "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python", + "python.terminal.activateEnvironment": true, + "python.testing.unittestEnabled": true, + "python.testing.unittestArgs": [ + "-v", + "-s", + ".", + "-p", + "test*.py" + ], + "python.testing.cwd": "${workspaceFolder}/src" } diff --git a/AGENTS.md b/AGENTS.md index 2b9d836..55bcf01 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,6 +51,13 @@ class HeadingBlock(blocks.StructBlock): **Security**: Use `EmbedBlock` (oEmbed) for embedded content, NEVER `RawHTMLBlock` (XSS risk). +**Navigation Menu Pattern**: See `src/navigation/blocks.py` for nested block structure that enforces 2-level maximum: +- `TopLevelMenuBlock` (StreamBlock) contains page_link, external_link, OR dropdown +- `DropdownMenuBlock` (StructBlock) contains title and items (MenuItemBlock) +- `MenuItemBlock` (StreamBlock) contains ONLY page_link and external_link (no nested dropdowns) + +This structural approach prevents 3+ level nesting at the schema level. + ### 4. Translation & Locale Management - Translation UI comes from `wagtail.contrib.simple_translation` (already installed) @@ -62,22 +69,42 @@ class HeadingBlock(blocks.StructBlock): ## Development Workflow -### Essential Commands (from `src/` directory) +### Essential Commands + +**IMPORTANT**: This project uses `uv` for package management. When running Python commands in terminals (especially from AI assistants or automated tools), the virtual environment may not be automatically activated. **Always prefix Python commands with `uv run`** to ensure the correct environment is used: + +```bash +# ✅ CORRECT - Use uv run for all Python commands +uv run python manage.py test +uv run python manage.py migrate +uv run python manage.py runserver + +# ❌ WRONG - May fail if virtual environment isn't activated +python manage.py test +``` + +#### Package Management (from project root) ```bash -# Package management (from project root) uv sync # Install all deps (creates .venv/) uv add package-name # Add runtime dependency uv add --dev package-name # Add dev dependency +``` + +#### Django Commands (from src/ directory) -# Django (from src/ directory) +```bash cd src -python manage.py migrate -python manage.py test # Run all tests (64 total) -python manage.py test locales.tests # Run specific app tests -python manage.py createsuperuser # One-time setup +uv run python manage.py migrate +uv run python manage.py test # Run all tests +uv run python manage.py test navigation # Run specific app tests +uv run python manage.py createsuperuser # One-time setup +uv run python manage.py runserver # Development server +``` -# Code quality (from project root) +#### Code Quality (from project root) + +```bash uv run pre-commit install # One-time setup uv run pre-commit run --all-files # Manual run uv run ruff check --fix . # Lint with auto-fix @@ -183,8 +210,9 @@ from core.constants import DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGES - **curlylint** - Template linting ### Migration Best Practices + 1. Test migrations are auto-generated -2. based on model changes +2. based on model changes 3. Run `python manage.py makemigrations` after model changes 4. All StreamField changes require migrations (block structure changes) 5. Check migration files into version control diff --git a/CHANGELOG.md b/CHANGELOG.md index d366e12..10ffc93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **Navigation Menu System**: Site-wide multi-lingual navigation with WCAG 2.1 AA accessibility + - Site-wide navigation menu configuration via Wagtail Settings (BaseSiteSetting pattern) + - StreamField-based menu structure with PageLinkBlock, ExternalLinkBlock, and DropdownMenuBlock + - **2-level menu maximum**: Enforced at schema level - prevents nested dropdowns + - **Locale-aware rendering**: Automatic page translation linking with fallback to default locale + - **Full WCAG 2.1 AA compliance**: ARIA menubar pattern, keyboard navigation, screen reader support + - **DaisyUI responsive design**: Mobile hamburger drawer, desktop horizontal menu + - **Accessibility features**: + - Skip link to main content (first focusable element) + - ARIA attributes (role, aria-label, aria-current, aria-expanded, aria-haspopup, aria-controls) + - 44x44px minimum touch targets for mobile + - Visible focus indicators (3:1 contrast ratio) + - Progressive enhancement with `
`/`` for dropdowns + - **Dropdown edge detection**: JavaScript prevents viewport overflow (opens left/right/down based on space) + - **Keyboard support**: Tab, Enter, Space, Escape, Arrow keys for full navigation + - **Theme-aware**: Automatic adaptation to light/dark mode via DaisyUI + - **7 comprehensive tests**: ModelTests, StreamFieldTests, IntegrationTests for dropdown structure + - Developer documentation in `specs/002-nav-menu-system/` (plan, data model, contracts, quickstart) + - Template tag: `{% load navigation_tags %}{% navigation_menu %}` - **Tailwind CSS Integration**: Modern utility-first CSS framework with DaisyUI components - Tailwind CSS v4 with @source directive for automatic template scanning - DaisyUI plugin with semantic component classes (buttons, cards, navigation, forms, alerts) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4459ee8..a4a78eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,16 +22,19 @@ cd QuakerCMS ### 2. Install uv (if not already installed) #### macOS/Linux + ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` #### Windows + ```powershell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` Alternatively, install via pip: + ```bash pip install uv ``` @@ -45,6 +48,7 @@ uv sync ``` This command will: + - Create a virtual environment in `.venv/` - Install all project dependencies - Install development dependencies (like `ruff` for linting) automatically @@ -52,22 +56,26 @@ This command will: ### 4. Activate the Virtual Environment #### macOS/Linux + ```bash source .venv/bin/activate ``` #### Windows (PowerShell) + ```powershell .venv\Scripts\Activate.ps1 ``` #### Windows (Command Prompt) + ```cmd .venv\Scripts\activate.bat ``` ### 5. Navigate to the Django Project Directory + ```bash cd src ``` @@ -98,7 +106,47 @@ Start the Django development server: python manage.py runserver ``` -### 9. Access the Site +### 9. Install Tailwind CSS Dependencies + +QuakerCMS uses Tailwind CSS with DaisyUI for styling. You need to install the Node.js dependencies: + +```bash +# Navigate to the Tailwind source directory +cd theme/static_src + +# Install npm dependencies +npm install + +# Return to the src directory +cd ../.. +``` + +### 10. Set Up Test Navigation Content (Optional but Recommended) + +To quickly set up sample pages and navigation menu for development: + +```bash +# This creates test pages (About, Programs, Contact) and configures the navigation menu +python manage.py scaffold_navbar_content +``` + +This command creates: + +- **About** page (top-level) +- **Programs** page with a dropdown containing: + - Programs overview + - Adult Education + - Youth Programs +- **FGC Website** external link +- **Contact** page (top-level) + +To reset and recreate the test content: + +```bash +python manage.py scaffold_navbar_content --delete +``` + +### 11. Access the Site Once the server is running, you can access: @@ -127,6 +175,81 @@ Access the site at ## Development Workflow +### Running Development Servers + +QuakerCMS requires **two development servers** running simultaneously: + +1. **Django development server** - Serves the application +2. **Tailwind CSS watcher** - Automatically rebuilds CSS when files change + +#### Option A: Two Terminal Windows (Recommended) + +**Terminal 1 - Django Server:** + +```bash +cd src +python manage.py runserver +``` + +**Terminal 2 - Tailwind CSS Watcher:** + +```bash +cd src/theme/static_src +npm run dev +``` + +This setup provides: +- ✅ Auto-reload when Python/template files change (Django) +- ✅ Auto-rebuild CSS when templates/classes change (Tailwind) +- ✅ Live browser refresh with django-browser-reload (in DEBUG mode) + +#### Option B: Single Command (Requires Honcho) + +If you have `honcho` installed (part of django-tailwind optional dependencies): + +```bash +cd src +python manage.py tailwind dev +``` + +This runs both servers together, but requires the `honcho` package. + +### Navigation Menu Configuration + +The navigation menu is configured in **Wagtail Admin → Settings → Navigation Menu**. + +#### Quick Setup with Test Data + +Use the scaffold command to quickly set up test pages and navigation: + +```bash +# First time setup or when you need fresh test data +python manage.py scaffold_navbar_content + +# Reset existing test data and recreate +python manage.py scaffold_navbar_content --delete + +# Create pages only (skip navigation menu configuration) +python manage.py scaffold_navbar_content --skip-menu +``` + +#### Manual Configuration + +To manually configure the navigation menu: + +1. Go to **Wagtail Admin** () +2. Navigate to **Settings → Navigation Menu** +3. Add menu items using the StreamField: + - **Page Link** - Links to Wagtail pages + - **External Link** - Links to external URLs + - **Dropdown** - Creates a dropdown with nested items (max 2 levels) + +The navigation system automatically: +- Shows the current page with `aria-current="page"` +- Links to translated versions in multilingual sites +- Provides mobile-responsive drawer navigation +- Ensures WCAG 2.1 AA accessibility compliance + ### Code Quality This project uses `ruff` for code linting and formatting, along with `pre-commit` hooks to automatically maintain code quality. @@ -213,10 +336,29 @@ QuakerCMS/ │ └── pull_request_template.md # PR template ├── src/ # Django project root │ ├── core/ # Main Django app with settings +│ │ ├── settings/ # Settings split by environment (base, dev, production) +│ │ ├── constants.py # Shared constants (e.g., language codes) +│ │ └── templates/ # Core templates (base.html, 404, 500) │ ├── home/ # Home page app +│ ├── content/ # General content pages with StreamField +│ ├── navigation/ # Navigation menu system +│ │ ├── blocks.py # StreamField blocks for menu items +│ │ ├── models.py # NavigationMenuSetting model +│ │ ├── templatetags/ # Template tags for rendering navigation +│ │ ├── templates/ # Navigation template +│ │ ├── management/ # Management commands (scaffold_navbar_content) +│ │ └── README.md # Navigation system documentation +│ ├── locales/ # Internationalization settings │ ├── search/ # Search functionality +│ ├── theme/ # Tailwind CSS theme +│ │ └── static_src/ # Tailwind source files +│ │ ├── src/ +│ │ │ └── styles.css # Tailwind configuration +│ │ ├── package.json # Node.js dependencies +│ │ └── postcss.config.js │ └── manage.py # Django management script ├── docs/ # Documentation +├── specs/ # Feature specifications and planning ├── .pre-commit-config.yaml # Pre-commit hooks configuration ├── CHANGELOG.md # Project changelog ├── docker-compose.yml # Docker development environment @@ -263,6 +405,109 @@ The project uses GitHub Actions for continuous integration. When you create a pu All checks must pass before a pull request can be merged. You can view the status of these checks on your pull request page. +## Troubleshooting + +### Tailwind CSS Not Working / Styles Missing + +**Problem**: Navigation menu or other components appear unstyled. + +**Solution**: Make sure the Tailwind CSS watcher is running: + +```bash +cd src/theme/static_src +npm run dev +``` + +If styles are still missing: + +```bash +# Rebuild Tailwind CSS in production mode +npm run build + +# Then hard refresh your browser (Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows/Linux) +``` + +### "Skip to main content" Link Always Visible + +**Problem**: The accessibility skip link appears all the time instead of only on focus. + +**Solution**: The Tailwind CSS watcher needs to be running. The `sr-only` utility class requires compiled CSS: + +```bash +cd src/theme/static_src +npm run dev +``` + +### Navigation Menu Not Appearing + +**Problem**: No navigation menu shows on pages. + +**Solutions**: + +1. **Check if navigation menu is configured**: + - Go to Wagtail Admin → Settings → Navigation Menu + - Add at least one menu item + +2. **Use the scaffold command**: + ```bash + cd src + python manage.py scaffold_navbar_content + ``` + +3. **Check if pages exist**: The menu only shows published pages. + +### Page Tree Errors When Creating Pages + +**Problem**: Error like `'NoneType' object has no attribute '_inc_path'` when creating pages. + +**Solution**: Fix the page tree structure: + +```bash +cd src +python manage.py fixtree +``` + +The `scaffold_navbar_content --delete` command automatically runs this after deletion. + +### Database Migration Issues + +**Problem**: Errors when running `python manage.py migrate`. + +**Solution**: + +```bash +# Check for migration conflicts +python manage.py makemigrations --check + +# If there are unapplied migrations, apply them +python manage.py migrate + +# If you have migration conflicts, you may need to merge migrations +python manage.py makemigrations --merge +``` + +### Import Errors / Module Not Found + +**Problem**: `ModuleNotFoundError` when running Django commands. + +**Solution**: Make sure your virtual environment is activated: + +```bash +# Activate the virtual environment +source .venv/bin/activate # macOS/Linux +.venv\Scripts\Activate.ps1 # Windows PowerShell + +# Verify Django is installed +python -c "import django; print(django.get_version())" +``` + +If Django is not installed: + +```bash +# Reinstall dependencies +uv sync +``` + ## Getting Help If you encounter any issues or have questions: @@ -271,6 +516,72 @@ If you encounter any issues or have questions: 2. Create a new issue with detailed information about your problem 3. Reach out to the maintainers +## Quick Reference + +### Common Commands + +```bash +# Start Django development server +cd src +python manage.py runserver + +# Start Tailwind CSS watcher +cd src/theme/static_src +npm run dev + +# Create test navigation content +cd src +python manage.py scaffold_navbar_content + +# Reset and recreate test content +python manage.py scaffold_navbar_content --delete + +# Run tests +cd src +python manage.py test + +# Run linting and formatting +uv run ruff check --fix . +uv run ruff format . + +# Fix page tree issues +cd src +python manage.py fixtree + +# Create database migrations +cd src +python manage.py makemigrations + +# Apply migrations +python manage.py migrate + +# Create superuser +python manage.py createsuperuser +``` + +### Important URLs + +- **Main Site**: +- **Wagtail Admin**: +- **Navigation Menu Settings**: + +### Key Files + +- `src/core/settings/base.py` - Main Django settings +- `src/core/constants.py` - Shared constants (language codes, etc.) +- `src/navigation/models.py` - Navigation menu model +- `src/navigation/templatetags/navigation_tags.py` - Navigation rendering logic +- `src/theme/static_src/src/styles.css` - Tailwind CSS configuration +- `pyproject.toml` - Project dependencies and configuration + +### Development Tips + +1. **Always run both servers** (Django + Tailwind) for development +2. **Use `scaffold_navbar_content`** to quickly set up test pages +3. **Run `fixtree`** if you encounter page tree errors +4. **Hard refresh browser** (Cmd+Shift+R / Ctrl+Shift+R) if CSS changes don't appear +5. **Check pre-commit hooks** run before commits for code quality + ## License By contributing to QuakerCMS, you agree that your contributions will be licensed under the AGPL-3.0-or-later license. diff --git a/README.md b/README.md index 332fb1d..24e7313 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ A specialized content management system designed for Quaker meetings and worship **Built for the global Quaker community** with translation and localization as first-class features, supporting the international and multilingual nature of Friends worldwide. +## Screenshots + +_Coming soon: Screenshots of the navigation system, content editing, and admin interface._ + ## Purpose QuakerCMS provides a standardized platform for Quaker communities to publish and discover important content, fostering connection and continuity within the broader Quaker movement. The system recognizes the unique content types and communication patterns that are central to Quaker spiritual life and community organization. @@ -25,26 +29,35 @@ We envision a federated network of Quaker websites that can share content with o ## Key Features +### Currently Implemented + +- **📱 Responsive Navigation** - Mobile-friendly menu system with dropdown support +- **🌍 Multilingual Ready** - Runtime-configurable language support for international communities +- **♿ Accessibility** - WCAG 2.1 AA compliant with screen reader support +- **📝 Flexible Content** - Rich text editing with structured content blocks +- **🎨 Modern Design** - Clean, Quaker-inspired aesthetic with customizable styling +- **🔍 Search** - Built-in search functionality for finding content + ### Content Types for Quaker Communities -QuakerCMS is designed to handle the specific types of content that Quaker communities regularly publish: +QuakerCMS is being designed to handle the specific types of content that Quaker communities regularly publish: -- **Epistles** - Formal spiritual letters and communications between meetings, part of the rich tradition of Quaker writings -- **Minutes** - Records of business meetings and corporate decisions -- **Announcements** - Community news and updates -- **Events** - Structured event information with relevant details (time, location, description) -- **Newsletters** - Regular community publications -- **Pamphlets** - Educational and spiritual materials +- **Epistles** - Formal spiritual letters and communications between meetings (Planned) +- **Minutes** - Records of business meetings and corporate decisions (Planned) +- **Announcements** - Community news and updates (Planned) +- **Events** - Structured event information (Planned) +- **Newsletters** - Regular community publications (Planned) +- **Pamphlets** - Educational and spiritual materials (Planned) -### Technical Goals +### Future Roadmap -- **Internationalization First** - Built-in support for 19+ languages with runtime-configurable localization, enabling Quaker communities worldwide to publish content in their native languages -- **Multi-tenant Architecture** - Single instance can host multiple meetings and worship groups +- **Multi-tenant Architecture** - Single instance hosting multiple meetings and worship groups - **Content Federation** - Meetings can share content with other instances for broader discovery -- **Standards-Based** - Uses open web standards for content syndication (RSS, Atom) -- **Mobile-Friendly** - Responsive design that works on all devices -- **Open Source** - No dependency on proprietary services or software -- **Simple Management** - Easy-to-use interface for content managers +- **Content Syndication** - RSS/Atom feeds for content distribution +- **Advanced Search** - Faceted search with filters for content types, dates, and topics +- **User Roles & Permissions** - Fine-grained access control for different community roles +- **Digital Archives** - Historical document preservation and organization +- **Custom Domains** - Each meeting can use their own domain name ## Use Cases @@ -88,20 +101,57 @@ QuakerCMS is designed to handle the specific types of content that Quaker commun ## Getting Started -For information on setting up a development environment or contributing to the project, see our [Contributing Guide](CONTRIBUTING.md). +### For Contributors + +Interested in contributing to QuakerCMS? Our [Contributing Guide](CONTRIBUTING.md) has everything you need: + +- Setting up your development environment +- Running the development servers +- Creating test content and navigation menus +- Code quality standards and testing +- Troubleshooting common issues + +### For Site Administrators + +Documentation for deploying and administering QuakerCMS instances is coming soon. + +### For Content Managers + +User guides for creating and managing content are in development. ## Technology Stack -QuakerCMS is built with: +QuakerCMS is built with modern, open-source technologies: + +- **[Wagtail CMS](https://wagtail.org/)** - Flexible, user-friendly content management +- **[Django](https://www.djangoproject.com/)** - Robust Python web framework +- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS framework +- **[DaisyUI](https://daisyui.com/)** - Accessible component library -- **Python 3.12+** - Modern Python for reliable backend development -- **Django** - Robust web framework for rapid development -- **Wagtail CMS** - Flexible content management system with excellent editing experience -- **uv** - Fast Python package management +All built on **Python 3.12+** with **[uv](https://docs.astral.sh/uv/)** for fast, reliable package management. ## Project Status -QuakerCMS is in active development. We are working toward an initial release that will support basic content management for individual meetings, with federation and multi-tenant capabilities planned for future releases. +**Current Phase**: Active Development (Pre-Alpha) + +### Recent Milestones + +- ✅ **Navigation System** - Responsive, accessible menu with dropdown support +- ✅ **Content Structure** - Flexible page building with rich text and structured blocks +- ✅ **Internationalization** - Runtime-configurable language support +- ✅ **Modern UI** - Tailwind CSS with DaisyUI components + +### Next Up + +- 🚧 **Specialized Content Types** - Epistles, Minutes, Events, Announcements +- 🚧 **User Authentication** - Member login and permissions +- 🚧 **Search Enhancement** - Improved search with filters and facets + +### Timeline + +We are working toward a **beta release in Q2 2026** that will support basic content management for individual meetings. Federation and multi-tenant capabilities are planned for future releases. + +Want to contribute? See our [Contributing Guide](CONTRIBUTING.md) to get involved! ## Community diff --git a/specs/002-nav-menu-system/checklists/requirements.md b/specs/002-nav-menu-system/checklists/requirements.md index 8446092..c2cabaf 100644 --- a/specs/002-nav-menu-system/checklists/requirements.md +++ b/specs/002-nav-menu-system/checklists/requirements.md @@ -74,9 +74,9 @@ All checklist items have been validated. The specification has been **enhanced** - **Multi-indicator Hover**: Not reliant on color alone (underline, background, border) **Template Structure**: - - **Component-based**: `navigation.html`, `navigation_item.html`, `navigation_dropdown.html` - - **Base Integration**: Included in `base.html` for site-wide availability - - **Reusable Blocks**: DRY principle for menu item rendering + - **Single Template**: `navigation.html` - Complete navigation with mobile drawer, desktop menubar, and dropdowns + - **Base Integration**: Included in `base.html` via `{% navigation_menu %}` tag for site-wide availability + - **DaisyUI Components**: Uses drawer, navbar, menu, and dropdown-hover components 3. **User Story Enhancement**: Added **User Story 4 - Accessible Navigation** (Priority P1) with 12 acceptance scenarios covering: - Keyboard-only navigation diff --git a/specs/002-nav-menu-system/plan.md b/specs/002-nav-menu-system/plan.md index 44014dd..706c360 100644 --- a/specs/002-nav-menu-system/plan.md +++ b/specs/002-nav-menu-system/plan.md @@ -101,18 +101,16 @@ src/ │ ├── admin.py # Admin customization (if needed) │ ├── blocks.py # Menu item StreamField blocks │ ├── tests.py # Comprehensive test suite +│ ├── templatetags/ +│ │ └── navigation_tags.py # Template tag for rendering menu │ ├── migrations/ │ │ └── 0001_initial.py │ └── templates/ │ └── navigation/ -│ ├── navigation.html # Main nav component -│ ├── navigation_item.html # Simple link block -│ └── navigation_dropdown.html # Dropdown menu block +│ └── navigation.html # Complete navigation template (mobile + desktop) ├── core/ │ ├── templates/ -│ │ ├── base.html # MODIFIED: Include navigation component -│ │ └── components/ -│ │ └── navigation.html # May be moved here from navigation app +│ │ └── base.html # MODIFIED: Include navigation_menu tag │ └── settings/ │ └── base.py # MODIFIED: Add 'navigation' to INSTALLED_APPS └── theme/ diff --git a/specs/002-nav-menu-system/spec.md b/specs/002-nav-menu-system/spec.md index 694cce3..cb2e0df 100644 --- a/specs/002-nav-menu-system/spec.md +++ b/specs/002-nav-menu-system/spec.md @@ -9,12 +9,18 @@ ### Session 2025-10-26 -- Q: For mobile devices (< 1024px), what UX pattern should the hamburger menu use when opened? → A: DaisyUI drawer component that slides in from left side -- Q: How should dropdown menus open on desktop devices? → A: Hover on desktop (≥1024px), click/tap on all devices +- Q: For mobile devices (mobile/tablet breakpoints: `< lg` / < 1024px), what UX pattern should the hamburger menu use when opened? → A: DaisyUI drawer component that slides in from left side +- Q: How should dropdown menus open on desktop devices? → A: Hover on desktop breakpoint (`lg+` / ≥1024px), click/tap on all devices - Q: How should dropdown menus behave inside the mobile hamburger drawer? → A: Accordion-style expansion within drawer (submenus expand in-place below parent item) - Q: When a page linked in a menu is deleted, how should the system handle that menu item? → A: Automatically remove from menu immediately when page is deleted (or prevent deletion to preserve referential integrity) - Q: When the navigation menu has no menu items configured, how should it render on the front-end? → A: Hide `