Giter VIP home page Giter VIP logo

Comments (16)

apotonick avatar apotonick commented on June 14, 2024

Sorry dude, in Rails 3.0 it's simply impossible to support capturing :-( Maybe we get a hook in 3.1 - what are you trying to do?

from cells.

 avatar commented on June 14, 2024

ok no worries; using cells to create graph type widgets; and simetimes I need to send js to the header;

from cells.

apotonick avatar apotonick commented on June 14, 2024

In Rails 3.1 will be some asset compiler which we will use in cells, too. I think this will remove the need for content capturing in cells.

Love the dynamic50 web site, btw... :-)

from cells.

ahmeij avatar ahmeij commented on June 14, 2024

If you want all content to be rendered with content_for like I needed, the following piece of code in the application_helper.rb will enable the functionality:

def render_cell_for(id, cell, action, options = nil, &block)
  content_for id do
    render_cell(cell, action, options, &block)
  end
end

Use
<%=render_cell_for(:content_for, :cell, :action) %>

in your views to render within a content for block.

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

@ahmeij That's useful, thanks.

@ahmeij, @apotonick How can we use content_for for only part of a cell view?

For example, one of my cell views has JavaScript that needs to be run when the document's ready. That'd be fine, except jQuery's loaded at the bottom of the page, and the cell view is rendered in the middle of the page. So when the JS in the cell view executes, $ is undefined.

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

I've found a work-around that's similar to what @ahmeij suggested. Unfortunately, it requires the creation of a new cell state, whose name is X_javascript, where X is the name of the target state. (Is "state" the correct word here?)

# app/helpers/application_helper.rb

# Renders two things:
# 1) The specified cell.
# 2) The corresponding cell whose name ends with "_javascript".
#
# The "X_javascript" cell is rendered first, and inside of "content_for :javascript",
# to ensure that the JavaScript is inserted at the end of the page.
def render_cell_with_javascript(cell, action, options = nil, &block)
  content_for :javascript do
    render_cell cell, "#{action}_javascript", options, &block
  end

  render_cell cell, action, options, &block
end
# app/cells/flags_cell.rb

class FlagsCell < Cell::Rails
  def for_curator(curator)
    @flags = Flag.where :curator_ids => curator.id
    render
  end 

  def for_curator_javascript
    render
  end 
end
<!-- app/cells/flags/for_curator_javascript.html.erb -->

<script type="text/javascript">
  $(document).ready(function() {
    console.log("JavaScript executing from app/cells/flags/for_curator_javascript.html.erb");
  });
</script>

It's a kludge, but it works.

from cells.

apotonick avatar apotonick commented on June 14, 2024

This is indeed an interesting solution. I basically like it! I like the fact that you extract JS generation to a separate state, this makes things cleaner and separates view and JS. Not a big fan of the capture helpers in Rails, but in your case, this really is done in a reasonable manner ;-)

We should think about a generic solution for that - maybe we won't need capture support within cells (it breaks encapsulation anyway).

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

I have to admit that I really dislike putting the JS in a separate state. The JS is dependent upon the view's content, so the two should be in the same view in my opinion.

What do you have against content_for? It's incredibly useful for building pages by piecing together many smaller components.

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

I just discovered why my work-around is insufficient: it doesn't work when called from a cell view. Fark.

@apotonick What will it take to get support for content_for in Cells?

from cells.

apotonick avatar apotonick commented on June 14, 2024

On Tue, Aug 9, 2011 at 10:57 PM, nickhoffman
[email protected]
wrote:

I just discovered why my work-around is insufficient: it doesn't work when called from a cell view. Fark.

@apotonick What will it take to get support for content_for in Cells?

The problem is that content_for is accessing the global ActionView
instance, the one rendered by the controller. In Rails 3.x, you cannot
grab that instance very easily and you have to apply violence to
inject the captured content from the cells into that instance. The
entire architecture - currently - is designed for one global,
monolithic view instance and we'd have to fix that, first.

Check Tyler's fork, he was working on that, too:
https://github.com/TylerRick/cells-capture

One reason we didn't work on this is that capturing is violating the
encapsulation that cells gives us, since we're injecting content from
a component into some global instance. Nevertheless, people find this
useful so we should work on it ;-)

Nick

Reply to this email directly or view it on GitHub:
#25 (comment)

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

Thanks for the info, Nick. Much appreciated. If you don't use content_for, how do you ensure that certain HTML is inserted into certain locations within the page? For example, that JavaScript is put at the end of the page?

from cells.

apotonick avatar apotonick commented on June 14, 2024

Nick, thanks. Cells were made to encapsulate visiblbly connected blocks in the page. That's all they were supposed to do, you simply call #render_cell and they return their markup. Now, injecting arbitrary content into some other "block" outside of the cell's scope violates encapsulation, since the cell has knowledge about the outer world (well, not really, but you get what I mean ;-) This is a new requirement which we have to meet.

Another idea could be that the cell has a second method to return JS, like the idea you had:

render_cell(..) do |cell|
  global_js_container << cell.javascript

I guess providing a content_for is less clumsy, although it breaks encapsulation.

from cells.

nickhoffman avatar nickhoffman commented on June 14, 2024

Ah, I didn't know that a block can be passed to render_cell!

Yesterday, I ended up doing this, which feels dirty because the 2 cell state renders are related, yet located far apart in the view:

<!-- ...other ERb... -->

<%= render_cell :flags, :report_a_flag %>

<!-- ...other ERb... -->

<% content_for :javascript do %>
  <!-- other JavaScript -->

  <%= render_cell :flags, :report_a_flag_javascript, :target => 'Catalog' %>
<% end %>

However, now I can change it to this, and keep the 2 cell state renders together:

<%= render_cell :flags, :report_a_flag do |cell| %>
  <% content_for(:javascript) { cell.report_a_flag_javascript :target => 'Catalog' } %>
<% end %>

The resulting syntax is obtuse and not particularly elegant, but I'd say it's a usable solution.

from cells.

adamgotterer avatar adamgotterer commented on June 14, 2024

Was wondering if there were any new thoughts on this thread? I understand the encapsulation concern. I'm actually doing something similar to the OP. I have 10 - 15 charts that get rendered on a page and being able to pass the JS to a Javascript block in the layout would be really helpful.

from cells.

apotonick avatar apotonick commented on June 14, 2024

Already decided to provide that in the next versions of cells - donations welcome.

from cells.

apotonick avatar apotonick commented on June 14, 2024

https://github.com/apotonick/cells-capture

from cells.

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.