# Long PDF Generation with Skills Sidebars ## Overview The long PDF generation feature creates a comprehensive CV that includes technical skills sidebars positioned on the left and right sides, while hiding UI elements for a clean, print-optimized output. **Page counts**: - **Long version** (9 pages) - Full-size fonts, comprehensive content - **Short version with skills** (5 pages) - Compact sidebar fonts for reduced page count ## Key Features - **9-page layout** with optimal content density - **25% sidebars** for skills/competencies display - **2-column approach** matching web layout (no wasted space) - **Page breaks** between left and right sidebar sections - **Hidden mobile UI elements** (accordion headers, navigation) - **Print media CSS** for compact, professional typography ## Architecture ### PDF Generation Flow ``` User clicks "Long CV (9 pages)" in PDF Modal ↓ Frontend: `/export/pdf?lang=es&length=long&icons=show&version=with_skills` ↓ Backend: GenerateFromURLWithOptions(url, cookies, RenderModeScreen) ↓ Chromedp: Navigate to URL with cookies ↓ CSS Injection: Override print.css + Show sidebars + 2-column layout ↓ PDF Generation: PrintToPDF with A4 dimensions ↓ Output: 9-page PDF with sidebars (or 5 pages with compact fonts for short version) ``` ### Critical Components #### 1. PDF Generator (`internal/pdf/generator.go`) **RenderMode**: - `RenderModePrint` - Clean version (hides sidebars) - `RenderModeScreen` - Long version (shows sidebars) **CSS Injection Strategy**: ```javascript // Override parent width constraints (full A4 width) '.cv-page, .cv-paper, .cv-container { max-width: 100% !important; ... }' // Show sidebars (override print.css hiding) '.cv-sidebar, .cv-sidebar-left, .cv-sidebar-right { display: block !important; }' // Hide mobile UI elements '.sidebar-accordion-header { display: none !important; }' // Force page break before page 2 '.page-2 { page-break-before: always !important; break-before: page !important; }' // 2-column layouts (no wasted space) '.page-1 .page-content { grid-template-columns: 25% 75% !important; }' '.page-2 .page-content { grid-template-columns: 75% 25% !important; }' ``` #### 2. HTML Structure (`templates/cv-content.html`) **Page 1**: Left sidebar + Main content ```html
...
``` **Page 2**: Main content + Right sidebar ```html
...
``` #### 3. Frontend Integration (`templates/partials/modals/pdf-modal.html`) **PDF Modal Options**: - Short CV (4 pages) - `version=clean` - **Long CV (9 pages)** - `version=with_skills` ← This feature - **Short CV with skills (5 pages)** - `length=short&version=with_skills` with compact fonts - Current View - Uses localStorage settings ## Why 2-Column Layout? ### ❌ Previous Approach (3-column - WRONG) ```css .page-1, .page-2: 25% | 50% | 25% /* Always 3 columns */ ``` - Page 1 had empty right column (25% wasted) - Page 2 had empty left column (25% wasted) - Result: 10-19 pages ### ✅ Current Approach (2-column - CORRECT) ```css .page-1: 25% | 75% /* Left sidebar + Main, NO right space */ .page-2: 75% | 25% /* Main + Right sidebar, NO left space */ ``` - No wasted space on either page - Matches web's actual layout exactly - Result: **9 pages** ## Configuration ### Sidebar Width Tuning Sidebar width affects page count: | Width | Layout | Pages | Notes | |-------|--------|-------|-------| | 18% | 18% \| 82% | 9 pages | Too narrow | | 20% | 20% \| 80% | 8 pages | Minimal sidebars | | **25%** | **25% \| 75%** | **9 pages** | ✅ **Current** (optimal balance) | | 30% | 30% \| 70% | 10+ pages | Too wide | **Current Setting**: 25% sidebars (`internal/pdf/generator.go:176,181`) ### Adjusting Sidebar Width To change sidebar width, update two lines in `internal/pdf/generator.go`: ```go // Page 1: Left sidebar (XX%) + Main (YY%) - NO right space '.page-1 .page-content { ' + 'grid-template-columns: XX% YY% !important; ' + '} ' + // Page 2: Main (YY%) + Right sidebar (XX%) - NO left space '.page-2 .page-content { ' + 'grid-template-columns: YY% XX% !important; ' + '} ' + ``` Where `XX + YY = 100` ## Print Media CSS The extended PDF uses `@media print` from `static/css/08-contexts/_print.css` for: - Compact fonts and spacing - Hiding UI chrome (navigation, buttons, footer) - Professional typography **Overridden in PDF**: - Sidebar hiding (`.cv-sidebar { display: none }` → `display: block !important`) - Accordion headers (`.sidebar-accordion-header { display: none !important }`) ## Testing ### Unit Tests The long PDF feature has comprehensive test coverage in `internal/handlers/pdf_test.go`: **Test Functions:** 1. `TestExportPDF_LongWithSkills` - Tests long PDF with multiple language/icon combinations 2. `TestPDFGenerator_RenderModes` - Tests both `RenderModePrint` and `RenderModeScreen` 3. `TestExportPDF_SkillsSidebarFeatures` - Tests specific skills sidebar features: - Version parameter validation (`clean`, `with_skills`) - PDF modal integration URLs - Frontend button parameter correctness 4. `TestPDFGenerator_CompactSidebarFonts` - Tests compact font feature for short version Run the tests: ```bash go test ./internal/handlers -v -run TestExportPDF ``` ### Integration Testing Check page count and PDF generation: ```bash # Download long PDF (9 pages with sidebars) curl "http://localhost:1999/export/pdf?lang=es&length=long&icons=show&version=with_skills" -o test-long.pdf # Download short PDF with skills (5 pages with compact fonts) curl "http://localhost:1999/export/pdf?lang=es&length=short&icons=show&version=with_skills" -o test-short-skills.pdf # Download short PDF clean (4 pages, no sidebars) curl "http://localhost:1999/export/pdf?lang=es&length=short&icons=show&version=clean" -o test-short.pdf # Verify page counts pdfinfo test-long.pdf | grep Pages # Expected: Pages: 9 pdfinfo test-short-skills.pdf | grep Pages # Expected: Pages: 5 pdfinfo test-short.pdf | grep Pages # Expected: Pages: 4 ``` ### Manual Verification **Long CV (9 pages):** 1. Open http://localhost:1999 in browser 2. Click "Descargar PDF" button 3. Select "CV Largo (9 páginas)" / "Long CV (9 pages)" 4. Click "Descargar PDF" 5. Verify downloaded PDF has: - 9 pages total - 25% sidebars on left (page 1) and right (page 2+) - Full-size fonts in sidebars - No "Competencias Técnicas" accordion header visible - Page break between page 1 and page 2 - Skills content displayed in sidebars **Short CV with skills (5 pages with compact fonts):** 1. Toggle to short view and with_skills theme 2. Download PDF 3. Verify: - 5 pages total - Compact sidebar fonts (0.94-0.98em) - All content fits naturally without overflow - Maintained readability ## API Endpoint **URL**: `/export/pdf` **Query Parameters**: - `lang` - Language (`es`, `en`) - `length` - CV length (`short`, `long`) - `icons` - Show icons (`show`, `hide`) - `version` - Layout version (`clean`, `with_skills`) **Examples**: ```bash # Long CV with skills (9 pages, full-size fonts) GET /export/pdf?lang=es&length=long&icons=show&version=with_skills # Short CV with skills (5 pages, compact sidebar fonts) GET /export/pdf?lang=es&length=short&icons=show&version=with_skills # Short CV clean (4 pages, no sidebars) GET /export/pdf?lang=es&length=short&icons=show&version=clean ``` ## Troubleshooting ### Issue: Sidebars not showing **Solution**: Check `RenderModeScreen` is being used (not `RenderModePrint`) ### Issue: Wrong page count **Solution**: 1. Check sidebar width percentage (should be 25%) 2. Verify CSS injection is working 3. Check for browser console errors ### Issue: Accordion header visible **Solution**: Ensure `.sidebar-accordion-header { display: none !important; }` in CSS injection ### Issue: No page break between pages **Solution**: Verify `.page-2 { page-break-before: always !important; }` is applied ## Compact Sidebar Fonts Feature ### Overview The compact sidebar fonts feature automatically reduces sidebar font sizes by 2-6% **only for short CVs with skills** (`length=short&version=with_skills`), reducing page count from 6 pages to 5 pages while maintaining excellent readability. **Impact:** - **Page count reduction**: 6 pages → 5 pages (16.7% reduction) - **Font size reduction**: 2-6% (very subtle, 0.94-0.98em) - **Readability**: Maintained - fonts remain professional and readable - **Only for short version**: Long version uses full-size fonts ### When It Activates The feature automatically activates when **both** conditions are met: 1. `length=short` (detected via `cv-length` cookie) 2. `version=with_skills` (RenderModeScreen with sidebars) **Does NOT activate for:** - Long CVs (`length=long`) - always use full-size fonts - Clean version (`version=clean`) - no sidebars shown - Short clean version - no sidebars to compact ### Implementation **Location**: `internal/pdf/generator.go` (lines 154-215) **Cookie Detection**: ```go // Check if this is a short version (to apply compact sidebar fonts) // The length parameter is passed as a cookie, not in the URL isShortVersion := cookies["cv-length"] == "short" ``` **CSS Injection** (only when `isShortVersion == true`): ```go compactFontCSS := "" if isShortVersion { compactFontCSS = ` + // Compact sidebar fonts (SHORT VERSION ONLY) - very subtle reduction '.cv-sidebar * { font-size: 0.96em !important; line-height: 1.4 !important; } ' + '.cv-sidebar h3 { font-size: 0.98em !important; margin: 0.4em 0 !important; } ' + '.cv-sidebar h4 { font-size: 0.96em !important; margin: 0.35em 0 !important; } ' + '.cv-sidebar p, .cv-sidebar li { font-size: 0.94em !important; line-height: 1.4 !important; } ' + '.cv-sidebar ul, .cv-sidebar ol { margin: 0.4em 0 0.4em 1.2em !important; } ' + '.cv-sidebar li { margin-bottom: 0.25em !important; } ' + '.cv-sidebar section { margin-bottom: 0.8em !important; } '` } ``` ### Font Size Breakdown | Element | Full-Size (Long) | Compact (Short) | Reduction | |---------|------------------|-----------------|-----------| | General text | 1.0em | 0.96em | 4% | | H3 headings | 1.0em | 0.98em | 2% | | H4 headings | 1.0em | 0.96em | 4% | | Paragraphs & lists | 1.0em | 0.94em | 6% | **Line height**: Consistent 1.4 for improved readability ### Design Philosophy **Why subtle reduction?** 1. **Readability first**: 2-6% reduction is barely noticeable 2. **Professional appearance**: No "squeezed" or cramped feel 3. **Natural flow**: Content reflows organically, not forced 4. **Consistent UX**: Main content uses full-size fonts **Why only short version?** - Short CV has less content → compact fonts sufficient - Long CV needs maximum readability for extensive content - Consistent with "short = concise, long = comprehensive" semantics ### Testing **Test function**: `TestPDFGenerator_CompactSidebarFonts` in `internal/handlers/pdf_test.go` **Test coverage:** 1. Cookie-based detection (`cv-length=short` vs `cv-length=long`) 2. PDF generation with compact fonts 3. Version parameter validation (`with_skills` vs `clean`) 4. Page count verification (5 pages for short with skills) **Run tests**: ```bash go test ./internal/handlers -v -run TestPDFGenerator_CompactSidebarFonts ``` ### Manual Verification 1. Navigate to http://localhost:1999 2. Toggle to **short view** (localStorage: `cv-length=short`) 3. Toggle to **with_skills theme** (localStorage: `cv-theme=default` or `with_skills`) 4. Download PDF 5. Verify: - **5 pages total** (not 6) - Sidebar fonts slightly smaller than main content - Still professional and readable - No content overflow or truncation **Compare with long version:** 1. Toggle to **long view** (`cv-length=long`) 2. Download PDF 3. Verify: - **9 pages total** - Sidebar fonts same size as short version main content - Full-size fonts throughout ### Troubleshooting #### Issue: Short PDF still has 6 pages **Solution**: 1. Verify `cv-length` cookie is set to `short` (check browser DevTools) 2. Ensure `isShortVersion` detection works in generator.go:156 3. Check CSS injection is applied (add debug logging) #### Issue: Fonts too small or hard to read **Solution**: 1. Adjust font size percentages in generator.go:206-214 2. Increase from 0.94em to 0.96em for paragraphs 3. Test with actual content to verify readability #### Issue: Long version also has compact fonts **Solution**: 1. Check cookie detection logic - must be `cookies["cv-length"] == "short"` 2. Verify compactFontCSS is only appended when `isShortVersion == true` 3. Ensure long version passes `cv-length=long` cookie ## Future Improvements - [ ] Make sidebar width configurable via query parameter - [ ] Add option to customize page break positioning - [ ] Support for different paper sizes (Letter, Legal) - [ ] Transparent background option - [ ] Custom padding/margin configuration ## Related Files - `internal/pdf/generator.go` - PDF generation logic - `templates/cv-content.html` - HTML structure - `templates/partials/modals/pdf-modal.html` - Frontend UI - `static/css/08-contexts/_print.css` - Print media CSS - `internal/handlers/pdf.go` - HTTP handler - `tests/mjs/24-pdf-download-params.test.mjs` - Frontend tests