v1.5.0: extend theme with navigation dropdowns, 9 page templates, auth UI, newsletter, contact panel

Major theme extension adding full-featured navigation with dropdown submenus (Tools, My Data, Resources),
9 new page templates (Calculator, Protocol Builder, Tracker, Subject Log, Documentation, Directory,
Science Feed, Profile, Sign In/Register), documentation page with sidebar ToC and scroll spy,
branded AJAX authentication forms, newsletter signup with admin export, slide-out contact/support panel,
Research Modules 6-card grid on front page, and comprehensive footer update.

Split functions.php (554→206 lines) into 6 focused inc/ modules: helpers, customizer, auth-handlers,
contact-handler, page-setup, newsletter-admin. All new components include dark mode support, CSRF
protection, input sanitization, output escaping, and graceful plugin degradation via shortcode_exists().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
peptiderepo
2026-04-14 08:38:30 +07:00
parent 6c7faa6eed
commit 9da702e746
31 changed files with 4311 additions and 1085 deletions

View File

@@ -2,384 +2,206 @@
## Overview
Peptide Starter (peptide-starter) is a premium, accessible WordPress theme for peptiderepo.com — a scientific peptide reference database. The theme is a classic (non-block) WordPress theme that assembles a modern, responsive frontend by combining a monolithic CSS architecture with vanilla JavaScript. It integrates seamlessly with three companion plugins (Peptide Search AI, Peptide News, PRAutoBlogger) via shortcodes, coordinates dark mode across the ecosystem via CSS custom properties and the DOM `data-theme` attribute, and provides customizable hero and footer sections through the WordPress Customizer.
Peptide Starter (peptide-starter) is a premium, accessible WordPress theme for peptiderepo.com — a scientific peptide reference database. The theme is a classic (non-block) WordPress theme that assembles a modern, responsive frontend by combining a monolithic CSS architecture with vanilla JavaScript. It integrates seamlessly with five companion plugins (Peptide Search AI, Peptide News, PRAutoBlogger, Peptide Tools, Peptide Tracker, Peptide Community) via shortcodes, coordinates dark mode across the ecosystem via CSS custom properties and the DOM `data-theme` attribute, and provides customizable hero, navigation, authentication, and footer sections.
## Directory Structure
```
peptide-starter/
├── style.css # All theme CSS (~44KB). Architecture: reset → tokens → typography →
│ # globals → components → regions → pages → animations → a11y → dark mode → responsive
├── style.css # All theme CSS. Architecture: reset → tokens → typography →
│ # globals → components → regions → pages → animations →
│ # a11y → dark mode → responsive → new feature sections
│
├── functions.php # Theme setup (430 lines)
├── functions.php # Theme setup entry point (~206 lines)
│ # - Constants, feature module loading
│ # - Theme support registration
│ # - Script/style enqueueing with wp_localize_script
│ # - 4x footer widget area registration
│ # - Customizer settings (hero, footer, dark mode)
│ # - Navigation Menu Walker for active states
│ # - Helper functions (get_hero_title, get_footer_copyright, etc.)
│ # - Inline dark mode script in wp_head (for flicker-free initialization)
│ # - Script/style enqueueing (incl conditional)
│ # - Widget areas, newsletter handler, dark mode inline script
│
├── header.php # Global header region (131 lines)
│ # - Site logo/branding
│ # - Primary navigation menu with fallback
│ # - Header icons (search, dark mode toggle, cart, mobile menu)
│ # - Search overlay for Peptide Search AI plugin
│ # - Nav overlay for mobile menu
├── inc/
│ ├── helpers.php # Nav walker, custom logo, hero/footer getters, pagination
│ ├── customizer.php # Customizer sections, settings, sanitize callbacks
│ ├── auth-handlers.php # AJAX login + registration handlers
│ ├── contact-handler.php # AJAX contact form handler (settings panel)
│ ├── page-setup.php # Auto-create pages on theme activation
│ └── newsletter-admin.php # Admin page to view/export subscriber emails
│
├── footer.php # Global footer region (81 lines)
│ # - Newsletter signup form (conditionally rendered)
│ # - 4-column footer widget grid
│ # - Default content fallback per column
│ # - Footer copyright text (from Customizer)
├── header.php # Global header (~190 lines)
│ # - Site logo, primary navigation with dropdowns
│ # - Sign In / User menu (state-aware)
│ # - Settings icon, language placeholder
│ # - Search, dark mode toggle, cart, mobile menu
│ # - Search overlay, fallback nav
│
├── front-page.php # Home page template (86 lines)
│ # - Hero section (title, subtitle, search)
│ # - PRAutoBlogger posts widget [prautoblogger_posts]
│ # - Peptide News feed section [peptide_news]
│ # - Shortcode integration with graceful degradation
├── footer.php # Global footer (~100 lines)
│ # - Newsletter signup (front page via template part)
│ # - 4-column widget grid with updated defaults
│ # - Copyright, disclaimer, language links
│ # - Settings panel include
│
├── page.php # Generic page template (53 lines)
│ # - Page header with title
│ # - Article container
│ # - Edit link display
├── front-page.php # Home page template (~100 lines)
│ # - Hero section (title, subtitle, search, CTAs)
│ # - Research Modules grid (6 cards)
│ # - [prautoblogger_posts] shortcode
│ # - [peptide_news] shortcode
│
├── index.php # Fallback template (27 lines)
│ # - Loop with dynamic post type content dispatch
│ # - Pagination via peptide_starter_pagination()
├── page-calculator.php # Calculator page template → [peptide_tools_calculator]
├── page-protocol-builder.php # Protocol Builder template → [peptide_tools_protocol_builder]
├── page-tracker.php # Tracker template → [peptide_tracker]
├── page-subject-log.php # Subject Log template → [peptide_tracker_subject_log]
├── page-documentation.php # Documentation/SOP page — two-column layout with ToC sidebar
├── page-directory.php # Peptide Directory template → [peptide_directory]
├── page-science-feed.php # Science Feed template → [peptide_news] + newsletter
├── page-profile.php # User Profile template → [peptide_community_profile]
├── page-auth.php # Sign In / Register — branded auth forms with AJAX
│
├── page.php # Generic page template
├── index.php # Fallback template
├── single-peptide.php # Peptide detail page (CPT)
│ # - Renders single peptide post
│
├── archive-peptide.php # Peptide archive (CPT grid)
│ # - Displays peptide CPT items in grid layout
│
├── 404.php # 404 error page
│ # - Default 404 handling
│
├── searchform.php # Search form template
│ # - Standard WordPress search form
│
├── template-parts/
│ ├── content.php # Default post/page loop item (19 lines)
│ # - Title, date, author, excerpt, read more link
│
│ ├── content.php # Default post/page loop item
│ ├── content-peptide.php # Peptide CPT card template
│ # - Peptide-specific card styling with .ps-card
│ ├── content-none.php # Empty state template
│ ├── module-cards.php # Research Modules 6-card grid (front page)
│ ├── newsletter-signup.php # Reusable newsletter signup section
│ └── settings-panel.php # Slide-out support/contact panel
│
│ └── content-none.php # Empty state template
│ # - Message when no posts found
│
├── assets/
│ └── js/
│ ├── navigation.js # Mobile menu toggle (85 lines)
│ # - Mobile hamburger menu state management
│ # - Nav overlay click handling
│ # - Escape key, resize, link click closing
│ # - aria-expanded attribute updates
│
│ └── theme.js # Dark mode + utilities (211 lines)
│ # - Dark mode toggle & localStorage persistence
│ # - System preference detection (prefers-color-scheme)
│ # - Custom 'themechange' event dispatch to plugins
│ # - Search overlay open/close functionality
│ # - Icon state toggling (sun/moon)
│ # - window.peptideStarterTheme API for plugin access
│ # - Smooth scroll + focus-visible polyfill
├── assets/js/
│ ├── navigation.js # Mobile menu toggle (85 lines)
│ ├── theme.js # Dark mode + search overlay + utilities (210 lines)
│ ├── documentation.js # ToC generation + scroll spy for docs page (145 lines)
│ ├── auth.js # Auth form toggle, validation, AJAX (192 lines)
│ └── settings-panel.js # Settings panel open/close + contact form (163 lines)
│
├── languages/ # Translation files (.pot, .po, .mo)
│ # - Text domain: peptide-starter
│
├── tests/
│ ├── bootstrap.php # PHPUnit bootstrap — loads WP test framework + theme
│ ├── test-functions.php # Tests for helper functions (hero, footer, newsletter, sanitize)
│ └── test-theme-setup.php # Tests for theme supports, menus, widgets, scripts
│
├── .phpcs.xml.dist # PHPCS config — WordPress-Core standard
├── phpunit.xml # PHPUnit config — points to tests/ directory
├── composer.json # Dev dependencies (PHPUnit, PHPCS, WPCS)
├── README.md # User-facing documentation
├── CLAUDE.md # Developer context notes
├── tests/ # PHPUnit tests
├── .phpcs.xml.dist # PHPCS config
├── phpunit.xml # PHPUnit config
├── composer.json # Dev dependencies
├── README.md # User-facing docs
├── CLAUDE.md # Developer context
├── CHANGELOG.md # Version history
└── screenshot.png # WordPress theme preview image
└── screenshot.png # Theme preview image
```
## Navigation Structure
```
Home | Tools ▾ | My Data ▾ | Resources ▾ | [Sign In / Username ▾] ⚙ 🌐 🔍 🌙
Tools dropdown:
├── Calculator → /calculator
├── Protocol Builder → /protocol-builder
└── Tracker → /tracker
My Data dropdown:
├── Peptides → /peptides
└── Subject Log → /subject-log
Resources dropdown:
├── Documentation → /documentation
└── Science Feed → /news
User menu (logged in):
├── My Profile → /profile
├── Tracker → /tracker
├── Subject Log → /subject-log
└── Sign Out
```
## Page Template Map
| Page Title | Slug | Template File | Plugin Shortcode |
|------------|------|---------------|-----------------|
| Calculator | calculator | page-calculator.php | [peptide_tools_calculator] |
| Protocol Builder | protocol-builder | page-protocol-builder.php | [peptide_tools_protocol_builder] |
| Tracker | tracker | page-tracker.php | [peptide_tracker] |
| Subject Log | subject-log | page-subject-log.php | [peptide_tracker_subject_log] |
| Documentation | documentation | page-documentation.php | (WordPress content + JS ToC) |
| Peptide Directory | peptides | page-directory.php | [peptide_directory] |
| Science Feed | news | page-science-feed.php | [peptide_news] |
| Profile | profile | page-profile.php | [peptide_community_profile] |
| Sign In | auth | page-auth.php | (Custom auth forms) |
Pages are auto-created on theme activation via `inc/page-setup.php`.
## Data Flow & Architecture Diagrams
### Front Page Assembly (Plugin Integration)
### Front Page Assembly
```
front-page.php
├─→ Hero Section (title, subtitle, search, CTAs)
│ └─→ [peptide_search] shortcode (Peptide Search AI plugin)
│
├─→ Hero Section (title, subtitle, search)
│ │
│ └─→ [peptide_search] shortcode
│ └─→ Peptide Search AI plugin (if active)
├─→ Research Modules Grid (template-parts/module-cards.php)
│ └─→ 6 cards linking to tool/section pages
│ └─→ Checks shortcode_exists() for graceful degradation
│
├─→ Hero CTAs (Browse Peptides, Learn More)
├─→ [prautoblogger_posts] shortcode (PRAutoBlogger plugin)
│
├─→ [prautoblogger_posts] shortcode
│ └─→ PRAutoBlogger plugin
│ └─→ Renders 6 auto-generated research articles
└─→ [peptide_news] shortcode (Peptide News plugin)
```
### Authentication Flow
```
page-auth.php
├─→ Sign In form → auth.js AJAX → inc/auth-handlers.php
│ └─→ wp_signon() → redirect to original page
│
└─→ [peptide_news] shortcode
└─→ Peptide News plugin
└─→ Renders news feed grid
└─→ Register form → auth.js AJAX → inc/auth-handlers.php
└─→ wp_create_user() → auto-login → redirect to /profile
```
### Dark Mode Coordination
```
functions.php (wp_head)
│
└─→ Inline script runs first (before CSS loads)
└─→ Sets html[data-theme] from:
1. localStorage (user's choice)
2. prefers-color-scheme (system)
3. dark_mode_default (Customizer setting)
└─→ Prevents flash of wrong color on page load
│
├─→ style.css reads data-theme
│ └─→ @media selector: html[data-theme="dark"]
│
└─→ theme.js detects theme changes
└─→ Dispatches 'themechange' event
└─→ Updates localStorage
└─→ Updates icon visibility
└─→ Plugins listen & update own styles
```
### Template Hierarchy & Routing
```
WordPress Request
│
├─→ is_front_page() ? front-page.php
│ └─→ Hero + [prautoblogger_posts] + [peptide_news]
│
├─→ is_singular('peptide') ? single-peptide.php
│ └─→ get_template_part('content-peptide')
│
├─→ is_archive() ? archive-peptide.php
│ └─→ Grid of peptide cards
│
├─→ is_page() ? page.php
│ └─→ get_template_part('content')
│
├─→ is_search() || is_category() || is_tag() ? index.php
│ └─→ Loop: get_template_part('content', get_post_type())
│ └─→ Dispatches to content.php or content-{type}.php
│
├─→ is_404() ? 404.php
│
└─→ Default ? index.php
└─→ Fallback loop template
```
### Script Loading & Dark Mode API
```
wp_enqueue_scripts (functions.php)
│
├─→ peptide-starter-style
│ └─→ style.css (PEPTIDE_STARTER_VERSION)
│
├─→ peptide-starter-navigation
│ └─→ assets/js/navigation.js (in footer, async)
│
└─→ peptide-starter-theme
├─→ assets/js/theme.js (in footer, async)
└─→ wp_localize_script('peptideStarterData')
├─→ siteUrl: home_url('/')
└─→ isDarkMode: get_theme_mod('dark_mode_default')
```
### Plugin Dark Mode Listening
Plugins can coordinate with the theme via three mechanisms:
```javascript
// 1. Custom event (recommended)
document.addEventListener('themechange', (e) => {
console.log('Theme changed to:', e.detail.theme); // 'dark' | 'light'
});
// 2. DOM attribute mutation
const observer = new MutationObserver(() => {
const theme = document.documentElement.getAttribute('data-theme');
});
observer.observe(document.documentElement, { attributes: true });
// 3. CSS custom properties (theme.js updates these)
const color = getComputedStyle(document.documentElement).getPropertyValue('--text-primary');
functions.php (wp_head inline script)
└─→ Sets html[data-theme] from localStorage → system pref → customizer default
├─→ style.css reads data-theme for color overrides
└─→ theme.js dispatches 'themechange' event to plugins
```
## External Integrations
### Plugin Integrations (via Shortcodes)
1. **Peptide Search AI** (`[peptide_search]`)
- Location: Hero section (header.php, front-page.php)
- Fallback: Standard WordPress search form
- Dark mode: Listens to `themechange` event
- Namespace: `.psa-*`
1. **Peptide Search AI** (`[peptide_search]`) — Hero + search overlay. Namespace: `.psa-*`
2. **Peptide News** (`[peptide_news]`) — Front page + science feed. Namespace: `.pn-*`
3. **PRAutoBlogger** (`[prautoblogger_posts]`) — Front page articles. Namespace: `.prab-*`
4. **Peptide Tools** (`[peptide_tools_calculator]`, `[peptide_tools_protocol_builder]`) — Tool pages
5. **Peptide Tracker** (`[peptide_tracker]`, `[peptide_tracker_subject_log]`) — Tracker pages
6. **Peptide Community** (`[peptide_community_profile]`, `[peptide_directory]`) — Profile + directory
2. **Peptide News** (`[peptide_news]`)
- Location: Front page (front-page.php)
- Renders: News feed grid with article cards
- Dark mode: Listens to `themechange` event
- Namespace: `.pn-*`
- Override: `functions.php` line 80-90 removes `-webkit-line-clamp` on excerpts
3. **PRAutoBlogger** (`[prautoblogger_posts]`)
- Location: Front page (front-page.php)
- Renders: 6 auto-generated research articles section
- Dark mode: Listens to `themechange` event
- Namespace: `.prab-*`
All plugins are checked with `shortcode_exists()` for graceful degradation.
### WooCommerce Integration
- Cart icon in header (header.php line 68)
- Conditionally rendered if `class_exists('WooCommerce')`
- Minimal theme styling; WooCommerce handles its own UI
- Icon: SVG shopping cart
### Google Fonts Integration
- Font: **Inter** (from Google Fonts)
- Loaded via CSS `@import url('...')`
- Fallback: System fonts (`-apple-system, BlinkMacSystemFont, etc.`)
- Display: `display=swap` for optimal loading
### REST API & Customizer
- Theme mods saved to `wp_options` table
- Customizer sections: Branding, Hero Section, Footer, Theme Mode
- All settings use `'transport' => 'postMessage'` for instant preview (except dark_mode_default which uses refresh)
All plugins checked with `shortcode_exists()` for graceful degradation.
## Key Architectural Decisions
### 1. Classic Theme (Not FSE/Block Theme)
1. **Classic Theme (Not FSE)** — Stability, control, plugin compatibility
2. **Monolithic CSS** — No build step, CSS custom properties for abstraction
3. **Vanilla JavaScript** — No bundler, direct browser ES6+, `node --check` validation
4. **Shortcode Integration** — Decouples plugins from theme via `shortcode_exists()`
5. **CSS Custom Properties for Dark Mode** — Single source of truth for colors
6. **No `!important` Policy** — Explicit specificity over cascade tricks
7. **Inline Dark Mode Script** — Prevents flash of wrong theme on load
8. **Split functions.php into inc/** — Keeps all files under 300 lines
**Why:** Peptide Repo predates WordPress Full Site Editing. Classic themes provide:
- Simpler, more stable template hierarchy for developers
- Full control over HTML structure without block markup
- Easier plugin compatibility without block interdependencies
- Proven stability for production scientific database
## Security
### 2. Monolithic CSS (Not SASS/LESS)
**Why:**
- No build step = instant deploy without compilation
- Single 44KB file loads fast (gzips to ~7KB)
- CSS custom properties (variables) provide all needed abstraction
- Theme can be edited directly on remote server if needed
- Reduces deployment complexity on Hostinger shared hosting
### 3. Vanilla JavaScript (No Bundler)
**Why:**
- Simple, maintainable code without build toolchain
- Direct browser compatibility (ES6+)
- Minimal overhead; only 296 lines total across 2 files
- Each script can be tested by running `node --check` syntax validation
- No dependencies = no supply chain risk
### 4. Shortcode Integration (Not Direct Function Calls)
**Why:**
- Plugins are independent; shortcodes decouple content from theme
- Shortcodes can be disabled/removed without theme breaking
- `shortcode_exists()` provides graceful degradation
- Theme doesn't need to know plugin implementation details
- Content (front-page.php) stays separate from plugin business logic
### 5. CSS Custom Properties for Dark Mode & Theming
**Why:**
- Single source of truth for all colors (defined in `:root`)
- Plugins can read theme colors via `getComputedStyle()`
- Easy to switch between light/dark without duplicate selectors
- No need for SASS mixins or preprocessor
- Future-proof: standard CSS, works in all modern browsers
### 6. No `!important` Policy (Global Scale)
**Why:**
- `!important` breaks plugin CSS specificity
- Forces explicit specificity through selector weight instead
- Theme respects plugin namespaces (`.pn-*`, `.psa-*`, `.prab-*`)
- Only exception: line 85 (necessary override of Peptide News line-clamp)
- Maintains CSS maintainability and plugin harmony
### 7. Inline Dark Mode Script in `wp_head`
**Why:**
- Runs *before* CSS loads, preventing white flash in dark mode
- Reads localStorage synchronously (no async needed here)
- Sets `data-theme` attribute before first paint
- Fallback chain: localStorage → system preference → customizer default
- Performance impact: minimal (~1ms execution)
### 8. Navigation Walker with Active State Detection
**Why:**
- Custom Walker class (line 243-300) detects current-menu-item
- Adds `.active` class for CSS styling (matches WordPress conventions)
- Enables dynamic nav styling without JS
- Integrates with WordPress menus natively
- Fallback function for sites with no primary menu
### 9. Helper Functions for Customizer Output
**Why:**
- `peptide_starter_get_*()` functions (lines 317-340) centralize theme mod retrieval
- Consistent defaults across templates
- Easy to update copy site-wide from one place
- Separates data layer from presentation
## Security & Performance Considerations
- **Escaping:** All output uses `esc_html()`, `esc_url()`, `esc_attr()` appropriately
- **Nonces:** Newsletter form uses `wp_nonce_field()` with CSRF verification in handler
- **Sanitize callbacks:** All Customizer settings have explicit `sanitize_callback` (text, kses, checkbox)
- **Form handling:** Newsletter signup routes through `admin_post` action with nonce + email validation
- **Permissions:** Check `is_active_sidebar()` before rendering widgets
- **Performance:** Script/style versions use `PEPTIDE_STARTER_VERSION` constant for cache busting
- **Accessibility:** Skip-to-main-content link (header.php line 20), WCAG AA color contrast, focus indicators
## Testing & CI/CD
- **CI pipeline** (`.github/workflows/deploy.yml`):
1. PHP lint (`php -l`) on all PHP files
2. PHPCS with WordPress-Core standard
3. JS syntax check (`node --check`) on all JS files
4. Deploy via rsync (only if validation passes)
5. Post-deploy health check (HTTP 200)
- **Unit tests** (`tests/`): PHPUnit with WordPress test framework
- `test-functions.php` — helpers, sanitizers, filters
- `test-theme-setup.php` — theme supports, menus, widgets, scripts
- **rsync safety**: Dev-only files excluded from deploy (tests/, vendor/, composer.json, phpunit.xml, .phpcs.xml.dist)
## Browser Support
- Chrome/Edge (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- iOS Safari 12+
- Chrome Android
- CSRF nonces on all forms (auth, newsletter, contact)
- All input sanitized at boundary (`sanitize_text_field`, `sanitize_email`, `sanitize_textarea_field`)
- All output escaped (`esc_html`, `esc_attr`, `esc_url`, `wp_kses_post`)
- Login redirect validated with `wp_validate_redirect()` to prevent open redirects
- Auth form uses AJAX to avoid exposing credentials in URL
- Contact form topics restricted to allowlist
## Version
**Current:** v1.3.1 (defined in `style.css` header line 7 and `functions.php` line 14 constant)
**Current:** v1.5.0
When releasing a new version, update both locations.
## Related Documentation
- **CONVENTIONS.md** — How to add templates, components, plugin integrations
- **CLAUDE.md** — Developer context and quick reference
- **README.md** — User-facing feature list and installation
- **CHANGELOG.md** — Release history
When releasing a new version, update `style.css` header (line 7) and `PEPTIDE_STARTER_VERSION` in `functions.php`.