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 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="{{url}}">{{title}}</a></h2>
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
- {{url}} - the URL for your content as defined in Orthor, or auto generated as /:template-prefix/category-id/content-id
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
 
@@ -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
- key = "#{id}-#{type}"
81
+ cache_key = "#{id}-#{type}"
81
82
  path = "/#{site_id}/#{type}/#{id}.#{suffix}"
82
83
 
83
- resp = cache ? get_cached_content(key, path) : get_response(path)
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 => e
123
- break
123
+ rescue
124
124
  end
125
125
  end
126
126
  response_content
@@ -37,32 +37,25 @@ class Orthor
37
37
  def self.parse(item, template_name_or_mapping)
38
38
  return "" if item == ""
39
39
 
40
- # ensure we're dealing with an array
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
- item.collect do |c|
50
- markup = template_for(c, template_name_or_mapping)
42
+ content_items.collect do |content|
43
+ markup = template_for(content, template_name_or_mapping)
51
44
 
52
- c.inject(markup) do |html, (key, val)|
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 Author.Email
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
- private_class_method :parse, :template_for
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
@@ -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] ||= "&larr;"
25
+ options[:next_label] ||= "&rarr;"
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
 
@@ -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
@@ -1,6 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
3
  require 'fake_web'
4
+ require 'rr'
4
5
  require File.join(File.dirname(__FILE__), '..', 'lib', 'orthor')
5
6
 
6
7
  SPEC_DIR = File.dirname(__FILE__) unless defined? SPEC_DIR
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: 19
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 4
10
- version: 0.1.4
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: 2010-06-10 00:00:00 +10:00
18
+ date: 2011-03-20 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency