Implement complete content injection and enhancement pipeline
- Add content API client with HTTP and mock implementations - Implement HTML content injection with database content replacement - Create enhance command for build-time content injection - Integrate enhancement with servedev for live development workflow - Add editor asset injection and serving (/_insertr/ endpoints) - Support on-the-fly HTML enhancement during development - Enable complete 'Tailwind of CMS' workflow: parse → inject → serve
This commit is contained in:
@@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/insertr/cli/pkg/content"
|
||||
)
|
||||
|
||||
var servedevCmd = &cobra.Command{
|
||||
@@ -21,8 +23,10 @@ with live rebuilds via Air.`,
|
||||
}
|
||||
|
||||
var (
|
||||
inputDir string
|
||||
port int
|
||||
inputDir string
|
||||
port int
|
||||
useMockContent bool
|
||||
devSiteID string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -30,6 +34,8 @@ func init() {
|
||||
|
||||
servedevCmd.Flags().StringVarP(&inputDir, "input", "i", ".", "Input directory to serve")
|
||||
servedevCmd.Flags().IntVarP(&port, "port", "p", 3000, "Port to serve on")
|
||||
servedevCmd.Flags().BoolVar(&useMockContent, "mock", true, "Use mock content for development")
|
||||
servedevCmd.Flags().StringVarP(&devSiteID, "site-id", "s", "demo", "Site ID for content lookup")
|
||||
}
|
||||
|
||||
func runServedev(cmd *cobra.Command, args []string) {
|
||||
@@ -44,18 +50,37 @@ func runServedev(cmd *cobra.Command, args []string) {
|
||||
log.Fatalf("Input directory does not exist: %s", absInputDir)
|
||||
}
|
||||
|
||||
fmt.Printf("🚀 Starting development server...\n")
|
||||
// Create content client
|
||||
var client content.ContentClient
|
||||
if useMockContent {
|
||||
fmt.Printf("🧪 Using mock content for development\n")
|
||||
client = content.NewMockClient()
|
||||
} else {
|
||||
// For now, default to mock if no API URL provided
|
||||
fmt.Printf("🧪 Using mock content for development (no API configured)\n")
|
||||
client = content.NewMockClient()
|
||||
}
|
||||
|
||||
fmt.Printf("🚀 Starting development server with content enhancement...\n")
|
||||
fmt.Printf("📁 Serving directory: %s\n", absInputDir)
|
||||
fmt.Printf("🌐 Server running at: http://localhost:%d\n", port)
|
||||
fmt.Printf("🏷️ Site ID: %s\n", devSiteID)
|
||||
fmt.Printf("🔄 Manually refresh browser to see changes\n\n")
|
||||
|
||||
// Create file server
|
||||
// Create enhanced file server
|
||||
fileServer := http.FileServer(&enhancedFileSystem{
|
||||
fs: http.Dir(absInputDir),
|
||||
dir: absInputDir,
|
||||
fs: http.Dir(absInputDir),
|
||||
dir: absInputDir,
|
||||
enhancer: content.NewEnhancer(client, devSiteID),
|
||||
})
|
||||
|
||||
// Handle all requests with our enhanced file server
|
||||
// Handle editor assets
|
||||
http.HandleFunc("/_insertr/", func(w http.ResponseWriter, r *http.Request) {
|
||||
assetPath := strings.TrimPrefix(r.URL.Path, "/_insertr/")
|
||||
serveEditorAsset(w, r, assetPath)
|
||||
})
|
||||
|
||||
// Handle all other requests with our enhanced file server
|
||||
http.Handle("/", fileServer)
|
||||
|
||||
// Start server
|
||||
@@ -63,25 +88,78 @@ func runServedev(cmd *cobra.Command, args []string) {
|
||||
log.Fatal(http.ListenAndServe(addr, nil))
|
||||
}
|
||||
|
||||
// serveEditorAsset serves editor JavaScript and CSS files
|
||||
func serveEditorAsset(w http.ResponseWriter, r *http.Request, assetPath string) {
|
||||
// Get the path to the CLI binary directory
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Look for assets relative to the CLI binary (for built version)
|
||||
assetsDir := filepath.Join(filepath.Dir(execPath), "assets", "editor")
|
||||
assetFile := filepath.Join(assetsDir, assetPath)
|
||||
|
||||
// If not found, look for assets relative to source (for development)
|
||||
if _, err := os.Stat(assetFile); os.IsNotExist(err) {
|
||||
// Assume we're running from source
|
||||
cwd, _ := os.Getwd()
|
||||
assetsDir = filepath.Join(cwd, "assets", "editor")
|
||||
assetFile = filepath.Join(assetsDir, assetPath)
|
||||
}
|
||||
|
||||
// Set appropriate content type
|
||||
if strings.HasSuffix(assetPath, ".js") {
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
} else if strings.HasSuffix(assetPath, ".css") {
|
||||
w.Header().Set("Content-Type", "text/css")
|
||||
}
|
||||
|
||||
// Serve the file
|
||||
http.ServeFile(w, r, assetFile)
|
||||
}
|
||||
|
||||
// enhancedFileSystem wraps http.FileSystem to provide enhanced HTML serving
|
||||
type enhancedFileSystem struct {
|
||||
fs http.FileSystem
|
||||
dir string
|
||||
fs http.FileSystem
|
||||
dir string
|
||||
enhancer *content.Enhancer
|
||||
}
|
||||
|
||||
func (efs *enhancedFileSystem) Open(name string) (http.File, error) {
|
||||
file, err := efs.fs.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// For HTML files, we'll eventually enhance them here
|
||||
// For now, just serve them as-is
|
||||
// For HTML files, enhance them on-the-fly
|
||||
if strings.HasSuffix(name, ".html") {
|
||||
fmt.Printf("📄 Serving HTML: %s\n", name)
|
||||
fmt.Println("🔍 Parser ran!")
|
||||
// TODO: Parse for insertr elements and enhance
|
||||
fmt.Printf("📄 Enhancing HTML: %s\n", name)
|
||||
return efs.serveEnhancedHTML(name)
|
||||
}
|
||||
|
||||
return file, nil
|
||||
// For non-HTML files, serve as-is
|
||||
return efs.fs.Open(name)
|
||||
}
|
||||
|
||||
// serveEnhancedHTML enhances an HTML file and returns it as an http.File
|
||||
func (efs *enhancedFileSystem) serveEnhancedHTML(name string) (http.File, error) {
|
||||
// Get the full file path
|
||||
inputPath := filepath.Join(efs.dir, name)
|
||||
|
||||
// Create a temporary output path (in-memory would be better, but this is simpler for now)
|
||||
tempDir := filepath.Join(os.TempDir(), "insertr-dev")
|
||||
outputPath := filepath.Join(tempDir, name)
|
||||
|
||||
// Ensure temp directory exists
|
||||
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
|
||||
fmt.Printf("⚠️ Failed to create temp directory: %v\n", err)
|
||||
return efs.fs.Open(name) // Fallback to original file
|
||||
}
|
||||
|
||||
// Enhance the file
|
||||
if err := efs.enhancer.EnhanceFile(inputPath, outputPath); err != nil {
|
||||
fmt.Printf("⚠️ Enhancement failed for %s: %v\n", name, err)
|
||||
return efs.fs.Open(name) // Fallback to original file
|
||||
}
|
||||
|
||||
// Serve the enhanced file
|
||||
tempFS := http.Dir(tempDir)
|
||||
return tempFS.Open(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user