Comments (16)
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.
ok no worries; using cells to create graph type widgets; and simetimes I need to send js to the header;
from cells.
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.
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.
@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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Already decided to provide that in the next versions of cells - donations welcome.
from cells.
https://github.com/apotonick/cells-capture
from cells.
Related Issues (20)
- Cells + Airbrake issue - double exceptions raised HOT 2
- Using Cells with Rails engine that has html.erb partials not being picked up HOT 5
- Confusing file structure - views or view? HOT 7
- Template Missing ... again! HOT 21
- how to render erb templates when haml/hamlit and erb extensions installed HOT 3
- Render an array inside view cell HOT 1
- Escaping implementation seems to be a glaring LAYER VIOLATION, methinks.
- Is there some way to do html escaping default with options?
- Publish latest version on Rubygems HOT 10
- should default to file_name.html.erb or .haml HOT 1
- Can't get form_with to work from a cell in Rails 6 HOT 3
- License HOT 1
- Form Input renders as raw text in cell HOT 1
- Feature Request: Support Recyclable Cache Key
- Still maintained? Documentation URLs broken. HOT 9
- Default cache key produces clashes HOT 4
- Options hash is same instance passed to each cell when using collections HOT 1
- Slim v5 breaks cells HOT 9
- Ruby 3.0 ArgumentError: wrong number of arguments error with keyword args for Cell::Testing
- Ruby 3.0 ArgumentError: wrong number of arguments error with Caching
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cells.