rethoth 0.4.1

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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/bin/thoth +233 -0
  4. data/lib/proto/config.ru +45 -0
  5. data/lib/proto/thoth.conf.sample +206 -0
  6. data/lib/thoth/cache.rb +53 -0
  7. data/lib/thoth/config.rb +158 -0
  8. data/lib/thoth/controller/admin.rb +75 -0
  9. data/lib/thoth/controller/api/comment.rb +73 -0
  10. data/lib/thoth/controller/api/page.rb +134 -0
  11. data/lib/thoth/controller/api/post.rb +122 -0
  12. data/lib/thoth/controller/api/tag.rb +59 -0
  13. data/lib/thoth/controller/archive.rb +50 -0
  14. data/lib/thoth/controller/comment.rb +173 -0
  15. data/lib/thoth/controller/main.rb +193 -0
  16. data/lib/thoth/controller/media.rb +172 -0
  17. data/lib/thoth/controller/page.rb +167 -0
  18. data/lib/thoth/controller/post.rb +310 -0
  19. data/lib/thoth/controller/search.rb +86 -0
  20. data/lib/thoth/controller/tag.rb +107 -0
  21. data/lib/thoth/controller.rb +48 -0
  22. data/lib/thoth/errors.rb +35 -0
  23. data/lib/thoth/helper/admin.rb +86 -0
  24. data/lib/thoth/helper/cookie.rb +45 -0
  25. data/lib/thoth/helper/error.rb +122 -0
  26. data/lib/thoth/helper/pagination.rb +131 -0
  27. data/lib/thoth/helper/wiki.rb +77 -0
  28. data/lib/thoth/helper/ysearch.rb +89 -0
  29. data/lib/thoth/importer/pants.rb +81 -0
  30. data/lib/thoth/importer/poseidon.rb +54 -0
  31. data/lib/thoth/importer/thoth.rb +103 -0
  32. data/lib/thoth/importer.rb +131 -0
  33. data/lib/thoth/layout/default.rhtml +47 -0
  34. data/lib/thoth/middleware/minify.rb +82 -0
  35. data/lib/thoth/migrate/001_create_schema.rb +108 -0
  36. data/lib/thoth/migrate/002_add_media_size.rb +37 -0
  37. data/lib/thoth/migrate/003_add_post_draft.rb +38 -0
  38. data/lib/thoth/migrate/004_add_comment_email.rb +37 -0
  39. data/lib/thoth/migrate/005_add_page_position.rb +37 -0
  40. data/lib/thoth/migrate/006_add_comment_close_delete.rb +43 -0
  41. data/lib/thoth/migrate/007_add_comment_summary.rb +37 -0
  42. data/lib/thoth/model/comment.rb +216 -0
  43. data/lib/thoth/model/media.rb +87 -0
  44. data/lib/thoth/model/page.rb +204 -0
  45. data/lib/thoth/model/post.rb +262 -0
  46. data/lib/thoth/model/tag.rb +80 -0
  47. data/lib/thoth/model/tags_posts_map.rb +34 -0
  48. data/lib/thoth/monkeypatch/sequel/model/errors.rb +37 -0
  49. data/lib/thoth/plugin/thoth_delicious.rb +105 -0
  50. data/lib/thoth/plugin/thoth_flickr.rb +86 -0
  51. data/lib/thoth/plugin/thoth_pinboard.rb +98 -0
  52. data/lib/thoth/plugin/thoth_tags.rb +68 -0
  53. data/lib/thoth/plugin/thoth_twitter.rb +175 -0
  54. data/lib/thoth/plugin.rb +59 -0
  55. data/lib/thoth/public/css/admin.css +223 -0
  56. data/lib/thoth/public/css/thoth.css +592 -0
  57. data/lib/thoth/public/images/admin-sprite.png +0 -0
  58. data/lib/thoth/public/images/thoth-sprite.png +0 -0
  59. data/lib/thoth/public/js/admin/comments.js +116 -0
  60. data/lib/thoth/public/js/admin/name.js +244 -0
  61. data/lib/thoth/public/js/admin/tagcomplete.js +332 -0
  62. data/lib/thoth/public/js/lazyload-min.js +4 -0
  63. data/lib/thoth/public/js/thoth.js +203 -0
  64. data/lib/thoth/public/robots.txt +5 -0
  65. data/lib/thoth/version.rb +37 -0
  66. data/lib/thoth/view/admin/index.rhtml +1 -0
  67. data/lib/thoth/view/admin/login.rhtml +23 -0
  68. data/lib/thoth/view/admin/toolbar.rhtml +117 -0
  69. data/lib/thoth/view/admin/welcome.rhtml +58 -0
  70. data/lib/thoth/view/archive/index.rhtml +24 -0
  71. data/lib/thoth/view/comment/comment.rhtml +47 -0
  72. data/lib/thoth/view/comment/delete.rhtml +15 -0
  73. data/lib/thoth/view/comment/form.rhtml +81 -0
  74. data/lib/thoth/view/comment/index.rhtml +68 -0
  75. data/lib/thoth/view/comment/list.rhtml +48 -0
  76. data/lib/thoth/view/media/delete.rhtml +15 -0
  77. data/lib/thoth/view/media/edit.rhtml +12 -0
  78. data/lib/thoth/view/media/form.rhtml +7 -0
  79. data/lib/thoth/view/media/list.rhtml +35 -0
  80. data/lib/thoth/view/media/media.rhtml +44 -0
  81. data/lib/thoth/view/media/new.rhtml +7 -0
  82. data/lib/thoth/view/page/delete.rhtml +15 -0
  83. data/lib/thoth/view/page/edit.rhtml +15 -0
  84. data/lib/thoth/view/page/form.rhtml +57 -0
  85. data/lib/thoth/view/page/index.rhtml +9 -0
  86. data/lib/thoth/view/page/list.rhtml +49 -0
  87. data/lib/thoth/view/page/new.rhtml +15 -0
  88. data/lib/thoth/view/post/comments.rhtml +12 -0
  89. data/lib/thoth/view/post/compact.rhtml +48 -0
  90. data/lib/thoth/view/post/delete.rhtml +15 -0
  91. data/lib/thoth/view/post/edit.rhtml +15 -0
  92. data/lib/thoth/view/post/form.rhtml +83 -0
  93. data/lib/thoth/view/post/index.rhtml +48 -0
  94. data/lib/thoth/view/post/list.rhtml +61 -0
  95. data/lib/thoth/view/post/new.rhtml +15 -0
  96. data/lib/thoth/view/post/tiny.rhtml +4 -0
  97. data/lib/thoth/view/search/index.rhtml +45 -0
  98. data/lib/thoth/view/tag/index.rhtml +34 -0
  99. data/lib/thoth/view/thoth/css.rhtml +9 -0
  100. data/lib/thoth/view/thoth/footer.rhtml +15 -0
  101. data/lib/thoth/view/thoth/header.rhtml +23 -0
  102. data/lib/thoth/view/thoth/index.rhtml +11 -0
  103. data/lib/thoth/view/thoth/js.rhtml +6 -0
  104. data/lib/thoth/view/thoth/sidebar.rhtml +38 -0
  105. data/lib/thoth/view/thoth/util/pager.rhtml +23 -0
  106. data/lib/thoth/view/thoth/util/simple_pager.rhtml +15 -0
  107. data/lib/thoth/view/thoth/util/table_sortheader.rhtml +20 -0
  108. data/lib/thoth.rb +394 -0
  109. metadata +409 -0
@@ -0,0 +1,203 @@
1
+ var Thoth = function () {
2
+ // Shorthand.
3
+ var d = document,
4
+ Y = YAHOO,
5
+ yut = Y.util,
6
+ yud = yut.Dom,
7
+ yue = yut.Event;
8
+
9
+ // -- Constants --------------------------------------------------------------
10
+
11
+ /**
12
+ * URLs for lazy-loaded JavaScript dependencies.
13
+ *
14
+ * @const js
15
+ * @type Object
16
+ * @private
17
+ */
18
+ var js = {
19
+ thoth: {
20
+ comments : '/js/admin/comments.js',
21
+ name : '/js/admin/name.js',
22
+ tagcomplete: '/js/admin/tagcomplete.js'
23
+ },
24
+ yui: {
25
+ anim : 'http://yui.yahooapis.com/2.8.0/build/animation/animation-min.js',
26
+ conn_json: 'http://yui.yahooapis.com/combo?2.8.0/build/connection/connection-min.js&2.8.0/build/json/json-min.js'
27
+ }
28
+ };
29
+
30
+ // -- Private Variables ------------------------------------------------------
31
+ var hotKeys = {},
32
+ next, prev, token;
33
+
34
+ // -- Private Methods --------------------------------------------------------
35
+
36
+ /**
37
+ * Attaches keyboard shortcut event listeners.
38
+ *
39
+ * @method attachKeys
40
+ * @private
41
+ */
42
+ function attachKeys() {
43
+ var inputs = d.body.getElementsByTagName('input'),
44
+ selects = d.body.getElementsByTagName('select'),
45
+ textareas = d.body.getElementsByTagName('textarea');
46
+
47
+ next = yud.get('next_url');
48
+ prev = yud.get('prev_url');
49
+
50
+ hotKeys.ctrl_alt_a = new yut.KeyListener(d,
51
+ { ctrl: true, alt: true, keys: 65 }, Thoth.toggleAdminToolbar);
52
+
53
+ hotKeys.n = new yut.KeyListener(d, { keys: 78 }, handleKeyNext);
54
+ hotKeys.p = new yut.KeyListener(d, { keys: 80 }, handleKeyPrev);
55
+
56
+ // Stop listening for hotkeys when a form element gets focus.
57
+ yue.on(inputs, 'blur', enableKeys, Thoth, true);
58
+ yue.on(inputs, 'focus', disableKeys, Thoth, true);
59
+ yue.on(selects, 'blur', enableKeys, Thoth, true);
60
+ yue.on(selects, 'focus', disableKeys, Thoth, true);
61
+ yue.on(textareas, 'blur', enableKeys, Thoth, true);
62
+ yue.on(textareas, 'focus', disableKeys, Thoth, true);
63
+
64
+ enableKeys();
65
+ }
66
+
67
+ /**
68
+ * Disables all key listeners.
69
+ *
70
+ * @method disableKeys
71
+ * @private
72
+ */
73
+ function disableKeys() {
74
+ var key;
75
+
76
+ for (key in hotKeys) {
77
+ if (hotKeys.hasOwnProperty(key) && key !== 'ctrl_alt_a') {
78
+ hotKeys[key].disable();
79
+ }
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Enables all key listeners.
85
+ *
86
+ * @method enableKeys
87
+ * @private
88
+ */
89
+ function enableKeys() {
90
+ var key;
91
+
92
+ for (key in hotKeys) {
93
+ if (hotKeys.hasOwnProperty(key)) {
94
+ hotKeys[key].enable();
95
+ }
96
+ }
97
+ }
98
+
99
+ // -- Private Event Handlers -------------------------------------------------
100
+
101
+ /**
102
+ * Handles the "next page" keyboard shortcut.
103
+ *
104
+ * @method handleKeyNext
105
+ * @private
106
+ */
107
+ function handleKeyNext() {
108
+ if (next) {
109
+ window.location = next.href;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Handles the "previous page" keyboard shortcut.
115
+ *
116
+ * @method handleKeyPrev
117
+ * @private
118
+ */
119
+ function handleKeyPrev() {
120
+ if (prev) {
121
+ window.location = prev.href;
122
+ }
123
+ }
124
+
125
+ return {
126
+ // -- Constants ------------------------------------------------------------
127
+
128
+ /**
129
+ * URLs for lazy-loaded JavaScript dependencies.
130
+ *
131
+ * @const js
132
+ * @type Object
133
+ */
134
+ js: js,
135
+
136
+ // -- Public Methods -------------------------------------------------------
137
+
138
+ /**
139
+ * Initializes the Thoth module.
140
+ *
141
+ * @method init
142
+ * @param {Boolean} admin (optional) whether or not we're in admin mode
143
+ * @param {String} formToken (optional) admin form token for this request
144
+ */
145
+ init: function (admin, formToken) {
146
+ var load = [];
147
+
148
+ attachKeys();
149
+
150
+ if (admin) {
151
+ token = formToken;
152
+
153
+ // Load the Name module if this page contains one or more name input
154
+ // elements.
155
+ if (yud.get('page-form') || yud.get('post-form')) {
156
+ load.push(js.thoth.name);
157
+ }
158
+
159
+ // Load the TagComplete module if this page contains one or more tag
160
+ // input elements.
161
+ if (yud.get('post-form')) {
162
+ load.push(js.thoth.tagcomplete);
163
+ }
164
+
165
+ // Load the Comments module if this page contains comments.
166
+ if (yud.get('comments')) {
167
+ load.push(js.thoth.comments);
168
+ }
169
+
170
+ if (load.length) {
171
+ load.unshift(js.yui.conn_json);
172
+ LazyLoad.js(load);
173
+ }
174
+ }
175
+ },
176
+
177
+ /**
178
+ * Gets the administrator form token for this request, if any.
179
+ *
180
+ * @method getToken
181
+ * @return {String|null} form token, or <i>null</i> if user is not an admin
182
+ */
183
+ getToken: function () {
184
+ return token;
185
+ },
186
+
187
+ /**
188
+ * Toggles the visibility of the admin toolbar.
189
+ *
190
+ * @method toggleAdminToolbar
191
+ */
192
+ toggleAdminToolbar: function () {
193
+ var toolbar = yud.get('adminToolbar'),
194
+ username = yud.get('username');
195
+
196
+ if (yud.addClass(toolbar, 'hidden')) {
197
+ if (username) { username.blur(); }
198
+ } else if (yud.removeClass(toolbar, 'hidden')) {
199
+ if (username) { username.focus(); }
200
+ }
201
+ }
202
+ };
203
+ }();
@@ -0,0 +1,5 @@
1
+ # robots.txt file for Thoth
2
+
3
+ User-agent: *
4
+ Disallow: /comment/new
5
+ Disallow: /search
@@ -0,0 +1,37 @@
1
+ #--
2
+ # Copyright (c) 2017 John Pagonis <john@pagonis.org>
3
+ # Copyright (c) 2010 Ryan Grove <ryan@wonko.com>
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ # * Neither the name of this project nor the names of its contributors may be
15
+ # used to endorse or promote products derived from this software without
16
+ # specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ #++
29
+
30
+ module Thoth
31
+ APP_NAME = 'Rethoth'
32
+ APP_VERSION = '0.4.1'
33
+ APP_AUTHORS = ['John Pagonis' ,'Ryan Grove']
34
+ APP_EMAIL = 'john@pagonis.org'
35
+ APP_URL = 'https://github.com/pagojo/rethoth'
36
+ APP_COPYRIGHT = 'Copyright (c) 2009 - 2012 Ryan Grove <ryan@wonko.com>, 2017 John Pagonis <john@pagonis.org>. All rights reserved.'
37
+ end
@@ -0,0 +1 @@
1
+ <%= Thoth::AdminController.render_view(auth_key_valid? ? :welcome : :login) %>
@@ -0,0 +1,23 @@
1
+ <h2>Login</h2>
2
+
3
+ <% if flash[:login_error] %>
4
+ <div class="flash error"><%== flash[:login_error] %></div>
5
+ <% end %>
6
+
7
+ <form id="login_page" action="<%= Thoth::AdminController.r(:login) %>" method="post">
8
+ <p>
9
+ <label for="username">Username</label><br />
10
+ <input type="text" name="username" id="username" maxlength="255"
11
+ tabindex="1" />
12
+ </p>
13
+
14
+ <p>
15
+ <label for="password">Password</label><br />
16
+ <input type="password" name="password" id="password" maxlength="255"
17
+ tabindex="2" />
18
+ </p>
19
+
20
+ <p>
21
+ <input type="submit" value="Login" tabindex="3" />
22
+ </p>
23
+ </form>
@@ -0,0 +1,117 @@
1
+ <div id="adminToolbar" class="toolbar robots-nocontent<%= ' hidden' unless auth_key_valid? %>">
2
+ <% if auth_key_valid? %>
3
+ <ul class="edit">
4
+ <li>
5
+ <a href="<%= Thoth::PostController.r(:new) %>"
6
+ title="Create a new blog post">
7
+ <span class="adminicon post-new"></span>
8
+ </a>
9
+ </li>
10
+
11
+ <% if @show_post_edit && @post %>
12
+ <li>
13
+ <a href="<%= Thoth::PostController.r(:edit, @post.id) %>#post-form"
14
+ title="Edit this blog post">
15
+ <span class="adminicon post-edit"></span>
16
+ </a>
17
+ </li>
18
+
19
+ <li>
20
+ <a href="<%= Thoth::PostController.r(:delete, @post.id) %>"
21
+ title="Delete this blog post">
22
+ <span class="adminicon post-delete"></span>
23
+ </a>
24
+ </li>
25
+ <% end %>
26
+
27
+ <li>
28
+ <a href="<%= Thoth::PageController.r(:new) %>"
29
+ title="Create a new page">
30
+ <span class="adminicon page-new"></span>
31
+ </a>
32
+ </li>
33
+
34
+ <% if @show_page_edit && @page %>
35
+ <li>
36
+ <a href="<%= Thoth::PageController.r(:edit, @page.id) %>#page-form"
37
+ title="Edit this page">
38
+ <span class="adminicon page-edit"></span>
39
+ </a>
40
+ </li>
41
+
42
+ <li>
43
+ <a href="<%= Thoth::PageController.r(:delete, @page.id) %>"
44
+ title="Delete this page">
45
+ <span class="adminicon page-delete"></span>
46
+ </a>
47
+ </li>
48
+ <% end %>
49
+
50
+ <li>
51
+ <a href="<%= Thoth::MediaController.r(:new) %>" title="Upload media">
52
+ <span class="adminicon media-new"></span>
53
+ </a>
54
+ </li>
55
+
56
+ <% if @show_file_edit && @file %>
57
+ <li>
58
+ <a href="<%= Thoth::MediaController.r(:delete, @file.id) %>"
59
+ title="Delete this file">
60
+ <span class="adminicon media-delete"></span>
61
+ </a>
62
+ </li>
63
+ <% end %>
64
+ </ul>
65
+
66
+ <ul class="tools">
67
+ <li>
68
+ <a href="<%= Thoth::PostController.r(:list) %>" title="List all blog posts and drafts">
69
+ <span class="adminicon post-list"></span>
70
+ </a>
71
+ </li>
72
+
73
+ <li>
74
+ <a href="<%= Thoth::PageController.r(:list) %>" title="List all pages">
75
+ <span class="adminicon page-list"></span>
76
+ </a>
77
+ </li>
78
+
79
+ <% if Thoth::Config.site['enable_comments'] %>
80
+ <li>
81
+ <a href="<%= Thoth::CommentController.r(:list) %>" title="List all comments">
82
+ <span class="adminicon comment-list"></span>
83
+ </a>
84
+ </li>
85
+ <% end %>
86
+
87
+ <li>
88
+ <a href="<%= Thoth::MediaController.r(:list) %>" title="List all media">
89
+ <span class="adminicon media-list"></span>
90
+ </a>
91
+ </li>
92
+ </ul>
93
+
94
+ <ul class="tools">
95
+ <li>
96
+ <a href="<%= Thoth::AdminController.r(:logout) %>" title="Log out">
97
+ <span class="adminicon logout"></span>
98
+ </a>
99
+ </li>
100
+ </ul>
101
+
102
+ <% else %>
103
+ <form id="login" action="<%= Thoth::AdminController.r(:login) %>" method="post">
104
+ <div>
105
+ <label for="username">Username:</label>
106
+ <input type="text" id="username" name="username" maxlength="64"
107
+ title="Enter your username" />
108
+
109
+ <label for="password">Password:</label>
110
+ <input type="password" id="password" name="password" maxlength="64"
111
+ title="Enter your password" />
112
+
113
+ <input type="submit" value="Login" />
114
+ </div>
115
+ </form>
116
+ <% end %>
117
+ </div>
@@ -0,0 +1,58 @@
1
+ <div class="welcome">
2
+ <h2>Welcome to Thoth!</h2>
3
+ <span class="version">Version <%== Thoth::APP_VERSION %></span>
4
+
5
+ <h4>Getting Started</h4>
6
+
7
+ <p>
8
+ Use the icons in the admin toolbar above to create new blog posts and pages.
9
+ To edit an existing blog post or page, simply browse to it and an edit icon
10
+ will appear in the toolbar.
11
+ </p>
12
+
13
+ <p>
14
+ When you want to login again in the future, you can either return to
15
+ <a href="<%= rs() %>">this page</a> or use the keyboard shortcut
16
+ <kbd>Ctrl+Alt+A</kbd> to login quickly from any Thoth URL.
17
+ </p>
18
+
19
+ <h4>Customizing Thoth</h4>
20
+
21
+ <p>
22
+ Tired of the default template and want to design your own? Just fire up your
23
+ favorite text editor and open up these directories:
24
+ </p>
25
+
26
+ <dl class="customizing">
27
+ <dt>Default Views</dt>
28
+ <dd><code><%== @view_root %></code></dd>
29
+ <dt>Default CSS, JS, etc.</dt>
30
+ <dd><code><%== @public_root %></code></dd>
31
+
32
+ <dt>Custom Views</dt>
33
+ <dd><code><%== File.join(Thoth::HOME_DIR, 'view') %></code></dd>
34
+ <dt>Custom CSS, JS, etc.</dt>
35
+ <dd><code><%== File.join(Thoth::HOME_DIR, 'public') %></code></dd>
36
+ </dl>
37
+
38
+ <p>
39
+ To customise your blog, find the default view or static resource you
40
+ want to change and copy it to the corresponding custom directory, then make
41
+ your changes to the copy. Thoth looks for a customised file first, then
42
+ loads the default file if no customised version is found.
43
+ </p>
44
+
45
+ <p>
46
+ You'll need to know some XHTML and CSS (and a wee touch of Ruby wouldn't
47
+ hurt), but you should be able to figure it out. You seem like a smart sort
48
+ of bean.
49
+ </p>
50
+
51
+ <h4>Useful Linkage</h4>
52
+
53
+ <ul>
54
+ <li><a href="<%== Thoth::APP_URL %>">Thoth Website</a></li>
55
+ <li><a href="https://github.com/pagojo/rethoth/wiki">Thoth Wiki</a></li>
56
+ <li><a href="http://github.com/pagojo/rethoth/tree/master">Source Code</a></li>
57
+ </ul>
58
+ </div>
@@ -0,0 +1,24 @@
1
+ <h2>Archived Posts</h2>
2
+
3
+ <p class="robots-nocontent">
4
+ Displaying posts
5
+ <strong><%== @pager.current_page_record_range.first %></strong> -
6
+ <strong><%== @pager.current_page_record_range.last %></strong> of
7
+ <strong><%== @pager.record_count %></strong>
8
+ </p>
9
+
10
+ <%=
11
+ Thoth::MainController.render_view('util/pager',
12
+ :prev_text => '&laquo; Newer stuff',
13
+ :next_text => 'Older stuff &raquo;')
14
+ %>
15
+
16
+ <% @posts.all do |post| %>
17
+ <%= Thoth::PostController.render_view(:compact, :post => post) %>
18
+ <% end %>
19
+
20
+ <%=
21
+ Thoth::MainController.render_view('util/pager',
22
+ :prev_text => '&laquo; Newer stuff',
23
+ :next_text => 'Older stuff &raquo;')
24
+ %>
@@ -0,0 +1,47 @@
1
+ <div id="comment-<%= @comment.id %>" class="comment">
2
+ <div class="hd">
3
+ <% unless @comment.title.empty? %>
4
+ <h4>
5
+ <a href="<%== @comment.relative_url %>"><%== @comment.title %></a>
6
+ </h4>
7
+ <% end %>
8
+
9
+ <% if auth_key_valid? && !@comment.new? %>
10
+ <div class="toolbar mini">
11
+ <ul>
12
+ <li>
13
+ <a href="<%= Thoth::CommentController.r(:delete, @comment.id) %>"
14
+ title="Delete this comment">
15
+ <span class="adminicon comment-delete"></span>
16
+ </a>
17
+ </li>
18
+ </ul>
19
+ </div>
20
+ <% end %>
21
+ </div>
22
+
23
+ <div class="bd">
24
+ <%= @comment.body_rendered %>
25
+ </div>
26
+
27
+ <div class="ft">
28
+ <% if Thoth::Config.site['gravatar']['enabled'] && @comment.gravatar_url %>
29
+ <a class="gravatar" href="http://www.gravatar.com/" rel="nofollow"><img
30
+ src="<%== @comment.gravatar_url %>" alt="Gravatar icon" /></a>
31
+ <% end %>
32
+ <div class="author">
33
+ <% if @comment.author_url.empty? %>
34
+ <%== @comment.author %>
35
+ <% else %>
36
+ <a href="<%== @comment.author_url %>" rel="nofollow">
37
+ <%== @comment.author %>
38
+ </a>
39
+ <% end %>
40
+ </div>
41
+ <div class="date robots-nocontent">
42
+ <a href="<%== @comment.relative_url %>">
43
+ <%= @comment.created_at(Thoth::Config.timestamp['long']) %>
44
+ </a>
45
+ </div>
46
+ </div>
47
+ </div>
@@ -0,0 +1,15 @@
1
+ <h2>Delete Comment</h2>
2
+
3
+ <p>
4
+ Are you sure you want to permanently delete the following comment?
5
+ </p>
6
+
7
+ <%= Thoth::CommentController.render_view(:comment, :comment => @comment) %>
8
+
9
+ <form action="<%= Thoth::CommentController.r(:delete, @comment.id) %>" method="post">
10
+ <p>
11
+ <input type="hidden" name="token" value="<%== form_token %>" />
12
+ <button name="confirm" value="yes">Yes, delete this comment forever</button>
13
+ <button name="confirm" value="no">No, do not delete this comment</button>
14
+ </p>
15
+ </form>
@@ -0,0 +1,81 @@
1
+ <form id="post-comment" class="robots-nocontent" method="post" action="<%== @form_action %>">
2
+
3
+ <% if @comment && @comment.valid? %>
4
+ <fieldset>
5
+ <%= Thoth::CommentController.render_view(:comment, :comment => @comment) %>
6
+ </fieldset>
7
+ <% end %>
8
+
9
+ <fieldset>
10
+ <legend>New comment</legend>
11
+
12
+ <p>
13
+ <label for="author">Name</label>
14
+ <input type="text" name="author" id="author" maxlength="32"
15
+ title="Enter your name" value="<%== @author %>" />
16
+ </p>
17
+
18
+ <% if @comment; @comment.errors.on_field(:author).each do |error| %>
19
+ <div class="flash error"><%== error %></div>
20
+ <% end; end %>
21
+
22
+ <p>
23
+ <label for="author_email">Email</label>
24
+ <input type="text" name="author_email" id="author_email" maxlength="255"
25
+ title="Enter your email address" value="<%== @author_email %>" />
26
+ <span class="tip">required, won't be displayed (but may be used for Gravatar)</span>
27
+ </p>
28
+
29
+ <% if @comment; @comment.errors.on_field(:author_email).each do |error| %>
30
+ <div class="flash error"><%== error %></div>
31
+ <% end; end %>
32
+
33
+ <p>
34
+ <label for="author_url">Website</label>
35
+ <input type="text" name="author_url" id="author_url" maxlength="255"
36
+ title="Enter the URL of your website (optional)"
37
+ value="<%== @author_url %>" />
38
+ <span class="tip">optional</span>
39
+ </p>
40
+
41
+ <% if @comment; @comment.errors.on_field(:author_url).each do |error| %>
42
+ <div class="flash error"><%== error %></div>
43
+ <% end; end %>
44
+
45
+ <p>
46
+ <textarea name="body" rows="15" cols="60"><%== @comment && @comment.body ? @comment.body : '' %></textarea>
47
+ </p>
48
+
49
+ <% if @comment; @comment.errors.on_field(:body).each do |error| %>
50
+ <div class="flash error"><%== error %></div>
51
+ <% end; end %>
52
+
53
+ <p class="noseeum">
54
+ Don't type anything here unless you're an evil robot:<br />
55
+ <input type="text" id="captcha" name="captcha" maxlength="50" />
56
+
57
+ <br /><br />
58
+ And especially don't type anything here:<br />
59
+ <textarea name="comment" rows="6" cols="60"></textarea>
60
+ </p>
61
+
62
+ <% if @comment_error %>
63
+ <div class="flash error"><%== @comment_error %></div>
64
+ <% end %>
65
+
66
+ <p>
67
+ <input type="submit" name="action" value="Preview Comment" />
68
+ <input type="submit" name="action" value="Post Comment" />
69
+ <input type="hidden" name="post_id" value="<%== @post.id %>" />
70
+ <input type="hidden" name="comment_id"
71
+ value="<%== @comment && @comment.id ? @comment.id : '' %>" />
72
+ </p>
73
+
74
+ <p class="tip">
75
+ Basic HTML (including links) is allowed, just don't try anything fishy.
76
+ Your comment will be auto-formatted unless you use your own
77
+ <code>&lt;p&gt;</code> tags for formatting. You're also welcome to use
78
+ <a href="http://redcloth.org/textile" target="_blank">Textile</a>.
79
+ </p>
80
+ </fieldset>
81
+ </form>