-
Presenter Pattern, Rails 3 and html_safe
I’ve been playing with the Presenter pattern lately, and ran across an issue: it felt like I was writing a lot of HTML in a
.rbfile.First off: there doesn’t seem to be any real resources into getting into Presenter patterns in Rails. Or rather, there are a few from 2008, but nothing modern. (Except draper, which I think is too complex. Or I don’t yet understand why it needs to be the way it is). Anyway, I’m winging it here: it’s possible I’m doing it wrong.
I was creating a presenter for an object with comments: a little titlebar for the most recent comment, which use a HTML5 DETAILS widget to show the other comments.
I started with something like this:
Which is horrible, and ugly. Big, kind of clumsy, with a lot of string concatenation going on.
Jim Gay suggested that I break my method into smaller methods, but still keep the string concatenation roots. (Our gist comment conversation)
Which I did… then I realized why string concatenation felt bad to me in the first place: because Rails 3 changes the rules
As of Rails 3, all HTML content inside strings is HTML escaped (meaning the browser says, “oh, this isn’t meant for me to read, to construct a page, but for a human to read”.
Except, in my specific case (creating HTML snippets in a Presenter pattern) I really want the browser to construct the page with that content.
So I needed a way to avoid that, and avoid that without too much pain. Because the last thing I want to do when writing Presenter functions is to worry about putting
.html_safebehindevery.html_safe,single.html_safe,bloody.html_safe,string.html_safe.At the end of the night, I had refactored everything to:
What, WTF is s”something”?
Glad you asked. This presenter inherits from an
ApplicationPresenterclass (which itself subclasses fromSimpleDelegator).ApplicationPresenterimplements one interesting method:The revised
primary_commentpresenter does some other things better:- Uses
content_tagin some strategic parts to clean up the HTML output. - Calls other presenter functions as appropriate
Also, this method has two interesting properties:
- Because of Ruby’s function calling semantics, in the case of
s"something"thatslooks like some clever magic prefix (like 0x for hex numbers) — but it is not. It’s just a method call. - When given a list, will call
html_safeon all thethings!parameters, then concatenate them together
Also, on line 14 we try to slip some bad HTML into the page. Perhaps the second parameter to
sis a user inputted description text, and their trying to hijack the site. Thehhelper says, “Wait a minute, I actually do want to escape that”Conclusion
I need to spend some time and talk more about my structure for Presenters, but that’s fodder for another article.
-
blinni-elliott reblogged this from rwilcox
-
trivuong reblogged this from rwilcox
-
rwilcox posted this
- Uses