refactor: centralize constants and reorganize documentation
- Create internal/constants package with all hardcoded values (environment, cookies, themes, headers, routes, cache) - Create internal/httputil package for HTTP helper functions - Update all handlers and middleware to use centralized constants - Reorganize documentation with numbered prefixes (00-26) - Remove duplicate docs from validation folder and docs/ - Delete handlers/constants.go (moved to internal/constants)
This commit is contained in:
@@ -8,6 +8,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/juanatsap/cv-site/internal/constants"
|
||||
"github.com/juanatsap/cv-site/internal/httputil"
|
||||
"github.com/juanatsap/cv-site/internal/middleware"
|
||||
"github.com/juanatsap/cv-site/internal/pdf"
|
||||
)
|
||||
@@ -31,14 +33,8 @@ func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get language from query parameter, default to English
|
||||
lang := r.URL.Query().Get("lang")
|
||||
if lang == "" {
|
||||
lang = "en"
|
||||
}
|
||||
|
||||
// Validate language
|
||||
if lang != "en" && lang != "es" {
|
||||
lang, ok := httputil.LangOrError(r)
|
||||
if !ok {
|
||||
HandleError(w, r, BadRequestError("Unsupported language. Use 'en' or 'es'"))
|
||||
return
|
||||
}
|
||||
@@ -74,7 +70,7 @@ func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.Header().Set(constants.HeaderContentType, constants.ContentTypeHTML)
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "index.html"))
|
||||
return
|
||||
@@ -83,14 +79,8 @@ func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// CVContent renders just the CV content for HTMX swaps
|
||||
func (h *CVHandler) CVContent(w http.ResponseWriter, r *http.Request) {
|
||||
// Get language from query parameter
|
||||
lang := r.URL.Query().Get("lang")
|
||||
if lang == "" {
|
||||
lang = "en"
|
||||
}
|
||||
|
||||
// Validate language
|
||||
if lang != "en" && lang != "es" {
|
||||
lang, ok := httputil.LangOrError(r)
|
||||
if !ok {
|
||||
HandleError(w, r, BadRequestError("Unsupported language. Use 'en' or 'es'"))
|
||||
return
|
||||
}
|
||||
@@ -109,7 +99,7 @@ func (h *CVHandler) CVContent(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.Header().Set(constants.HeaderContentType, constants.ContentTypeHTML)
|
||||
if err := tmpl.Execute(w, data); err != nil {
|
||||
HandleError(w, r, TemplateError(err, "cv-content.html"))
|
||||
return
|
||||
@@ -137,7 +127,7 @@ func (h *CVHandler) DefaultCVShortcut(w http.ResponseWriter, r *http.Request) {
|
||||
lang := strings.TrimSuffix(langWithExt, ".pdf")
|
||||
|
||||
// Validate language
|
||||
if lang != "en" && lang != "es" {
|
||||
if !constants.SupportedLanguages[lang] {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
@@ -157,11 +147,11 @@ func (h *CVHandler) DefaultCVShortcut(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Prepare cookies for PDF generation (short, with_skills, light mode)
|
||||
cookies := map[string]string{
|
||||
"cv-length": "short",
|
||||
"cv-icons": "show",
|
||||
"cv-language": lang,
|
||||
"cv-theme": "default", // with_skills = default theme
|
||||
"color-theme": "light", // Always light for PDFs
|
||||
constants.CookieCVLength: constants.CVLengthShort,
|
||||
constants.CookieCVIcons: constants.CVIconsShow,
|
||||
constants.CookieCVLanguage: lang,
|
||||
constants.CookieCVTheme: constants.CVThemeDefault, // with_skills = default theme
|
||||
constants.CookieColorTheme: constants.ColorThemeLight, // Always light for PDFs
|
||||
}
|
||||
|
||||
// Construct URL for PDF generation
|
||||
@@ -180,9 +170,9 @@ func (h *CVHandler) DefaultCVShortcut(w http.ResponseWriter, r *http.Request) {
|
||||
filename := filepath.Base(path) // cv-jamr-2025-en.pdf
|
||||
|
||||
// Set response headers with shortcut filename
|
||||
w.Header().Set("Content-Type", "application/pdf")
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
|
||||
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(pdfData)))
|
||||
w.Header().Set(constants.HeaderContentType, constants.ContentTypePDF)
|
||||
w.Header().Set(constants.HeaderContentDisposition, fmt.Sprintf("attachment; filename=%s", filename))
|
||||
w.Header().Set(constants.HeaderContentLength, fmt.Sprintf("%d", len(pdfData)))
|
||||
|
||||
// Write PDF data
|
||||
if _, err := w.Write(pdfData); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user