如何使用Revel框架执行HTML Minify

My first idea was to get the response body within the filter, then use one of minify libraries like tdewolff/minify and write to response, but i cant find the way to get response body. Is there any better solutions?

It seems, by looking at the docs, that a filter can access the Controller type, which contains the Response. This response contains Out which is a ResponseWriter (and thus also an io.Writer). We need to replace only the Write method to redirect the write to the minifier, which then writes to the response writer. We need to use io.Pipe and a goroutine for this.

type MinifyResponseWriter struct {
    http.ResponseWriter
    io.Writer
}

func (f MinifyResponseWriter) Write(b []byte) (int, error) {
    return f.Writer.Write(b)
}

func MinifyFilter(c *Controller, fc []Filter) {
    pr, pw := io.Pipe()
    go func(w io.Writer) {
        m := minify.New()
        m.AddFunc("text/css", css.Minify)
        m.AddFunc("text/html", html.Minify)
        m.AddFunc("text/javascript", js.Minify)
        m.AddFunc("image/svg+xml", svg.Minify)
        m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
        m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)

        if err := m.Minify("mimetype", w, pr); err != nil {
            panic(err)
        }
    }(c.Response.Out)
    c.Response.Out = MinifyResponseWriter{c.Response.Out, pw}
}

Something along those lines (not tested). Here we take the incoming io.Writer (which is part of the ResponseWriter), and wrap a struct around that. It keeps the original methods for the response writer, but the Write method is overrided to be replaced by the PipeWriter. This means that any write to the new response writer goes to PipeWriter, which is coupled to PipeReader. Minify Reads from that reader and writes to the original response writer.

Because we change the value of c.Response.Out, we need to pass it explicitly to the goroutine. Make sure you obtain the correct mimetype (through extension?) or call the appropriate minify function directly.