Description:
The tabbed navbar generator creates the CSS and sample HTML for a 3-state
tab bar (unselected, mouseover, and selected). The images that are
used MUST be a single image containing the three states of the tab in
this order from top to bottom: unselected, mouseover, selected. It is
compatible with Win/IE 5.0+, Safari, FireFox and Opera browsers.
The generator takes the relative paths of each image in the tab bar as
parameters. The public/images folder is assumed to be where the images
reside. The width and height of each image can be placed before the
file name to override any defaults:
50x90:tab_home.gif
If the dimensions are not specified, the tabbed navbar generator will
attempt to get the dimensions using the "file" shell command. "File"
only gets GIF image dimensions.
The generator creates a CSS stylesheet in in public/stylesheets, and
a sample HTML tab bar in app/views.
Example:
./script/generate tabbed_navbar tab_home.gif tab_cart.gif tab_logout.gif
./script/generate tabbed_navbar 50x90:tab_home.jpg 60x90:tab_cart.jpg 55x90:tab_logout.jpg
class TabbedNavbarGenerator < Rails::Generator::Base
attr_accessor :height_in_pixels, :width_in_pixels, :images
def initialize(*runtime_args)
super(*runtime_args)
@images = args.collect { |i| Image.new(i) }
# Height of the Tabbed navbar is the height of any image in that bar / 3
@height_in_pixels = @images[0].height / 3
# Sum of each tab's width
@width_in_pixels = @images.inject(0) { |sum, img| sum + img.width }
end
def manifest
record do |m|
# Stylesheet and public directories.
m.directory File.join('public', 'stylesheets')
m.directory File.join('app', 'views')
# Model class, unit test, and fixtures.
m.template 'tabbed_navbar.css', File.join('public', 'stylesheets', "tabbed_navbar.css")
m.template '_tabbed_navbar.rhtml', File.join('app', 'views', "_tabbed_navbar.rhtml")
end
end
protected
# Override with your own usage banner.
def banner
"Usage: #{$0} #{spec.name} [WIDTHxHEIGHT:image1 [WIDTHxHEIGHT:image2 [ ... ]]]"
end
end
class Image
attr_accessor :basename, :filename, :extension
attr_accessor :css_tag, :width, :height, :uri
DEFAULT_WIDTH = 50
DEFAULT_HEIGHT = 60 # 20 * 3
def initialize(arg)
if arg =~ /(\d+)x(\d+)\:(.+)$/
@width, @height, @filename = $1.to_i, $2.to_i, $3
elsif arg =~ /(.+)/
@filename = $1
end
@basename = @filename.split("/").last || ""
@css_tag = @basename.split(".")[0].gsub("/", "_")
@extension = @basename.split(".")[1]
@uri = "/images/#{@filename}"
set_dimensions unless @width and @height
show_dimensions
end
protected
def set_dimensions
puts "Setting dimensions automatically for #{@filename}"
case @extension
when "gif":
dimensions = `file public/images/#{filename}`
if dimensions.match /GIF.+ (\d+) x (\d+)/
@width = $1.to_i; @height = $2.to_i
end
end
unless @width and @height
puts "Setting dimensions of #{@filename} to default " +
"#{DEFAULT_WIDTH} x #{DEFAULT_HEIGHT}."
@width, @height = DEFAULT_WIDTH, DEFAULT_HEIGHT
end
end
def show_dimensions
if @width and @height
puts "Dimensions of #{@filename}: #{@width} x #{@height}"
if @height % 3 != 0
puts "WARNING: Height of #{@filename} is not evenly divisible by 3."
end
else
puts "Dimensions of #{@filename} unknown."
end
end
end
#nav_container {
position: relative;
padding-left: 0;
clear: none;
/* margin: 3px 0 20px 0; */
/* background: #7FA0B1; */
width: <%= width_in_pixels %>px;
height: <%= height_in_pixels %>px;
}
#nav {
position: absolute;
top: 0px;
left: 40px;
margin: 0;
padding: 0;
list-style: none;
display: inline;
overflow: hidden;
width: <%= width_in_pixels %>px;
height: <%= height_in_pixels %>px;
}
#nav li {
margin: 0;
padding: 0;
list-style-type: none;
display: inline;
}
#nav a {
float: left;
padding: <%= height_in_pixels %>px 0 0 0;
overflow: hidden;
height: 0px !important;
height /**/:<%= height_in_pixels %>px; /* for IE5/Win only */
}
#nav a:hover {
background-position: 0 -<%= height_in_pixels %>px;
}
#nav a:active, #nav a.selected {
background-position: 0 -<%= height_in_pixels * 2 %>px;
}
/* Custom link tabs for each nav element in this application */
<% for image in images %>
/* <%= image.filename %> */
#<%= image.css_tag %> a {
width: <%= image.width %>px;
background: url(<%= image.uri %>) top left no-repeat;
}
<% end %>
<div id="nav_container">
<ul id="nav">
<% for image in images -%>
<li id="<%= image.css_tag %>"><%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %></li>
<% end -%>
</ul>
</div>
Note: The complicated-looking eRb switching in the tabbed_navbar.rhtml file is due to the fact that in this generator, we actually want to generate eRb code. Normal escaping using <%= and > may or may not work. In any case, I chose to split it up as in the example above so that eRb didn’t falsely detect the end of the escaped eRb tag.
category: Generator, Example
From:MaurizioMarek
You can avoid the escaping using doubles. So you can write this:
<%<%=link_to <%= image.css_tag.humanize %>%>
instead of this:
<%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %>