aerial 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.gitignore +4 -1
  2. data/README.md +23 -28
  3. data/Rakefile +27 -52
  4. data/VERSION +1 -1
  5. data/aerial.gemspec +134 -0
  6. data/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
  7. data/bin/aerial +5 -0
  8. data/config/config.sample.ru +19 -0
  9. data/config/config.sample.yml +29 -0
  10. data/config/config.test.yml +49 -0
  11. data/config/config.yml +3 -3
  12. data/config/thin.sample.yml +13 -0
  13. data/examples/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
  14. data/{lib/spec/fixtures → examples}/public/javascripts/application.js +0 -0
  15. data/{lib/spec/fixtures → examples}/public/javascripts/jquery-1.3.1.min.js +0 -0
  16. data/{lib/spec/fixtures → examples}/public/javascripts/jquery.template.js +0 -0
  17. data/{lib/spec/fixtures → examples}/views/article.haml +1 -1
  18. data/{lib/spec/fixtures → examples}/views/articles.haml +0 -0
  19. data/{lib/spec/fixtures → examples}/views/comment.haml +1 -1
  20. data/{lib/spec/fixtures → examples}/views/home.haml +0 -0
  21. data/{lib/spec/fixtures → examples}/views/layout.haml +1 -1
  22. data/examples/views/not_found.haml +1 -0
  23. data/{lib/spec/fixtures → examples}/views/post.haml +0 -0
  24. data/{lib/spec/fixtures → examples}/views/rss.haml +2 -2
  25. data/{lib/spec/fixtures → examples}/views/sidebar.haml +8 -0
  26. data/{lib/spec/fixtures → examples}/views/style.sass +0 -0
  27. data/{lib/features → features}/article.feature +0 -0
  28. data/features/home.feature +16 -0
  29. data/{lib/features → features}/step_definitions/article_steps.rb +0 -0
  30. data/{lib/features → features}/step_definitions/home_steps.rb +0 -0
  31. data/{lib/features → features}/support/env.rb +0 -0
  32. data/{lib/features → features}/support/pages/article.rb +0 -0
  33. data/{lib/features → features}/support/pages/homepage.rb +0 -0
  34. data/index.html +164 -0
  35. data/lib/aerial.rb +38 -87
  36. data/lib/aerial/app.rb +93 -0
  37. data/lib/aerial/article.rb +28 -30
  38. data/lib/aerial/base.rb +24 -32
  39. data/lib/aerial/comment.rb +10 -19
  40. data/lib/aerial/content.rb +12 -21
  41. data/lib/aerial/installer.rb +119 -0
  42. data/public/javascripts/application.js +109 -0
  43. data/public/javascripts/jquery-1.3.1.min.js +19 -0
  44. data/public/javascripts/jquery.template.js +255 -0
  45. data/spec/aerial_spec.rb +19 -0
  46. data/{lib/spec/aerial_spec.rb → spec/app_spec.rb} +32 -40
  47. data/{lib/spec → spec}/article_spec.rb +21 -21
  48. data/{lib/spec → spec}/base_spec.rb +1 -5
  49. data/{lib/spec → spec}/comment_spec.rb +8 -8
  50. data/{lib/spec → spec}/config_spec.rb +0 -0
  51. data/spec/fixtures/articles/congratulations-aerial-is-configured-correctly/congratulations-aerial-is-configured-correctly.article +6 -0
  52. data/spec/fixtures/articles/sample-article/sample-article.article +6 -0
  53. data/spec/fixtures/articles/test-article-one/test-article.article +7 -0
  54. data/spec/fixtures/articles/test-article-three/test-article.article +7 -0
  55. data/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +8 -0
  56. data/spec/fixtures/articles/test-article-two/test-article.article +7 -0
  57. data/spec/fixtures/articles/test-article-two/test-comment.comment +10 -0
  58. data/{lib/spec → spec}/fixtures/config.yml +0 -0
  59. data/spec/fixtures/public/javascripts/application.js +109 -0
  60. data/spec/fixtures/public/javascripts/jquery-1.3.1.min.js +19 -0
  61. data/spec/fixtures/public/javascripts/jquery.template.js +255 -0
  62. data/spec/fixtures/views/article.haml +19 -0
  63. data/spec/fixtures/views/articles.haml +2 -0
  64. data/spec/fixtures/views/comment.haml +8 -0
  65. data/spec/fixtures/views/home.haml +2 -0
  66. data/spec/fixtures/views/layout.haml +22 -0
  67. data/spec/fixtures/views/not_found.haml +1 -0
  68. data/spec/fixtures/views/post.haml +27 -0
  69. data/spec/fixtures/views/rss.haml +15 -0
  70. data/spec/fixtures/views/sidebar.haml +29 -0
  71. data/spec/fixtures/views/style.sass +163 -0
  72. data/{lib/spec → spec}/spec_helper.rb +15 -3
  73. data/views/article.haml +19 -0
  74. data/views/articles.haml +2 -0
  75. data/views/comment.haml +8 -0
  76. data/views/home.haml +2 -0
  77. data/views/layout.haml +22 -0
  78. data/views/not_found.haml +1 -0
  79. data/views/post.haml +27 -0
  80. data/views/rss.haml +15 -0
  81. data/views/sidebar.haml +29 -0
  82. data/views/style.sass +163 -0
  83. metadata +86 -40
  84. data/lib/features/home.feature +0 -16
  85. data/lib/spec/fixtures/articles/sample-article/sample-article.article +0 -6
  86. data/lib/spec/fixtures/articles/test-article-one/test-article.article +0 -7
  87. data/lib/spec/fixtures/articles/test-article-three/test-article.article +0 -7
  88. data/lib/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +0 -8
  89. data/lib/spec/fixtures/articles/test-article-two/test-article.article +0 -7
  90. data/lib/spec/fixtures/articles/test-article-two/test-comment.comment +0 -10
@@ -0,0 +1,19 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/spec_helper"
3
+
4
+ describe 'main aerial application' do
5
+
6
+ before do
7
+ setup_repo
8
+ end
9
+
10
+ it "should load the configuration from the file" do
11
+ Aerial.config.should_not be_nil
12
+ Aerial.config.name.should == "Aerial"
13
+ Aerial.config.public.dir.should == "public"
14
+ Aerial.config.author.should == "Awesome Ruby Developor"
15
+ Aerial.config.subtitle.should == "Article, Pages, and such"
16
+ Aerial.config.email.should == "aerial@example.com"
17
+ end
18
+
19
+ end
@@ -1,38 +1,30 @@
1
1
  require "#{File.dirname(__FILE__)}/spec_helper"
2
2
 
3
- describe 'main aerial application' do
3
+ describe 'main app application' do
4
4
 
5
5
  before do
6
- @articles = Article.all
7
6
  setup_repo
8
- end
9
-
10
- it "should define the root directory" do
11
- AERIAL_ROOT.should_not be_nil
12
- end
13
-
14
- it "should define the configuration file" do
15
- CONFIG.should_not be_nil
7
+ @articles = Article.all
16
8
  end
17
9
 
18
10
  it 'should show the default index page' do
19
11
  get '/'
20
- @response.should be_ok
12
+ last_response.status.should == 200
21
13
  end
22
14
 
23
- it 'should send 404 properly' do
24
- get '/not-found.html'
25
- @response.status.should == 404
15
+ it 'should send the not_found action if page does not exists' do
16
+ get '/does_not_exist.html'
17
+ last_response.status.should == 200
26
18
  end
27
19
 
28
20
  it "should render a single article page" do
29
21
  get '/2009/1/31/test-article'
30
- @response.status.should == 200
22
+ last_response.status.should == 200
31
23
  end
32
24
 
33
25
  it "should render the home page" do
34
26
  get '/home'
35
- @response.status.should == 200
27
+ last_response.status.should == 200
36
28
  end
37
29
 
38
30
  describe "calling /style.css" do
@@ -42,21 +34,21 @@ describe 'main aerial application' do
42
34
  end
43
35
 
44
36
  it "should return an okay status code" do
45
- @response.status.should == 200
37
+ last_response.status.should == 200
46
38
  end
47
39
 
48
40
  it "should return a css stylesheet" do
49
- @response.headers["Content-Type"].should == "text/css;charset=utf-8"
41
+ last_response.headers["Content-Type"].should == "text/css;charset=utf-8"
50
42
  end
51
43
 
52
44
  end
53
45
 
54
- describe "calling /tags" do
46
+ describe "calling /tags" do
55
47
 
56
48
  before do
57
49
  @article = Article.new(:title => "Test Article",
58
50
  :tags => "git, sinatra",
59
- :published_at => DateTime.new,
51
+ :publish_date => DateTime.new,
60
52
  :comments => [],
61
53
  :file_name => "test-article")
62
54
  Aerial::Article.stub!(:with_tag).and_return([@article])
@@ -64,11 +56,11 @@ describe 'main aerial application' do
64
56
  end
65
57
 
66
58
  it "should return a valid response" do
67
- @response.status.should == 200
59
+ last_response.status.should == 200
68
60
  end
69
61
 
70
62
  it "should return a response body" do
71
- @response.body.should_not be_empty
63
+ last_response.body.should_not be_empty
72
64
  end
73
65
 
74
66
  end
@@ -82,42 +74,42 @@ describe 'main aerial application' do
82
74
  end
83
75
 
84
76
  it "should produce an rss tag" do
85
- @response.body.should have_tag('//rss')
77
+ last_response.body.should have_tag('//rss')
86
78
  end
87
79
 
88
80
  it "should contain a title tag" do
89
- @response.body.should have_tag('//title').with_text(Aerial.config.title)
81
+ last_response.body.should have_tag('//title').with_text(Aerial.config.title)
90
82
  end
91
83
 
92
84
  it "should contain a language tag" do
93
- @response.body.should have_tag('//language').with_text("en-us")
85
+ last_response.body.should have_tag('//language').with_text("en-us")
94
86
  end
95
87
 
96
88
  it "should contain a description tag that containts the subtitle" do
97
- @response.body.should have_tag('//description').with_text(Aerial.config.subtitle)
89
+ last_response.body.should have_tag('//description').with_text(Aerial.config.subtitle)
98
90
  end
99
91
 
100
92
  it "should contain an item tag" do
101
- @response.body.should have_tag('//item')
93
+ last_response.body.should have_tag('//item')
102
94
  end
103
95
 
104
96
  it "should have the title tags for the articles" do
105
- @response.body.should have_tag('//item[1]/title').with_text(@articles[0].title)
106
- @response.body.should have_tag('//item[2]/title').with_text(@articles[1].title)
97
+ last_response.body.should have_tag('//item[1]/title').with_text(@articles[0].title)
98
+ last_response.body.should have_tag('//item[2]/title').with_text(@articles[1].title)
107
99
  end
108
100
 
109
101
  it "should have the link tag with the articles permalink" do
110
- #@response.body.should have_tag('//item[1]/link').with_text("http://#{@articles[0].permalink}")
102
+ #last_response.body.should have_tag('//item[1]/link').with_text("http://#{@articles[0].permalink}")
111
103
  end
112
104
 
113
105
  it "should have a pubDate tag with the article's publication date" do
114
- @response.body.should have_tag('//item[1]/pubDate').with_text(@articles[0].published_at.to_s)
115
- @response.body.should have_tag('//item[2]/pubDate').with_text(@articles[1].published_at.to_s)
106
+ last_response.body.should have_tag('//item[1]/pubDate').with_text(@articles[0].publish_date.to_s)
107
+ last_response.body.should have_tag('//item[2]/pubDate').with_text(@articles[1].publish_date.to_s)
116
108
  end
117
109
 
118
110
  it "should have a guid date that matches the articles id" do
119
- @response.body.should have_tag('//item[1]/guid').with_text(@articles[0].id)
120
- @response.body.should have_tag('//item[2]/guid').with_text(@articles[1].id)
111
+ last_response.body.should have_tag('//item[1]/guid').with_text(@articles[0].id)
112
+ last_response.body.should have_tag('//item[2]/guid').with_text(@articles[1].id)
121
113
  end
122
114
 
123
115
  after do
@@ -135,22 +127,22 @@ describe 'main aerial application' do
135
127
  end
136
128
 
137
129
  it "should return a valid response" do
138
- @response.status.should == 200
130
+ last_response.status.should == 200
139
131
  end
140
132
 
141
133
  it "should return a response body" do
142
- @response.body.should_not be_empty
134
+ last_response.body.should_not be_empty
143
135
  end
144
136
 
145
137
  end
146
138
 
147
139
 
148
- describe "calling /arhives" do
140
+ describe "calling /archives" do
149
141
  before do
150
142
  @article = Article.new(:title => "Test Article",
151
143
  :body => "Test Content",
152
144
  :id => 333,
153
- :published_at => DateTime.new,
145
+ :publish_date => DateTime.new,
154
146
  :comments => [],
155
147
  :file_name => "test-article.article")
156
148
  Aerial::Article.stub!(:with_date).and_return([@article])
@@ -158,7 +150,7 @@ describe 'main aerial application' do
158
150
  end
159
151
 
160
152
  it "should return a valid response" do
161
- @response.status.should == 200
153
+ last_response.status.should == 200
162
154
  end
163
155
 
164
156
  end
@@ -178,7 +170,7 @@ describe 'main aerial application' do
178
170
  end
179
171
 
180
172
  it "should return a valid response" do
181
- @response.status.should == 204
173
+ last_response.status.should == 204
182
174
  end
183
175
  end
184
176
 
@@ -12,9 +12,9 @@ describe 'article' do
12
12
  @article = Article.with_name("test-article-one")
13
13
  end
14
14
 
15
- it "should find an article with .article extenstion " do
16
- @article.should_not be_nil
17
- end
15
+ it "should find an article with .article extension " do
16
+ @article.should_not be_nil
17
+ end
18
18
 
19
19
  it "should assign the article's author" do
20
20
  @article.author.should == "Matt Sears"
@@ -37,7 +37,7 @@ describe 'article' do
37
37
  end
38
38
 
39
39
  it "should assign the article a publication date" do
40
- @article.published_at.should == DateTime.new(y=2009,m=1,d=31)
40
+ @article.publish_date.should == DateTime.new(y=2009,m=1,d=31)
41
41
  end
42
42
 
43
43
  it "should assign the article a body attribute" do
@@ -101,11 +101,11 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
101
101
 
102
102
  end
103
103
 
104
- describe "when articles don't exitst" do
104
+ describe "when articles don't exist" do
105
105
 
106
106
  it "should raise error when article could not be found" do
107
107
  lambda {
108
- @article = Article.find("doesn't exists")
108
+ @article = Article.find("doesn't exist")
109
109
  }.should raise_error(RuntimeError)
110
110
  end
111
111
 
@@ -164,8 +164,8 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
164
164
  @articles.should be_instance_of(Array)
165
165
  end
166
166
 
167
- it "should contain more than one Article" do
168
- @articles.size.should == 4
167
+ it "should contain 5 articles" do
168
+ @articles.size.should == 5
169
169
  end
170
170
 
171
171
  it "should contain a comments array even if empty" do
@@ -191,8 +191,8 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
191
191
  @articles.should be_instance_of(Array)
192
192
  end
193
193
 
194
- it "should contain more than one Article" do
195
- @articles.size.should == 3
194
+ it "should contain 4 articles" do
195
+ @articles.size.should == 4
196
196
  end
197
197
 
198
198
  it "should include articles with a specific task" do
@@ -216,11 +216,11 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
216
216
  end
217
217
 
218
218
  it "should return 2 articles published in the 12th month" do
219
- @articles.each { |a| a.published_at.month.should == 12}
219
+ @articles.each { |a| a.publish_date.month.should == 12}
220
220
  end
221
221
 
222
- it "should return 2 articles published in the year 2009" do
223
- @articles.each { |a| a.published_at.year.should == 2009}
222
+ it "should return 3 articles published in the year 2009" do
223
+ @articles.each { |a| a.publish_date.year.should == 2009}
224
224
  end
225
225
 
226
226
  it "should find articles with dates in string format" do
@@ -242,7 +242,7 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
242
242
  end
243
243
 
244
244
  it "should return a list of publication dates" do
245
- @archives.should == {["2009/01", "January 2009"]=>2, ["2009/12", "December 2009"]=>2}
245
+ @archives.should == {["2009/01", "January 2009"]=>2, ["2009/03", "March 2009"]=>1, ["2009/12", "December 2009"]=>2}
246
246
  end
247
247
 
248
248
  end
@@ -305,8 +305,8 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
305
305
  @tags.should be_instance_of(Array)
306
306
  end
307
307
 
308
- it "should return a list of tag strings" do
309
- @tags.size.should == 3
308
+ it "should return a list of 4 tag strings" do
309
+ @tags.size.should == 4
310
310
  end
311
311
 
312
312
  end
@@ -315,11 +315,11 @@ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
315
315
 
316
316
  before(:each) do
317
317
  @article = Article.with_name("test-article-one")
318
- @comment = Comment.new(:author => "Matt Sears",
319
- :body => "Comment content",
320
- :email => "matt@mattsears.com",
321
- :published => Date.today,
322
- :homepage => "http://example.com")
318
+ @comment = Comment.new(:author => "Matt Sears",
319
+ :body => "Comment content",
320
+ :email => "matt@mattsears.com",
321
+ :publish_date => Date.today,
322
+ :homepage => "http://example.com")
323
323
  end
324
324
 
325
325
  it "should add a new comment with no errors" do
@@ -1,3 +1,4 @@
1
+
1
2
  require "#{File.dirname(__FILE__)}/spec_helper"
2
3
 
3
4
  describe 'article' do
@@ -31,11 +32,6 @@ describe 'article' do
31
32
  link_to_tags(tags).should == "<a href='/tags/ruby' rel='ruby'>ruby</a>, <a href='/tags/sinatra' rel='sinatra'>sinatra</a>"
32
33
  end
33
34
 
34
- it "should default the current path to 'index' for the root of the application" do
35
- request.stub!(:env).and_return('/')
36
- path.should == "index"
37
- end
38
-
39
35
  end
40
36
 
41
37
  describe Aerial::Git do
@@ -50,7 +50,7 @@ describe 'comment' do
50
50
  end
51
51
 
52
52
  it "should assign an IP address of the commenter" do
53
- @comment.user_ip.should == "127.0.0.1"
53
+ @comment.ip.should == "127.0.0.1"
54
54
  end
55
55
 
56
56
  it "should assign a homepage of the commenter" do
@@ -67,7 +67,7 @@ describe 'comment' do
67
67
 
68
68
  it "should format the string version of the comment" do
69
69
  comment = Comment.new(:author => "author", :email => "test@test.com")
70
- comment.to_s.should == "Author: author \nPublished: #{comment.published_at} \nEmail: test@test.com \n"
70
+ comment.to_s.should == "Author: author \nPublish Date: #{comment.publish_date} \nEmail: test@test.com \n"
71
71
  end
72
72
 
73
73
  describe "without a homepage field" do
@@ -147,11 +147,11 @@ describe 'comment' do
147
147
 
148
148
  before do
149
149
  @article = Article.with_name("test-article-two")
150
- @comment = Comment.new(:author => "Matt Sears",
151
- :body => "Comment content",
152
- :email => "matt@mattsears.com",
153
- :published => Date.today,
154
- :homepage => "http://example.com")
150
+ @comment = Comment.new(:author => "Matt Sears",
151
+ :body => "Comment content",
152
+ :email => "matt@mattsears.com",
153
+ :publish_date => Date.today,
154
+ :homepage => "http://example.com")
155
155
  end
156
156
 
157
157
  it "should NOT have written a new comment to disk yet" do
@@ -172,7 +172,7 @@ describe 'comment' do
172
172
 
173
173
  it "should assign a publication date of the comment" do
174
174
  @comment.save(@article.archive_name).should == @comment
175
- @comment.published_at.should be_instance_of(DateTime)
175
+ @comment.publish_date.should be_instance_of(DateTime)
176
176
  end
177
177
 
178
178
  it "should write a new comment to disk" do
File without changes
@@ -0,0 +1,6 @@
1
+ Title : Congratulations! Aerial is configured correctly
2
+ Tags : ruby, sinatra, git, aerial
3
+ Publish Date : 03/31/2009
4
+ Author : Aerial
5
+
6
+ Congratulations! Aerial appears to be up and running. This is a sample article created during the bootstrap process. You may overwrite this article or create a new one.
@@ -0,0 +1,6 @@
1
+ Title : Sample article
2
+ Tags : ruby, sinatra, git
3
+ Publish Date : 01/31/2009
4
+ Author : Aerial
5
+
6
+ This is a sample article created during the bootstrap process. You may overwrite this article or create a new one.
@@ -0,0 +1,7 @@
1
+ Title : This is the first article
2
+ Tags : ruby, sinatra, git
3
+ Publish Date : 01/31/2009
4
+ Author : Matt Sears
5
+
6
+ Lorem ipsum dolor sit amet, adipisicing **elit**, sed do eiusmod
7
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
@@ -0,0 +1,7 @@
1
+ Title : This is the third test article
2
+ Tags : ruby, sinatra, git
3
+ Publish Date : 12/25/2009
4
+ Author : Matt Sears
5
+
6
+ Lorem ipsum dolor sit amet, adipisicing **elit**, sed do eiusmod
7
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
@@ -0,0 +1,8 @@
1
+ Author : Anonymous Coward
2
+ Email : anonymous@coward.com
3
+ Homepage :
4
+ Referrer : http://mattsears.com
5
+ Publish Date : 10/26/2009
6
+ IP : 127.0.0.1
7
+
8
+ This is a comment with a few fields missing above
@@ -0,0 +1,7 @@
1
+ Title : This is the second article
2
+ Tags : ruby, git
3
+ Publish Date : 12/15/2009
4
+ Author : Matt Sears
5
+
6
+ Lorem ipsum dolor sit amet, adipisicing **elit**, sed do eiusmod
7
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia
@@ -0,0 +1,10 @@
1
+ Author : Anonymous Coward
2
+ Email : anonymous@coward.com
3
+ Homepage : http://littlelines.com
4
+ Referrer : http://mattsears.com
5
+ User-Agent : CERN-LineMode/2.15 libwww/2.17b3
6
+ Publish Date : 10/26/2009
7
+ IP : 127.0.0.1
8
+
9
+ Lorem ipsum dolor sit amet, adipisicing **comment**, sed do eiusmod
10
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia
File without changes
@@ -0,0 +1,109 @@
1
+ /*------------------------------------
2
+ Global Javascripts
3
+ Aerial
4
+ Version / 1.0
5
+ Author / att Sears
6
+ email / matt@mattsears.com
7
+ website / www.mattsears.com
8
+ -------------------------------------*/
9
+
10
+ /* When page is loaded
11
+ ----------------------------*/
12
+ $(document).ready(function() {
13
+ externalLinks();
14
+ });
15
+
16
+ //
17
+ var Comment = {
18
+
19
+ author: '',
20
+ homepage: '',
21
+ email: '',
22
+ body: '',
23
+ article: '',
24
+
25
+ // Submit a new comment to the server via ajax
26
+ submit: function(article_id) {
27
+
28
+ this.author = $("input#comment_author").val();
29
+ this.homepage = $("input#comment_website").val();
30
+ this.email = $("input#comment_email").val();
31
+ this.body = $("textarea#comment_body").val();
32
+ this.article = article_id;
33
+
34
+ // Make sure we have the required fields
35
+ if (!this.valid()){
36
+ return false;
37
+ }
38
+
39
+ // Append a new comment if post is successful
40
+ if (this.post()){
41
+ this.appendNew();
42
+ }
43
+ },
44
+
45
+ // Post the comment back to the server
46
+ post: function() {
47
+
48
+ // Data posted to server
49
+ var data = 'author='+ this.author + '&email=' + this.email + '&homepage=' + this.phone + '&body=' + this.body;
50
+ var url = "/article/" + this.article + "/comments";
51
+
52
+ $.ajax({
53
+ type: "POST",
54
+ url: url,
55
+ data: data
56
+ });
57
+
58
+ return true;
59
+ },
60
+
61
+ // Add a div for the new comment
62
+ appendNew: function() {
63
+
64
+ // Template for the new comment div
65
+ var t = $.template(
66
+ "<div class='comment'><h2>${author}<span>${date}</span></h2><p>${message}</p></div>"
67
+ );
68
+
69
+ // Append
70
+ $("#comments").append( t , {
71
+ author: this.author,
72
+ homepage: this.homepage,
73
+ message: this.body
74
+ });
75
+ },
76
+
77
+ // Ensure all required fields are filled-in
78
+ valid: function() {
79
+
80
+ if (this.author == "") {
81
+ $("#author_label").addClass("error");
82
+ return false;
83
+ }
84
+
85
+ if (this.email == "") {
86
+ $("#email_label").addClass("error");
87
+ return false;
88
+ }
89
+
90
+ if (this.comment == "") {
91
+ $("#comment_label").addClass("error");
92
+ return false;
93
+ }
94
+ return true;
95
+ },
96
+
97
+ }
98
+
99
+ // Make all 'external' links in a new window
100
+ function externalLinks() {
101
+ if (!document.getElementsByTagName) return;
102
+ var anchors = document.getElementsByTagName("a");
103
+ for (var i = 0; i < anchors.length; i++) {
104
+ var anchor = anchors[i];
105
+ if (anchor.getAttribute("href") &&
106
+ anchor.getAttribute("rel") == "external")
107
+ anchor.target = "_blank";
108
+ }
109
+ }