feat: initial blog engine with multi-language, profile, and role system
- Gin + GORM + Tailwind CSS blog engine - OS-aware config (Linux /etc/blog_go/, Windows ./win/etc/blog_go/) - SQLite by default, MySQL support via config - Auto-migrate database + seed admin user on first run - Session-based auth (login/logout) - i18n: Chinese/English with auto-detect + manual switch - Avatar dropdown nav with click-to-toggle menu - Profile page: avatar upload, edit info, change password - Role system: admin (full access) and author (profile only) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/sessions/cookie"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"go_blog/config"
|
||||
"go_blog/handlers"
|
||||
"go_blog/middleware"
|
||||
"go_blog/models"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 1. Load configuration (auto-creates if missing).
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
// 2. Initialize the database (auto-migrates, seeds admin).
|
||||
db := models.InitDB(cfg)
|
||||
|
||||
// 3. Create session store (cookie-based).
|
||||
store := cookie.NewStore([]byte(cfg.Secret))
|
||||
store.Options(sessions.Options{
|
||||
Path: "/",
|
||||
MaxAge: 86400, // 24 hours
|
||||
HttpOnly: true, // prevent XSS access
|
||||
Secure: false, // set true in production with HTTPS
|
||||
})
|
||||
|
||||
// 4. Create Gin router.
|
||||
router := gin.Default()
|
||||
|
||||
// 5. Load HTML templates.
|
||||
router.LoadHTMLGlob("templates/**/*.html")
|
||||
|
||||
// 6. Serve uploaded files (avatars etc.) from the storage path.
|
||||
router.Static("/uploads", cfg.Path)
|
||||
|
||||
// 6. Global session middleware.
|
||||
router.Use(sessions.Sessions("blog_session", store))
|
||||
|
||||
// 7. Global context middleware (sets IsLoggedIn, Username for templates).
|
||||
router.Use(middleware.SetUserContext(db))
|
||||
|
||||
// 8. Register routes.
|
||||
router.GET("/", handlers.HomePage())
|
||||
router.GET("/login", handlers.LoginPage())
|
||||
router.POST("/login", handlers.Login(db))
|
||||
router.POST("/logout", handlers.Logout())
|
||||
|
||||
// Protected admin routes.
|
||||
admin := router.Group("/admin")
|
||||
admin.Use(middleware.AuthRequired())
|
||||
{
|
||||
admin.GET("", handlers.AdminDashboard())
|
||||
}
|
||||
|
||||
// Protected profile routes.
|
||||
profile := router.Group("/profile")
|
||||
profile.Use(middleware.AuthRequired())
|
||||
{
|
||||
profile.GET("", handlers.ProfilePage(db))
|
||||
profile.POST("", handlers.UpdateProfile(db, cfg.Path))
|
||||
}
|
||||
|
||||
// 9. Start the server.
|
||||
addr := fmt.Sprintf(":%s", cfg.Port)
|
||||
log.Printf("Go Blog starting on http://localhost%s", addr)
|
||||
if err := router.Run(addr); err != nil {
|
||||
log.Fatalf("Failed to start server: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user