insightful 0.0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +40 -0
- data/Rakefile +78 -0
- data/init.rb +1 -0
- data/lib/insightful/adapter.rb +14 -0
- data/lib/insightful/body_helper.rb +18 -0
- data/lib/insightful/grid_helper.rb +31 -0
- data/lib/insightful/head_helper.rb +213 -0
- data/lib/insightful/navigation_helper.rb +119 -0
- data/lib/insightful/system_helper.rb +61 -0
- data/lib/insightful/tooltip_helper.rb +13 -0
- data/lib/insightful.rb +22 -0
- data/rails/init.rb +1 -0
- metadata +80 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Lance Pollard (lancejpollard@gmail.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.
|
data/README.markdown
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Insightful
|
2
|
+
|
3
|
+
<q>DRY, SEO-friendly Rails Views</q>
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
### Install
|
8
|
+
|
9
|
+
sudo gem install represent
|
10
|
+
|
11
|
+
### Helpers
|
12
|
+
|
13
|
+
#### Tooltip Helpers
|
14
|
+
|
15
|
+
Ever want to centralize tooltips and helpful hints for form fields in your projects? Now you can.
|
16
|
+
|
17
|
+
#### Metadata Helpers
|
18
|
+
|
19
|
+
Adding metadata to your views is easy (`app/views/pages/index.html.erb`):
|
20
|
+
|
21
|
+
<% title @post.title %>
|
22
|
+
<% description @post.description %>
|
23
|
+
<% keywords @post.tag_list %>
|
24
|
+
<% body_class "post post-template" %>
|
25
|
+
|
26
|
+
<div id="content">...</div>
|
27
|
+
|
28
|
+
Default metadata is just as easy (`app/views/layouts/application.html.erb`):
|
29
|
+
|
30
|
+
<%= meta_tags "My Site",
|
31
|
+
:keywords => "Rails 3, jQuery",
|
32
|
+
:description => "This is what Facebook displays" %>
|
33
|
+
|
34
|
+
#### System Helpers
|
35
|
+
|
36
|
+
Need to check what browser it is? No problem.
|
37
|
+
|
38
|
+
#### Layout Helpers
|
39
|
+
|
40
|
+
Would you like to create a nested menu, or a grid? No problem.
|
data/Rakefile
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require "rake/rdoctask"
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
s.name = "insightful"
|
7
|
+
s.authors = ["Lance Pollard"]
|
8
|
+
s.version = "0.0.1.5"
|
9
|
+
s.summary = "Insightful: DRY, SEO-friendly Rails Views"
|
10
|
+
s.homepage = "http://github.com/viatropos/insightful"
|
11
|
+
s.email = "lancejpollard@gmail.com"
|
12
|
+
s.description = "DRY, SEO-friendly Rails Views"
|
13
|
+
s.has_rdoc = false
|
14
|
+
s.rubyforge_project = "insightful"
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.files = %w(README.markdown Rakefile init.rb MIT-LICENSE) + Dir["{lib,rails,test}/**/*"] - Dir["test/tmp"]
|
17
|
+
s.require_path = "lib"
|
18
|
+
end
|
19
|
+
|
20
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
21
|
+
pkg.gem_spec = spec
|
22
|
+
pkg.package_dir = "pkg"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'run unit tests'
|
26
|
+
task :test do
|
27
|
+
Dir["test/**/*"].each do |file|
|
28
|
+
next unless File.basename(file) =~ /test_/
|
29
|
+
next unless File.extname(file) == ".rb"
|
30
|
+
system "ruby #{file}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Create .gemspec file (useful for github)"
|
35
|
+
task :gemspec do
|
36
|
+
File.open("pkg/#{spec.name}.gemspec", "w") do |f|
|
37
|
+
f.puts spec.to_ruby
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Build the gem into the current directory"
|
42
|
+
task :gem => :gemspec do
|
43
|
+
`gem build pkg/#{spec.name}.gemspec`
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Publish gem to rubygems"
|
47
|
+
task :publish => [:package] do
|
48
|
+
%x[gem push pkg/#{spec.name}-#{spec.version}.gem]
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Print a list of the files to be put into the gem"
|
52
|
+
task :manifest do
|
53
|
+
File.open("Manifest", "w") do |f|
|
54
|
+
spec.files.each do |file|
|
55
|
+
f.puts file
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Install the gem locally"
|
61
|
+
task :install => [:package] do
|
62
|
+
File.mkdir("pkg") unless File.exists?("pkg")
|
63
|
+
command = "gem install pkg/#{spec.name}-#{spec.version} --no-ri --no-rdoc"
|
64
|
+
command = "sudo #{command}" if ENV["SUDO"] == true
|
65
|
+
sh %{#{command}}
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Generate the rdoc"
|
69
|
+
Rake::RDocTask.new do |rdoc|
|
70
|
+
files = ["README.markdown", "lib/**/*.rb"]
|
71
|
+
rdoc.rdoc_files.add(files)
|
72
|
+
rdoc.main = "README.markdown"
|
73
|
+
rdoc.title = spec.summary
|
74
|
+
end
|
75
|
+
|
76
|
+
task :yank do
|
77
|
+
`gem yank #{spec.name} -v #{spec.version}`
|
78
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
File.dirname(__FILE__) + "/rails/init.rb"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# since I love the haml pretty-printed output so much,
|
2
|
+
# this makes it so I can use that instead of the built in
|
3
|
+
# rails ugly printing
|
4
|
+
module Insightful
|
5
|
+
module Adapter
|
6
|
+
def render_tag(name, *args, &block)
|
7
|
+
if self.respond_to?("is_haml?".to_sym) and is_haml?
|
8
|
+
haml_tag(name.to_sym, options)
|
9
|
+
else
|
10
|
+
tag(name.to_sym)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Insightful
|
2
|
+
module BodyHelper
|
3
|
+
def body_id(string)
|
4
|
+
@body_id = string
|
5
|
+
end
|
6
|
+
|
7
|
+
def body_class(string)
|
8
|
+
@body_class = string
|
9
|
+
end
|
10
|
+
|
11
|
+
def body_attributes(options = {})
|
12
|
+
options[:class] = @body_class if @body_class
|
13
|
+
options[:id] = @body_id if @body_id
|
14
|
+
|
15
|
+
options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Insightful
|
2
|
+
module GridHelper
|
3
|
+
def grid_for(array, options = {}, &block)
|
4
|
+
return "" if array.empty?
|
5
|
+
columns = options[:columns] || 3
|
6
|
+
(array / columns).each do |row|
|
7
|
+
yield row
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def row_for(array, options = {}, &block)
|
12
|
+
return "" if array.empty?
|
13
|
+
array.each_with_index do |node, i|
|
14
|
+
attributes = options.has_key?(:li_attributes) ? options[:li_attributes] : {}
|
15
|
+
attributes[:class] ||= ""
|
16
|
+
if i == 0 and options.has_key?(:first)
|
17
|
+
attributes[:class] << "#{options[:first]}"
|
18
|
+
elsif i == array.length - 1 and options.has_key?(:last)
|
19
|
+
attributes[:class] << "#{options[:last]}"
|
20
|
+
end
|
21
|
+
haml_tag :li, attributes do
|
22
|
+
if block_given?
|
23
|
+
yield node, i
|
24
|
+
else
|
25
|
+
haml_concat node.title
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
module Insightful
|
2
|
+
module HeadHelper
|
3
|
+
|
4
|
+
def meta(options = {})
|
5
|
+
title(options[:title]) if options.has_key?(:title)
|
6
|
+
description(options[:description]) if options.has_key?(:description)
|
7
|
+
keywords(options[:keywords]) if options.has_key?(:keywords)
|
8
|
+
copyright(options[:copyright]) if options.has_key?(:copyright)
|
9
|
+
end
|
10
|
+
|
11
|
+
def meta_tags(*args)
|
12
|
+
options = args.extract_options!
|
13
|
+
site = options[:site] || args.first
|
14
|
+
result = title_tag(site, options[:title])
|
15
|
+
result << "\n"
|
16
|
+
result << content_type_tag
|
17
|
+
result << "\n"
|
18
|
+
result << description_tag(options[:description])
|
19
|
+
result << "\n"
|
20
|
+
result << keywords_tag(options[:keywords])
|
21
|
+
result << "\n"
|
22
|
+
result << copyright_tag(options[:copyright])
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
# country
|
27
|
+
# classification
|
28
|
+
# author
|
29
|
+
# apple-mobile-web-app-capable
|
30
|
+
# apple-touch-fullscreen
|
31
|
+
# google-analytics
|
32
|
+
# Revisit-After
|
33
|
+
# category
|
34
|
+
def meta_tag(name, content = '')
|
35
|
+
tag(:meta, :name => name, :content => content)
|
36
|
+
end
|
37
|
+
|
38
|
+
def title(string)
|
39
|
+
@content_for_title = string
|
40
|
+
end
|
41
|
+
|
42
|
+
def title_tag(*args)
|
43
|
+
options = args.extract_options!
|
44
|
+
|
45
|
+
site = options[:site] || args.first
|
46
|
+
# Prefix (leading space)
|
47
|
+
if options[:prefix]
|
48
|
+
prefix = options[:prefix]
|
49
|
+
elsif options[:prefix] === false
|
50
|
+
prefix = ''
|
51
|
+
else
|
52
|
+
prefix = ' '
|
53
|
+
end
|
54
|
+
|
55
|
+
# Separator
|
56
|
+
unless options[:separator].blank?
|
57
|
+
separator = options[:separator]
|
58
|
+
else
|
59
|
+
separator = '|'
|
60
|
+
end
|
61
|
+
|
62
|
+
# Suffix (trailing space)
|
63
|
+
if options[:suffix]
|
64
|
+
suffix = options[:suffix]
|
65
|
+
elsif options[:suffix] === false
|
66
|
+
suffix = ''
|
67
|
+
else
|
68
|
+
suffix = ' '
|
69
|
+
end
|
70
|
+
|
71
|
+
# Title
|
72
|
+
title = @content_for_title
|
73
|
+
if options[:lowercase] === true
|
74
|
+
title = title.downcase unless title.blank?
|
75
|
+
end
|
76
|
+
|
77
|
+
# title
|
78
|
+
if title.blank?
|
79
|
+
result = content_tag :title, site
|
80
|
+
else
|
81
|
+
title = normalize_title(title)
|
82
|
+
title = [site] + title
|
83
|
+
title.reverse! if options[:reverse] === true
|
84
|
+
sep = prefix + separator + suffix
|
85
|
+
result = content_tag(:title, title.join(sep))
|
86
|
+
end
|
87
|
+
result
|
88
|
+
end
|
89
|
+
|
90
|
+
def description(string)
|
91
|
+
@content_for_description = string
|
92
|
+
end
|
93
|
+
|
94
|
+
def description_tag(default='')
|
95
|
+
content = normalize_description(@content_for_description || default)
|
96
|
+
tag(:meta, :name => :description, :content => content) unless content.blank?
|
97
|
+
end
|
98
|
+
|
99
|
+
def keywords(string)
|
100
|
+
@content_for_keywords = string
|
101
|
+
end
|
102
|
+
|
103
|
+
def keywords_tag(default = '')
|
104
|
+
content = normalize_keywords(@content_for_keywords || default)
|
105
|
+
tag(:meta, :name => :keywords, :content => content) unless content.blank?
|
106
|
+
end
|
107
|
+
|
108
|
+
def copyright(string)
|
109
|
+
@content_for_copyright = string
|
110
|
+
end
|
111
|
+
|
112
|
+
def copyright_tag(default='')
|
113
|
+
content = @content_for_copyright || default
|
114
|
+
tag(:meta, :name => :copyright, :content => content) unless content.blank?
|
115
|
+
end
|
116
|
+
|
117
|
+
def robots(*args)
|
118
|
+
content_for(:robots, args.join(", "))
|
119
|
+
end
|
120
|
+
|
121
|
+
def robots_tag(*args)
|
122
|
+
options = args.extract_options!
|
123
|
+
|
124
|
+
noindex_name = tags[:noindex].is_a?(String) ? tags[:noindex] : 'robots'
|
125
|
+
nofollow_name = tags[:nofollow].is_a?(String) ? tags[:nofollow] : 'robots'
|
126
|
+
|
127
|
+
if noindex_name == nofollow_name
|
128
|
+
content = [(tags[:noindex] ? 'noindex' : nil), (tags[:nofollow] ? 'nofollow' : nil)].compact.join(', ')
|
129
|
+
unless content.blank?
|
130
|
+
result << "\n"
|
131
|
+
result << tag(:meta, :name => noindex_name, :content => content)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
if tags[:noindex]
|
135
|
+
result << "\n"
|
136
|
+
result << tag(:meta, :name => noindex_name, :content => 'noindex')
|
137
|
+
end
|
138
|
+
if tags[:nofollow]
|
139
|
+
result << "\n"
|
140
|
+
result << tag(:meta, :name => nofollow_name, :content => 'nofollow')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
# canonical
|
144
|
+
unless tags[:canonical].blank?
|
145
|
+
result << "\n"
|
146
|
+
result << tag(:link, :rel => :canonical, :href => tags[:canonical])
|
147
|
+
end
|
148
|
+
|
149
|
+
return result
|
150
|
+
end
|
151
|
+
|
152
|
+
def copyright(from)
|
153
|
+
now = Time.now.year
|
154
|
+
now.eql?(from) ? now : "#{from} - #{now}"
|
155
|
+
end
|
156
|
+
|
157
|
+
# Apple
|
158
|
+
# http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html
|
159
|
+
|
160
|
+
# Facebook (and opengraph)
|
161
|
+
# http://developers.facebook.com/docs/opengraph#types
|
162
|
+
|
163
|
+
# http://wiki.developers.facebook.com/index.php/Facebook_Share/Specifying_Meta_Tags
|
164
|
+
def snapshot_tag(href)
|
165
|
+
tag(:link, :rel => "image_src", :href => href)
|
166
|
+
end
|
167
|
+
|
168
|
+
# http://wiki.developers.facebook.com/index.php/Facebook_Share/Specifying_Meta_Tags
|
169
|
+
def medium(type)
|
170
|
+
tag(:meta, :name => :medium, :content => type)
|
171
|
+
end
|
172
|
+
|
173
|
+
def classification(type)
|
174
|
+
tag(:meta, :name => "og:type", :content => type)
|
175
|
+
end
|
176
|
+
|
177
|
+
def content_type_tag(type = "text/html", charset = "UTF-8")
|
178
|
+
meta_tag("Content-Type", "#{type}; charset=#{charset}")
|
179
|
+
end
|
180
|
+
|
181
|
+
def search_link_tag(href, title)
|
182
|
+
link_tag({:rel => "search", :type => "application/opensearchdescription+xml", :href => href, :title => title})
|
183
|
+
end
|
184
|
+
|
185
|
+
def favicon_link_tag(favicon = "/favicon.ico")
|
186
|
+
link_tag({:rel => "shortcut icon", :href => favicon, :type => "image/x-icon"})
|
187
|
+
end
|
188
|
+
|
189
|
+
def link_tag(options = {})
|
190
|
+
tag(:link, options)
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def normalize_title(title)
|
196
|
+
if title.is_a? String
|
197
|
+
title = [title]
|
198
|
+
end
|
199
|
+
title.map { |t| h(strip_tags(t)) }
|
200
|
+
end
|
201
|
+
|
202
|
+
def normalize_description(description)
|
203
|
+
return '' unless description
|
204
|
+
truncate(strip_tags(description).gsub(/\s+/, ' '), :length => 200)
|
205
|
+
end
|
206
|
+
|
207
|
+
def normalize_keywords(keywords)
|
208
|
+
return '' unless keywords
|
209
|
+
keywords = keywords.flatten.join(', ') if keywords.is_a?(Array)
|
210
|
+
strip_tags(keywords).mb_chars.downcase
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Insightful
|
2
|
+
module NavigationHelper
|
3
|
+
|
4
|
+
# - menu(c(:menu)) do |attributes, node|
|
5
|
+
# - attributes[:class] = "one two"
|
6
|
+
# - node[:title]
|
7
|
+
def menu(nodes, options = {}, &block)
|
8
|
+
menu_builder(nodes, 0, options, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def nested_set_menu(clazz, options = {}, &block)
|
12
|
+
menu(simple_nested_set(clazz), options) do |node, children, level|
|
13
|
+
if block_given?
|
14
|
+
case block.arity
|
15
|
+
when 1
|
16
|
+
yield node[:node]
|
17
|
+
when 2
|
18
|
+
yield node[:node], children
|
19
|
+
when 3
|
20
|
+
yield node[:node], children, level
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def menu_builder(nodes, level = 0, options = {}, &block)
|
27
|
+
return "" if nodes.empty?
|
28
|
+
|
29
|
+
menu_attributes = options[:menu_attributes] if options.has_key?(:menu_attributes)
|
30
|
+
options.delete(:menu_attributes)
|
31
|
+
|
32
|
+
haml_tag :ul, menu_attributes do
|
33
|
+
nodes.each_with_index do |node, i|
|
34
|
+
# set the attributes
|
35
|
+
attributes = options[:li_attributes].blank? ? {} : options[:li_attributes].dup
|
36
|
+
attributes[:class] ||= ""
|
37
|
+
if i == 0 and options.has_key?(:first)
|
38
|
+
attributes[:class] << " #{options[:first]}".squeeze(" ")
|
39
|
+
elsif i == nodes.length - 1 and options.has_key?(:last)
|
40
|
+
attributes[:class] << " #{options[:last]}".squeeze(" ")
|
41
|
+
end
|
42
|
+
|
43
|
+
haml_tag :li, attributes do
|
44
|
+
children = nil
|
45
|
+
if node.has_key?(:children)
|
46
|
+
children = node[:children]
|
47
|
+
elsif node.respond_to?(:children)
|
48
|
+
children = node.children
|
49
|
+
end
|
50
|
+
|
51
|
+
if block_given?
|
52
|
+
case block.arity
|
53
|
+
when 1
|
54
|
+
yield node
|
55
|
+
when 2
|
56
|
+
yield node, children
|
57
|
+
when 3
|
58
|
+
yield node, children, level
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# pass it in again
|
63
|
+
menu_builder(children, level + 1, options, &block) unless children.empty?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def simple_nested_set(clazz) # Post for example
|
70
|
+
stack = [] # Post for example
|
71
|
+
result = []
|
72
|
+
clazz.all(:order => "lft").each do |node|
|
73
|
+
if stack.empty?
|
74
|
+
stack.push({:node => node, :children => []})
|
75
|
+
result << stack.last
|
76
|
+
next
|
77
|
+
end
|
78
|
+
if stack.last[:node].lft < node.lft && node.lft < stack.last[:node].rgt
|
79
|
+
child = {:node => node, :children => []}
|
80
|
+
stack.last[:children] << child
|
81
|
+
unless node.leaf? # (node.rgt - node.lft == 1)
|
82
|
+
stack.push(child)
|
83
|
+
end
|
84
|
+
|
85
|
+
if node.rgt + 1 == stack.last[:node].rgt
|
86
|
+
stack.pop
|
87
|
+
end
|
88
|
+
else
|
89
|
+
stack.pop
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
result
|
94
|
+
end
|
95
|
+
|
96
|
+
def breadcrumb(item, options = {}, &block)
|
97
|
+
options[:from] ||= "/" + item.url.gsub(/^\//, "").split("/").first
|
98
|
+
options[:to] ||= item.url
|
99
|
+
breadcrumb_builder(options[:from], options, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
def breadcrumb_builder(current_url, options, &block)
|
103
|
+
item = site.find_by_url(current_url)
|
104
|
+
return "" unless item
|
105
|
+
haml_tag :a, options.merge(:href => current_url) do
|
106
|
+
if block_given?
|
107
|
+
yield item
|
108
|
+
else
|
109
|
+
haml_concat item.title
|
110
|
+
end
|
111
|
+
end
|
112
|
+
if options[:to] != current_url
|
113
|
+
haml_concat options[:delimiter] || " » "
|
114
|
+
next_node = options[:to].gsub(/#{current_url}\/?/, "").split("/").first
|
115
|
+
breadcrumb_builder("#{current_url}/#{next_node}", options, &block)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Insightful
|
2
|
+
module SystemHelper
|
3
|
+
# check the current browser (via user agent) for the following:
|
4
|
+
# :mozilla / :firefox
|
5
|
+
# :ie6
|
6
|
+
# :ie7
|
7
|
+
# :ie
|
8
|
+
# :iphone
|
9
|
+
# :safari
|
10
|
+
def browser_is? name
|
11
|
+
name = name.to_s.strip
|
12
|
+
|
13
|
+
return true if browser_name == name
|
14
|
+
return true if (name == 'mozilla' or name == "firefox") && 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 == 'iphone' && browser_name == 'iphone'
|
19
|
+
return true if name == 'webkit' && browser_name == 'safari'
|
20
|
+
end
|
21
|
+
|
22
|
+
# find the current browser name
|
23
|
+
def browser_name
|
24
|
+
@browser_name ||= begin
|
25
|
+
ua = request.user_agent.to_s.downcase
|
26
|
+
if ua.index('msie') && !ua.index('opera') && !ua.index('webtv')
|
27
|
+
'ie'+ua[ua.index('msie')+5].chr
|
28
|
+
elsif ua.index('gecko/')
|
29
|
+
'gecko'
|
30
|
+
elsif ua.index('opera')
|
31
|
+
'opera'
|
32
|
+
elsif ua.index('konqueror')
|
33
|
+
'konqueror'
|
34
|
+
elsif ua.index('iphone')
|
35
|
+
'iphone'
|
36
|
+
elsif ua.index('applewebkit/')
|
37
|
+
'safari'
|
38
|
+
elsif ua.index('mozilla/')
|
39
|
+
'gecko'
|
40
|
+
else
|
41
|
+
""
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def windows?
|
47
|
+
# Can't match for just 'win' cause it will match darwin as well.
|
48
|
+
(/win32|mswin|mingw/).match(RUBY_PLATFORM) ? true : false
|
49
|
+
end
|
50
|
+
|
51
|
+
# Works on Debian and Ubuntu, don't have anything else to test on.
|
52
|
+
def linux?
|
53
|
+
(/linux/).match(RUBY_PLATFORM) ? true : false
|
54
|
+
end
|
55
|
+
|
56
|
+
# Works on my MacBook Pro, don't have anything else to test on,
|
57
|
+
def mac?
|
58
|
+
(/darwin/).match(RUBY_PLATFORM) ? true : false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Insightful
|
2
|
+
module TooltipHelper
|
3
|
+
# associates the "title" attribute of a node with a rendered partial
|
4
|
+
def insight(partial, options = {})
|
5
|
+
if options.has_key?(:class)
|
6
|
+
options[:class] << " insightful"
|
7
|
+
else
|
8
|
+
options[:class] = "insightful"
|
9
|
+
end
|
10
|
+
{:title => (render :partial => partial).to_s}.merge!(options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/insightful.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
# This takes care of the rest of functionality you need
|
3
|
+
# for an SEO and easy to build page.
|
4
|
+
# It includes: metadata helpers, grid helpers (e.g. for photo gallerys),
|
5
|
+
# navigation helpers (menus and breadcrumbs),
|
6
|
+
# better render method so you can pass a block to partials
|
7
|
+
# http://github.com/rpheath/navigation_helper.git
|
8
|
+
# http://github.com/justinfrench/lovely-layouts.git
|
9
|
+
# http://github.com/ianwhite/truncate_html
|
10
|
+
# http://github.com/dekart/breadcrumbs.git
|
11
|
+
# http://github.com/html/once/blob/master/lib/once.rb
|
12
|
+
# http://github.com/fnando/breadcrumbs.git
|
13
|
+
# http://github.com/semanticart/smart-meta
|
14
|
+
|
15
|
+
Dir["#{File.expand_path(File.dirname(__FILE__))}/insightful/*"].each {|file| require file}
|
16
|
+
|
17
|
+
Insightful.send(:include, Insightful::HeadHelper)
|
18
|
+
Insightful.send(:include, Insightful::BodyHelper)
|
19
|
+
Insightful.send(:include, Insightful::NavigationHelper)
|
20
|
+
|
21
|
+
ActionView::Base.send(:include, Insightful) if defined?(ActionView)
|
22
|
+
ActionController::Base.helper(Insightful) if defined?(ActionController)
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'insightful'
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: insightful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 65
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
- 5
|
11
|
+
version: 0.0.1.5
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- Lance Pollard
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-07-02 00:00:00 -07:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: DRY, SEO-friendly Rails Views
|
24
|
+
email: lancejpollard@gmail.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- README.markdown
|
33
|
+
- Rakefile
|
34
|
+
- init.rb
|
35
|
+
- MIT-LICENSE
|
36
|
+
- lib/insightful/adapter.rb
|
37
|
+
- lib/insightful/body_helper.rb
|
38
|
+
- lib/insightful/grid_helper.rb
|
39
|
+
- lib/insightful/head_helper.rb
|
40
|
+
- lib/insightful/navigation_helper.rb
|
41
|
+
- lib/insightful/system_helper.rb
|
42
|
+
- lib/insightful/tooltip_helper.rb
|
43
|
+
- lib/insightful.rb
|
44
|
+
- rails/init.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/viatropos/insightful
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project: insightful
|
75
|
+
rubygems_version: 1.3.7
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: "Insightful: DRY, SEO-friendly Rails Views"
|
79
|
+
test_files: []
|
80
|
+
|