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.
- data/README.md +20 -20
- data/lib/orthor.rb +49 -14
- data/spec/orthor_spec.rb +54 -0
- 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>{{
|
47
|
+
template :basic_content, %(<div>{{content}}</div>)
|
48
48
|
|
49
49
|
template :blog_entry, %(
|
50
50
|
<div class="blog-entry">
|
51
|
-
<h2>{{
|
52
|
-
<div class="blog-content">{{
|
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="{{
|
57
|
-
<p>{{
|
58
|
-
<div class="blog-content">{{
|
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>{{
|
64
|
-
<p class="last-updated">Last updated: {{
|
65
|
-
<div class="content">{{
|
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
|
-
{{
|
95
|
-
{{
|
96
|
-
{{
|
97
|
-
{{
|
98
|
-
{{
|
99
|
-
{{
|
100
|
-
{{
|
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
|
-
{{
|
107
|
-
{{Featured News Item
|
108
|
-
{{Supporting Image
|
109
|
-
{{Markdown
|
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
|
|
data/lib/orthor.rb
CHANGED
@@ -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
|
-
|
80
|
+
path = "/#{account_id}/#{type}/#{id}.#{suffix}"
|
62
81
|
|
63
|
-
resp = cache ? get_cached_content(key,
|
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(
|
74
|
-
content = cache[
|
92
|
+
def self.get_cached_content(key, path)
|
93
|
+
content = cache[key]
|
75
94
|
if content.nil? || content.empty?
|
76
|
-
content = get_response(
|
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.
|
86
|
-
|
87
|
-
|
88
|
-
|
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
|
data/spec/orthor_spec.rb
CHANGED
@@ -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
|