valodzka-view_fu 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +40 -0
- data/README +145 -0
- data/Rakefile +22 -0
- data/init.rb +1 -0
- data/lib/browser_detect/helper.rb +45 -0
- data/lib/headliner/README +118 -0
- data/lib/headliner/helper.rb +62 -0
- data/lib/javascripter/README +87 -0
- data/lib/javascripter/helper.rb +112 -0
- data/lib/styler/README +95 -0
- data/lib/styler/helper.rb +117 -0
- data/lib/view_fu/controller_extensions.rb +13 -0
- data/lib/view_fu/meta_helper.rb +51 -0
- data/lib/view_fu/tag_helper.rb +166 -0
- data/lib/view_fu.rb +18 -0
- data/rails/init.rb +1 -0
- data/test/browser_detect_test.rb +14 -0
- data/test/headliner_test.rb +106 -0
- data/test/styler_test.rb +14 -0
- data/test/view_fu_test.rb +16 -0
- data/view_fu.gemspec +45 -0
- metadata +83 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
ViewFu - Copyright (c) 2008 NeoRails.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
Original Plugins (Styler, Javascripter, Headliner) - Copyright (c) 2007 Patrick Crowley, the.railsi.st
|
23
|
+
|
24
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
25
|
+
of this software and associated documentation files (the "Software"), to deal
|
26
|
+
in the Software without restriction, including without limitation the rights
|
27
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
28
|
+
copies of the Software, and to permit persons to whom the Software is
|
29
|
+
furnished to do so, subject to the following conditions:
|
30
|
+
|
31
|
+
The above copyright notice and this permission notice shall be included in
|
32
|
+
all copies or substantial portions of the Software.
|
33
|
+
|
34
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
35
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
36
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
37
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
38
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
39
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
40
|
+
THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
ViewFu
|
2
|
+
======
|
3
|
+
|
4
|
+
ViewFu is a Rails plugin that provides all the miscellaneous View tasks. It's a combination of the functionality of Styler, Javascripter, and Headline (from Patrick Crowley, the.railsi.st) - along with additional tweaks such as providing commonly used View Helpers Methods.
|
5
|
+
|
6
|
+
|
7
|
+
Maintainer Info
|
8
|
+
======
|
9
|
+
|
10
|
+
Tyler Crocker
|
11
|
+
NeoRails.com
|
12
|
+
|
13
|
+
Looking for *the one* awesome rails developer to add to your project? I may be available to help out. Contact me at neorails@gmail.com.
|
14
|
+
|
15
|
+
|
16
|
+
ViewFu HTML Helpers
|
17
|
+
=======
|
18
|
+
ViewFu provides helpers for commonly used html elements
|
19
|
+
|
20
|
+
br #=> <br />
|
21
|
+
hr #=> <hr />
|
22
|
+
anchor("posts") #=> <a name='posts'></a>
|
23
|
+
clear #=> <div class="clear"></div>
|
24
|
+
clear(:left) #=> <div class="clearleft"></div>
|
25
|
+
clear_tag(:br) #=> <br class="clear" />
|
26
|
+
lorem #=> Lorem ipsum dolor...
|
27
|
+
|
28
|
+
|
29
|
+
ViewFu Helper Queries
|
30
|
+
=======
|
31
|
+
production? #=> returns true if Rails.env == "production"
|
32
|
+
is_new? #=> returns true is we're on a "new" or "create" action
|
33
|
+
is_edit? #=> returns true is we're on an "edit" or "update" action
|
34
|
+
use_cache? #=> returns true if perform_caching is turned on
|
35
|
+
|
36
|
+
|
37
|
+
ViewFu Misc Helpers
|
38
|
+
=======
|
39
|
+
paging(@array) #=> display a will_paginate paging links (only if the array is a valid paging collection)
|
40
|
+
paging(@array, :sabros) #=> wrap the paging links with a class "sabros"
|
41
|
+
|
42
|
+
|
43
|
+
Haml Specific Helpers
|
44
|
+
=======
|
45
|
+
Haml allows you to pash a hash of attributes. ViewFu assists this by providing a simple "hidden" helper that allows you to conditionally hide page elements.
|
46
|
+
|
47
|
+
%div{hidden} #=> <div style="display:none">
|
48
|
+
%div.posts{hidden_if(@posts.empty?)} #=> hide the .posts div if the array is empty
|
49
|
+
%p.empty{hidden_unless(@posts.empty?)} #=> hide the empty posts message if the array has elements
|
50
|
+
|
51
|
+
|
52
|
+
Stylesheets
|
53
|
+
=======
|
54
|
+
ViewFu allows you to add a dynamic stylesheets collection to the top of your page. If you have any partials that depend on a stylesheet, they just need to call add_stylesheet(path) and the styles will be available on the page.
|
55
|
+
|
56
|
+
You'll just need to add a call *stylesheets* somewhere your page header.
|
57
|
+
|
58
|
+
stylesheets
|
59
|
+
writes the stylesheet collection to html
|
60
|
+
|
61
|
+
stylesheet
|
62
|
+
alias around stylesheet_link_tag
|
63
|
+
|
64
|
+
stylesheet_folder(path)
|
65
|
+
lets you include a recursive folder of stylesheets
|
66
|
+
|
67
|
+
page_stylesheets
|
68
|
+
output stylesheets specific to a page
|
69
|
+
|
70
|
+
add_stylesheet(path)
|
71
|
+
adds a stylesheet to the collection to be included on the page
|
72
|
+
|
73
|
+
ignore_stylesheet(path)
|
74
|
+
removes a stylesheet from the collection to be included on the page
|
75
|
+
|
76
|
+
See lib/stylesheet/README for more details
|
77
|
+
|
78
|
+
|
79
|
+
Javascripts
|
80
|
+
=======
|
81
|
+
ViewFu allows you to add a dynamic javascript collection to the top(or bottom) of your page. Now, if you have a partial that depends on a javascript library, you can just include it via add_javascript(path) and it will appear on the top of your page.
|
82
|
+
|
83
|
+
You'll just need add a call to *javascripts* to your layout and the javascripts you included an all your partials will appear.
|
84
|
+
|
85
|
+
javascripts
|
86
|
+
writes the javascript collection to html
|
87
|
+
|
88
|
+
javascript
|
89
|
+
alias around javascript_include_tag
|
90
|
+
|
91
|
+
javascript_folder(path)
|
92
|
+
lets you include a recursive folder of javascripts
|
93
|
+
|
94
|
+
page_javascripts
|
95
|
+
output javascripts specific to a page
|
96
|
+
|
97
|
+
add_javascript(path)
|
98
|
+
adds a javascript to the collection to be included on the page
|
99
|
+
|
100
|
+
ignore_javascript(path)
|
101
|
+
removes a javascript from the collection to be included on the page
|
102
|
+
|
103
|
+
See lib/javascripter/README for more details
|
104
|
+
|
105
|
+
Page Titles
|
106
|
+
=======
|
107
|
+
ViewFu allows you to easily set the current page title from anywhere on your views
|
108
|
+
|
109
|
+
title
|
110
|
+
Displays the current page title
|
111
|
+
|
112
|
+
title(new_title)
|
113
|
+
Sets the page title
|
114
|
+
|
115
|
+
See lib/headliner/README for more details
|
116
|
+
|
117
|
+
|
118
|
+
Meta Tags
|
119
|
+
=======
|
120
|
+
ViewFu allows you to set meta tags on your page header from anywhere. Just add a call to meta_tags somewhere in your page header.
|
121
|
+
|
122
|
+
meta_tags
|
123
|
+
output all the html meta tags currently on the page
|
124
|
+
|
125
|
+
meta_keywords
|
126
|
+
output the meta keywords tag
|
127
|
+
|
128
|
+
meta_keywords(val)
|
129
|
+
set the page meta keywords
|
130
|
+
|
131
|
+
meta_description
|
132
|
+
output the meta description tag
|
133
|
+
|
134
|
+
meta_description(val)
|
135
|
+
set the page meta description
|
136
|
+
|
137
|
+
|
138
|
+
More Plugins
|
139
|
+
======
|
140
|
+
|
141
|
+
If you like ViewFu, you'll *love* FormFu. It provides a beautiful way to generate tableless Rails html forms. Works just like form_for, except it'll generate the entire XHTML (label, wrapper, validation message, etc).
|
142
|
+
https://github.com/neorails/form_fu
|
143
|
+
|
144
|
+
|
145
|
+
Copyright (c) 2008 NeoRails.com, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the view_fu plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the view_fu plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'ViewFu'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init"
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module BrowserDetect::Helper
|
2
|
+
|
3
|
+
# check the current browser (via user agent) for the following:
|
4
|
+
# :mozilla
|
5
|
+
# :ie6
|
6
|
+
# :ie7
|
7
|
+
# :ie
|
8
|
+
# :safari
|
9
|
+
def browser_is? name
|
10
|
+
|
11
|
+
name = name.to_s.strip
|
12
|
+
|
13
|
+
return true if browser_name == name
|
14
|
+
return true if name == 'mozilla' && browser_name == 'gecko'
|
15
|
+
return true if name == 'ie6' && browser_name.index('ie6')
|
16
|
+
return true if name == 'ie7' && browser_name.index('ie7')
|
17
|
+
return true if name == 'ie' && browser_name.index('ie')
|
18
|
+
return true if name == 'webkit' && browser_name == 'safari'
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# find the current browser name
|
23
|
+
def browser_name
|
24
|
+
@browser_name ||= begin
|
25
|
+
|
26
|
+
ua = request.env['HTTP_USER_AGENT'].to_s.downcase
|
27
|
+
|
28
|
+
if ua.index('msie') && !ua.index('opera') && !ua.index('webtv')
|
29
|
+
'ie'+ua[ua.index('msie')+5].chr
|
30
|
+
elsif ua.index('gecko/')
|
31
|
+
'gecko'
|
32
|
+
elsif ua.index('opera')
|
33
|
+
'opera'
|
34
|
+
elsif ua.index('konqueror')
|
35
|
+
'konqueror'
|
36
|
+
elsif ua.index('applewebkit/')
|
37
|
+
'safari'
|
38
|
+
elsif ua.index('mozilla/')
|
39
|
+
'gecko'
|
40
|
+
else
|
41
|
+
""
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
=========
|
2
|
+
Headliner
|
3
|
+
=========
|
4
|
+
|
5
|
+
Headliner DRYs up your page titles.
|
6
|
+
|
7
|
+
|
8
|
+
Background
|
9
|
+
==========
|
10
|
+
|
11
|
+
Normally, if your Rails application has lots of actions and a shared
|
12
|
+
layout, you might find yourself setting custom page title names in your
|
13
|
+
controllers.
|
14
|
+
|
15
|
+
Here's an example:
|
16
|
+
|
17
|
+
class PagesController < ApplicationController
|
18
|
+
def about
|
19
|
+
@title = "About us"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Then, in your main layout, you might have something like this:
|
24
|
+
|
25
|
+
<head>
|
26
|
+
<title>My website<% if @title %>: <%= @title %><% end %></title>
|
27
|
+
</head
|
28
|
+
|
29
|
+
This works okay... but page titles don't really belong in controllers, do
|
30
|
+
they?
|
31
|
+
|
32
|
+
So, by moving these titles into your views, we can DRY things up a bit and
|
33
|
+
reinforce the MVC design pattern that's so fundamental to Ruby on Rails.
|
34
|
+
|
35
|
+
|
36
|
+
Usage
|
37
|
+
=====
|
38
|
+
|
39
|
+
First, add this code to your main layout:
|
40
|
+
|
41
|
+
<head>
|
42
|
+
<%= title :site => "My website" %>
|
43
|
+
</head>
|
44
|
+
|
45
|
+
Then, to set the page title, add this to each of your views:
|
46
|
+
|
47
|
+
<h1><%= title "My page title" %></h1>
|
48
|
+
|
49
|
+
When views are rendered, the page title will be included in the right
|
50
|
+
spots:
|
51
|
+
|
52
|
+
<head>
|
53
|
+
<title>My website | My page title</title>
|
54
|
+
</head>
|
55
|
+
<body>
|
56
|
+
<h1>My page title</h1>
|
57
|
+
</body>
|
58
|
+
|
59
|
+
|
60
|
+
Options
|
61
|
+
=======
|
62
|
+
|
63
|
+
Use these options to customize the title format:
|
64
|
+
|
65
|
+
:prefix (text between site name and separator)
|
66
|
+
:separator (text used to separate website name from page title)
|
67
|
+
:suffix (text between separator and page title)
|
68
|
+
:lowercase (when true, the page name will be lowercase)
|
69
|
+
:reverse (when true, the page and site names will be reversed)
|
70
|
+
|
71
|
+
And here are a few examples to give you ideas.
|
72
|
+
|
73
|
+
<%= title :separator => "—" %>
|
74
|
+
<%= title :prefix => false, :separator => ":" %>
|
75
|
+
<%= title :lowercase => true %>
|
76
|
+
<%= title :reverse => true, :prefix => false %>
|
77
|
+
|
78
|
+
|
79
|
+
Dealing with special pages
|
80
|
+
==========================
|
81
|
+
|
82
|
+
How do you set the page title without showing it in the view?
|
83
|
+
|
84
|
+
<% title "My page title" %>
|
85
|
+
|
86
|
+
What if your view headline is different from your page title?
|
87
|
+
|
88
|
+
<%= title "My page title", "My headline" %>
|
89
|
+
|
90
|
+
|
91
|
+
Mr. T says, ‘Use my method, fool!’
|
92
|
+
==================================
|
93
|
+
|
94
|
+
Just like ERB's HTML safe method, you can invoke Headliner with a single
|
95
|
+
letter alias.
|
96
|
+
|
97
|
+
<h1><%=t "My page title" %></h1>
|
98
|
+
|
99
|
+
|
100
|
+
How does it work?
|
101
|
+
=================
|
102
|
+
|
103
|
+
Ruby on Rails renders actions *before* inserting them into layouts. So, if
|
104
|
+
you set a variable in your view, it will be accessible in your layout. But,
|
105
|
+
at first glance, it looks like you're using a variable (in the head)
|
106
|
+
before it's been assigned a value (in the body). Cool, huh?
|
107
|
+
|
108
|
+
|
109
|
+
Credits
|
110
|
+
=======
|
111
|
+
|
112
|
+
Special thanks to Nick Zadrozny and Jordan Fowler for their input.
|
113
|
+
|
114
|
+
|
115
|
+
Feedback
|
116
|
+
========
|
117
|
+
|
118
|
+
Comments, bug reports, and svn diffs welcome at http://the.railsi.st.
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Headliner
|
2
|
+
module Helper
|
3
|
+
def title(options, headline='')
|
4
|
+
if options.is_a? String
|
5
|
+
save_title(options, headline)
|
6
|
+
else
|
7
|
+
display_title(options)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def save_title(title, headline)
|
12
|
+
@title = title.gsub(/<\/?[^>]*>/, '')
|
13
|
+
headline.blank? ? title : headline
|
14
|
+
end
|
15
|
+
|
16
|
+
def display_title(options)
|
17
|
+
# Prefix (leading space)
|
18
|
+
if options[:prefix]
|
19
|
+
prefix = options[:prefix]
|
20
|
+
elsif options[:prefix] == false
|
21
|
+
prefix = ''
|
22
|
+
else
|
23
|
+
prefix = ' '
|
24
|
+
end
|
25
|
+
|
26
|
+
# Separator
|
27
|
+
unless options[:separator].blank?
|
28
|
+
separator = options[:separator]
|
29
|
+
else
|
30
|
+
separator = '|'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Suffix (trailing space)
|
34
|
+
if options[:suffix]
|
35
|
+
suffix = options[:suffix]
|
36
|
+
elsif options[:suffix] == false
|
37
|
+
suffix = ''
|
38
|
+
else
|
39
|
+
suffix = ' '
|
40
|
+
end
|
41
|
+
|
42
|
+
# Lowercase title?
|
43
|
+
if options[:lowercase] == true
|
44
|
+
@title = @title.downcase unless @title.blank?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Set website/page order
|
48
|
+
unless @title.blank?
|
49
|
+
if options[:reverse] == true
|
50
|
+
# Reverse order => "Page : Website"
|
51
|
+
return content_tag(:title, @title + prefix + separator + suffix + options[:site])
|
52
|
+
else
|
53
|
+
# Standard order => "Website : Page"
|
54
|
+
return content_tag(:title, options[:site] + prefix + separator + suffix + @title)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# If title is blank, return only website name
|
59
|
+
content_tag :title, options[:site]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
======
|
2
|
+
Javascripter
|
3
|
+
======
|
4
|
+
|
5
|
+
Javascripter is designed to DRY up the process of including and generating
|
6
|
+
javascripts, so you can think less about javascript configuration and more
|
7
|
+
about scripting.
|
8
|
+
|
9
|
+
|
10
|
+
Usage
|
11
|
+
=====
|
12
|
+
|
13
|
+
To use Javascripter, just update your layout(s) with this code:
|
14
|
+
|
15
|
+
<head>
|
16
|
+
<title>the.rails.ist</title>
|
17
|
+
<%= javascripts %>
|
18
|
+
</head>
|
19
|
+
|
20
|
+
Javascripter will then include your javascripts automatically:
|
21
|
+
|
22
|
+
<head>
|
23
|
+
<title>the.rails.ist</title>
|
24
|
+
<link href="/javascripts/application.js?1170968897" />
|
25
|
+
</head>
|
26
|
+
|
27
|
+
Javascripter will also dynamically include javascripts for each of your
|
28
|
+
controllers (if such javascripts are present), so you can keep your scripts
|
29
|
+
organized into logical sections.
|
30
|
+
|
31
|
+
|
32
|
+
Organize your javascripts
|
33
|
+
=========================
|
34
|
+
|
35
|
+
Javascripter uses a simple set of conventions:
|
36
|
+
|
37
|
+
- Javascripts for your entire application should be stored in application.js
|
38
|
+
- Javascripts for specific controllers should be stored in controller.js
|
39
|
+
- Javascripts for specific actions should be stored in controller_action.js
|
40
|
+
|
41
|
+
When used in combination, these conventions can scale up to support pretty
|
42
|
+
big applications.
|
43
|
+
|
44
|
+
|
45
|
+
Include additional javascripts
|
46
|
+
==============================
|
47
|
+
|
48
|
+
Conventions are great, but need to add your own javascripts?
|
49
|
+
|
50
|
+
<%= javascripts :include => "reset" %>
|
51
|
+
<%= javascripts :include => ["reset", "fonts"] %>
|
52
|
+
|
53
|
+
|
54
|
+
Use nested javascripts (optional)
|
55
|
+
=================================
|
56
|
+
|
57
|
+
For bigger projects, you might wish to break your javascripts into separate
|
58
|
+
directories.
|
59
|
+
|
60
|
+
To use nested javascripts, just create subdirectories in public/javascripts
|
61
|
+
for each of your controllers, and then add javascripts for individual
|
62
|
+
actions you wish to script.
|
63
|
+
|
64
|
+
- Javascripts for an entire controller should be stored in controller.js
|
65
|
+
- Javascripts for specific actions should be stored in controller/action.js
|
66
|
+
|
67
|
+
|
68
|
+
Generator
|
69
|
+
=========
|
70
|
+
|
71
|
+
Javascripter also includes a generator that will create a default set of
|
72
|
+
javascripts (application.js) and a separate
|
73
|
+
javascript for each controller in your application.
|
74
|
+
|
75
|
+
To use the generator, run this command in your terminal:
|
76
|
+
|
77
|
+
script/generate javascripts
|
78
|
+
|
79
|
+
If you add a new controller, just run the generator again and a new
|
80
|
+
javascript for the controller will be created. (Javascripter will safely ignore
|
81
|
+
any existing javascripts.)
|
82
|
+
|
83
|
+
|
84
|
+
Feedback
|
85
|
+
========
|
86
|
+
|
87
|
+
Comments, bug reports, and svn diffs welcome at http://the.railsi.st.
|