// Example 1: Web Server with Templates package main

import ( “html/template” “log” “net/http” “time” )

// Article represents a blog post type Article struct { Title string Content string PublishedAt time.Time Author string Tags []string }

func main() { // Define custom functions for templates funcMap := template.FuncMap{ “formatDate”: func(t time.Time) string { return t.Format(“January 2, 2006”) }, “join”: func(sep string, items []string) string { result := "" for i, item := range items { if i > 0 { result += sep } result += item } return result }, }

// Parse templates with function map
tmpl, err := template.New("").Funcs(funcMap).ParseGlob("templates/*.html")
if err != nil {
	log.Fatalf("Error parsing templates: %v", err)
}

// Handler for the blog article
http.HandleFunc("/article", func(w http.ResponseWriter, r *http.Request) {
	article := Article{
		Title:       "Understanding Go Templates",
		Content:     "Go templates are a powerful way to generate textual output based on data...",
		PublishedAt: time.Date(2023, 5, 15, 12, 0, 0, 0, time.UTC),
		Author:      "Jane Smith",
		Tags:        []string{"golang", "templates", "web-development"},
	}

	err := tmpl.ExecuteTemplate(w, "article.html", article)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
})

// Start the server
log.Println("Starting server on :8080...")
log.Fatal(http.ListenAndServe(":8080", nil))

}

/* templates/layout.html:

{{block "title" .}}My Blog{{end}}
<main>
    {{block "content" .}}{{end}}
</main>

<footer>
    <p>&copy; 2023 My Blog</p>
</footer>
*/

/* templates/article.html: {{template “layout.html” .}}

{{define “title”}}{{.Title}} | My Blog{{end}}

{{define “content”}}

{{.Title}}

Published on by {{.Author}}
<div class="content">
    {{.Content}}
</div>

{{if .Tags}}
<div class="tags">
    Tags: {{join ", " .Tags}}
</div>
{{end}}
{{end}} */

// Example 2: Data-driven Email Template Generator package main

import ( “bytes” “fmt” “log” “text/template” “time” )

type Customer struct { Name string Email string LastPurchase time.Time }

type Product struct { Name string Description string Price float64 ImageURL string }

type EmailData struct { Customer Customer RecommendedProducts []Product CouponCode string ExpiryDate time.Time }

func generateEmail(customer Customer) (string, error) { // Create email data data := EmailData{ Customer: customer, RecommendedProducts: []Product{ { Name: “Wireless Headphones”, Description: “High-quality noise-cancelling headphones”, Price: 129.99, ImageURL: “https://example.com/images/headphones.jpg”, }, { Name: “Smart Watch”, Description: “Track your fitness and stay connected”, Price: 199.99, ImageURL: “https://example.com/images/smartwatch.jpg”, }, }, CouponCode: “WELCOME20”, ExpiryDate: time.Now().AddDate(0, 0, 14), // 14 days from now }

// Define template functions
funcMap := template.FuncMap{
	"formatDate": func(t time.Time) string {
		return t.Format("January 2, 2006")
	},
	"formatPrice": func(price float64) string {
		return fmt.Sprintf("$%.2f", price)
	},
	"daysSince": func(t time.Time) int {
		return int(time.Since(t).Hours() / 24)
	},
}

// Define email templates
const emailTemplate = `

{{define “text”}} Hello {{.Customer.Name}},

We noticed it’s been {{daysSince .Customer.LastPurchase}} days since your last purchase. We have some recommendations just for you!

{{range .RecommendedProducts}}

  • {{.Name}} - {{formatPrice .Price}} {{.Description}}

{{end}}

Use coupon code {{.CouponCode}} for 20% off your next purchase! Valid until {{formatDate .ExpiryDate}}.

Thank you for shopping with us! {{end}}

{{define “html”}}

Special Recommendations for You

Hello {{.Customer.Name}},

<p>We noticed it's been <strong>{{daysSince .Customer.LastPurchase}} days</strong> since your last purchase. 
We have some recommendations just for you!</p>

{{range .RecommendedProducts}}
<div class="product">
    <h2>{{.Name}} - {{formatPrice .Price}}</h2>
    <p>{{.Description}}</p>
    <img src="{{.ImageURL}}" alt="{{.Name}}" style="max-width: 200px;">
</div>
{{end}}

<p>Use coupon code <span class="coupon">{{.CouponCode}}</span> for 20% off your next purchase!</p>
<p>Valid until <strong>{{formatDate .ExpiryDate}}</strong>.</p>

<p>Thank you for shopping with us!</p>
{{end}} `
tmpl, err := template.New("email").Funcs(funcMap).Parse(emailTemplate)
if err != nil {
	return "", fmt.Errorf("template parsing error: %v", err)
}

// Generate text version
var textBuffer bytes.Buffer
err = tmpl.ExecuteTemplate(&textBuffer, "text", data)
if err != nil {
	return "", fmt.Errorf("text template execution error: %v", err)
}

// Generate HTML version
var htmlBuffer bytes.Buffer
err = tmpl.ExecuteTemplate(&htmlBuffer, "html", data)
if err != nil {
	return "", fmt.Errorf("HTML template execution error: %v", err)
}

// In a real application, you would use these to send an email
// For this example, we'll just return the HTML version
return htmlBuffer.String(), nil

}

func main() { customer := Customer{ Name: “John Doe”, Email: “[email protected]”, LastPurchase: time.Now().AddDate(0, 0, -30), // 30 days ago }

emailHTML, err := generateEmail(customer)
if err != nil {
	log.Fatalf("Error generating email: %v", err)
}

fmt.Println("Generated email HTML:")
fmt.Println(emailHTML)

}

// Example 3: Configuration File Generator package main

import ( “fmt” “os” “path/filepath” “text/template” )

type DatabaseConfig struct { Host string Port int User string Password string Database string MaxConns int SSL bool }

type ServerConfig struct { Host string Port int LogLevel string TLS bool CertFile string KeyFile string RateLimit int }

type Config struct { Environment string Database DatabaseConfig Server ServerConfig Features map[string]bool }

func generateConfigs(baseConfig Config) error { // Define environments to generate configs for environments := []string{“dev”, “staging”, “production”}

// Create templates directory if it doesn't exist
if err := os.MkdirAll("configs", 0755); err != nil {
	return fmt.Errorf("failed to create configs directory: %v", err)
}

// Define template functions
funcMap := template.FuncMap{
	"indent": func(n int, s string) string {
		padding := ""
		for i := 0; i < n; i++ {
			padding += "  "
		}
		return padding + s
	},
	"toLowerCase": func(s string) string {
		return s
	},
}

// Define templates for different output formats
templates := map[string]string{
	"json": `{

“environment”: ”{{.Environment}}”, “database”: { “host”: ”{{.Database.Host}}”, “port”: {{.Database.Port}}, “user”: ”{{.Database.User}}”, “password”: ”{{.Database.Password}}”, “database”: ”{{.Database.Database}}”, “maxConns”: {{.Database.MaxConns}}, “ssl”: {{.Database.SSL}} }, “server”: { “host”: ”{{.Server.Host}}”, “port”: {{.Server.Port}}, “logLevel”: ”{{.Server.LogLevel}}”, “tls”: {{.Server.TLS}}, “certFile”: ”{{.Server.CertFile}}”, “keyFile”: ”{{.Server.KeyFile}}”, “rateLimit”: {{.Server.RateLimit}} }, “features”: { {{first := true}} {{range key, value := .Features}} {{if first}}{{first = false}}{{else}},{{end}} "{{key}}”: {{value}} {{end}} } }`, "yaml": `environment: {{.Environment}} database: host: {{.Database.Host}} port: {{.Database.Port}} user: {{.Database.User}} password: {{.Database.Password}} database: {{.Database.Database}} maxConns: {{.Database.MaxConns}} ssl: {{.Database.SSL}} server: host: {{.Server.Host}} port: {{.Server.Port}} logLevel: {{.Server.LogLevel}} tls: {{.Server.TLS}} certFile: {{.Server.CertFile}} keyFile: {{.Server.KeyFile}} rateLimit: {{.Server.RateLimit}} features: {{range key, value := .Features}} {{key}}: {{$value}} {{end}}, "toml": environment = ”{{.Environment}}”

[database] host = ”{{.Database.Host}}” port = {{.Database.Port}} user = ”{{.Database.User}}” password = ”{{.Database.Password}}” database = ”{{.Database.Database}}” maxConns = {{.Database.MaxConns}} ssl = {{.Database.SSL}}

[server] host = ”{{.Server.Host}}” port = {{.Server.Port}} logLevel = ”{{.Server.LogLevel}}” tls = {{.Server.TLS}} certFile = ”{{.Server.CertFile}}” keyFile = ”{{.Server.KeyFile}}” rateLimit = {{.Server.RateLimit}}

[features] {{range value := .Features}} {{key}} = {{value}} {{end}}`, }

// Parse templates
parsedTemplates := make(map[string]*template.Template)
for format, templateContent := range templates {
	tmpl, err := template.New(format).Funcs(funcMap).Parse(templateContent)
	if err != nil {
		return fmt.Errorf("error parsing %s template: %v", format, err)
	}
	parsedTemplates[format] = tmpl
}

// Generate configs for each environment and format
for _, env := range environments {
	// Create a copy of the base config and customize for this environment
	envConfig := baseConfig
	envConfig.Environment = env

	// Adjust configuration based on environment
	switch env {
	case "dev":
		envConfig.Database.Host = "localhost"
		envConfig.Database.SSL = false
		envConfig.Server.TLS = false
		envConfig.Server.RateLimit = 0 // No rate limiting in dev
	case "staging":
		envConfig.Database.Host = "staging-db.example.com"
		envConfig.Database.SSL = true
		envConfig.Server.TLS = true
		envConfig.Server.RateLimit = 100
	case "production":
		envConfig.Database.Host = "db.example.com"
		envConfig.Database.SSL = true
		envConfig.Server.TLS = true
		envConfig.Server.RateLimit = 50
		envConfig.Server.LogLevel = "warn" // Less verbose in production
	}

	// Generate each format
	for format, tmpl := range parsedTemplates {
		// Create file name
		fileName := filepath.Join("configs", fmt.Sprintf("config.%s.%s", env, format))

		// Create file
		file, err := os.Create(fileName)
		if err != nil {
			return fmt.Errorf("error creating config file %s: %v", fileName, err)
		}
		defer file.Close()

		// Execute template
		if err := tmpl.Execute(file, envConfig); err != nil {
			return fmt.Errorf("error executing template for %s: %v", fileName, err)
		}

		fmt.Printf("Generated config file: %s\n", fileName)
	}
}

return nil

}

func main() { // Base configuration config := Config{ Environment: “base”, // Will be overridden Database: DatabaseConfig{ Port: 5432, User: “app_user”, Password: “secret_password”, // In a real app, use environment variables Database: “myapp”, MaxConns: 20, }, Server: ServerConfig{ Host: “0.0.0.0”, Port: 8080, LogLevel: “info”, CertFile: “certs/server.crt”, KeyFile: “certs/server.key”, }, Features: map[string]bool{ “newUserSignup”: true, “analytics”: true, “notifications”: true, “betaFeature”: false, }, }

if err := generateConfigs(config); err != nil {
	fmt.Printf("Error generating configs: %v\n", err)
	os.Exit(1)
}

fmt.Println("Configuration files generated successfully!")

}