Skip to content

Instantly share code, notes, and snippets.

@Cdaprod
Last active July 1, 2024 21:33
Show Gist options
  • Save Cdaprod/5d72288e3fa4307534baa00177aa7ed1 to your computer and use it in GitHub Desktop.
Save Cdaprod/5d72288e3fa4307534baa00177aa7ed1 to your computer and use it in GitHub Desktop.
By following these steps, you can create a dynamic, recursive photo album viewer in Golang, where each webpage represents a folder and its image contents, with filenames and folder names persisted.

To create a recursive-like traversal of folders and files for your photography albums, where each webpage represents a folder and its image contents, you can dynamically generate the pages based on the directory structure. This way, you won't need to manually specify folder or file names. Here's a step-by-step guide to achieve this using Golang:

Step 1: Organize Your Photos

Ensure your photos are organized into folders as follows:

/albums
  /vacation2024
    - photo1.jpg
    - photo2.jpg
  /family
    - photo1.jpg
    - photo2.jpg

Step 2: Set Up Your Golang Project

  1. Initialize Your Project:

    mkdir my-photography-site
    cd my-photography-site
    go mod init my-photography-site
  2. Create the main.go file:

    package main
    
    import (
        "html/template"
        "log"
        "net/http"
        "os"
        "path/filepath"
    )
    
    var tmpl = template.Must(template.ParseFiles("template.html"))
    
    type Album struct {
        Name  string
        Path  string
        Photos []string
    }
    
    type PageData struct {
        Title  string
        Albums []Album
    }
    
    func main() {
        http.HandleFunc("/", indexHandler)
        http.Handle("/albums/", http.StripPrefix("/albums/", http.FileServer(http.Dir("./albums"))))
    
        log.Println("Listening on :8080...")
        log.Fatal(http.ListenAndServe(":8080", nil))
    }
    
    func indexHandler(w http.ResponseWriter, r *http.Request) {
        root := "./albums" + r.URL.Path
        if _, err := os.Stat(root); os.IsNotExist(err) {
            http.NotFound(w, r)
            return
        }
    
        albums, err := getAlbums(root)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    
        data := PageData{
            Title:  filepath.Base(root),
            Albums: albums,
        }
    
        tmpl.Execute(w, data)
    }
    
    func getAlbums(root string) ([]Album, error) {
        var albums []Album
    
        err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
            if err != nil {
                return err
            }
    
            if info.IsDir() && path != root {
                album := Album{Name: filepath.Base(path), Path: path}
                filepath.Walk(path, func(p string, i os.FileInfo, e error) error {
                    if !i.IsDir() {
                        album.Photos = append(album.Photos, filepath.Join("/albums", filepath.Rel(root, p)))
                    }
                    return nil
                })
                albums = append(albums, album)
                return filepath.SkipDir
            }
            return nil
        })
        return albums, err
    }

Step 3: Create the HTML Template

  1. Create a template.html file:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{{ .Title }}</title>
        <style>
            body { font-family: Arial, sans-serif; }
            .album { margin: 20px 0; }
            .album h2 { margin: 0; }
            .photos { display: flex; flex-wrap: wrap; }
            .photos img { max-width: 200px; margin: 10px; }
            .navigation { margin: 20px 0; }
            .navigation a { margin: 0 10px; }
        </style>
    </head>
    <body>
        <h1>{{ .Title }}</h1>
        {{ range .Albums }}
        <div class="album">
            <h2><a href="{{ .Path }}">{{ .Name }}</a></h2>
            <div class="photos">
                {{ range .Photos }}
                <img src="{{ . }}" alt="">
                {{ end }}
            </div>
        </div>
        {{ end }}
        <div class="navigation">
            <a href="/">Home</a>
        </div>
    </body>
    </html>

Step 4: Run the Server

  1. Run your Golang server:

    go run main.go
  2. Navigate through your albums in the browser:

    • Open http://localhost:8080 to start at the root directory.
    • Click on album names to navigate into each album and view its photos.

Explanation:

  • Index Handler: Dynamically handles requests to directories, generating an HTML page listing albums and their photos.
  • getAlbums Function: Recursively walks through the directory structure, gathering album names and photos.
  • HTML Template: Renders albums as links, with each album displaying its photos.

By following these steps, you can create a dynamic, recursive photo album viewer in Golang, where each webpage represents a folder and its image contents, with filenames and folder names persisted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment