Giter Club home page Giter Club logo

Comments (4)

ajb avatar ajb commented on July 29, 2024

Hey, it works with adding require 'fortitude/rails/helpers' at the top! But still feels weird.

from fortitude.

ageweke avatar ageweke commented on July 29, 2024

Ah! So, the simple part first — you should be able to just call helper on any widget class directly, and, if you do so, you shouldn’t need that require. For example:

class Views::Base < Fortitude::Widget
  helper :simple_form_for, :transform => :output_return_value, 
end

(You could even do this on Fortitude::Widget, if you wanted.)

If you run into problems with this, let me know, but it ought to work just fine. I see specs for this stuff and they're passing (although I can always believe I screwed something up!). The output_yielded_methods stuff is trickier. I built it for form_for (and fields_for). Let me see if I can explain it with a comparison.

(this part, I’m sure you’re aware of) Almost all Rails helpers return data, rather than output it; calling text_field_tag :foo, … returns the HTML for a text field, rather than rendering it. But this would mean having to write, in Fortitude, rawtext(text_field_tag :foo, …), which is really ugly. So I added the :transform => :output_return_value transformer, which outputs the return value of the helper, so we can just write text_field_tag :foo, …, like we want to.

(the even trickier part) form_for (and fields_for) is the difficult one. ERb usage is:

<%= form_for @my_model do |f| %>
  Bar: <%= f.text_field :bar, … %>
  Baz: <%= f.text_field :baz,  %>
<% end %>

form_for itself actually returns a little HTML itself (the <form> tag), but, more importantly, it yields something to its block that, when you call methods like text_field on it, returns HTML of various forms. If all we did was declare it with the :transform => :output_return_value trick, we could write just form_for … in Fortitude and get the <form> tag just fine — but the calls to (e.g.) f.text_field would just be returning HTML that got thrown away, unless we wrote rawtext(f.text_field :bar, …), which, again, is ugly.

The :output_yielded_methods magic actually takes the object that the block yields (the f in the above example) and wraps it in another object (an instance of Fortitude::Rails::YieldedObjectOutputter) that simply passes through all calls to the underlying fexcept that if they’re in the named list of methods you provide, it renders their return value on the way out. This is what allows us to write form_for in the “idiomatically correct” way in Fortitude, and not have to worry about sprinkling rawtext calls in various places. It should also let you use simple_form_for (which we use at my current employer, as well), too. So you end up with Fortitude code like:

form_for @my_model do |f|
  text "Bar: "
  f.text_field :bar, 
  text "Baz: "
  f.text_field :baz, 
end

…which, at least to me, feels “natural” and right.

(Oh, and by the way, with all this stuff, any time we automatically output the return value of any method, inside a block or otherwise, we replace its return value with '' — so that if you still wrap it in rawtext(…), it doesn’t harm anything.)

Hope I explained that at least sort-of reasonably well! Let me know if it’s not clear. It’s definitely one of the more voodoo corners of the Fortitude codebase, although I’m pretty happy with its net effect for users, too — it makes this stuff “just work” the way you expect it to work, instead of having to think carefully about output vs. return.

from fortitude.

ajb avatar ajb commented on July 29, 2024

Thanks for the great reply. I'm familiar with this stuff from the Erector codebase too, where it was a bit of a mess. (https://github.com/ajb/erector-rails4/issues/16, https://github.com/ajb/erector-rails4/issues/31, etc.)

Your implementation was a bit harder to grok at first glance, but it looks like it will work a whole lot better. Thanks again for the detailed explanation!

from fortitude.

ageweke avatar ageweke commented on July 29, 2024

Yeah, totally. As I write docs, I'm planning to do user-facing and code comments at the same time, exactly for bits of implementation like this that are a bit impenetrable. That should hopefully make contributing to the code base a whole lot easier.

from fortitude.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.