orthor 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/lib/orthor.rb +21 -21
- data/lib/orthor/templates.rb +16 -14
- data/lib/orthor_helper.rb +45 -4
- data/spec/orthor/templates_spec.rb +11 -9
- data/spec/orthor_spec.rb +11 -0
- data/spec/spec_helper.rb +1 -0
- metadata +5 -5
data/README.md
CHANGED
@@ -77,7 +77,7 @@ If you don't want to use the with_orthor_* helpers you can use named templates:
|
|
77
77
|
</div>)
|
78
78
|
template :blog_entry_brief, %(
|
79
79
|
<div class="blog-entry">
|
80
|
-
<h2><a href="{{
|
80
|
+
<h2><a href="{{orthor_url}}">{{title}}</a></h2>
|
81
81
|
<p>{{published_on}}</p>
|
82
82
|
<div class="blog-content">{{wysiwyg.blurb}}</div>
|
83
83
|
</div>)
|
@@ -121,7 +121,7 @@ These tags are available to all content:
|
|
121
121
|
{{author}} - a hash of the original authors details
|
122
122
|
{{updater}} - a hash of the updater details
|
123
123
|
{{published_on}} - the date your content was published
|
124
|
-
{{
|
124
|
+
{{orthor_url}} - the URL for your content as defined in Orthor, or auto generated as /:template-prefix/category-id/content-id
|
125
125
|
{{template}} - the name of the template this content was created from
|
126
126
|
{{category}} - a hash of this items category details
|
127
127
|
|
data/lib/orthor.rb
CHANGED
@@ -13,6 +13,23 @@ class Orthor
|
|
13
13
|
attr_accessor :cache, :cache_expiry, :site_id
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.content(id, options = {})
|
17
|
+
Templates.render(get(:content_items, id), options[:template])
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.query(id, options = {})
|
21
|
+
Templates.render(get(:queries, id), options[:template])
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.category(id, options = {})
|
25
|
+
id = options[:page] && options[:page].to_i > 1 ? "#{id}-#{options[:page]}" : id
|
26
|
+
Templates.render(get(:categories, id), options[:template])
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.feed(id)
|
30
|
+
get(:feeds, id)
|
31
|
+
end
|
32
|
+
|
16
33
|
def self.load_content
|
17
34
|
raise "No point loading content when you don't have a cache setup" unless cache
|
18
35
|
|
@@ -31,22 +48,6 @@ class Orthor
|
|
31
48
|
end
|
32
49
|
end
|
33
50
|
|
34
|
-
def self.content(id, template = nil)
|
35
|
-
Templates.render(get(:content_items, id), template)
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.query(id, template = nil)
|
39
|
-
Templates.render(get(:queries, id), template)
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.category(id, template = nil)
|
43
|
-
Templates.render(get(:categories, id), template)
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.feed(id)
|
47
|
-
get(:feeds, id)
|
48
|
-
end
|
49
|
-
|
50
51
|
def self.render(items, template)
|
51
52
|
Templates.render(items, template)
|
52
53
|
end
|
@@ -65,7 +66,7 @@ class Orthor
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def self.setup(&block)
|
68
|
-
raise ArgumentError unless block_given?
|
69
|
+
raise ArgumentError, "Block required" unless block_given?
|
69
70
|
self.cache = false # default
|
70
71
|
|
71
72
|
class_eval &block
|
@@ -77,10 +78,10 @@ private
|
|
77
78
|
|
78
79
|
begin
|
79
80
|
suffix = type == :feeds ? "rss" : "json"
|
80
|
-
|
81
|
+
cache_key = "#{id}-#{type}"
|
81
82
|
path = "/#{site_id}/#{type}/#{id}.#{suffix}"
|
82
83
|
|
83
|
-
resp = cache ? get_cached_content(
|
84
|
+
resp = cache ? get_cached_content(cache_key, path) : get_response(path)
|
84
85
|
|
85
86
|
return resp unless suffix == "json"
|
86
87
|
|
@@ -119,8 +120,7 @@ private
|
|
119
120
|
response_content = r.body
|
120
121
|
break
|
121
122
|
end
|
122
|
-
rescue
|
123
|
-
break
|
123
|
+
rescue
|
124
124
|
end
|
125
125
|
end
|
126
126
|
response_content
|
data/lib/orthor/templates.rb
CHANGED
@@ -37,32 +37,25 @@ class Orthor
|
|
37
37
|
def self.parse(item, template_name_or_mapping)
|
38
38
|
return "" if item == ""
|
39
39
|
|
40
|
-
|
41
|
-
unless item.is_a?(Array)
|
42
|
-
if item["type"] == "category"
|
43
|
-
item = item["content"]
|
44
|
-
else
|
45
|
-
item = [item]
|
46
|
-
end
|
47
|
-
end
|
40
|
+
content_items = content_items_from(item)
|
48
41
|
|
49
|
-
|
50
|
-
markup = template_for(
|
42
|
+
content_items.collect do |content|
|
43
|
+
markup = template_for(content, template_name_or_mapping)
|
51
44
|
|
52
|
-
|
45
|
+
content.inject(markup) do |html, (key, val)|
|
53
46
|
if val.is_a?(String) && html.include?("{{#{key}.blurb}}")
|
54
47
|
val = "#{val.to_s.gsub(/<\/?[^>]*>/, "")[0..150]}..."
|
55
48
|
key = "#{key}.blurb"
|
56
49
|
|
57
50
|
html = html.gsub("{{#{key}}}", val.to_s)
|
58
51
|
elsif val.is_a?(Hash) && html.include?("{{#{key}.")
|
59
|
-
# we've got something like
|
52
|
+
# we've got something like author.email
|
60
53
|
html = val.inject(html) { |h, (k, v)| h = h.gsub("{{#{key}.#{k}}}", v.to_s) }
|
61
54
|
else
|
62
55
|
html = html.gsub("{{#{key}}}", val.to_s)
|
63
56
|
end
|
64
57
|
end
|
65
|
-
end.join("")
|
58
|
+
end.join("")
|
66
59
|
rescue Orthor::Templates::Unknown => e
|
67
60
|
raise e
|
68
61
|
rescue => e
|
@@ -89,6 +82,15 @@ class Orthor
|
|
89
82
|
markup
|
90
83
|
end
|
91
84
|
|
92
|
-
|
85
|
+
def self.content_items_from(item)
|
86
|
+
if item.is_a?(Array)
|
87
|
+
content_items = item # content queries return an array
|
88
|
+
elsif item["type"] == "category"
|
89
|
+
content_items = item["content"]
|
90
|
+
else
|
91
|
+
content_items = [item]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
private_class_method :parse, :template_for, :content_items_from
|
93
95
|
end
|
94
96
|
end
|
data/lib/orthor_helper.rb
CHANGED
@@ -4,9 +4,9 @@ module OrthorHelper
|
|
4
4
|
render_orthor_result(:content, id, &blk)
|
5
5
|
end
|
6
6
|
|
7
|
-
def with_orthor_category(id, &blk)
|
7
|
+
def with_orthor_category(id, page = nil, &blk)
|
8
8
|
return unless block_given?
|
9
|
-
render_orthor_result(:category, id, &blk)
|
9
|
+
render_orthor_result(:category, id, page, &blk)
|
10
10
|
end
|
11
11
|
|
12
12
|
def with_orthor_query(id, &blk)
|
@@ -14,12 +14,53 @@ module OrthorHelper
|
|
14
14
|
render_orthor_result(:query, id, &blk)
|
15
15
|
end
|
16
16
|
|
17
|
+
def orthor_pagination(category_id, options = {})
|
18
|
+
return unless defined?(request) && defined?(params)
|
19
|
+
|
20
|
+
current_page = params[:page] ? params[:page].to_i : 1
|
21
|
+
category = Orthor.category(category_id, :page => current_page)
|
22
|
+
return if category == "" || category["total_pages"] == 1 # no pagination required
|
23
|
+
|
24
|
+
options[:prev_label] ||= "←"
|
25
|
+
options[:next_label] ||= "→"
|
26
|
+
|
27
|
+
if params[:page] && params[:page].to_i > 0
|
28
|
+
href = request.url
|
29
|
+
else
|
30
|
+
href = request.url + (request.url.include?("?") ? "&" : "?") + "page=#{current_page}"
|
31
|
+
end
|
32
|
+
|
33
|
+
previous_link = if current_page > 1
|
34
|
+
%!<a class="previous" href="#{href.gsub("page=#{current_page}", "page=#{current_page - 1}")}">#{options[:prev_label]}</a>!
|
35
|
+
else
|
36
|
+
%!<span class="previous disabled">#{options[:prev_label]}</span>!
|
37
|
+
end
|
38
|
+
next_link = if current_page < category["total_pages"]
|
39
|
+
%!<a class="next" href="#{href.gsub("page=#{current_page}", "page=#{current_page + 1}")}">#{options[:next_label]}</a>!
|
40
|
+
else
|
41
|
+
%!<span class="next disabled">#{options[:next_label]}</span>!
|
42
|
+
end
|
43
|
+
|
44
|
+
html = <<-HTML
|
45
|
+
<div class="orthor-pagination">
|
46
|
+
#{previous_link}
|
47
|
+
#{next_link}
|
48
|
+
</div>
|
49
|
+
HTML
|
50
|
+
|
51
|
+
make_safe(html)
|
52
|
+
end
|
53
|
+
|
17
54
|
private
|
18
|
-
def render_orthor_result(method, id, &blk)
|
55
|
+
def render_orthor_result(method, id, page = nil, &blk)
|
19
56
|
html = defined?(capture) ? capture(&blk) : yield
|
20
|
-
parsed_html = Orthor.send(method, id, html)
|
57
|
+
parsed_html = make_safe(Orthor.send(method, id, :page => page, :template => html))
|
21
58
|
defined?(concat) ? concat(parsed_html) : parsed_html
|
22
59
|
end
|
60
|
+
|
61
|
+
def make_safe(html)
|
62
|
+
html.respond_to?(:html_safe) ? html.html_safe : html
|
63
|
+
end
|
23
64
|
end
|
24
65
|
|
25
66
|
ActionView::Base.send(:include, OrthorHelper) if defined?(ActionView::Base)
|
@@ -8,6 +8,8 @@ describe Orthor::Templates do
|
|
8
8
|
:body => File.join(SPEC_DIR, 'resources', 'query.json'))
|
9
9
|
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/categories/category.json",
|
10
10
|
:body => File.join(SPEC_DIR, 'resources', 'category.json'))
|
11
|
+
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/categories/category-2.json",
|
12
|
+
:body => File.join(SPEC_DIR, 'resources', 'category-2.json'))
|
11
13
|
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/queries/varied.json",
|
12
14
|
:body => File.join(SPEC_DIR, 'resources', 'varied_content.json'))
|
13
15
|
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/feeds/feed.rss",
|
@@ -33,7 +35,7 @@ describe Orthor::Templates do
|
|
33
35
|
|
34
36
|
describe "utf8" do
|
35
37
|
it "should be able to parse utf8" do
|
36
|
-
Orthor.content("utf8", :brief).should == "<h2>Q&A with Tobias Lütke of Shopify - (37signals)</h2>"
|
38
|
+
Orthor.content("utf8", :template => :brief).should == "<h2>Q&A with Tobias Lütke of Shopify - (37signals)</h2>"
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
@@ -55,22 +57,22 @@ describe Orthor::Templates do
|
|
55
57
|
|
56
58
|
describe "nested attributes" do
|
57
59
|
it "should support User.Email, User.First name, User.Last name" do
|
58
|
-
Orthor.content("content", :user).should == "<div>demo@orthor.com</div><div>Bob Demo</div>"
|
60
|
+
Orthor.content("content", :template => :user).should == "<div>demo@orthor.com</div><div>Bob Demo</div>"
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
62
64
|
describe "a content item" do
|
63
65
|
it "should display content using the named template" do
|
64
|
-
Orthor.content("content", :basic).should == %!<h2>What is Orthor</h2><div class="content"><h2>So what is Orthor really??</h2></div>!
|
66
|
+
Orthor.content("content", :template => :basic).should == %!<h2>What is Orthor</h2><div class="content"><h2>So what is Orthor really??</h2></div>!
|
65
67
|
end
|
66
68
|
|
67
69
|
it "should respect given template name" do
|
68
|
-
Orthor.content("content", :brief).should == %!<h2>What is Orthor</h2>!
|
70
|
+
Orthor.content("content", :template => :brief).should == %!<h2>What is Orthor</h2>!
|
69
71
|
end
|
70
72
|
|
71
73
|
describe "blurb" do
|
72
74
|
it "should truncate some of the text, strip html and add ..." do
|
73
|
-
Orthor.content("content", :blurb).should == "<div>So what is Orthor really??...</div>"
|
75
|
+
Orthor.content("content", :template => :blurb).should == "<div>So what is Orthor really??...</div>"
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
@@ -83,13 +85,13 @@ describe Orthor::Templates do
|
|
83
85
|
|
84
86
|
describe "a content query" do
|
85
87
|
it "should render the template for each item" do
|
86
|
-
Orthor.query("query", :brief).should == %!<h2>User Manual updated</h2><h2>Account event tracking</h2><h2>Tutorials have been updated</h2>!
|
88
|
+
Orthor.query("query", :template => :brief).should == %!<h2>User Manual updated</h2><h2>Account event tracking</h2><h2>Tutorials have been updated</h2>!
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
92
|
describe "a category" do
|
91
93
|
it "should render the template for each item" do
|
92
|
-
Orthor.category("category", :brief).should == %!<h2>User Manual updated</h2><h2>Account event tracking</h2><h2>Tutorials have been updated</h2><h2>Content Queries have landed in Orthor</h2>!
|
94
|
+
Orthor.category("category", :template => :brief).should == %!<h2>User Manual updated</h2><h2>Account event tracking</h2><h2>Tutorials have been updated</h2><h2>Content Queries have landed in Orthor</h2>!
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
@@ -109,7 +111,7 @@ describe Orthor::Templates do
|
|
109
111
|
|
110
112
|
describe "with a non-existant template" do
|
111
113
|
it "should raise an error" do
|
112
|
-
lambda { Orthor.category("category", :blah) }.should raise_error(Orthor::Templates::Unknown)
|
114
|
+
lambda { Orthor.category("category", :template => :blah) }.should raise_error(Orthor::Templates::Unknown)
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
@@ -124,7 +126,7 @@ describe Orthor::Templates do
|
|
124
126
|
|
125
127
|
describe "with a named map" do
|
126
128
|
it "should find the template from the map" do
|
127
|
-
Orthor.content("content", :listing).should == "<h2>What is Orthor</h2>"
|
129
|
+
Orthor.content("content", :template => :listing).should == "<h2>What is Orthor</h2>"
|
128
130
|
end
|
129
131
|
end
|
130
132
|
|
data/spec/orthor_spec.rb
CHANGED
@@ -8,6 +8,8 @@ describe Orthor do
|
|
8
8
|
:body => File.join(SPEC_DIR, 'resources', 'query.json'))
|
9
9
|
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/categories/category.json",
|
10
10
|
:body => File.join(SPEC_DIR, 'resources', 'category.json'))
|
11
|
+
FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/categories/category-2.json",
|
12
|
+
:body => File.join(SPEC_DIR, 'resources', 'category-2.json'))
|
11
13
|
|
12
14
|
# account and cache loading resources
|
13
15
|
[ "top-level", "second-level" ].each do |name|
|
@@ -84,6 +86,14 @@ describe Orthor do
|
|
84
86
|
it 'should be able to fetch categories' do
|
85
87
|
Orthor.category("category").to_s.should include("The User Manual has recently had a big overhaul")
|
86
88
|
end
|
89
|
+
|
90
|
+
describe "category pages" do
|
91
|
+
it "should support optional page argument" do
|
92
|
+
Orthor.category("category", :page => 2)["content"].length.should == 1
|
93
|
+
Orthor.category("category", :page => 1)["content"].length.should == 4
|
94
|
+
Orthor.category("category", :page => nil)["content"].length.should == 4
|
95
|
+
end
|
96
|
+
end
|
87
97
|
end
|
88
98
|
|
89
99
|
describe "loading cache" do
|
@@ -191,6 +201,7 @@ describe Orthor do
|
|
191
201
|
it "should use www.orthor.com if content.orthor.com is down" do
|
192
202
|
# initial request will go to content.orthor.com and return an empty string
|
193
203
|
Orthor.content("missing").should_not == ""
|
204
|
+
Orthor.content("missing")["title"].should == "What is Orthor"
|
194
205
|
end
|
195
206
|
end
|
196
207
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orthor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Anthony Langhorne
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-03-20 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|