green_monkey 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/Gemfile.haml-edge +4 -0
- data/Gemfile.lock +131 -0
- data/Gemfile.rails-3.0.11 +4 -0
- data/Gemfile.rails-3.1.3 +4 -0
- data/README.md +152 -0
- data/Rakefile +15 -0
- data/green_monkey.gemspec +29 -0
- data/lib/green_monkey/ext/action_view.rb +22 -0
- data/lib/green_monkey/ext/active_model.rb +29 -0
- data/lib/green_monkey/ext/haml.rb +67 -0
- data/lib/green_monkey/ext/mida.rb +34 -0
- data/lib/green_monkey/ext/view_helper.rb +60 -0
- data/lib/green_monkey/railtie.rb +17 -0
- data/lib/green_monkey.rb +3 -0
- data/spec/haml_spec.rb +85 -0
- data/spec/mida_spec.rb +18 -0
- data/spec/model_spec.rb +19 -0
- data/spec/post.haml +9 -0
- data/spec/spec_helper.rb +54 -0
- data/tmp/rails/config/database.yml +9 -0
- data/tmp/rails/config/environments/development.rb +0 -0
- metadata +158 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# just let autotest know about rspec
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.haml-edge
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/Paxa/chronic_duration.git
|
3
|
+
revision: 8c0d0e101bdbaf2b2299f33e7bfa880b0885a017
|
4
|
+
ref: 8c0d0e101b
|
5
|
+
specs:
|
6
|
+
chronic_duration (0.9.6)
|
7
|
+
numerizer (~> 0.1.1)
|
8
|
+
|
9
|
+
PATH
|
10
|
+
remote: .
|
11
|
+
specs:
|
12
|
+
green_monkey (0.1)
|
13
|
+
chronic_duration
|
14
|
+
haml (>= 3.1.0)
|
15
|
+
mida (>= 0.3.3)
|
16
|
+
rails (>= 3.0.0)
|
17
|
+
|
18
|
+
GEM
|
19
|
+
remote: http://rubygems.org/
|
20
|
+
specs:
|
21
|
+
actionmailer (3.1.3)
|
22
|
+
actionpack (= 3.1.3)
|
23
|
+
mail (~> 2.3.0)
|
24
|
+
actionpack (3.1.3)
|
25
|
+
activemodel (= 3.1.3)
|
26
|
+
activesupport (= 3.1.3)
|
27
|
+
builder (~> 3.0.0)
|
28
|
+
erubis (~> 2.7.0)
|
29
|
+
i18n (~> 0.6)
|
30
|
+
rack (~> 1.3.5)
|
31
|
+
rack-cache (~> 1.1)
|
32
|
+
rack-mount (~> 0.8.2)
|
33
|
+
rack-test (~> 0.6.1)
|
34
|
+
sprockets (~> 2.0.3)
|
35
|
+
activemodel (3.1.3)
|
36
|
+
activesupport (= 3.1.3)
|
37
|
+
builder (~> 3.0.0)
|
38
|
+
i18n (~> 0.6)
|
39
|
+
activerecord (3.1.3)
|
40
|
+
activemodel (= 3.1.3)
|
41
|
+
activesupport (= 3.1.3)
|
42
|
+
arel (~> 2.2.1)
|
43
|
+
tzinfo (~> 0.3.29)
|
44
|
+
activeresource (3.1.3)
|
45
|
+
activemodel (= 3.1.3)
|
46
|
+
activesupport (= 3.1.3)
|
47
|
+
activesupport (3.1.3)
|
48
|
+
multi_json (~> 1.0)
|
49
|
+
arel (2.2.1)
|
50
|
+
blankslate (2.1.2.4)
|
51
|
+
builder (3.0.0)
|
52
|
+
diff-lcs (1.1.3)
|
53
|
+
erubis (2.7.0)
|
54
|
+
haml (3.1.3)
|
55
|
+
hike (1.2.1)
|
56
|
+
i18n (0.6.0)
|
57
|
+
json (1.6.1)
|
58
|
+
mail (2.3.0)
|
59
|
+
i18n (>= 0.4.0)
|
60
|
+
mime-types (~> 1.16)
|
61
|
+
treetop (~> 1.4.8)
|
62
|
+
mida (0.3.3)
|
63
|
+
blankslate
|
64
|
+
nokogiri (>= 1.5)
|
65
|
+
mime-types (1.17.2)
|
66
|
+
multi_json (1.0.3)
|
67
|
+
nokogiri (1.5.0)
|
68
|
+
numerizer (0.1.1)
|
69
|
+
polyglot (0.3.3)
|
70
|
+
rack (1.3.5)
|
71
|
+
rack-cache (1.1)
|
72
|
+
rack (>= 0.4)
|
73
|
+
rack-mount (0.8.3)
|
74
|
+
rack (>= 1.0.0)
|
75
|
+
rack-ssl (1.3.2)
|
76
|
+
rack
|
77
|
+
rack-test (0.6.1)
|
78
|
+
rack (>= 1.0)
|
79
|
+
rails (3.1.3)
|
80
|
+
actionmailer (= 3.1.3)
|
81
|
+
actionpack (= 3.1.3)
|
82
|
+
activerecord (= 3.1.3)
|
83
|
+
activeresource (= 3.1.3)
|
84
|
+
activesupport (= 3.1.3)
|
85
|
+
bundler (~> 1.0)
|
86
|
+
railties (= 3.1.3)
|
87
|
+
railties (3.1.3)
|
88
|
+
actionpack (= 3.1.3)
|
89
|
+
activesupport (= 3.1.3)
|
90
|
+
rack-ssl (~> 1.3.2)
|
91
|
+
rake (>= 0.8.7)
|
92
|
+
rdoc (~> 3.4)
|
93
|
+
thor (~> 0.14.6)
|
94
|
+
rake (0.9.2.2)
|
95
|
+
rdoc (3.11)
|
96
|
+
json (~> 1.4)
|
97
|
+
rspec (2.7.0)
|
98
|
+
rspec-core (~> 2.7.0)
|
99
|
+
rspec-expectations (~> 2.7.0)
|
100
|
+
rspec-mocks (~> 2.7.0)
|
101
|
+
rspec-core (2.7.1)
|
102
|
+
rspec-expectations (2.7.0)
|
103
|
+
diff-lcs (~> 1.1.2)
|
104
|
+
rspec-mocks (2.7.0)
|
105
|
+
rspec-rails (2.7.0)
|
106
|
+
actionpack (~> 3.0)
|
107
|
+
activesupport (~> 3.0)
|
108
|
+
railties (~> 3.0)
|
109
|
+
rspec (~> 2.7.0)
|
110
|
+
sprockets (2.0.3)
|
111
|
+
hike (~> 1.2)
|
112
|
+
rack (~> 1.0)
|
113
|
+
tilt (~> 1.1, != 1.3.0)
|
114
|
+
sqlite3 (1.3.4)
|
115
|
+
thor (0.14.6)
|
116
|
+
tilt (1.3.3)
|
117
|
+
treetop (1.4.10)
|
118
|
+
polyglot
|
119
|
+
polyglot (>= 0.3.1)
|
120
|
+
tzinfo (0.3.31)
|
121
|
+
|
122
|
+
PLATFORMS
|
123
|
+
ruby
|
124
|
+
|
125
|
+
DEPENDENCIES
|
126
|
+
bundler (>= 1.0.0)
|
127
|
+
chronic_duration!
|
128
|
+
green_monkey!
|
129
|
+
rspec (>= 2.7.0)
|
130
|
+
rspec-rails
|
131
|
+
sqlite3
|
data/Gemfile.rails-3.1.3
ADDED
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# Green Monkey
|
2
|
+
|
3
|
+
## About
|
4
|
+
|
5
|
+
This Gem allows you to make html-layout with microdata properties easier. It works with ruby 1.9, rails 3, haml 3.
|
6
|
+
|
7
|
+
![Green Monkey](http://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/Bijilo-Portrait-of-a-Callithrix-Monkey.jpg/320px-Bijilo-Portrait-of-a-Callithrix-Monkey.jpg)
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
Add to Gemfile
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem "green_monkey"
|
15
|
+
```
|
16
|
+
|
17
|
+
## Examples
|
18
|
+
|
19
|
+
### helper `time_tag`
|
20
|
+
|
21
|
+
It almost as rails' time_tag but make `datetime` attribute in iso8601 format, according to Microdata specifications
|
22
|
+
Also it accepts Numeric values as duration
|
23
|
+
|
24
|
+
Haml & HTML:
|
25
|
+
|
26
|
+
```haml
|
27
|
+
= time_tag post.created_at
|
28
|
+
= time_tag post.created_at, itemprop: "datePublished"
|
29
|
+
= time_tag 3.hours + 30.minutes
|
30
|
+
```
|
31
|
+
|
32
|
+
```html
|
33
|
+
<time datetime="2011-11-23T00:00:00.0Z">23 Nov 2011</time>
|
34
|
+
<time datetime="2011-11-23T00:00:00.0Z" itemprop="datePublished">23 Nov 2011</time>
|
35
|
+
<time datetime="PT3H30M" title="3 hours 30 minutes">about 4 hours</time>
|
36
|
+
```
|
37
|
+
|
38
|
+
### helper `time_tag_interval`
|
39
|
+
|
40
|
+
The same with `time_tag` but made for time intervals
|
41
|
+
|
42
|
+
```haml
|
43
|
+
= time_tag_interval Time.parse("14 March 1879"), Time.parse("18 April 1955"), :format => '%d %h %Y'
|
44
|
+
= time_tag_interval Time.parse("14 March 1989"), 150.hours, :format => :short
|
45
|
+
```
|
46
|
+
|
47
|
+
```html
|
48
|
+
<time datetime="1879-03-14T00:00:00+07:30/1955-04-18T00:00:00+07:30">14 Mar 1879 - 14 Mar 1879</time>
|
49
|
+
<time datetime="1989-05-06T00:00:00+08:00/P6DT6H">06 May 00:00 in 6d 6h</time>
|
50
|
+
```
|
51
|
+
|
52
|
+
### ActiveRecord::Base#html\_schema\_type
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class User < ActiveRecord::Base
|
56
|
+
html_schema_type :Person
|
57
|
+
end
|
58
|
+
|
59
|
+
User.html_schema_type #=> Mida::SchemaOrg::Person
|
60
|
+
User.find(1).html_schema_type => Mida::SchemaOrg::Person
|
61
|
+
```
|
62
|
+
|
63
|
+
### Haml magic
|
64
|
+
|
65
|
+
Attribute `itemprop`
|
66
|
+
|
67
|
+
```haml
|
68
|
+
%span[:name]= item.name
|
69
|
+
<span itemprop='name'>Item name</span>
|
70
|
+
```
|
71
|
+
|
72
|
+
`itemscope` and `iteptype` attributes
|
73
|
+
|
74
|
+
```haml
|
75
|
+
%article[Mida(:Event)] # =>
|
76
|
+
<article itemscope itemtype='http://schema.org/Event'></article>
|
77
|
+
|
78
|
+
%article[Mida(:Event, :DrinkUp)] # =>
|
79
|
+
<article itemscope itemtype='http://schema.org/Event/DrinkUp'></article>
|
80
|
+
|
81
|
+
%article[@user] # =>
|
82
|
+
<article class='user' id='1' itemid='1' itemscope iteptype='http://schema.org/Person'></article>
|
83
|
+
```
|
84
|
+
|
85
|
+
### Real examples
|
86
|
+
Haml:
|
87
|
+
|
88
|
+
```haml
|
89
|
+
%article[post]
|
90
|
+
= link_to "/posts/#{post.id}", :itemprop => "url" do
|
91
|
+
%h3[:name]>= post.title
|
92
|
+
.post_body[:articleBody]= post.body.html_safe
|
93
|
+
= time_tag(post.created_at, :itemprop => "datePublished")
|
94
|
+
```
|
95
|
+
|
96
|
+
Output:
|
97
|
+
|
98
|
+
```html
|
99
|
+
<article class='post' id='post_1' itemid='1' itemscope itemtype='http://schema.org/BlogPosting'>
|
100
|
+
<a href="/posts/1" itemprop="url">
|
101
|
+
<h3 itemprop='name'>Hello world!</h3>
|
102
|
+
</a>
|
103
|
+
<div class='post_body' itemprop='articleBody'>Some text</div>
|
104
|
+
<time datetime="2011-11-22T09:16:57.0Z" itemprop="datePublished">November 22, 2011 09:16</time>
|
105
|
+
</article>
|
106
|
+
```
|
107
|
+
|
108
|
+
Haml:
|
109
|
+
|
110
|
+
```haml
|
111
|
+
%article[project]
|
112
|
+
%header
|
113
|
+
= link_to project.url, itemprop: 'url', target: "_blank" do
|
114
|
+
%h3[:name]<>= project.title
|
115
|
+
= " "
|
116
|
+
- if project.source_code.present?
|
117
|
+
= link_to "(source code)", project.source_code, class: "source_link", target: "_blank"
|
118
|
+
%section[:description]
|
119
|
+
= simple_format project.description
|
120
|
+
|
121
|
+
%ul
|
122
|
+
- for item_type in project.item_types.split(" ")
|
123
|
+
%li[Mida(:WebPageElement, :ItemType), :mentions]
|
124
|
+
%span[:name]= item_type
|
125
|
+
```
|
126
|
+
|
127
|
+
Output:
|
128
|
+
|
129
|
+
```html
|
130
|
+
<article class='project' id='project_2' itemid='2' itemscope itemtype='http://schema.org/WebPage'>
|
131
|
+
<header>
|
132
|
+
<a href="http://lawrencewoodman.github.com/mida/" itemprop="url" target="_blank">
|
133
|
+
<h3 itemprop='name'>Mida - A Microdata extractor/parser library for Ruby</h3>
|
134
|
+
</a>
|
135
|
+
<a href="http://github.com/LawrenceWoodman/mida" class="source_link" target="_blank">(source code)</a>
|
136
|
+
</header>
|
137
|
+
|
138
|
+
<section itemprop='description'>
|
139
|
+
<p>A Ruby Microdata parser/extractor</p>
|
140
|
+
</section>
|
141
|
+
|
142
|
+
<ul>
|
143
|
+
<li itemprop='mentions' itemscope itemtype='http://schema.org/WebPageElement/ItemType'>
|
144
|
+
<span itemprop='name'>http://schema.org/Blog</span>
|
145
|
+
</li>
|
146
|
+
</ul>
|
147
|
+
</article>
|
148
|
+
```
|
149
|
+
|
150
|
+
--------
|
151
|
+
|
152
|
+
I use it in [Microdata tools](http://github.com/paxa/semantic_data/ "my own project")
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
task :default => :spec
|
4
|
+
|
5
|
+
desc "Run Specs"
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
html5 microdata tags easy with green_monkey
|
10
|
+
|
11
|
+
I just launched <a href="http://">plugin saving time and let you make nice haml templates</a>
|
12
|
+
|
13
|
+
904a3032
|
14
|
+
Unlock Code = 39329878
|
15
|
+
Flash Code= 62867076
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "green_monkey"
|
5
|
+
s.version = '0.1'
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Pavel Evstigneev"]
|
8
|
+
s.email = ["pavel.evst@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/paxa/green_monkey"
|
10
|
+
s.summary = "Rails and Haml microdata layout helpers"
|
11
|
+
s.description = "It hacks Rails and Haml"
|
12
|
+
|
13
|
+
s.required_rubygems_version = ">= 1.2.0"
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'rails', '>= 3.0.0'
|
16
|
+
s.add_runtime_dependency 'haml', '>= 3.1.0'
|
17
|
+
s.add_runtime_dependency 'mida', '>= 0.3.3'
|
18
|
+
s.add_runtime_dependency 'chronic_duration'
|
19
|
+
|
20
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
21
|
+
s.add_development_dependency "rspec", ">= 2.7.0"
|
22
|
+
s.add_development_dependency "rspec-rails"
|
23
|
+
s.add_development_dependency 'sqlite3'
|
24
|
+
|
25
|
+
s.files = `git ls-files`.split("\n")
|
26
|
+
s.executables = []
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActionView::Helpers::TagHelper
|
2
|
+
BOOLEAN_ATTRIBUTES.merge(['itemscope', :itemscope])
|
3
|
+
|
4
|
+
private
|
5
|
+
def tag_options(options, escape = true)
|
6
|
+
#p [options, escape, BOOLEAN_ATTRIBUTES]
|
7
|
+
unless options.blank?
|
8
|
+
attrs = []
|
9
|
+
options.each_pair do |key, value|
|
10
|
+
if BOOLEAN_ATTRIBUTES.include?(key)
|
11
|
+
attrs << key.to_s if value
|
12
|
+
elsif !value.nil?
|
13
|
+
final_value = value.is_a?(Array) ? value.join(" ") : value
|
14
|
+
final_value = html_escape(final_value) if escape
|
15
|
+
attrs << %(#{key}="#{final_value}")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
" #{attrs.sort * ' '}".html_safe unless attrs.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module GreenMonkey
|
4
|
+
module ModelHelpers
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def html_schema_type(value = nil)
|
10
|
+
return @html_schema_type unless value
|
11
|
+
|
12
|
+
value = /#{value}/ if value.is_a?(Symbol)
|
13
|
+
if value.is_a?(Regexp)
|
14
|
+
value = Mida::Vocabulary.vocabularies.find do |vocabulary|
|
15
|
+
vocabulary.itemtype.to_s =~ value && vocabulary.itemtype.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
@html_schema_type = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module InstanceMethods
|
24
|
+
def html_schema_type
|
25
|
+
self.class.html_schema_type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "haml"
|
2
|
+
|
3
|
+
# this hack looks at active-record object's :html_schema_type field and adds itemscope, itemid and itemtype to element
|
4
|
+
# example:
|
5
|
+
#
|
6
|
+
# %article[post]
|
7
|
+
# => <article class="post" itemscope itemtype="http://schema.org/BlogPosting" itemid="1">
|
8
|
+
#
|
9
|
+
# %section[Mida(:Blog)]
|
10
|
+
# => <section itemscope itemtype="http://schema.org/Blog">
|
11
|
+
#
|
12
|
+
# %section[Mida(:Blog), :sexjokes]
|
13
|
+
# => <section itemscope itemtype="http://schema.org/Blog/SexJokes">
|
14
|
+
# according to "Extension Mechanism" at http://schema.org/docs/extension.html
|
15
|
+
#
|
16
|
+
# %span[:title] Hello
|
17
|
+
# => <span itemprop="title">Hello</span>
|
18
|
+
|
19
|
+
class Haml::Buffer
|
20
|
+
|
21
|
+
# this methods calls then you pass
|
22
|
+
# %tag[object1, object2]
|
23
|
+
# ref argument is array
|
24
|
+
def parse_object_ref(ref)
|
25
|
+
options = {}
|
26
|
+
ref.each do |obj|
|
27
|
+
next if obj == "local-variable"
|
28
|
+
self.class.merge_attrs(options, process_object_ref(obj))
|
29
|
+
end
|
30
|
+
|
31
|
+
options
|
32
|
+
end
|
33
|
+
|
34
|
+
def process_object_ref(obj)
|
35
|
+
return {} if !obj
|
36
|
+
|
37
|
+
if obj.is_a?(Symbol)
|
38
|
+
# symbol => "itemprop" attribute
|
39
|
+
return {'itemprop' => obj.to_s}
|
40
|
+
elsif obj.kind_of?(Mida::Vocabulary)
|
41
|
+
# Mida::Vocabulary => itemprop and itemtype
|
42
|
+
return {itemscope: true, itemtype: obj.itemtype.source}
|
43
|
+
elsif obj.is_a?(String)
|
44
|
+
return {class: obj}
|
45
|
+
else
|
46
|
+
options = {}
|
47
|
+
options[:class] = obj.respond_to?(:haml_object_ref) ? obj.haml_object_ref : underscore(obj.class)
|
48
|
+
options[:id] = "#{options[:class]}_#{obj.id || 'new'}" if obj.respond_to?(:id)
|
49
|
+
|
50
|
+
# my hack for microdata attributes
|
51
|
+
if obj.respond_to?(:html_schema_type)
|
52
|
+
options[:itemscope] = true
|
53
|
+
options[:itemid] = obj.id
|
54
|
+
|
55
|
+
if obj.html_schema_type.kind_of?(Mida::Vocabulary)
|
56
|
+
options[:itemtype] = obj.html_schema_type.itemtype.source
|
57
|
+
else
|
58
|
+
raise "No vocabulary found (#{obj.html_schema_type})" unless Mida::Vocabulary.find(obj.html_schema_type)
|
59
|
+
options[:itemtype] = obj.html_schema_type
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
return options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "mida"
|
2
|
+
|
3
|
+
class Mida::Vocabulary::Custom < Mida::Vocabulary
|
4
|
+
attr_reader :itemtype
|
5
|
+
def initialize(itemtype)
|
6
|
+
@itemtype = %r{#{itemtype}}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def Mida(itemtype, addition = nil)
|
11
|
+
if itemtype.is_a?(Symbol)
|
12
|
+
itemtype = "http://schema.org/#{itemtype}"
|
13
|
+
end
|
14
|
+
|
15
|
+
found_voc = Mida::Vocabulary.find(itemtype)
|
16
|
+
|
17
|
+
if found_voc == Mida::GenericVocabulary
|
18
|
+
found_voc = Mida::Vocabulary::Custom.new(itemtype)
|
19
|
+
end
|
20
|
+
|
21
|
+
if addition
|
22
|
+
Mida::Vocabulary::Custom.new(found_voc.itemtype.source + "/#{addition}")
|
23
|
+
else
|
24
|
+
found_voc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
require "uri"
|
29
|
+
|
30
|
+
module URI
|
31
|
+
def to_json
|
32
|
+
to_s.to_json
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "chronic_duration"
|
4
|
+
module GreenMonkey
|
5
|
+
module ViewHelper
|
6
|
+
|
7
|
+
# it shortcut for this
|
8
|
+
#%time{:datetime => post.published_at.iso8601(10) }= post.published_at.strftime("%d %h %Y")
|
9
|
+
|
10
|
+
# = time_tag post.created_at
|
11
|
+
# = time_tag post.created_at, format: "%d %h %Y %R%p"
|
12
|
+
# = time_tag post.created_at, itemprop: "datePublished"
|
13
|
+
def time_tag(time, *args)
|
14
|
+
options = args.extract_options!
|
15
|
+
format = options.delete(:format) || :long
|
16
|
+
datetime = time_to_iso8601(time)
|
17
|
+
|
18
|
+
|
19
|
+
if time.acts_like?(:time)
|
20
|
+
title = nil
|
21
|
+
content = args.first || I18n.l(time, format: format)
|
22
|
+
elsif time.kind_of?(Numeric)
|
23
|
+
title = ChronicDuration.output(time, :format => format)
|
24
|
+
content = args.first || distance_of_time_in_words(time)
|
25
|
+
end
|
26
|
+
|
27
|
+
content_tag(:time, content, options.reverse_merge(datetime: datetime, title: title))
|
28
|
+
end
|
29
|
+
|
30
|
+
def time_tag_interval(from, to, *args)
|
31
|
+
options = args.extract_options!
|
32
|
+
format = options.delete(:format) || :long
|
33
|
+
|
34
|
+
datetime = [from, to].map(&method(:time_to_iso8601)).join("/")
|
35
|
+
content = args.first || [from, to].map do |time|
|
36
|
+
if time.acts_like?(:time)
|
37
|
+
I18n.l(from, format: format)
|
38
|
+
else
|
39
|
+
ChronicDuration.output(time, :format => format)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if to.acts_like?(:time)
|
44
|
+
content = content.join(" - ")
|
45
|
+
else
|
46
|
+
content = content.join(" in ")
|
47
|
+
end
|
48
|
+
|
49
|
+
content_tag(:time, content, options.reverse_merge(datetime: datetime))
|
50
|
+
end
|
51
|
+
|
52
|
+
def time_to_iso8601(time)
|
53
|
+
if time.acts_like?(:time)
|
54
|
+
time.iso8601
|
55
|
+
elsif time.kind_of?(Numeric)
|
56
|
+
ChronicDuration.output(time, :format => :iso8601)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module GreenMonkey
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
initializer "load extentions and patches" do
|
6
|
+
require "green_monkey/ext/active_model"
|
7
|
+
ActiveModel::Dirty.send :include, GreenMonkey::ModelHelpers
|
8
|
+
|
9
|
+
require 'green_monkey/ext/view_helper'
|
10
|
+
ActionView::Base.send :include, GreenMonkey::ViewHelper
|
11
|
+
|
12
|
+
require "green_monkey/ext/action_view"
|
13
|
+
require "green_monkey/ext/haml"
|
14
|
+
require "green_monkey/ext/mida"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/green_monkey.rb
ADDED
data/spec/haml_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "pathname"
|
3
|
+
|
4
|
+
$t = 0
|
5
|
+
|
6
|
+
describe "Haml generation" do
|
7
|
+
def render_file(file, options = {})
|
8
|
+
ActionController::Base.new.render_to_string(file: file, locals: options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def render_haml(template, options = {})
|
12
|
+
$t += 1
|
13
|
+
file = File.expand_path(File.dirname(__FILE__) + "/../tmp/#{$t}.haml")
|
14
|
+
File.delete(file) if File.exist?(file)
|
15
|
+
File.open(file, 'w+') {|f| f.write template }
|
16
|
+
render_file(file, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should render itemscope as a boolean attribute" do
|
20
|
+
render_haml("%b{:itemscope => true}").should =~ /<b\s+itemscope\s*>/
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should get AR object" do
|
24
|
+
user = User.create
|
25
|
+
tpl = "%article[user]"
|
26
|
+
str = render_haml(tpl, user: user)
|
27
|
+
|
28
|
+
str.should =~ /itemtype=('|")#{Regexp.escape 'http://example.com/User'}('|")/
|
29
|
+
str.should =~ /itemid=.?#{user.id}/
|
30
|
+
str.should =~ /itemscope/
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should render itemprop attribute" do
|
34
|
+
render_haml("%b[:title] Dada").should =~ /itemprop=.?title/
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should generate valid microdata layout" do
|
38
|
+
post = Post.create(title: "Post 1", body: "Some text")
|
39
|
+
tpl = Pathname.new(__FILE__).dirname.join("post.haml")
|
40
|
+
str = render_file(tpl, post: post)
|
41
|
+
|
42
|
+
doc = Mida::Document.new(str, "http://example.com/")
|
43
|
+
|
44
|
+
props = doc.items[0].properties
|
45
|
+
props['url'][0].to_s.should == "http://example.com/posts/#{post.id}"
|
46
|
+
props['name'][0].should == post.title
|
47
|
+
props['articleBody'][0].should == post.body
|
48
|
+
props['datePublished'][0].to_i.should == post.created_at.to_i
|
49
|
+
|
50
|
+
doc.items[0].id.should == post.id.to_s
|
51
|
+
doc.items[0].type.should == post.html_schema_type.itemtype.source
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'time_tag' do
|
55
|
+
it "should produce itemprop if specified" do
|
56
|
+
str = render_haml("= time_tag(Time.now, itemprop: 'time')")
|
57
|
+
str.should =~ /itemprop="time"/
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should run with time" do
|
61
|
+
time = Time.now
|
62
|
+
str = render_haml("= time_tag(time)", time: time)
|
63
|
+
|
64
|
+
str.should =~ /<time.+datetime=.?#{Regexp.escape time.iso8601}/
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should run with duration" do
|
68
|
+
str = render_haml("= time_tag(time)", time: 3.hours + 30.minutes)
|
69
|
+
str.should =~ /datetime=.PT3H30M/
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should run with time interval of 2 dates" do
|
73
|
+
time = [Time.parse("14 March 1879"), Time.parse("18 April 1955")]
|
74
|
+
|
75
|
+
str = render_haml("= time_tag_interval(*time, :format => '%d %h %Y')", time: time)
|
76
|
+
str.should =~ /<time.+datetime=.?#{Regexp.escape time[0].iso8601}\/#{Regexp.escape time[1].iso8601}/
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should run with date and duration" do
|
80
|
+
time = [Time.parse("6 May 1989"), 150.hours]
|
81
|
+
str = render_haml("= time_tag_interval(*time, :format => :short)", time: time)
|
82
|
+
str.should =~ /<time.+datetime=.?#{Regexp.escape time[0].iso8601}\/P6DT6H/
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/mida_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Mida helper" do
|
4
|
+
it "should find vocabulary class" do
|
5
|
+
Mida(:BlogPosting).should == Mida::SchemaOrg::BlogPosting
|
6
|
+
Mida("http://schema.org/BlogPosting").should == Mida::SchemaOrg::BlogPosting
|
7
|
+
|
8
|
+
custom = Mida("http://t.co/BlogPosting")
|
9
|
+
custom.itemtype.source == "http://t.co/BlogPosting"
|
10
|
+
custom.class.should == Mida::Vocabulary::Custom
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should make Mida::Vocabulary::Custom for extended vocabularies" do
|
14
|
+
extended = Mida(:Blog, :SexJokes)
|
15
|
+
extended.class.should == Mida::Vocabulary::Custom
|
16
|
+
extended.itemtype.source == "http://schema.org/Blog/SexJokes"
|
17
|
+
end
|
18
|
+
end
|
data/spec/model_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveModel do
|
4
|
+
it "should check ActiveModel extention" do
|
5
|
+
ActiveRecord::Base.should respond_to(:html_schema_type)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return schema-type on #html_schema_type" do
|
9
|
+
Post.html_schema_type.should == Post.new.html_schema_type
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return instance of kind Mida::Vocabulary" do
|
13
|
+
Post.new.html_schema_type.should == Mida::SchemaOrg::BlogPosting
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return string on unknown itemtype" do
|
17
|
+
User.html_schema_type.should == "http://example.com/User"
|
18
|
+
end
|
19
|
+
end
|
data/spec/post.haml
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
2
|
+
ENV['RAILS_ENV'] ||= 'development'
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'rails/all'
|
7
|
+
require 'rails/generators'
|
8
|
+
require 'rails/generators/test_case'
|
9
|
+
|
10
|
+
require "green_monkey"
|
11
|
+
|
12
|
+
class TestApp < Rails::Application
|
13
|
+
config.root = File.dirname(__FILE__)
|
14
|
+
config.active_support.deprecation :log
|
15
|
+
#config.logger = Logger.new(STDOUT)
|
16
|
+
config.log_level = :error
|
17
|
+
end
|
18
|
+
|
19
|
+
Rails.application = TestApp
|
20
|
+
|
21
|
+
module Rails
|
22
|
+
def self.root
|
23
|
+
@root ||= File.expand_path("../../tmp/rails", __FILE__)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Rails.application.config.root = Rails.root
|
28
|
+
TestApp.initialize!
|
29
|
+
|
30
|
+
ActiveRecord::Schema.define(:version => 20111023054000) do
|
31
|
+
create_table "posts" do |t|
|
32
|
+
t.string "title"
|
33
|
+
t.text "body"
|
34
|
+
t.string "link"
|
35
|
+
t.datetime "published_at"
|
36
|
+
t.datetime "created_at"
|
37
|
+
t.datetime "updated_at"
|
38
|
+
end
|
39
|
+
|
40
|
+
create_table "users" do |t|
|
41
|
+
t.string "name"
|
42
|
+
t.string "location"
|
43
|
+
t.string "github"
|
44
|
+
t.string "password"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Post < ActiveRecord::Base
|
49
|
+
html_schema_type :BlogPosting
|
50
|
+
end
|
51
|
+
|
52
|
+
class User < ActiveRecord::Base
|
53
|
+
html_schema_type "http://example.com/User"
|
54
|
+
end
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: green_monkey
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pavel Evstigneev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &2152695500 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152695500
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: haml
|
27
|
+
requirement: &2152679260 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.1.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152679260
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mida
|
38
|
+
requirement: &2152675760 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.3.3
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2152675760
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: chronic_duration
|
49
|
+
requirement: &2152674300 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2152674300
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bundler
|
60
|
+
requirement: &2152664740 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.0.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2152664740
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: &2152648240 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 2.7.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2152648240
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec-rails
|
82
|
+
requirement: &2152639820 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2152639820
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: sqlite3
|
93
|
+
requirement: &2152633580 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2152633580
|
102
|
+
description: It hacks Rails and Haml
|
103
|
+
email:
|
104
|
+
- pavel.evst@gmail.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- .gitignore
|
110
|
+
- .rspec
|
111
|
+
- .travis.yml
|
112
|
+
- Gemfile
|
113
|
+
- Gemfile.haml-edge
|
114
|
+
- Gemfile.lock
|
115
|
+
- Gemfile.rails-3.0.11
|
116
|
+
- Gemfile.rails-3.1.3
|
117
|
+
- README.md
|
118
|
+
- Rakefile
|
119
|
+
- green_monkey.gemspec
|
120
|
+
- lib/green_monkey.rb
|
121
|
+
- lib/green_monkey/ext/action_view.rb
|
122
|
+
- lib/green_monkey/ext/active_model.rb
|
123
|
+
- lib/green_monkey/ext/haml.rb
|
124
|
+
- lib/green_monkey/ext/mida.rb
|
125
|
+
- lib/green_monkey/ext/view_helper.rb
|
126
|
+
- lib/green_monkey/railtie.rb
|
127
|
+
- spec/haml_spec.rb
|
128
|
+
- spec/mida_spec.rb
|
129
|
+
- spec/model_spec.rb
|
130
|
+
- spec/post.haml
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- tmp/rails/config/database.yml
|
133
|
+
- tmp/rails/config/environments/development.rb
|
134
|
+
homepage: https://github.com/paxa/green_monkey
|
135
|
+
licenses: []
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: 1.2.0
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.10
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: Rails and Haml microdata layout helpers
|
158
|
+
test_files: []
|