snipp 0.1.3 → 0.1.4
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/config/locales/snipp.yml +1 -1
- data/lib/snipp/config.rb +2 -2
- data/lib/snipp/markups/html.rb +48 -57
- data/lib/snipp/version.rb +1 -1
- data/spec/snipp/markups/html_spec.rb +164 -35
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 465823834c0c140c8671238c418ca36b48e9ec9b
|
4
|
+
data.tar.gz: c8b1abe51f22938ff64b7797427823a3ddf6bfac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d4b3efb494b9c37fbde22e170cc29b5e582c7fa22775b73680ec572d94a369343c59c5894b6e6a195fad38ed75cfb1ecd767face7178eb90223a0ad951d7854
|
7
|
+
data.tar.gz: 0c5a136614681a4908db3be3cc1fd7896b56ecbdeba44d694d21dc8e30f4b5360d455427aaf7595caf9ef1a4ec577e95ec715682568d8e99bf6de1cf51fa023f
|
data/.travis.yml
CHANGED
data/config/locales/snipp.yml
CHANGED
data/lib/snipp/config.rb
CHANGED
@@ -12,7 +12,7 @@ module Snipp
|
|
12
12
|
|
13
13
|
class Configuration #:nodoc:
|
14
14
|
include ActiveSupport::Configurable
|
15
|
-
config_accessor :root_url, :markup, :
|
15
|
+
config_accessor :root_url, :markup, :html_meta
|
16
16
|
|
17
17
|
def param_name
|
18
18
|
config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name
|
@@ -26,7 +26,7 @@ module Snipp
|
|
26
26
|
|
27
27
|
configure do |config|
|
28
28
|
config.markup = :microdata
|
29
|
-
config.
|
29
|
+
config.html_meta = {
|
30
30
|
title: '',
|
31
31
|
description: '',
|
32
32
|
keywords: '',
|
data/lib/snipp/markups/html.rb
CHANGED
@@ -3,49 +3,30 @@ module Snipp
|
|
3
3
|
module Html
|
4
4
|
|
5
5
|
def set_html_meta args, options = {}
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}.merge(options)
|
10
|
-
|
11
|
-
link = args.delete(:link)
|
12
|
-
html_meta.merge!(link: link) if link
|
13
|
-
|
14
|
-
Snipp.config.html_meta_tags.each do |name, content|
|
15
|
-
value = html_meta_contents(name, content, args[name], i18n_options)
|
16
|
-
html_meta[name] = value unless value.blank?
|
17
|
-
end
|
6
|
+
merger = lambda {|key, old, new| Hash === old && Hash === new ? old.merge(new, &merger) : new }
|
7
|
+
html_meta.merge!(args, &merger)
|
8
|
+
meta_options.merge!(options)
|
18
9
|
end
|
19
10
|
|
20
11
|
def set_html_meta! args
|
21
|
-
@html_meta =
|
22
|
-
link = args.delete(:link)
|
23
|
-
html_meta.merge!(link: link) if link
|
24
|
-
|
25
|
-
args.each do |name, content|
|
26
|
-
html_meta[name] = html_meta_contents(name, content, content, {}) if content
|
27
|
-
end
|
12
|
+
@html_meta = args
|
28
13
|
end
|
29
14
|
|
30
15
|
def html_meta_tags
|
31
16
|
result = ''
|
32
|
-
|
17
|
+
|
33
18
|
meta_link = html_meta.delete(:link)||{}
|
34
19
|
|
35
|
-
#
|
20
|
+
# Title
|
36
21
|
title = html_meta.delete(:title)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
if content.is_a?(Hash)
|
44
|
-
result << build_meta_property_tags(name, content)
|
22
|
+
title = select_content(:title) if title.empty?
|
23
|
+
result << content_tag(:title, title) unless title.blank?
|
24
|
+
|
25
|
+
html_meta.each do |name, value|
|
26
|
+
if value.is_a?(Hash)
|
27
|
+
result << build_property_contents(value, name, name)
|
45
28
|
else
|
46
|
-
|
47
|
-
result << tag(:meta, name: name, content: c) unless c.blank?
|
48
|
-
end
|
29
|
+
result << build_contents(name, value)
|
49
30
|
end
|
50
31
|
end
|
51
32
|
|
@@ -57,45 +38,55 @@ module Snipp
|
|
57
38
|
end
|
58
39
|
|
59
40
|
private
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
41
|
+
def html_meta
|
42
|
+
@html_meta ||= Snipp.config.html_meta.dup
|
43
|
+
end
|
44
|
+
|
45
|
+
def meta_options
|
46
|
+
@meta_options ||= { default: '' }
|
47
|
+
end
|
48
|
+
|
49
|
+
def select_content key, options = {}
|
50
|
+
#puts key
|
51
|
+
options[:scope] ||= "views.#{params[:controller].gsub(%r{/}, '.')}.#{params[:action]}.meta"
|
52
|
+
options[:default] ||= 'default.meta'
|
53
|
+
content = I18n.t("#{options[:scope]}.#{key}" ,meta_options)
|
54
|
+
content = I18n.t("#{options[:default]}.#{key}" ,default: '') if content.empty?
|
55
|
+
content
|
56
|
+
end
|
57
|
+
|
58
|
+
# <meta name="xxx" content="yyy" />
|
59
|
+
def build_contents name, content
|
60
|
+
result = ''
|
61
|
+
Array(content).each do |content|
|
62
|
+
#puts "#{name} => #{content}"
|
63
|
+
content = select_content(name) if content.empty?
|
64
|
+
result << tag(:meta, name: name, content: content) unless content.empty?
|
73
65
|
end
|
74
66
|
result
|
75
67
|
end
|
76
68
|
|
77
|
-
|
69
|
+
# <meta property="xxx:yyy" content="zzz" />
|
70
|
+
def build_property_contents values, property, key
|
78
71
|
result = ''
|
79
|
-
if
|
80
|
-
|
81
|
-
result <<
|
72
|
+
if values.is_a?(Hash)
|
73
|
+
values.each do |k, v|
|
74
|
+
result << build_property_contents(v, "#{property}:#{k}", "#{key}.#{k}")
|
82
75
|
end
|
83
76
|
else
|
84
|
-
Array(
|
85
|
-
if
|
86
|
-
result <<
|
77
|
+
Array(values).each do |content|
|
78
|
+
if content.is_a?(Hash)
|
79
|
+
result << build_contents(content, property, key)
|
87
80
|
else
|
88
|
-
|
81
|
+
#puts "#{key} => #{content}"
|
82
|
+
content = select_content(key) if content.empty?
|
83
|
+
result << tag(:meta, property: "#{property}", content: content) unless content.empty?
|
89
84
|
end
|
90
85
|
end
|
91
86
|
end
|
92
87
|
result
|
93
88
|
end
|
94
89
|
|
95
|
-
def html_meta
|
96
|
-
@html_meta ||= {}
|
97
|
-
end
|
98
|
-
|
99
90
|
end
|
100
91
|
end
|
101
92
|
end
|
data/lib/snipp/version.rb
CHANGED
@@ -1,51 +1,180 @@
|
|
1
1
|
# coding: UTF-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
class Snipp::Markup::Html::Spec
|
5
|
-
|
6
|
-
DEFAULT_SCOPE = [:default, :meta]
|
7
|
-
PAGE_SCOPE = [:views, :snipp, :html, :meta]
|
8
|
-
|
9
|
-
META = {
|
10
|
-
title: I18n.t(:title ,scope: PAGE_SCOPE, value: "Embedding Values"),
|
11
|
-
description: I18n.t(:description ,scope: PAGE_SCOPE),
|
12
|
-
keywords: I18n.t(:keywords ,scope: DEFAULT_SCOPE)
|
13
|
-
}
|
14
|
-
OG = {
|
15
|
-
site_name: I18n.t("og.site_name" ,scope: DEFAULT_SCOPE),
|
16
|
-
title: I18n.t("og.title" ,scope: PAGE_SCOPE ,text: "Insert"),
|
17
|
-
description: I18n.t("og.description" ,scope: DEFAULT_SCOPE),
|
18
|
-
type: "article"
|
19
|
-
}
|
20
|
-
LINK = {
|
21
|
-
canonical: 'http://127.0.0.1/canonical'
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
4
|
describe Snipp::Markup::Html do
|
26
5
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
6
|
+
let(:view) do
|
7
|
+
clazz = Class.new do
|
8
|
+
include ActionView::Helpers
|
9
|
+
include Snipp::Markup::Html
|
10
|
+
end
|
11
|
+
view = clazz.new
|
12
|
+
view.stub(:params).and_return(params)
|
13
|
+
view
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:params) { { controller: "snipp", action: "html" } }
|
17
|
+
|
18
|
+
describe "#set_html_meta" do
|
19
|
+
let(:args) do
|
20
|
+
{
|
21
|
+
title: "Spec Title",
|
22
|
+
description: "Spec Description",
|
23
|
+
keywords: "Spec Keywords",
|
24
|
+
og: {
|
25
|
+
site_name: "Spec OG Site Name",
|
26
|
+
title: "Spec OG Title",
|
27
|
+
description: "Spec OG Description",
|
28
|
+
type: "article",
|
29
|
+
image: "https://github.com/yulii/snipp"
|
30
|
+
},
|
31
|
+
link: {
|
32
|
+
canonical: "https://github.com/yulii/snipp"
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:object) do
|
38
|
+
view.set_html_meta(args.dup)
|
39
|
+
view.send(:html_meta)
|
40
|
+
end
|
41
|
+
|
42
|
+
it do
|
43
|
+
expect(object).to include(args)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when do nothing" do
|
47
|
+
let(:params) { { controller: "nothing", action: "undefined" } }
|
48
|
+
let(:args) do
|
49
|
+
Snipp.config.html_meta.select {|k, v| not v.nil? and not v.empty? }
|
50
|
+
end
|
51
|
+
|
52
|
+
it do
|
53
|
+
expect(object).to include(args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#html_meta_tags" do
|
59
|
+
let(:args) do
|
60
|
+
{
|
61
|
+
title: "Spec Title",
|
62
|
+
description: "Spec Description",
|
63
|
+
keywords: "Spec Keywords",
|
64
|
+
og: {
|
65
|
+
site_name: "Spec OG Site Name",
|
66
|
+
title: "Spec OG Title",
|
67
|
+
description: "Spec OG Description",
|
68
|
+
type: "article",
|
69
|
+
url: "https://github.com/yulii/snipp",
|
70
|
+
image: "https://github.com/yulii/snipp"
|
71
|
+
},
|
72
|
+
link: {
|
73
|
+
canonical: "https://github.com/yulii/snipp"
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
let(:object) do
|
79
|
+
view.set_html_meta(args.dup)
|
80
|
+
view.send(:html_meta_tags)
|
81
|
+
end
|
82
|
+
|
83
|
+
it { expect(object).to include(view.content_tag(:title, args[:title])) }
|
84
|
+
[:description, :keywords].each do |name|
|
85
|
+
it { expect(object).to include(view.tag(:meta, name: name, content: args[name])) }
|
86
|
+
end
|
87
|
+
[:site_name, :title, :description, :type, :url, :image].each do |property|
|
88
|
+
it { expect(object).to include(view.tag(:meta, property: "og:#{property}", content: args[:og][property])) }
|
89
|
+
end
|
90
|
+
[:canonical].each do |rel|
|
91
|
+
it { expect(object).to include(view.tag(:link, rel: rel, href: args[:link][rel])) }
|
92
|
+
end
|
93
|
+
|
31
94
|
end
|
32
95
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
96
|
+
describe "#select_content" do
|
97
|
+
let(:options) do
|
98
|
+
{ value: 'Value', default: '' }
|
99
|
+
end
|
100
|
+
|
101
|
+
let(:object) do
|
102
|
+
view.stub(:meta_options).and_return(options)
|
103
|
+
view
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when there is I18n dictionary of controller/action" do
|
107
|
+
[:title, :description].each do |key|
|
108
|
+
it { expect(object.send(:select_content, key)).to eq(I18n.t("views.snipp.html.meta.#{key}", options)) }
|
37
109
|
end
|
38
110
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
111
|
+
|
112
|
+
context "when there is NOT I18n dictionary of controller/action" do
|
113
|
+
let(:params) { { controller: "nothing", action: "undefined" } }
|
114
|
+
|
115
|
+
[:title, :description, :keywords].each do |key|
|
116
|
+
it { expect(object.send(:select_content, key)).to eq(I18n.t("default.meta.#{key}")) }
|
117
|
+
end
|
118
|
+
[:site_name, :title, :description, :type].each do |property|
|
119
|
+
it { expect(object.send(:select_content, "og.#{property}")).to eq(I18n.t("default.meta.og.#{property}")) }
|
42
120
|
end
|
43
121
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
122
|
+
|
123
|
+
context "when there is no I18n dictionaries" do
|
124
|
+
[:nothing, :undefined].each do |key|
|
125
|
+
it { expect(view.send(:select_content, key)).to be_empty }
|
47
126
|
end
|
48
127
|
end
|
49
128
|
end
|
50
129
|
|
130
|
+
describe "#build_contents" do
|
131
|
+
context "when content is Scalar" do
|
132
|
+
it do
|
133
|
+
expect(
|
134
|
+
view.send(:build_contents, :name, 'content')
|
135
|
+
).to eq(
|
136
|
+
view.tag(:meta, name: :name, content: 'content')
|
137
|
+
)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
context "when content is Array" do
|
141
|
+
it do
|
142
|
+
expect(
|
143
|
+
view.send(:build_contents, 'robots', ['index', 'follow'])
|
144
|
+
).to eq(
|
145
|
+
view.tag(:meta, name: 'robots', content: 'index') +
|
146
|
+
view.tag(:meta, name: 'robots', content: 'follow')
|
147
|
+
)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
context "when content is empty string" do
|
151
|
+
it { expect(view.send(:build_contents, :name, '')).to be_empty }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when HTML document has rendered" do
|
156
|
+
before(:all) do
|
157
|
+
Snipp::Hooks.init
|
158
|
+
visit "/html"
|
159
|
+
end
|
160
|
+
|
161
|
+
let(:scope) { 'views.snipp.html.meta' }
|
162
|
+
let(:default) { 'default.meta' }
|
163
|
+
let(:url) { 'http://127.0.0.1/canonical' }
|
164
|
+
|
165
|
+
# HTML Meta
|
166
|
+
it { expect(page).to have_selector("title", count: 1, text: I18n.t("#{scope}.title" ,value: "Embedding Values")) }
|
167
|
+
it { expect(page).to have_selector("meta[name=\"description\"][content=\"#{I18n.t("#{scope}.description")}\"]", count: 1) }
|
168
|
+
it { expect(page).to have_selector("meta[name=\"keywords\"][content=\"#{I18n.t("#{default}.keywords")}\"]", count: 1) }
|
169
|
+
|
170
|
+
# Open Graph
|
171
|
+
it { expect(page).to have_selector("meta[property=\"og:site_name\"][content=\"#{I18n.t("#{default}.og.site_name")}\"]", count: 1) }
|
172
|
+
it { expect(page).to have_selector("meta[property=\"og:type\"][content=\"#{I18n.t("#{default}.og.type")}\"]", count: 1) }
|
173
|
+
it { expect(page).to have_selector("meta[property=\"og:title\"][content=\"#{I18n.t("#{scope}.og.title" ,text: "Insert")}\"]", count: 1) }
|
174
|
+
it { expect(page).to have_selector("meta[property=\"og:description\"][content=\"#{I18n.t("#{default}.og.description")}\"]", count: 1) }
|
175
|
+
|
176
|
+
# Link Tags
|
177
|
+
it { expect(page).to have_selector("link[rel=\"canonical\"][href=\"#{url}\"]", count: 1) }
|
178
|
+
end
|
179
|
+
|
51
180
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snipp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yulii
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|