Skip to content

Slim Capture Html #68

Closed
DAddYE opened this Issue Mar 25, 2011 · 26 comments

8 participants

@DAddYE
DAddYE commented Mar 25, 2011

As for erb and erubis can you give us the ability to capture html? Take a look here: stonean/slim@74f1125

@judofyr
Collaborator
judofyr commented Mar 25, 2011

Yeah, I agree: Tilt should contain information for capturing blocks and concatting to the buffer. That would make it possible to create framework-agnostic helpers. Any suggestions for how the API should be?

@nesquena
nesquena commented Apr 4, 2011

I would absolutely agree that Tilt should support the idea of capturing and concatting to the buffer of all templates. As it stands, Rails basically has its own custom functionality for that and outside of Rails it is very hard to get this stuff working in a framework agnostic way.

In Padrino, I have been having to work with the authors of Slim and Erubis to get this working. Once the next version of tilt comes out, we should have full Slim and Erubis helper support.

I would like nothing more though then to strip out all of that logic from Padrino and be able to rely on tilt to give me concat and capture helpers for all the frameworks it supports. Take a look at the Padrino implementation to see how we are currently tackling this issue:

@judofyr
Collaborator
judofyr commented Apr 4, 2011

Thanks, those links will be very helpful!

@nesquena
nesquena commented Apr 4, 2011

Yeah I am happy to work through getting this added to tilt if we all agree its worth the effort. Unfortunately I am aware that my current implementation of the handlers are a bit flimsy (hardcoded expectations of the output buffer). However, once we incorporate something similar into tilt, then we can rely on the output buffer specified when the engine is initialized which should address that issue.

This gist should also shed some light on the bare minimum Padrino (and probably any rack based framework) would need to create all the usual helpers:

@judofyr
Collaborator
judofyr commented Apr 12, 2011

Well, we can't depend on the output buffer only. It's technically an implementation detail, but more importantly: different engines might use different types of buffers. For instance, Slim uses an array buffer while ERB uses a string buffer. The default behavior of Tilt might assume one kind of buffer, but we'll have to make it a per-template-class-decision.

I'm still wondering how big this change might be (and if it belongs to Tilt at all)…

@nesquena

That's a good point. I think something that provides an agnostic way to uniformly capture/concat to template engines would be an awesome supporting library. I agree it is not clear whether it could live within tilt or as a separate gem. Would be curious to hear people's thoughts.

@rkh
Collaborator
rkh commented Apr 13, 2011

We use dummy templates in sinatra-contrib to make capturing implementation independent: content_for.rb#L84-88
One option would be to ship those with Tilt. I am not sure what the runtime overhead is, but the actual implementation is super easy.
Exposing it over an API like caputre(&block) would still allow hooking in better implementations.

@DAddYE
DAddYE commented Apr 13, 2011

Yep, I agree with u @rkh, your way is dead simple and more stable. Should be a feature of next version of tilt.

@rkh
Collaborator
rkh commented Apr 20, 2011

I have to say, I don't get the use case for concatenation, if you support (and use) capturing.

@DAddYE
DAddYE commented Apr 20, 2011

@rkh to display this how do you do?

<% form_tag .... do %>
...
<% end %>
-form_tag ... do
...

I know we can use <%= form_tag or =form_tag but I think is not a standard. No?

@rkh
Collaborator
rkh commented Apr 20, 2011

I think Rails 3 uses <%= form_for do %> and it makes more sense to me, the implicit output is just confusing.

@DAddYE
DAddYE commented Apr 20, 2011

Yep, sure that have more sense, but a lot of coders uses the old way especially with haml.

@DAddYE
DAddYE commented Apr 21, 2011

@rkh, Rails uses <%= form_for do %> because dropped support to Erb and use instead erubis, with erb is not possibile do that without concat :(

@rkh
Collaborator
rkh commented Apr 21, 2011

oh, right, <%= does not work multiline in erb. Man, erb sucks.

@DAddYE
DAddYE commented Apr 21, 2011

@rkh, we can drop it on sinatra/padrino :D ?

@rkh
Collaborator
rkh commented Apr 21, 2011

Not is Sinatra, no. I see two solutions: Support concatenation, but just for erb, or don't support form helpers for erb. Note that with Tilt 1.3 Sinatra will automatically use erubis for erb templates, if available.

But you'd probably have to modify erubis, too: http://timelessrepo.com/block-helpers-in-rails3

@judofyr what's your take on concatination?

@DAddYE
DAddYE commented Apr 21, 2011

@rkh, I see yesterday the Rails hack and is horrible ... IMHO. I prefer the ...old way..., but, it's a lot of years that I don't use erb like things.

@rkh
Collaborator
rkh commented Apr 24, 2011

An option would be something like this:

def output(content)
  return content unless @current_engine == :erb
  concat content
  "" # so it still works with <%= %>
end

def form_for(&block)
  output "<form>#{capture(&block)}</form>"
end

And implement concatenation for erb only.

@jlong
jlong commented May 25, 2011

Any idea when something like this will be integrated with Tilt? I'd really like to get content_for working for Slim on Serve (http://github.com/jlong/serve).

@nesquena

My guess is probably not soon, it is difficult problem to solve in a uniform way. We ended up solving it ourselves good enough in Padrino although I still would love for concat/capture to be something any framework could use

@jlong
jlong commented May 25, 2011

Isn't there someway to add limited support for this? Get it working, then make it right? The main thing I want is to get content_for working.

@minad
minad commented Aug 25, 2011

@jlong: I took a look at serve and I think you only have to add a trivial capture_slim helper.

def capture_slim
  yield
end

Slim has an automatic capturing mechanism. The block returns the captured content.

= capture_slim do
   p Hello

As an alternative you can also configure slim so that it behaves like erb (buffer variable name - option :buffer, disable automatic capturing - option :disable_capture).

Please tell me if it works.

@lukeholder

any news on this?

@judofyr
Collaborator
judofyr commented May 1, 2013

I don't see an easy way to accomplish this with the current abstraction. Tilt only defines a Str -> Str-abstraction and capturing goes beyond this. This requires changes in the template engines themselves (Erubis, Slim, Haml, etc.) and I would recommend that the maintainers of these projects try to find a solution.

I'm closing this. Please open a new issue if you have a specific proposal for how we can solve this in Tilt (hint: I don't it's possible, but please prove me wrong).

@judofyr judofyr closed this May 1, 2013
@minad minad referenced this issue in padrino/padrino-framework Oct 9, 2013
Closed

Improve slim test #1439

@Wardrop
Wardrop commented Feb 13, 2014

Is there any suggested strategy for getting the ball rolling on this. Could we not implement support for the template engines that DO support this. If the provisions are made, template engine maintainers would receive more pressure to implement support.

@Wardrop
Wardrop commented Feb 17, 2014

Can I also ask how you would imagine ERB making this easier? You can't really change the behaviour of blocks within ERB templates as they're used extensively for #each loops and so on. Capturing the output buffer is really the only means I can think of. ERB can't exactly provide a capture helper method or anything, as if it did, it would be defining a method in whatever scope it's executed in, which would not be very nice.

This was referenced Dec 14, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.