I''ll contribute this to the Rails core, but I thought it''s coolness factor high enough that others might like to try it now. A few days ago, I learned about this gem from Michael Daines on the snippets site (http://www.bigbold.com/snippets/): def rounded_box(&block) concat ''<div class="rounded"><div class="top"></div><div class="body">'' + capture(&block) + ''</div><div class="bottom"></div></div>'', block.binding end Which can be called like this in your view: <% rounded_box do %> <h1>HTML goes here</h1> This will all be wrapped inside of a rounded div, assuming your CSS is set up right to do so. <% end %> The "capture" method used above that currently comes with Rails, however, does not allow for any arguments to be passed to the block. This is unfortunate, because arguments would make it very flexible. Consider this call to a helper method, for example: <% show_calendar(:year => Time.now.year) do |day, options| %> <% options[:bgcolor] = ''#dfd'' if 10..15.include? day %> [<%= day %>] <% end %> This renders an entire calendar, with each day being rendered by the contents of the block! This is flexible in that, for example, the background color for days that contain bookings or events can be set using the passed-in options hash. In addition, the "current day" is passed in so that it can be displayed or tested. In the above example, the calendar would render a table like this: Mon Tue Wed Thu Fri Sat Sun [1] [2] [3] [4] [5] [6] [7] [8] ... etc. The show_calendar method uses a very slightly modified "capture" method, dubbed "capture2" which in addition to the function of the capture method, takes parameters and passes them to the block: def capture2(*args, &block) # execute the block buffer = eval("_erbout", block.binding) pos = buffer.length block.call(*args) # extract the block data = buffer[pos..-1] # replace it in the original with empty string buffer[pos..-1] = '''' data end Thus, in the following show_calendar helper method, I can do the kind of view/rhtml code simplification seen above: module CalendarHelper WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] SECONDS_IN_A_DAY = (60 * 60 * 24) def show_calendar(options, &block) default_options = { :year => Time.now.year, :month => Time.now.month, :width => nil, :height => nil, :cell_width => nil, :cell_height => nil, :heading_height => 10, :weekday_heading_letters => 3 } options = default_options.merge(options) # Simplify the erb concatenation by making an ''insert'' proc that knows # about our block''s binding context insert = Proc.new {|text| concat text, block.binding} options[:width] = 400 if options[:width].nil? and options [:cell_width].nil? options[:height] = 300 if options[:height].nil? and options [:cell_height].nil? table_size = String.new table_size << " width=''#{options[:width]}''" if options[:width] table_size << " height=''#{options[:height]}''" if options[:height] first_day_of_this_month = Time.gm(options[:year], options [:month], 1, 0, 1) next_month = options[:month] < 12 ? options[:month] + 1 : 1 next_year = options[:month] < 12 ? options[:year] : options [:year] + 1 first_day_of_next_month = Time.gm(next_year, next_month, 1, 0, 1) days_in_month = (first_day_of_next_month - first_day_of_this_month) / SECONDS_IN_A_DAY weekday = first_day_of_this_month.wday weeks = ((weekday + days_in_month) / 7).ceil.to_i trailing_days = (weeks * 7 - days_in_month - weekday).to_i insert["<table class=''calendar''#{table_size}><tr>\n"] 7.times do |day| insert["<th>#{WEEKDAYS[day][0...options [:weekday_heading_letters]]}</th>\n"] end insert["</tr><tr>\n"] insert["<td class=''calendar_blank'' colspan=''#{weekday}''> </ td>\n"] unless weekday == 0 cell_attrs = Hash.new cell_attrs[:width] = options[:cell_width] if options[:cell_width] cell_attrs[:height] = options[:cell_height] if options [:cell_height] for day in 1..days_in_month do captured_text = capture2(day, cell_attrs, &block) insert[tag("td", cell_attrs) + captured_text + "</td>\n"] insert["</tr><tr>\n"] if ((weekday + day) % 7 == 0) end insert["<td class=''calendar_blank'' colspan=''# {trailing_days}''> </td>\n"] unless trailing_days == 0 insert["</tr>\n</table>\n"] end end And in case anyone wants the CSS: .calendar { border-top: 1px solid #f0f0f0; border-bottom: 2px solid #909090; border-left: 1px solid #e5e5e5; border-right: 2px solid #aaa; border-collapse: collapse; table-layout: fixed; } .calendar th { border: solid thin; background-color: #FFFAD9; border-color: #E0E0FF; font-family: arial; text-align: center; color: #000; height: 2em; } .calendar td { border: solid thin; border-color: #E0E0FF; text-align: center; } .calendar_blank { border: solid thin; background-color: #F5F5EE; border-color: #E0E0FF; } Duane Johnson (canadaduane) _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Dee Zsombor
2005-Jun-20 13:59 UTC
Re: Round Corners was ([REUSE] Capture2 and an example Calendar Helper)
On 6/20/05, Duane Johnson <duane.johnson-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''ll contribute this to the Rails core, but I thought it''s coolness factor > high enough that others might like to try it now. > > A few days ago, I learned about this gem from Michael Daines on the snippets > site (http://www.bigbold.com/snippets/): > def rounded_box(&block) > concat ''<div class="rounded"><div class="top"></div><div class="body">'' > + > capture(&block) + > ''</div><div class="bottom"></div></div>'', block.binding > end > > Which can be called like this in your view: > <% rounded_box do %> > <h1>HTML goes here</h1> > This will all be wrapped inside of a > rounded div, assuming your CSS is set > up right to do so. > <% end %>I was just looking at beautiful round corner implementation from http://beta.technorati.com/. They use a single 20x20 image for all corners with transparent round shape in the middle. Also additional tags are placed after content and not before thus keeping nesting low. -- http://deezsombor.blogspot.com
On Jun 20, 2005, at 9:59 AM, Dee Zsombor wrote:> > I was just looking at beautiful round corner implementation from > http://beta.technorati.com/. They use a single 20x20 image for all > corners with transparent round shape in the middle. Also additional > tags are placed after content and not before thus keeping nesting low. >A pretty neat technique. Eric Meyer blogs a bit about it [1]. I switched a site to this technique from one of the "sliding doors" techniques on ALA and this one seems a bit more flexible w.r.t. larger sized elements. I hit a few snags along the way, but in the end I like this technique. -Scott [1] http://meyerweb.com/eric/thoughts/2005/06/21/technorati-redesigns/ _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Technorati''s method is cool, but I like this one, no extra markup, one image, and it expands as long as you want vertically and as wide as the image goes horizontally. http://www.456bereastreet.com/lab/teaser/one_image/ http://www.456bereastreet.com/lab/ has all kinds of cool techniques there!
On 6/22/05, Casey Gollan <caseygollan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Technorati''s method is cool, but I like this one, no extra markup, > one image, and it expands as long as you want vertically and as wide > as the image goes horizontally. > > http://www.456bereastreet.com/lab/teaser/one_image/Actually it has extra markup: you need a h3 tag placed first in each rounded div. Without it top corners will not be present. And it will need a different image for every shadow/border color used. Technorati''s will also expands vertically and I suspect it will work with arbitrary widths too... Also one image is used regardless of what color rounded div has. Brilliant! -- http://deezsombor.blogspot.com
> Technorati''s will also expands vertically and I suspect it will work > with arbitrary widths too... Also one image is used regardless of what > color rounded div has. Brilliant!Dee, good points! I have actually used the technique and its very cool, I was just pointing out another cool one that allows for more advanced border/corner images.
Actually, there are different images depending on the border color, or no border at all.>Technorati''s will also expands vertically and I suspect it will work >with arbitrary widths too... Also one image is used regardless of what >color rounded div has. Brilliant! > > >
On 6/22/05, Sean Stephens <schmoboy-j9pdmedNgrk@public.gmane.org> wrote:> Actually, there are different images depending on the border color, or > no border at all.You are right, if borders are needed single image will not suffice. But it looks great without borders too.