maragudk / gomponents

HTML components in pure Go.
https://www.gomponents.com
MIT License
1.3k stars 32 forks source link

pretty output? #198

Closed gaspardleon closed 2 months ago

gaspardleon commented 2 months ago

Love this package, it's really nice.

Any chance of indented (human-readable) HTML output?

I currently have a work-around by piping the output into another package: https://github.com/Joker/hpp But would be nice as an "option"

buff := new(bytes.Buffer) err = SomeGompFunc.Render(buf) hpp.Format(buf, w) // read buffer, format, then write formatted bytes into responseWriter

markuswustenberg commented 2 months ago

Hi @gaspardleon! Thank you for the suggestion. 😊

The short answer is: no, I don't think it's something I want to add to the core library. The aim of the project is to produce valid HTML components, and I'd like to keep it simple.

I would think it's better suited as a form of HTTP middleware that takes the output into a response buffer, formats it, and sends it out to the client. Maybe the library you link to can be wrapped like that and published somewhere as middleware?

gaspardleon commented 2 months ago

Fair enough, it's nice to keep the simplicity.

I'll look into making the other package into a middleware; that does seem like a decent option.

gaspardleon commented 2 months ago

just for completeness here is the middleware version:

package middleware

import (
    "bytes"
    "net/http"

    "github.com/Joker/hpp"
)

type prettyPrintResponseWrapper struct {
    buf        *bytes.Buffer
    httpWriter http.ResponseWriter
}

func (wrapper prettyPrintResponseWrapper) Header() http.Header {
    return wrapper.httpWriter.Header() // straight pass through
}
func (wrapper prettyPrintResponseWrapper) Write(bytes []byte) (int, error) {
    return wrapper.buf.Write(bytes) // capture the written bytes in a buffer
}
func (wrapper prettyPrintResponseWrapper) WriteHeader(statusCode int) {
    wrapper.httpWriter.WriteHeader(statusCode) // straight pass through
}

func PrettyPrintHTML(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        wrapped := prettyPrintResponseWrapper{
            buf:        new(bytes.Buffer),
            httpWriter: w,
        }
        defer func(toClose *bytes.Buffer) {
            toClose.Reset()
            toClose = nil
        }(wrapped.buf)
        next.ServeHTTP(wrapped, r) // run the next middleware or end function but with a dummy buffer to collect it's output
        hpp.Format(wrapped.buf, w) // read the dummy output buffer, format the HTML in it, then write the formatted HTML into the real http.ResponseWriter
    })
}
markuswustenberg commented 2 months ago

Thanks for sharing it!