393 lines
14 KiB
Markdown
393 lines
14 KiB
Markdown
|
|
# Site Builder - Project Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
A visual drag-and-drop website builder using GrapesJS. Users can create multi-page websites without writing code, with server-side file storage for assets and localStorage persistence for editor state.
|
||
|
|
|
||
|
|
## File Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
site-builder/
|
||
|
|
├── router.php # PHP built-in server router (dev server)
|
||
|
|
├── .htaccess # Apache rewrite rules for /api/* routing
|
||
|
|
├── .user.ini # PHP upload/memory limits for Apache
|
||
|
|
├── index.html # Main editor page
|
||
|
|
├── preview.html # Preview page (renders saved content with page navigation)
|
||
|
|
├── CLAUDE.md # This documentation file
|
||
|
|
├── api/
|
||
|
|
│ ├── index.php # API handler (assets, projects, health endpoints)
|
||
|
|
│ └── image-resize.php # Image resize/crop endpoint
|
||
|
|
├── css/
|
||
|
|
│ └── editor.css # Custom editor styles (dark theme, ~1300 lines)
|
||
|
|
├── js/
|
||
|
|
│ ├── editor.js # Editor initialization and all functionality (~1900 lines)
|
||
|
|
│ ├── assets.js # Asset management (upload, browse, deploy)
|
||
|
|
│ └── whp-integration.js # WHP control panel integration
|
||
|
|
├── storage/
|
||
|
|
│ ├── assets/ # Uploaded asset files (images, videos, etc.)
|
||
|
|
│ ├── projects/ # Saved project data (JSON files)
|
||
|
|
│ └── tmp/ # Temporary files
|
||
|
|
└── docs/
|
||
|
|
└── plans/
|
||
|
|
└── 2026-01-26-site-builder-design.md # Design document
|
||
|
|
```
|
||
|
|
|
||
|
|
## Dependencies (CDN)
|
||
|
|
|
||
|
|
All dependencies are loaded from CDN in index.html:
|
||
|
|
- **GrapesJS Core** (`unpkg.com/grapesjs`) - Main editor engine
|
||
|
|
- **grapesjs-blocks-basic** - Basic building blocks
|
||
|
|
- **grapesjs-preset-webpage** - Webpage blocks (hero, features, etc.)
|
||
|
|
- **grapesjs-plugin-forms** - Form elements
|
||
|
|
- **grapesjs-style-gradient** - Gradient background support
|
||
|
|
- **Font Awesome 5** - Block icons
|
||
|
|
- **Google Fonts** - Inter, Roboto, Open Sans, Poppins, Montserrat, Playfair Display, Merriweather, Source Code Pro
|
||
|
|
|
||
|
|
## Running the Project
|
||
|
|
|
||
|
|
The project uses PHP for its API backend. Assets are stored as files on disk (not base64 in localStorage), which avoids browser storage quota issues.
|
||
|
|
|
||
|
|
### Production (Apache)
|
||
|
|
The `.htaccess` file routes `/api/*` requests to `api/index.php`. The `.user.ini` sets PHP upload limits. Just deploy to any Apache + PHP host.
|
||
|
|
|
||
|
|
### Local Development (PHP built-in server)
|
||
|
|
```bash
|
||
|
|
php -d upload_max_filesize=500M -d post_max_size=512M -S localhost:8081 router.php
|
||
|
|
```
|
||
|
|
|
||
|
|
Then open `http://localhost:8081`
|
||
|
|
|
||
|
|
### Server API Endpoints
|
||
|
|
|
||
|
|
| Method | Endpoint | Description |
|
||
|
|
|--------|----------|-------------|
|
||
|
|
| GET | `/api/health` | Server health check |
|
||
|
|
| POST | `/api/assets/upload` | Upload file (multipart/form-data) |
|
||
|
|
| GET | `/api/assets` | List all stored assets |
|
||
|
|
| DELETE | `/api/assets/<filename>` | Delete an asset |
|
||
|
|
| POST | `/api/projects/save` | Save project data (JSON body) |
|
||
|
|
| GET | `/api/projects/list` | List all saved projects |
|
||
|
|
| GET | `/api/projects/<id>` | Load a specific project |
|
||
|
|
| DELETE | `/api/projects/<id>` | Delete a project |
|
||
|
|
|
||
|
|
## Editor Interface
|
||
|
|
|
||
|
|
### Top Navigation Bar
|
||
|
|
- Logo/branding
|
||
|
|
- Device switcher (Desktop/Tablet/Mobile)
|
||
|
|
- Undo/Redo buttons
|
||
|
|
- Clear canvas button
|
||
|
|
- Export button (download site as ZIP with options)
|
||
|
|
- Preview button (opens preview.html in new tab)
|
||
|
|
|
||
|
|
### Left Panel (3 tabs)
|
||
|
|
1. **Blocks** - Draggable components organized by category
|
||
|
|
2. **Pages** - Multi-page management (add/edit/delete pages)
|
||
|
|
3. **Layers** - Component hierarchy tree view
|
||
|
|
|
||
|
|
### Center Canvas
|
||
|
|
- Live preview of the website
|
||
|
|
- Click to select, drag to reposition
|
||
|
|
- Right-click for context menu
|
||
|
|
- Resize handles on selected components
|
||
|
|
|
||
|
|
### Right Panel (2 tabs)
|
||
|
|
1. **Styles** - Two modes:
|
||
|
|
- **Guided Mode**: Context-aware presets based on selected element type
|
||
|
|
- **Advanced Mode**: Full GrapesJS style manager with all CSS properties
|
||
|
|
2. **Settings** - Component-specific traits/attributes (like Video URL)
|
||
|
|
|
||
|
|
## Block Categories
|
||
|
|
|
||
|
|
### Layout
|
||
|
|
| Block | Description |
|
||
|
|
|-------|-------------|
|
||
|
|
| Section | Basic content section with centered container |
|
||
|
|
| Section (Background) | Section with image background and overlay |
|
||
|
|
| Section (Video BG) | Section with video background (YouTube/Vimeo/MP4) and overlay |
|
||
|
|
| Logo | Styled logo with icon and text |
|
||
|
|
| Navigation | Dynamic nav bar with page sync |
|
||
|
|
| Footer | Footer with links and copyright |
|
||
|
|
| 1-4 Columns | Flexible column layouts |
|
||
|
|
| 2 Columns 3/7 | Asymmetric column layout |
|
||
|
|
|
||
|
|
### Basic
|
||
|
|
| Block | Description |
|
||
|
|
|-------|-------------|
|
||
|
|
| Text | Paragraph text |
|
||
|
|
| Heading | H2 heading |
|
||
|
|
| Button | Styled link button |
|
||
|
|
| Divider | Horizontal rule (color/thickness editable) |
|
||
|
|
| Spacer | Vertical spacing element |
|
||
|
|
| Text Box | Styled container for overlaying on backgrounds |
|
||
|
|
|
||
|
|
### Media
|
||
|
|
| Block | Description |
|
||
|
|
|-------|-------------|
|
||
|
|
| Image | Responsive image |
|
||
|
|
| Video | Universal video (YouTube, Vimeo, or direct file) |
|
||
|
|
|
||
|
|
### Sections
|
||
|
|
| Block | Description |
|
||
|
|
|-------|-------------|
|
||
|
|
| Hero (Image) | Hero with image background and overlay |
|
||
|
|
| Hero (Video) | Hero with video background and overlay |
|
||
|
|
| Hero (Simple) | Hero with gradient background |
|
||
|
|
| Features Grid | 3-column feature cards |
|
||
|
|
| Testimonials | Customer testimonials with star ratings |
|
||
|
|
| Pricing Table | 3-tier pricing comparison with featured tier |
|
||
|
|
| Contact Section | Contact info with form |
|
||
|
|
| Call to Action | CTA banner with gradient background |
|
||
|
|
|
||
|
|
### Forms
|
||
|
|
Form, Input, Textarea, Select, Button, Label, Checkbox, Radio
|
||
|
|
|
||
|
|
## Context-Aware Styling (Guided Mode)
|
||
|
|
|
||
|
|
The guided panel shows different controls based on selected element:
|
||
|
|
|
||
|
|
### Text Elements (p, h1-h6, span, label)
|
||
|
|
- Text Color (8 presets)
|
||
|
|
- Font Family (8 Google Fonts)
|
||
|
|
- Text Size (XS, S, M, L, XL, 2XL)
|
||
|
|
- Font Weight (Light, Normal, Medium, Semi, Bold)
|
||
|
|
|
||
|
|
### Links/Buttons (a)
|
||
|
|
- Link URL input with "Open in new tab" option
|
||
|
|
- Button Color (8 presets, auto-adjusts text for contrast)
|
||
|
|
- Text styling options
|
||
|
|
- Border Radius and Padding
|
||
|
|
|
||
|
|
### Containers (div, section, etc.)
|
||
|
|
- Background Color (8 presets)
|
||
|
|
- Background Gradient (12 presets)
|
||
|
|
- Background Image (URL with size/position controls)
|
||
|
|
- Padding and Border Radius
|
||
|
|
|
||
|
|
### Overlays (.bg-overlay)
|
||
|
|
- Overlay Color (6 presets)
|
||
|
|
- Opacity Slider (0-100%)
|
||
|
|
|
||
|
|
### Navigation (nav)
|
||
|
|
- "Sync with Pages" button (auto-generates links from page list)
|
||
|
|
- "Add Link" button
|
||
|
|
- Link list with delete buttons
|
||
|
|
|
||
|
|
### Dividers (hr)
|
||
|
|
- Divider Color (8 presets)
|
||
|
|
- Line Thickness (1-6px)
|
||
|
|
|
||
|
|
## Video System
|
||
|
|
|
||
|
|
### Supported Formats
|
||
|
|
The Video block and Section Video BG support:
|
||
|
|
- **YouTube**: `youtube.com/watch?v=ID`, `youtu.be/ID`
|
||
|
|
- **Vimeo**: `vimeo.com/ID`
|
||
|
|
- **Direct files**: `.mp4`, `.webm`, `.ogg`, `.mov`
|
||
|
|
|
||
|
|
### How Videos Work
|
||
|
|
1. URLs are auto-detected and converted to proper embed format
|
||
|
|
2. YouTube/Vimeo use iframe embeds
|
||
|
|
3. Direct files use HTML5 video element
|
||
|
|
4. Background videos auto-play muted and loop
|
||
|
|
|
||
|
|
### Editing Video URL
|
||
|
|
1. Select the video container (use Layers panel if needed)
|
||
|
|
2. Go to **Settings** tab
|
||
|
|
3. Paste URL in "Video URL" field
|
||
|
|
4. Video loads automatically
|
||
|
|
|
||
|
|
## Multi-Page System
|
||
|
|
|
||
|
|
### Storage
|
||
|
|
- Pages stored in localStorage key: `sitebuilder-pages`
|
||
|
|
- Each page has: id, name, slug, html, css
|
||
|
|
|
||
|
|
### Page Management
|
||
|
|
- **Add Page**: Click "Add Page" in Pages tab
|
||
|
|
- **Edit Page**: Click edit icon on page item
|
||
|
|
- **Delete Page**: Click delete icon (cannot delete last page)
|
||
|
|
- **Switch Pages**: Click on page item (auto-saves current page)
|
||
|
|
|
||
|
|
### Navigation Sync
|
||
|
|
1. Add Navigation block to page
|
||
|
|
2. Select the nav element
|
||
|
|
3. In Settings, click "Sync with Pages"
|
||
|
|
4. Links auto-generate from page list
|
||
|
|
5. CTA button (with `.nav-cta` class) is preserved
|
||
|
|
|
||
|
|
## Context Menu (Right-Click)
|
||
|
|
|
||
|
|
| Action | Shortcut | Description |
|
||
|
|
|--------|----------|-------------|
|
||
|
|
| Edit Content | - | Enable inline text editing |
|
||
|
|
| Duplicate | Ctrl+D | Copy element in place |
|
||
|
|
| Copy | Ctrl+C | Copy to clipboard |
|
||
|
|
| Paste | Ctrl+V | Paste from clipboard |
|
||
|
|
| Move Up | - | Move element up in parent |
|
||
|
|
| Move Down | - | Move element down in parent |
|
||
|
|
| Select Parent | - | Select parent container |
|
||
|
|
| Wrap in Container | - | Wrap in new div |
|
||
|
|
| Delete | Del | Remove element |
|
||
|
|
|
||
|
|
## Keyboard Shortcuts
|
||
|
|
|
||
|
|
| Shortcut | Action |
|
||
|
|
|----------|--------|
|
||
|
|
| Ctrl/Cmd + Z | Undo |
|
||
|
|
| Ctrl/Cmd + Shift + Z | Redo |
|
||
|
|
| Ctrl/Cmd + Y | Redo (alternative) |
|
||
|
|
| Ctrl/Cmd + C | Copy |
|
||
|
|
| Ctrl/Cmd + V | Paste |
|
||
|
|
| Ctrl/Cmd + D | Duplicate |
|
||
|
|
| Delete / Backspace | Remove selected |
|
||
|
|
| Escape | Deselect / Close modals |
|
||
|
|
|
||
|
|
## Storage Architecture
|
||
|
|
|
||
|
|
### Server-Side Storage (primary, when server.py is running)
|
||
|
|
| Location | Purpose |
|
||
|
|
|----------|---------|
|
||
|
|
| `storage/assets/` | Uploaded files (images, videos, etc.) stored on disk |
|
||
|
|
| `storage/projects/` | Project data as JSON files |
|
||
|
|
| `storage/tmp/` | Temporary files |
|
||
|
|
|
||
|
|
Assets are uploaded via `POST /api/assets/upload` and stored as actual files on disk. They are referenced in the editor by URL (e.g., `/storage/assets/1234567_abc123_photo.jpg`), avoiding localStorage quota limits.
|
||
|
|
|
||
|
|
### localStorage Keys (lightweight metadata and editor state)
|
||
|
|
| Key | Purpose |
|
||
|
|
|-----|---------|
|
||
|
|
| `sitebuilder-project` | GrapesJS auto-save (components, styles) |
|
||
|
|
| `sitebuilder-pages` | Multi-page data (array of page objects) |
|
||
|
|
| `sitebuilder-assets` | Asset metadata index (URLs and names only, no file contents) |
|
||
|
|
| `sitebuilder-project-preview` | Preview data (all pages for preview.html) |
|
||
|
|
|
||
|
|
**Important:** Asset file contents (images, videos) are NOT stored in localStorage. Only metadata (filename, URL, type) is cached there. This prevents the `QuotaExceededError` that occurred with base64-encoded large files.
|
||
|
|
|
||
|
|
## Export Feature
|
||
|
|
|
||
|
|
### How to Export
|
||
|
|
1. Click the **Export** button in the top navigation bar
|
||
|
|
2. Choose export options:
|
||
|
|
- **Minify CSS**: Reduces file size by removing whitespace/comments
|
||
|
|
- **Include Google Fonts**: Adds font preload links (recommended)
|
||
|
|
3. Click **Download ZIP**
|
||
|
|
4. All pages are exported as standalone HTML files
|
||
|
|
|
||
|
|
### Exported File Structure
|
||
|
|
```
|
||
|
|
site-export.zip
|
||
|
|
├── index.html # Home page
|
||
|
|
├── about.html # About page (based on page slug)
|
||
|
|
├── contact.html # etc.
|
||
|
|
```
|
||
|
|
|
||
|
|
### Technical Details
|
||
|
|
- Uses JSZip library (loaded dynamically on first export)
|
||
|
|
- Each HTML file includes embedded CSS styles
|
||
|
|
- Responsive CSS reset included in each file
|
||
|
|
- Mobile column stacking rules included
|
||
|
|
|
||
|
|
## Preview System
|
||
|
|
|
||
|
|
`preview.html` loads saved content from localStorage and renders it:
|
||
|
|
- Supports multi-page with page selector buttons
|
||
|
|
- Backwards compatible with legacy single-page format
|
||
|
|
- Includes Google Fonts and responsive styles
|
||
|
|
- "Back to Editor" button
|
||
|
|
|
||
|
|
## CSS Architecture (editor.css)
|
||
|
|
|
||
|
|
### Main Sections
|
||
|
|
1. **Base Layout** (~lines 1-100) - Editor container, panels
|
||
|
|
2. **Top Navigation** (~lines 100-200) - Nav bar, device buttons
|
||
|
|
3. **Left Panel** (~lines 200-400) - Blocks, pages, layers
|
||
|
|
4. **Right Panel** (~lines 400-600) - Styles, traits
|
||
|
|
5. **Guided Styles** (~lines 600-800) - Color presets, font presets
|
||
|
|
6. **Context Menu** (~lines 800-900) - Right-click menu
|
||
|
|
7. **Pages Panel** (~lines 900-1000) - Page list, page items
|
||
|
|
8. **Modals** (~lines 1000-1100) - Page settings modal
|
||
|
|
9. **New Controls** (~lines 1100-1300) - Background, overlay, nav controls
|
||
|
|
|
||
|
|
### Theme
|
||
|
|
- Dark theme with `#16161a` base
|
||
|
|
- Accent color: `#3b82f6` (blue)
|
||
|
|
- Text: `#e4e4e7` (light gray)
|
||
|
|
- Borders: `#3f3f46` (dark gray)
|
||
|
|
|
||
|
|
## JavaScript Architecture (editor.js)
|
||
|
|
|
||
|
|
### Structure (approximate line numbers)
|
||
|
|
1. **GrapesJS Init** (1-200) - Editor configuration, plugins
|
||
|
|
2. **Custom Blocks** (200-820) - All block definitions including new sections
|
||
|
|
3. **Component Types** (900-1040) - Video wrapper types with traits
|
||
|
|
4. **Device Switching** (1040-1080)
|
||
|
|
5. **Undo/Redo/Clear** (1080-1120)
|
||
|
|
6. **Preview** (1120-1140)
|
||
|
|
7. **Panel Tabs** (1140-1200)
|
||
|
|
8. **Style Mode Toggle** (1200-1220)
|
||
|
|
9. **Context-Aware UI** (1220-1400) - Element type detection, section visibility
|
||
|
|
10. **Color/Style Presets** (1400-1600) - Click handlers for all presets
|
||
|
|
11. **Background/Overlay Controls** (1600-1700)
|
||
|
|
12. **Navigation Controls** (1700-1800) - Sync with pages, add/remove links
|
||
|
|
13. **Link Editing** (1800-1850)
|
||
|
|
14. **Save Status** (1850-1900)
|
||
|
|
15. **Keyboard Shortcuts** (1900-1950)
|
||
|
|
16. **Selection Handling** (1950-2050) - Update UI on selection change
|
||
|
|
17. **Context Menu** (2050-2200) - Right-click functionality
|
||
|
|
18. **Page Management** (2200-2600) - Pages CRUD, switching, modals
|
||
|
|
19. **Export Functionality** (2630-2810) - ZIP export with JSZip
|
||
|
|
|
||
|
|
### Key Functions
|
||
|
|
- `convertToEmbedUrl(url)` - Converts YouTube/Vimeo URLs to embed format
|
||
|
|
- `applyVideoUrl(component, url)` - Applies video to wrapper component
|
||
|
|
- `getElementType(tagName)` - Returns element category for context-aware UI
|
||
|
|
- `showSectionsForElement(component)` - Shows relevant guided panel sections
|
||
|
|
- `loadPages()` / `savePages()` - Page persistence
|
||
|
|
- `switchToPage(pageId)` - Page switching with auto-save
|
||
|
|
- `loadNavLinks(component)` - Populate nav links list in guided panel
|
||
|
|
- `generatePageHtml(page, includeFonts, minifyCss)` - Generate standalone HTML for export
|
||
|
|
- `createAndDownloadZip(includeFonts, minifyCss)` - Create ZIP and trigger download
|
||
|
|
|
||
|
|
## Development Notes
|
||
|
|
|
||
|
|
### Adding New Blocks
|
||
|
|
1. Add to `blockManager.add()` section
|
||
|
|
2. Choose appropriate category
|
||
|
|
3. Use inline styles for immediate visibility
|
||
|
|
4. Add `data-*` attributes for custom component types if needed
|
||
|
|
|
||
|
|
### Adding New Guided Controls
|
||
|
|
1. Add HTML section in `index.html` inside `#guided-styles`
|
||
|
|
2. Add section reference in `sections` object
|
||
|
|
3. Update `showSectionsForElement()` to show for relevant element types
|
||
|
|
4. Add click handlers for presets
|
||
|
|
5. Add CSS in `editor.css`
|
||
|
|
|
||
|
|
### Custom Component Types
|
||
|
|
Use `editor.DomComponents.addType()` for:
|
||
|
|
- Custom traits in Settings panel
|
||
|
|
- Special behavior on attribute changes
|
||
|
|
- Detection via `isComponent` function
|
||
|
|
|
||
|
|
### Testing Video Embeds
|
||
|
|
YouTube/Vimeo embeds may not work in GrapesJS canvas (nested iframe issue) but work correctly in Preview mode and published sites.
|
||
|
|
|
||
|
|
## Future Enhancements (from design doc)
|
||
|
|
|
||
|
|
### Phase 2: Backend Integration
|
||
|
|
- PHP backend for user authentication
|
||
|
|
- Database storage for projects
|
||
|
|
- Multiple project support
|
||
|
|
|
||
|
|
### Phase 3: Publishing
|
||
|
|
- Save/publish sites to server
|
||
|
|
- Subdomain or custom domain support
|
||
|
|
- Template library
|
||
|
|
|
||
|
|
### Phase 4: Enhancements
|
||
|
|
- More block types
|
||
|
|
- Custom CSS injection
|
||
|
|
- Asset manager for images
|
||
|
|
- SEO settings per page
|