norman-disqus-api 0.2.0
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/MIT-LICENSE +20 -0
- data/README.rdoc +118 -0
- data/Rakefile +43 -0
- data/init.rb +6 -0
- data/lib/disqus.rb +70 -0
- data/lib/disqus/api.rb +264 -0
- data/lib/disqus/author.rb +27 -0
- data/lib/disqus/forum.rb +126 -0
- data/lib/disqus/post.rb +51 -0
- data/lib/disqus/thread.rb +73 -0
- data/lib/disqus/view_helpers.rb +45 -0
- data/lib/disqus/widget.rb +181 -0
- data/test/api_test.rb +80 -0
- data/test/config.yml.sample +3 -0
- data/test/forum_test.rb +70 -0
- data/test/merb_test.rb +15 -0
- data/test/post_test.rb +18 -0
- data/test/rails_test.rb +18 -0
- data/test/responses/bad_api_key.json +1 -0
- data/test/responses/create_post.json +23 -0
- data/test/responses/get_forum_api_key.json +1 -0
- data/test/responses/get_forum_list.json +12 -0
- data/test/responses/get_num_posts.json +11 -0
- data/test/responses/get_thread_by_url.json +18 -0
- data/test/responses/get_thread_list.json +16 -0
- data/test/responses/get_thread_posts.json +37 -0
- data/test/responses/thread_by_identifier.json +17 -0
- data/test/responses/update_thread.json +5 -0
- data/test/test_helper.rb +32 -0
- data/test/thread_test.rb +28 -0
- data/test/view_helpers_test.rb +37 -0
- data/test/widget_test.rb +58 -0
- metadata +87 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
class BaseAuthor
|
4
|
+
attr_reader :url, :email_hash
|
5
|
+
end
|
6
|
+
|
7
|
+
class Author < BaseAuthor
|
8
|
+
attr_reader :id, :username, :display_name, :has_avatar
|
9
|
+
def initialize(id, username, display_name, url, email_hash, has_avatar)
|
10
|
+
@id, @username, @display_name, @url, @email_hash, @has_avatar = id, username, display_name, url, email_hash, has_avatar
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the user's <tt>display_name</tt> or <tt>username</tt> if <tt>display_name</tt> is blank.
|
14
|
+
def name
|
15
|
+
@display_name.blank? ? @username : @display_name
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class AnonymousAuthor < BaseAuthor
|
21
|
+
attr_reader :name
|
22
|
+
def initialize(name, url, email_hash)
|
23
|
+
@name, @url, @email_hash = name, url, email_hash
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/lib/disqus/forum.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
class Forum
|
4
|
+
attr_reader :id, :shortname, :name, :created_at, :threads
|
5
|
+
|
6
|
+
def initialize(id, shortname, name, created_at, include_threads = false)
|
7
|
+
@id, @shortname, @name, @created_at = id.to_i, shortname, name, Time.parse(created_at.to_s)
|
8
|
+
@key = nil
|
9
|
+
@threads = include_threads ? load_threads : []
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other_forum)
|
13
|
+
id == other_forum.id &&
|
14
|
+
shortname == other_forum.shortname &&
|
15
|
+
name == other_forum.name &&
|
16
|
+
key == other_forum.key
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of Forum objects belonging to the user indicated by the API key.
|
20
|
+
def self.list(user_api_key = nil)
|
21
|
+
opts = user_api_key ? {:api_key => user_api_key} : {}
|
22
|
+
response = Disqus::Api::get_forum_list(opts)
|
23
|
+
if response["succeeded"]
|
24
|
+
return response["message"].map{|forum| Forum.new(forum["id"], forum["shortname"], forum["name"], forum["created_at"])}
|
25
|
+
else
|
26
|
+
raise_api_error(response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns a Forum object corresponding to the given forum_id or nil if it was not found.
|
31
|
+
def self.find(forum_id, user_api_key = nil)
|
32
|
+
opts = user_api_key ? {:api_key => user_api_key} : {}
|
33
|
+
list = Forum.list(opts)
|
34
|
+
if list
|
35
|
+
list.select{|f| f.id == forum_id}.first
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the forum API Key for this forum.
|
40
|
+
def key(user_api_key = nil)
|
41
|
+
@key ||= load_key(user_api_key)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an array of threads belonging to this forum.
|
45
|
+
def threads(force_update = false)
|
46
|
+
if (@threads.nil? or @threads.empty? or force_update)
|
47
|
+
@threads = Disqus::Thread.list(self)
|
48
|
+
end
|
49
|
+
@threads
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a thread associated with the given URL.
|
53
|
+
#
|
54
|
+
# A thread will only have an associated URL if it was automatically
|
55
|
+
# created by Disqus javascript embedded on that page.
|
56
|
+
def get_thread_by_url(url)
|
57
|
+
response = Disqus::Api::get_thread_by_url(:url => url, :forum_api_key => key)
|
58
|
+
if response["succeeded"]
|
59
|
+
t = response["message"]
|
60
|
+
Thread.new(t["id"], self, t["slug"], t["title"], t["created_at"], t["allow_comments"], t["url"], t["identifier"])
|
61
|
+
else
|
62
|
+
raise_api_error(response)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Create or retrieve a thread by an arbitrary identifying string of your
|
67
|
+
# choice. For example, you could use your local database's ID for the
|
68
|
+
# thread. This method allows you to decouple thread identifiers from the
|
69
|
+
# URL's on which they might be appear. (Disqus would normally use a
|
70
|
+
# thread's URL to identify it, which is problematic when URL's do not
|
71
|
+
# uniquely identify a resource.) If no thread exists for the given
|
72
|
+
# identifier (paired with the forum) yet, one will be created.
|
73
|
+
#
|
74
|
+
# Returns a Thread object representing the thread that was created or
|
75
|
+
# retrieved.
|
76
|
+
def thread_by_identifier(identifier, title)
|
77
|
+
# TODO - should we separate thread retrieval from thread creation? The API to me seems confusing here.
|
78
|
+
response = Disqus::Api::thread_by_identifier(:identifier => identifier, :title => title, :forum_api_key => key)
|
79
|
+
if response["succeeded"]
|
80
|
+
t = response["message"]["thread"]
|
81
|
+
Thread.new(t["id"], self, t["slug"], t["title"], t["created_at"], t["allow_comments"], t["url"], t["identifier"])
|
82
|
+
else
|
83
|
+
raise_api_error(response)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Sets the provided values on the thread object.
|
88
|
+
#
|
89
|
+
# Returns an empty success message.
|
90
|
+
#
|
91
|
+
# Options:
|
92
|
+
#
|
93
|
+
# * <tt>:title</tt> - the title of the thread
|
94
|
+
# * <tt>:slug</tt> - the per-forum-unique string used for identifying this thread in disqus.com URL's relating to this thread. Composed of underscore-separated alphanumeric strings.
|
95
|
+
# * <tt>:url</tt> - the URL this thread is on, if known.
|
96
|
+
# * <tt>:allow_comment</tt> - whether this thread is open to new comments
|
97
|
+
def update_thread(thread_id, opts = {})
|
98
|
+
result = Disqus::Api::update_thread(
|
99
|
+
:forum_api_key => key,
|
100
|
+
:thread_id => thread_id,
|
101
|
+
:title => opts[:title],
|
102
|
+
:slug => opts[:slug],
|
103
|
+
:url => opts[:url],
|
104
|
+
:allow_comments => opts[:allow_comments]
|
105
|
+
)
|
106
|
+
return result["succeeded"]
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def raise_api_error(response)
|
112
|
+
raise "Error: #{response['code']}: #{response['message']}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def load_key(user_api_key = nil)
|
116
|
+
opts = user_api_key ? {:api_key => user_api_key} : {}
|
117
|
+
response = Disqus::Api::get_forum_api_key(opts.merge(:forum_id => self.id))
|
118
|
+
if response["succeeded"]
|
119
|
+
return @key = response["message"]
|
120
|
+
else
|
121
|
+
raise_api_error(response)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
data/lib/disqus/post.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
class Post
|
4
|
+
attr_reader :id, :forum, :thread, :created_at, :message, :parent_post, :shown, :is_anonymous, :author
|
5
|
+
|
6
|
+
def initialize(id, forum, thread, created_at, message, parent_post, shown, is_anonymous, author)
|
7
|
+
@id, @forum, @thread, @created_at, @message, @parent_post, @shown, @is_anonymous, @author = id.to_i, forum, thread, Time.parse(created_at.to_s), message, parent_post, shown, is_anonymous, author
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns an array of Post objects representing all posts belonging to the
|
11
|
+
# given thread. The array is sorted by the "created_at" date descending.
|
12
|
+
def self.list(thread)
|
13
|
+
response = Disqus::Api::get_thread_posts(:thread_id =>thread.id, :forum_api_key => thread.forum.key)
|
14
|
+
if response["succeeded"]
|
15
|
+
posts = response["message"].map do |post|
|
16
|
+
author = nil
|
17
|
+
if post["is_anonymous"]
|
18
|
+
author = AnonymousAuthor.new(
|
19
|
+
post["anonymous_author"]["name"],
|
20
|
+
post["anonymous_author"]["url"],
|
21
|
+
post["anonymous_author"]["email_hash"]
|
22
|
+
)
|
23
|
+
else
|
24
|
+
author = Author.new(
|
25
|
+
post["author"]["id"].to_i,
|
26
|
+
post["author"]["username"],
|
27
|
+
post["author"]["display_name"],
|
28
|
+
post["author"]["url"],
|
29
|
+
post["author"]["email_hash"],
|
30
|
+
post["author"]["has_avatar"]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
Post.new(
|
34
|
+
post["id"],
|
35
|
+
thread.forum,
|
36
|
+
thread,
|
37
|
+
post["created_at"],
|
38
|
+
post["message"],
|
39
|
+
post["parent_post"],
|
40
|
+
post["shown"],
|
41
|
+
post["is_anonymous"],
|
42
|
+
author
|
43
|
+
)
|
44
|
+
end
|
45
|
+
posts.sort!{|a,b| a.created_at <=> b.created_at}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
class Thread
|
4
|
+
attr_reader :id, :forum, :slug, :title, :created_at, :allow_comments, :url, :identifier, :forum
|
5
|
+
|
6
|
+
def initialize(id, forum, slug, title, created_at, allow_comments, url, identifier)
|
7
|
+
@id, @forum, @slug, @title, @created_at, @allow_comments, @url, @identifier = id.to_i, forum, slug, title, Time.parse(created_at.to_s), allow_comments, url, identifier
|
8
|
+
@posts = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Threads are equal if all their attributes are equal.
|
12
|
+
def ==(other_thread)
|
13
|
+
id == other_thread.id &&
|
14
|
+
forum == other_thread.forum &&
|
15
|
+
slug == other_thread.slug &&
|
16
|
+
title == other_thread.title &&
|
17
|
+
created_at == other_thread.created_at &&
|
18
|
+
allow_comments == other_thread.allow_comments &&
|
19
|
+
url == other_thread.url &&
|
20
|
+
identifier == other_thread.identifier
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns an array of Thread objects representing the threads belonging to the given Forum.
|
24
|
+
def self.list(forum, opts = {})
|
25
|
+
response = Disqus::Api::get_thread_list(opts.merge(:forum_id =>forum.id, :forum_api_key => forum.key))
|
26
|
+
if response["succeeded"]
|
27
|
+
list = response["message"].map do |thread|
|
28
|
+
Thread.new(
|
29
|
+
thread["id"],
|
30
|
+
forum,
|
31
|
+
thread["slug"],
|
32
|
+
thread["title"],
|
33
|
+
thread["created_at"],
|
34
|
+
thread["allow_comments"],
|
35
|
+
thread["url"],
|
36
|
+
thread["identifier"]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns an array of posts belonging to this thread.
|
43
|
+
def posts(force_update = false)
|
44
|
+
if (@posts.nil? or @posts.empty? or force_update)
|
45
|
+
@posts = Disqus::Post.list(self)
|
46
|
+
end
|
47
|
+
@posts
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sets the provided values on the thread object.
|
51
|
+
#
|
52
|
+
# Options:
|
53
|
+
#
|
54
|
+
# * :thread_id
|
55
|
+
# * :title
|
56
|
+
# * :slug
|
57
|
+
# * :url
|
58
|
+
# * :allow_comments
|
59
|
+
def update(opts = {})
|
60
|
+
result = Disqus::Api::update_thread(opts.merge(
|
61
|
+
:forum_api_key => forum.key,
|
62
|
+
:thread_id => id,
|
63
|
+
:title => title,
|
64
|
+
:slug => slug,
|
65
|
+
:url => url,
|
66
|
+
:allow_comments => allow_comments)
|
67
|
+
)
|
68
|
+
return result["succeeded"]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
# Shortcuts to access the widgets as simple functions as opposed to using
|
4
|
+
# their full qualified names. These helpers are loaded automatically in
|
5
|
+
# Rails and Merb apps.
|
6
|
+
#
|
7
|
+
# For Sinatra, Camping, Nitro or other frameworks, you can include the
|
8
|
+
# helper if you wish, or use the fully-qualified names. Really this is just
|
9
|
+
# here for aesthetic purposes and to make it less likely to step on anyone's
|
10
|
+
# namespace.
|
11
|
+
module ViewHelpers
|
12
|
+
|
13
|
+
# See Disqus::Widget.thread
|
14
|
+
def disqus_thread(options = {})
|
15
|
+
Disqus::Widget::thread(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# See Disqus::Widget.comment_counts
|
19
|
+
def disqus_comment_counts(options = {})
|
20
|
+
Disqus::Widget::comment_counts(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# See Disqus::Widget.top_commenters
|
24
|
+
def disqus_top_commenters(options = {})
|
25
|
+
Disqus::Widget::top_commenters(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
# See Disqus::Widget.popular_threads
|
29
|
+
def disqus_popular_threads(options = {})
|
30
|
+
Disqus::Widget::popular_threads(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
# See Disqus::Widget.recent_comments
|
34
|
+
def disqus_recent_comments(options = {})
|
35
|
+
Disqus::Widget::recent_comments(options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# See Disqus::Widget.combo
|
39
|
+
def disqus_combo(options = {})
|
40
|
+
Disqus::Widget::combo(options)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
# Disqus Widget generator.
|
4
|
+
#
|
5
|
+
# All of the methods accept various options, and "account" is required for
|
6
|
+
# all of them. You can avoid having to pass in the account each time by
|
7
|
+
# setting it in the defaults like this:
|
8
|
+
#
|
9
|
+
# Disqus::defaults[:account] = "my_account"
|
10
|
+
class Widget
|
11
|
+
|
12
|
+
VALID_COLORS = ['blue', 'grey', 'green', 'red', 'orange']
|
13
|
+
VALID_NUM_ITEMS = 5..20
|
14
|
+
VALID_DEFAULT_TABS = ['people', 'recent', 'popular']
|
15
|
+
VALID_AVATAR_SIZES = [24, 32, 48, 92, 128]
|
16
|
+
VALID_ORIENTATIONS = ['horizontal', 'vertical']
|
17
|
+
|
18
|
+
ROOT_PATH = 'http://disqus.com/forums/%s/'
|
19
|
+
THREAD = ROOT_PATH + 'embed.js'
|
20
|
+
COMBO = ROOT_PATH + 'combination_widget.js?num_items=%d&color=%s&default_tab=%s'
|
21
|
+
RECENT = ROOT_PATH + 'recent_comments_widget.js?num_items=%d&avatar_size=%d'
|
22
|
+
POPULAR = ROOT_PATH + 'popular_threads_widget.js?num_items=%d'
|
23
|
+
TOP = ROOT_PATH + 'top_commenters_widget.js?num_items=%d&avatar_size=%d&orientation=%s'
|
24
|
+
class << self
|
25
|
+
|
26
|
+
# Show the main Disqus thread widget.
|
27
|
+
# Options:
|
28
|
+
# * <tt>account:</tt> Your Discus account (required).
|
29
|
+
def thread(opts = {})
|
30
|
+
opts = Disqus::defaults.merge(opts)
|
31
|
+
opts[:view_thread_text] ||= "View the discussion thread"
|
32
|
+
validate_opts!(opts)
|
33
|
+
s = '<div id="disqus_thread"></div>'
|
34
|
+
s << '<script type="text/javascript" src="' + THREAD + '"></script>'
|
35
|
+
s << '<noscript><a href="http://%s.disqus.com/?url=ref">'
|
36
|
+
s << opts[:view_thread_text]
|
37
|
+
s << '</a></noscript>'
|
38
|
+
if opts[:show_powered_by]
|
39
|
+
s << '<a href="http://disqus.com" class="dsq-brlink">blog comments '
|
40
|
+
s << 'powered by <span class="logo-disqus">Disqus</span></a>'
|
41
|
+
end
|
42
|
+
s % [opts[:account], opts[:account]]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Loads Javascript to show the number of comments for the page.
|
46
|
+
#
|
47
|
+
# The Javascript sets the inner html to the comment count for any links
|
48
|
+
# on the page that have the anchor "disqus_thread". For example, "View
|
49
|
+
# Comments" below would be replaced by "1 comment" or "23 comments" etc.
|
50
|
+
#
|
51
|
+
# <a href="http://my.website/article-permalink#disqus_thread">View Comments</a>
|
52
|
+
# <a href="http://my.website/different-permalink#disqus_thread">View Comments</a>
|
53
|
+
# Options:
|
54
|
+
# * <tt>account:</tt> Your Discus account (required).
|
55
|
+
def comment_counts(opts = {})
|
56
|
+
opts = Disqus::defaults.merge(opts)
|
57
|
+
validate_opts!(opts)
|
58
|
+
s = <<-WHIMPER
|
59
|
+
<script type="text/javascript">
|
60
|
+
//<[CDATA[
|
61
|
+
(function() {
|
62
|
+
var links = document.getElementsByTagName('a');
|
63
|
+
var query = '?';
|
64
|
+
for(var i = 0; i < links.length; i++) {
|
65
|
+
if(links[i].href.indexOf('#disqus_thread') >= 0) {
|
66
|
+
query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
|
67
|
+
}
|
68
|
+
}
|
69
|
+
document.write('<script type="text/javascript" src="#{ROOT_PATH}get_num_replies.js' + query + '"></' + 'script>');
|
70
|
+
})();
|
71
|
+
//]]>
|
72
|
+
</script>
|
73
|
+
WHIMPER
|
74
|
+
s % opts[:account]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Show the top commenters Disqus thread widget.
|
78
|
+
# Options:
|
79
|
+
# * <tt>account:</tt> Your Discus account (required).
|
80
|
+
# * <tt>header:</tt> HTML snipper with header (default h2) tag and text.
|
81
|
+
# * <tt>show_powered_by:</tt> Show or hide the powered by Disqus text.
|
82
|
+
# * <tt>num_items:</tt>: How many items to show.
|
83
|
+
# * <tt>hide_mods:</tt> Don't show moderators.
|
84
|
+
# * <tt>hide_avatars:</tt> Don't show avatars.
|
85
|
+
# * <tt>avatar_size:</tt> Avatar size.
|
86
|
+
def top_commenters(opts = {})
|
87
|
+
opts = Disqus::defaults.merge(opts)
|
88
|
+
opts[:header] ||= '<h2 class="dsq-widget-title">Top Commenters</h2>'
|
89
|
+
validate_opts!(opts)
|
90
|
+
s = '<div id="dsq-topcommenters" class="dsq-widget">'
|
91
|
+
s << opts[:header]
|
92
|
+
s << '<script type="text/javascript" src="'
|
93
|
+
s << TOP
|
94
|
+
s << '&hide_avatars=1' if opts[:hide_avatars]
|
95
|
+
s << '&hide_mods=1' if opts[:hide_mods]
|
96
|
+
s << '"></script>'
|
97
|
+
s << '</div>'
|
98
|
+
if opts[:show_powered_by]
|
99
|
+
s << '<a href="http://disqus.com">Powered by Disqus</a>'
|
100
|
+
end
|
101
|
+
s % [opts[:account], opts[:num_items], opts[:avatar_size], opts[:orientation]]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Show the popular threads Disqus widget.
|
105
|
+
# Options:
|
106
|
+
# * <tt>account:</tt> Your Discus account (required).
|
107
|
+
# * <tt>header:</tt> HTML snipper with header (default h2) tag and text.
|
108
|
+
# * <tt>num_items:</tt>: How many items to show.
|
109
|
+
# * <tt>hide_mods:</tt> Don't show moderators.
|
110
|
+
def popular_threads(opts = {})
|
111
|
+
opts = Disqus::defaults.merge(opts)
|
112
|
+
opts[:header] ||= '<h2 class="dsq-widget-title">Popular Threads</h2>'
|
113
|
+
validate_opts!(opts)
|
114
|
+
s = '<div id="dsq-popthreads" class="dsq-widget">'
|
115
|
+
s << opts[:header]
|
116
|
+
s << '<script type="text/javascript" src="'
|
117
|
+
s << POPULAR
|
118
|
+
s << '&hide_mods=1' if opts[:hide_mods]
|
119
|
+
s << '"></script>'
|
120
|
+
s << '</div>'
|
121
|
+
s << '<a href="http://disqus.com">Powered by Disqus</a>' if opts[:show_powered_by]
|
122
|
+
s % [opts[:account], opts[:num_items]]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Show the recent comments Disqus widget.
|
126
|
+
# Options:
|
127
|
+
# * <tt>account:</tt> Your Discus account (required).
|
128
|
+
# * <tt>header:</tt> HTML snipper with header (default h2) tag and text.
|
129
|
+
# * <tt>num_items:</tt>: How many items to show.
|
130
|
+
# * <tt>hide_avatars:</tt> Don't show avatars.
|
131
|
+
# * <tt>avatar_size:</tt> Avatar size.
|
132
|
+
def recent_comments(opts = {})
|
133
|
+
opts = Disqus::defaults.merge(opts)
|
134
|
+
opts[:header] ||= '<h2 class="dsq-widget-title">Recent Comments</h2>'
|
135
|
+
validate_opts!(opts)
|
136
|
+
s = '<div id="dsq-recentcomments" class="dsq-widget">'
|
137
|
+
s << opts[:header]
|
138
|
+
s << '<script type="text/javascript" src="'
|
139
|
+
s << RECENT
|
140
|
+
s << '&hide_avatars=1' if opts[:hide_avatars]
|
141
|
+
s << '"></script>'
|
142
|
+
s << '</div>'
|
143
|
+
if opts[:show_powered_by]
|
144
|
+
s << '<a href="http://disqus.com">Powered by Disqus</a>'
|
145
|
+
end
|
146
|
+
s % [opts[:account], opts[:num_items], opts[:avatar_size]]
|
147
|
+
end
|
148
|
+
|
149
|
+
# Show the Disqus combo widget. This is a three-tabbed box with links
|
150
|
+
# popular threads, top posters, and recent threads.
|
151
|
+
# Options:
|
152
|
+
# * <tt>:account:</tt> Your Discus account (required).
|
153
|
+
# * <tt>:num_items:</tt> How many items to show.
|
154
|
+
# * <tt>:hide_mods:</tt> Don't show moderators.
|
155
|
+
# * <tt>:default_tab:</tt> Should be 'people', 'recent', or 'popular'.
|
156
|
+
def combo(opts = {})
|
157
|
+
opts = Disqus::defaults.merge(opts)
|
158
|
+
validate_opts!(opts)
|
159
|
+
s = '<script type="text/javascript" src="'
|
160
|
+
s << COMBO
|
161
|
+
s << '&hide_mods=1' if opts[:hide_mods]
|
162
|
+
s << '"></script>'
|
163
|
+
s % [opts[:account], opts[:num_items], opts[:color], opts[:default_tab]]
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def validate_opts!(opts)
|
169
|
+
raise ArgumentError.new("You must specify an :account") if !opts[:account]
|
170
|
+
raise ArgumentError.new("Invalid color") if opts[:color] && !VALID_COLORS.include?(opts[:color])
|
171
|
+
raise ArgumentError.new("Invalid num_items") if opts[:num_items] && !VALID_NUM_ITEMS.include?(opts[:num_items])
|
172
|
+
raise ArgumentError.new("Invalid default_tab") if opts[:default_tab] && !VALID_DEFAULT_TABS.include?(opts[:default_tab])
|
173
|
+
raise ArgumentError.new("Invalid avatar size") if opts[:avatar_size] && !VALID_AVATAR_SIZES.include?(opts[:avatar_size])
|
174
|
+
raise ArgumentError.new("Invalid orientation") if opts[:orientation] && !VALID_ORIENTATIONS.include?(opts[:orientation])
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|