insightful 0.0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|