Open robacarp opened 5 years ago
I don't know of a way currently (bar injecting a middleware that messes with the response body - gonna be uuuugly :D).
Widening the scope of this issue a bit (sorry for that):
I still think what Brandon Williams detailed in a series of posts starting with https://www.fewbutripe.com/swift/html/dsl/2017/06/22/type-safe-html-in-swift.html does would be a nice goal for luckys html dsl to pursuit as well. We have a nice block based html dsl, but as we append strings to internal state @view
it's not trivial to apply transforms to that.
If we could build our html roughly like we do right now, and then have a tree that we can apply functions to, that could make pretty-printed html soo easy to achieve.
I've been thinking about this a lot lately. I've even caught a bug in Lucky from viewing the source that the dev inspector didn't catch. Right now we're doing a lot of new SPA stuff, and it's nice to view the source to see what's actually being rendered in the raw especially when using curl and printing the source to the terminal.
This would greatly help out in development; however, this would require an HTML beautifier to work.
I did find a shard to do the html beautifying! My thought is after the view is generated, we pass that @view
to this MyHTML shard.
myhtml = Myhtml::Parser.new(@view)
myhtml.to_pretty_html
I talked with @paulcsmith a little bit about this. One thing is Lucky generally doesn't add in outside libraries, so adding this in by default might not be a thing. What is the consensus on adding a handler in to Lucky that gives you access to the markup for any processing?
I'm not sure exactly how'd that look just yet, but
class MyPrettyFormatter < Lucky::BeforeRenderHandler
def call(view)
myhtml = Myhtml::Parser.new(view)
myhtml.to_pretty_html
end
end
So the idea here would be that Lucky doesn't actually do the "uncompressing". Instead, you as the dev would just include this shard in each project you wanted to use it in as a development dependecy, and you just hooked in to this call.
I ran into this again. People tell me I shouldn't read the source so much.
require "myhtml"
class HtmlBeautificationHandler
include HTTP::Handler
def initialize(@enabled = false)
end
def call(context : HTTP::Server::Context)
unless @enabled
return call_next context
end
to_client = context.response.output
unpretty = IO::Memory.new
context.response.output = unpretty
call_next context
if context.response.headers["Content-Type"]? == "text/html"
to_client << Myhtml::Parser.new(unpretty.to_s).to_pretty_html
else
to_client << unpretty
end
context.response.output = to_client
end
end
class AppServer < Lucky::BaseAppServer
def middleware : Array(HTTP::Handler)
[
Lucky::ForceSSLHandler.new,
Lucky::HttpMethodOverrideHandler.new,
Lucky::LogHandler.new,
Lucky::ErrorHandler.new(action: Errors::Show),
Lucky::RemoteIpHandler.new,
+ HtmlBeautificationHandler.new(enabled: Lucky::Env.development?),
Lucky::RouteHandler.new,
Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
Lucky::StaticFileHandler.new("./public", fallthrough: false, directory_listing: false),
Lucky::RouteNotFoundHandler.new,
] of HTTP::Handler
end
This solved it for me, at least for the general case. If that warrants closing the issue here, I'm game.
That's nice. I actually forgot about this, but I think we can keep this open. I still like that idea of the Lucky::BeforeRenderHandler
that you could hook in to. It's nice to see an example though. We may be able to use that as some guide in to adding this thing in.
Perhaps it got renamed, but I couldn't find anything under BeforeRenderHandler. Adding a middleware feels risky, especially if anything is done with chunked responses or socket type open comms. But it's not a bad way to read the source for a wedge or two.
We don't have one yet 😅 I was saying I liked the idea of adding one. I don't think it would be a middleware, but more just a hook in to the @view
IO that you could alter before sending the response.
HTML is a finicky beast, and so are browsers. Most of the time, what's rendered in the browser inspector is fine, but some times it's not and reading the source is necessary. Currently the source shows up all on one or two lines, and it's a bit of a bear.
Is it possible and reasonable to produce non-minified html?