orthor 0.1.1 → 0.1.2

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.
Files changed (4) hide show
  1. data/README.md +20 -20
  2. data/lib/orthor.rb +49 -14
  3. data/spec/orthor_spec.rb +54 -0
  4. metadata +2 -2
data/README.md CHANGED
@@ -44,25 +44,25 @@ If you do not provide a template_name to render your content with, you will get
44
44
  Orthor returns all of your content in JSON so to make the job of translating JSON -> HTML easier, we provide some templating help:
45
45
 
46
46
  Orthor::Templates.define do
47
- template :basic_content, %(<div>{{Content}}</div>)
47
+ template :basic_content, %(<div>{{content}}</div>)
48
48
 
49
49
  template :blog_entry, %(
50
50
  <div class="blog-entry">
51
- <h2>{{Title}}</h2>
52
- <div class="blog-content">{{Wysiwyg}}</div>
51
+ <h2>{{title}}</h2>
52
+ <div class="blog-content">{{wysiwyg}}</div>
53
53
  </div>)
54
54
  template :blog_entry_brief, %(
55
55
  <div class="blog-entry">
56
- <h2><a href="{{URL}}">{{Title}}</a></h2>
57
- <p>{{Published on}}</p>
58
- <div class="blog-content">{{Wysiwyg.blurb}}</div>
56
+ <h2><a href="{{url}}">{{title}}</a></h2>
57
+ <p>{{published_on}}</p>
58
+ <div class="blog-content">{{wysiwyg.blurb}}</div>
59
59
  </div>)
60
60
 
61
61
  template :user_manual, %(
62
62
  <div class="user-manual-entry">
63
- <h2>{{Title}}</h2>
64
- <p class="last-updated">Last updated: {{Updated on}}</p>
65
- <div class="content">{{Wysiwyg}}</div>
63
+ <h2>{{title}}</h2>
64
+ <p class="last-updated">Last updated: {{updated_on}}</p>
65
+ <div class="content">{{wysiwyg}}</div>
66
66
  </div>)
67
67
 
68
68
  mapping :detail_templates, {
@@ -91,22 +91,22 @@ A call to Orthor.category("blog", :blog_types) means that any content item using
91
91
  These tags are available to all content:
92
92
 
93
93
  {{id}} - the orthor id of your content item
94
- {{Title}} - your content title
95
- {{Created on}} - the date your content was created
96
- {{Updated on}} - the date your content was last updated
97
- {{Author}} - a hash of the original authors details
98
- {{Updater}} - a hash of the updater details
99
- {{Published on}} - the date your content was published
100
- {{URL}} - the URL for your content as defined in Orthor, or auto generated as /:template-prefix/category-id/content-id
94
+ {{title}} - your content title
95
+ {{created_on}} - the date your content was created
96
+ {{updated_on}} - the date your content was last updated
97
+ {{author}} - a hash of the original authors details
98
+ {{updater}} - a hash of the updater details
99
+ {{published_on}} - the date your content was published
100
+ {{url}} - the URL for your content as defined in Orthor, or auto generated as /:template-prefix/category-id/content-id
101
101
  {{template}} - the name of the template this content was created from
102
102
  {{category}} - a hash of this items category details
103
103
 
104
104
  Other attributes that will be present on a per item specific basis are are the names of your template elements, e.g.
105
105
 
106
- {{Content}}
107
- {{Featured News Item}}
108
- {{Supporting Image}}
109
- {{Markdown body}}
106
+ {{content}} # Template field name in Orthor: Content
107
+ {{featured_news_item}} # Template field name in Orthor: Featured News Item
108
+ {{supporting_image}} # Template field name in Orthor: Supporting Image
109
+ {{markdown_body}} # Template field name in Orthor: Markdown Body
110
110
 
111
111
  ## Questions? Comments?
112
112
 
@@ -3,6 +3,7 @@ $KCODE = 'u' if RUBY_VERSION < '1.9'
3
3
 
4
4
  require 'moneta'
5
5
  require 'json'
6
+ require 'net/http'
6
7
 
7
8
  require 'orthor/templates'
8
9
 
@@ -11,6 +12,24 @@ class Orthor
11
12
  attr_accessor :cache, :cache_expiry, :account_id
12
13
  end
13
14
 
15
+ def self.load_content
16
+ raise "No point loading content when you don't have a cache setup" unless cache
17
+
18
+ load_category = lambda do |id|
19
+ cat = category(id)
20
+ cat["children"].each { |child| load_category[child["id"]] } if cat["children"]
21
+ cat["content"].each { |item| content(item["id"]) } if cat["content"]
22
+ end
23
+
24
+ JSON.parse(get_response("/#{account_id}.json")).each do |item|
25
+ if item["type"] == "category"
26
+ load_category[item["id"]]
27
+ else
28
+ content(item["id"])
29
+ end
30
+ end
31
+ end
32
+
14
33
  def self.content(id, template = nil)
15
34
  Templates.render(get(:content_items, id), template)
16
35
  end
@@ -58,9 +77,9 @@ private
58
77
  begin
59
78
  suffix = type == :feeds ? "rss" : "json"
60
79
  key = "#{id}-#{type}"
61
- url = "http://content.orthor.com/#{account_id}/#{type}/#{id}.#{suffix}"
80
+ path = "/#{account_id}/#{type}/#{id}.#{suffix}"
62
81
 
63
- resp = cache ? get_cached_content(key, url) : get_response(url)
82
+ resp = cache ? get_cached_content(key, path) : get_response(path)
64
83
 
65
84
  return resp unless suffix == "json"
66
85
 
@@ -70,24 +89,40 @@ private
70
89
  end
71
90
  end
72
91
 
73
- def self.get_cached_content(id, url)
74
- content = cache[id]
92
+ def self.get_cached_content(key, path)
93
+ content = cache[key]
75
94
  if content.nil? || content.empty?
76
- content = get_response(url)
77
-
78
- options = {}
79
- options[:expires_in] = cache_expiry if cache_expiry
80
- cache.store(id, content, options) unless content.empty?
95
+ content = get_response(path)
96
+ cache_content(key, content)
81
97
  end
82
98
  content
83
99
  end
84
100
 
85
- def self.get_response(uri)
86
- r = Net::HTTP.get_response(URI.parse(uri))
87
- r.code.to_i == 200 ? r.body : ""
88
- rescue => e
89
- ""
101
+ def self.cache_content(key, content)
102
+ return if content.empty?
103
+
104
+ options = {}
105
+ options[:expires_in] = cache_expiry if cache_expiry
106
+ cache.store(key, content, options)
90
107
  end
91
108
 
109
+ def self.get_response(path)
110
+ # default to content.orthor.com, if thats down, try www.orthor.com
111
+ uris = [ "http://content.orthor.com#{path}", "http://www.orthor.com#{path}" ]
112
+ response_content = ""
113
+
114
+ uris.each do |uri|
115
+ begin
116
+ r = Net::HTTP.get_response(URI.parse(uri))
117
+ if r.code.to_i == 200
118
+ response_content = r.body
119
+ break
120
+ end
121
+ rescue => e
122
+ break
123
+ end
124
+ end
125
+ response_content
126
+ end
92
127
  private_class_method :get, :get_cached_content, :get_response
93
128
  end
@@ -8,8 +8,22 @@ 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
+
12
+ # account and cache loading resources
13
+ [ "top-level", "second-level" ].each do |name|
14
+ FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/categories/#{name}.json",
15
+ :body => File.join(SPEC_DIR, 'resources', "#{name}.json"))
16
+ end
17
+
11
18
  FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/feeds/feed.rss",
12
19
  :body => File.join(SPEC_DIR, 'resources', 'feed.rss'))
20
+ FakeWeb.register_uri(:get, "http://content.orthor.com/orthor.json",
21
+ :body => File.join(SPEC_DIR, 'resources', 'account.json'))
22
+
23
+ FakeWeb.register_uri(:get, "http://content.orthor.com/orthor/content_items/missing.json",
24
+ :body => "", :status => 500)
25
+ FakeWeb.register_uri(:get, "http://www.orthor.com/orthor/content_items/missing.json",
26
+ :body => File.join(SPEC_DIR, 'resources', 'content.json'))
13
27
  end
14
28
 
15
29
  describe "setup" do
@@ -60,6 +74,33 @@ describe Orthor do
60
74
  end
61
75
  end
62
76
 
77
+ describe "loading cache" do
78
+ describe "without cache setting" do
79
+ before do
80
+ Orthor.setup { account "orthor" }
81
+ end
82
+
83
+ it "should raise an error" do
84
+ lambda { Orthor.load_content }.should raise_error
85
+ end
86
+ end
87
+
88
+ describe "with cache setting" do
89
+ before do
90
+ Orthor.setup do
91
+ account "orthor"
92
+ caching :memory, 20
93
+ end
94
+ end
95
+
96
+ it "should load all items into the cache" do
97
+ Orthor.load_content
98
+ Orthor.cache["news-categories"].should_not be_nil
99
+ Orthor.cache["content-content_items"].should_not be_nil
100
+ end
101
+ end
102
+ end
103
+
63
104
  describe "caching" do
64
105
  describe "no config" do
65
106
  before(:all) do
@@ -127,4 +168,17 @@ describe Orthor do
127
168
  end
128
169
  end
129
170
  end
171
+
172
+ describe "failover" do
173
+ before(:all) do
174
+ Orthor.setup do
175
+ account "orthor"
176
+ end
177
+ end
178
+
179
+ it "should use www.orthor.com if content.orthor.com is down" do
180
+ # initial request will go to content.orthor.com and return an empty string
181
+ Orthor.content("missing").should_not == ""
182
+ end
183
+ end
130
184
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 1
9
- version: 0.1.1
8
+ - 2
9
+ version: 0.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Anthony Langhorne