Files
cv-site/internal/routes/routes.go
T
juanatsap 66e06a6cb0 feat: Add year-aware PDF shortcut URLs + Default CV modal option
## Shortcut URLs
- New routes: /cv-jamr-{year}-{lang}.pdf (e.g., /cv-jamr-2025-en.pdf)
- Year validation: Only current year accepted, returns 404 for past/future
- Auto-redirects (301) to: /export/pdf?lang={lang}&length=short&icons=show&version=with_skills
- Both languages supported: en and es

## PDF Modal Updates
- Replaced "Current View" option with "Default CV (Recommended)"
- Visual highlighting: purple gradient badge, star emoji , bold text
- Uses shortcut URL with dynamic year detection
- Clear recommendation for users (5 pages, short with skills)

## Technical Details
- Handler: DefaultCVShortcut() in internal/handlers/cv.go
- Pattern check in Home() handler for proper routing
- Helper function: window.openPdfModal() for references section
- Documentation: PDF-SHORTCUT-IMPLEMENTATION.md

Benefits:
- Memorable, shareable URLs (juan.andres.morenorub.io/cv-jamr-2025-en.pdf)
- Auto-updates yearly without code changes
- Clear user guidance for recommended CV format
2025-11-20 12:14:53 +00:00

52 lines
1.6 KiB
Go

package routes
import (
"net/http"
"time"
"github.com/juanatsap/cv-site/internal/handlers"
"github.com/juanatsap/cv-site/internal/middleware"
)
// Setup configures all application routes and middleware
func Setup(cvHandler *handlers.CVHandler, healthHandler *handlers.HealthHandler) http.Handler {
mux := http.NewServeMux()
// Shortcut routes for default CV (year-aware) - MUST be before "/" route
// Pattern: /cv-jamr-{year}-{lang}.pdf (e.g., /cv-jamr-2025-en.pdf)
mux.HandleFunc("/cv-jamr-", cvHandler.DefaultCVShortcut)
// Public routes
mux.HandleFunc("/", cvHandler.Home)
mux.HandleFunc("/cv", cvHandler.CVContent)
mux.HandleFunc("/health", healthHandler.Check)
// HTMX endpoints for interactive controls
mux.HandleFunc("/switch-language", cvHandler.SwitchLanguage)
mux.HandleFunc("/toggle/length", cvHandler.ToggleLength)
mux.HandleFunc("/toggle/icons", cvHandler.ToggleIcons)
mux.HandleFunc("/toggle/theme", cvHandler.ToggleTheme)
// Protected PDF endpoint with rate limiting (3 requests/minute per IP)
pdfRateLimiter := middleware.NewRateLimiter(3, 1*time.Minute)
protectedPDFHandler := middleware.OriginChecker(
pdfRateLimiter.Middleware(
http.HandlerFunc(cvHandler.ExportPDF),
),
)
mux.Handle("/export/pdf", protectedPDFHandler)
// Static files with cache control
staticHandler := http.StripPrefix("/static/", http.FileServer(http.Dir("static")))
mux.Handle("/static/", middleware.CacheControl(staticHandler))
// Apply comprehensive middleware chain
handler := middleware.Recovery(
middleware.Logger(
middleware.SecurityHeaders(mux),
),
)
return handler
}