shinmun 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/LICENSE +18 -0
- data/README.md +249 -0
- data/Rakefile +60 -0
- data/bin/shinmun +12 -0
- data/example/posts/2008/9/example.md +19 -0
- data/example/posts/blog.yml +10 -0
- data/example/posts/uuid.state +3 -0
- data/example/public/controllers/comments.php +56 -0
- data/example/public/images/loading.gif +0 -0
- data/example/public/javascripts/comments.js +60 -0
- data/example/public/javascripts/highlight.js +505 -0
- data/example/public/javascripts/images/bg-fill.png +0 -0
- data/example/public/javascripts/images/bg.png +0 -0
- data/example/public/javascripts/images/blockquote.png +0 -0
- data/example/public/javascripts/images/bold.png +0 -0
- data/example/public/javascripts/images/code.png +0 -0
- data/example/public/javascripts/images/h1.png +0 -0
- data/example/public/javascripts/images/hr.png +0 -0
- data/example/public/javascripts/images/img.png +0 -0
- data/example/public/javascripts/images/italic.png +0 -0
- data/example/public/javascripts/images/link.png +0 -0
- data/example/public/javascripts/images/ol.png +0 -0
- data/example/public/javascripts/images/redo.png +0 -0
- data/example/public/javascripts/images/separator.png +0 -0
- data/example/public/javascripts/images/ul.png +0 -0
- data/example/public/javascripts/images/undo.png +0 -0
- data/example/public/javascripts/images/wmd-on.png +0 -0
- data/example/public/javascripts/images/wmd.png +0 -0
- data/example/public/javascripts/jquery-form.js +869 -0
- data/example/public/javascripts/jquery.js +3383 -0
- data/example/public/javascripts/languages/1c.js +82 -0
- data/example/public/javascripts/languages/axapta.js +52 -0
- data/example/public/javascripts/languages/bash.js +80 -0
- data/example/public/javascripts/languages/diff.js +64 -0
- data/example/public/javascripts/languages/dos.js +33 -0
- data/example/public/javascripts/languages/dynamic.js +460 -0
- data/example/public/javascripts/languages/ini.js +36 -0
- data/example/public/javascripts/languages/javascript.js +38 -0
- data/example/public/javascripts/languages/lisp.js +86 -0
- data/example/public/javascripts/languages/mel.js +50 -0
- data/example/public/javascripts/languages/profile.js +50 -0
- data/example/public/javascripts/languages/renderman.js +71 -0
- data/example/public/javascripts/languages/smalltalk.js +53 -0
- data/example/public/javascripts/languages/sql.js +50 -0
- data/example/public/javascripts/languages/static.js +175 -0
- data/example/public/javascripts/languages/vbscript.js +25 -0
- data/example/public/javascripts/languages/www.js +245 -0
- data/example/public/javascripts/prettyDate.js +36 -0
- data/example/public/javascripts/showdown.js +421 -0
- data/example/public/javascripts/template.js +165 -0
- data/example/public/javascripts/wmd-base.js +1799 -0
- data/example/public/javascripts/wmd-plus.js +311 -0
- data/example/public/javascripts/wmd.js +73 -0
- data/example/public/stylesheets/grid.css +243 -0
- data/example/public/stylesheets/grid.png +0 -0
- data/example/public/stylesheets/highlight/ascetic.css +38 -0
- data/example/public/stylesheets/highlight/dark.css +96 -0
- data/example/public/stylesheets/highlight/default.css +91 -0
- data/example/public/stylesheets/highlight/far.css +95 -0
- data/example/public/stylesheets/highlight/idea.css +75 -0
- data/example/public/stylesheets/highlight/sunburst.css +112 -0
- data/example/public/stylesheets/highlight/zenburn.css +108 -0
- data/example/public/stylesheets/print.css +76 -0
- data/example/public/stylesheets/reset.css +45 -0
- data/example/public/stylesheets/style.css +141 -0
- data/example/public/stylesheets/typography.css +59 -0
- data/example/templates/feed.rxml +21 -0
- data/example/templates/layout.rhtml +54 -0
- data/example/templates/page.rhtml +4 -0
- data/example/templates/post.rhtml +57 -0
- data/example/templates/posts.rhtml +10 -0
- data/lib/shinmun.rb +420 -0
- metadata +151 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*~
|
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2008 Matthias Georgi <http://www.matthias-georgi.de>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,249 @@
|
|
1
|
+
Shinmun, a small and beautiful blog engine
|
2
|
+
==========================================
|
3
|
+
|
4
|
+
### Intro
|
5
|
+
|
6
|
+
Shinmun is a **minimalist blog engine**. You just write posts as text files,
|
7
|
+
render them to static files and push your blog to your server.
|
8
|
+
|
9
|
+
This allows you to write posts in your favorite editor like Emacs or
|
10
|
+
VI and use a VCS like git.
|
11
|
+
|
12
|
+
Your layout can be customized by set of *ERB templates*. These
|
13
|
+
templates have access to `Post` objects and *helper methods* so that
|
14
|
+
anybody who knows *Rails* should feel comfortable with it.
|
15
|
+
|
16
|
+
Shinmun has some common features of blog engines like:
|
17
|
+
|
18
|
+
* Index summary page
|
19
|
+
* Category summary page
|
20
|
+
* Archive pages for each month
|
21
|
+
* RSS feeds for index and category pages
|
22
|
+
* AJAX comment system with PHP JSON file storage
|
23
|
+
* Integration of the WMD-Markdown Editor for comments
|
24
|
+
|
25
|
+
### Quickstart
|
26
|
+
|
27
|
+
Install the gem by typing:
|
28
|
+
gem install shinmun
|
29
|
+
|
30
|
+
Issue the following commands and the output will go to the public
|
31
|
+
folder:
|
32
|
+
|
33
|
+
cd example
|
34
|
+
../bin/shinmun
|
35
|
+
|
36
|
+
### Writing Posts
|
37
|
+
|
38
|
+
Posts can be created by using the `shinmun` command inside your blog folder:
|
39
|
+
|
40
|
+
shinmun new 'The title of the post'
|
41
|
+
|
42
|
+
Shinmun will then create a post file in the right place, for example
|
43
|
+
in `posts/2008/9/the-title-of-the-post.md`. After creating you will
|
44
|
+
probably open the file, set the category and start writing your new
|
45
|
+
article.
|
46
|
+
|
47
|
+
After finishing your post, you may just run `shinmun` without arguments
|
48
|
+
and the output will be rendered to the *public* folder.
|
49
|
+
|
50
|
+
|
51
|
+
### Post Format
|
52
|
+
|
53
|
+
Each blog post is just a text file with an optional header section and
|
54
|
+
a markup body, which are separated by a newline.
|
55
|
+
|
56
|
+
The **first line** of the header should start with 3 dashes as usual
|
57
|
+
for a YAML document.
|
58
|
+
|
59
|
+
The **first and the second line** of the body becomes the title of the
|
60
|
+
post.
|
61
|
+
|
62
|
+
The header may have following attributes:
|
63
|
+
|
64
|
+
* `date`: post will show up in blog page and archive pages
|
65
|
+
* `category`: post will show up in the defined category page
|
66
|
+
* `guid`: will be set automatically by Shinmun
|
67
|
+
|
68
|
+
Posts without a date are by definition static pages.
|
69
|
+
|
70
|
+
Example post:
|
71
|
+
|
72
|
+
<pre>
|
73
|
+
|
74
|
+
---
|
75
|
+
category: Ruby
|
76
|
+
date: 2008-09-05
|
77
|
+
guid: 7ad04f10-5dd6-012b-b53c-001a92975b89
|
78
|
+
|
79
|
+
BlueCloth, a Markdown library
|
80
|
+
=============================
|
81
|
+
|
82
|
+
This is the summary, which is by definition the first paragraph of the
|
83
|
+
article. The summary shows up in category listings or the index listing.
|
84
|
+
|
85
|
+
</pre>
|
86
|
+
|
87
|
+
The guid should never change, as it will be you used for identifying
|
88
|
+
posts for comments.
|
89
|
+
|
90
|
+
|
91
|
+
### Directory layout
|
92
|
+
|
93
|
+
* All your **posts** reside in the `posts` folder sorted by year/month.
|
94
|
+
|
95
|
+
* All the **output** will be rendered to the `public` folder.
|
96
|
+
|
97
|
+
* **Template** files are in the `templates` folder.
|
98
|
+
|
99
|
+
* The **properties of your blog** defined in `posts/blog.yml`
|
100
|
+
|
101
|
+
* **Static files** should be put into the directories `public/images`,
|
102
|
+
`public/stylesheets`, `public/javascripts`.
|
103
|
+
|
104
|
+
* Archive pages will be rendered to files like `public/2008/9/index.html`.
|
105
|
+
|
106
|
+
* Category pages will be rendered to files like `public/categories/ruby.html`.
|
107
|
+
|
108
|
+
* The *home page* of your blog will go to `public/index.html`.
|
109
|
+
|
110
|
+
An example tree:
|
111
|
+
|
112
|
+
+ posts
|
113
|
+
+ blog.yml
|
114
|
+
+ about.md
|
115
|
+
+ 2007
|
116
|
+
+ 2008
|
117
|
+
+ 9
|
118
|
+
+ my-article.md
|
119
|
+
|
120
|
+
+ public
|
121
|
+
+ index.html
|
122
|
+
+ about.html
|
123
|
+
+ categories
|
124
|
+
+ emacs.html
|
125
|
+
+ ruby.html
|
126
|
+
+ 2007
|
127
|
+
+ 2008
|
128
|
+
+ 9
|
129
|
+
+ my-article.html
|
130
|
+
+ images
|
131
|
+
+ stylesheets
|
132
|
+
+ javascripts
|
133
|
+
|
134
|
+
+ templates
|
135
|
+
+ feed.rxml
|
136
|
+
+ layout.rhtml
|
137
|
+
+ page.rhtml
|
138
|
+
+ post.rhtml
|
139
|
+
+ posts.rhtml
|
140
|
+
|
141
|
+
|
142
|
+
### Layout
|
143
|
+
|
144
|
+
Layout and templates are rendered by *ERB*. The layout is defined in
|
145
|
+
`layout.rhtml`. The content will be provided in the variable
|
146
|
+
`@content`. A minimal example:
|
147
|
+
|
148
|
+
<html>
|
149
|
+
<head>
|
150
|
+
<title><%= @blog_title %></title>
|
151
|
+
<%= stylesheet_link_tag 'style' %>
|
152
|
+
</head>
|
153
|
+
<body>
|
154
|
+
<%= @content %>
|
155
|
+
</body>
|
156
|
+
</html>
|
157
|
+
|
158
|
+
|
159
|
+
### Helpers
|
160
|
+
|
161
|
+
There are also helper methods, which work the same way like the *Rails*
|
162
|
+
helpers. The most important ones are these:
|
163
|
+
|
164
|
+
* `stylesheet_link_tag(*names)` links a stylesheet with a timestamp
|
165
|
+
|
166
|
+
* `javascript_tag(*names)` includes a javascript with a timestamp
|
167
|
+
|
168
|
+
* `image_tag(src, options = {})` renders an image tag
|
169
|
+
|
170
|
+
* `link_to(text, path, options = {})` renders a link
|
171
|
+
|
172
|
+
Stylesheets, javascripts and images should be included by using theses
|
173
|
+
helpers. The helper methods will include a timestamp of the
|
174
|
+
modification time as `querystring`, so that the browser will fetch the
|
175
|
+
new resource if it has been changed.
|
176
|
+
|
177
|
+
|
178
|
+
### Post Template
|
179
|
+
|
180
|
+
The attributes of a post are accessible as instance variables in a template:
|
181
|
+
|
182
|
+
<div class="article">
|
183
|
+
|
184
|
+
<div class="date">
|
185
|
+
<%= date @date %>
|
186
|
+
</div>
|
187
|
+
|
188
|
+
<h2><%= @title %></h2>
|
189
|
+
|
190
|
+
<%= @body %>
|
191
|
+
|
192
|
+
<h3>Comments</h3>
|
193
|
+
|
194
|
+
<!-- Here you may put my commenting system -->
|
195
|
+
</div>
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
### RSS Feeds
|
200
|
+
|
201
|
+
Feeds will be rendered by one *ERB template*. Some of the variables
|
202
|
+
have been read from the `blog.yml`, like `@blog_title`, other variables
|
203
|
+
have been determined by the engine like `@posts` and `@category`.
|
204
|
+
|
205
|
+
<?xml version="1.0" encoding="utf-8"?>
|
206
|
+
<rss version="2.0">
|
207
|
+
<channel>
|
208
|
+
<title><%= @category ? @blog_title + ' - ' + @category : @blog_title %></title>
|
209
|
+
<link><%= @blog_url %></link>
|
210
|
+
<description><%= @category ? 'Category ' + @category : @blog_description %></description>
|
211
|
+
<language><%= @blog_language %></language>
|
212
|
+
<copyright><%= @blog_author %></copyright>
|
213
|
+
<pubDate><%= rfc822 Time.now %></pubDate>
|
214
|
+
<% for post in @posts %>
|
215
|
+
<item>
|
216
|
+
<title><%= post.title %></title>
|
217
|
+
<description><%= post.text_summary %></description>
|
218
|
+
<link><%= post.link %></link>
|
219
|
+
<author><%= @blog_author %></author>
|
220
|
+
<guid><%= post.guid %></guid>
|
221
|
+
<pubDate><%= rfc822 post.date %></pubDate>
|
222
|
+
</item>
|
223
|
+
<% end %>
|
224
|
+
</channel>
|
225
|
+
</rss>
|
226
|
+
|
227
|
+
### Commenting System
|
228
|
+
|
229
|
+
As I am not willing to build up a whole Rails stack for a single blog,
|
230
|
+
I was looking for a simple storage for comments. I really like the
|
231
|
+
JSON format. It works seamlessly with Javascript libraries and can be
|
232
|
+
serialized and deserialized from almost any language.
|
233
|
+
|
234
|
+
Read about my [lightweight commenting system][2].
|
235
|
+
|
236
|
+
|
237
|
+
### Download
|
238
|
+
|
239
|
+
Simply install the gem:
|
240
|
+
|
241
|
+
gem install shinmun
|
242
|
+
|
243
|
+
|
244
|
+
Download or fork the package at my [github repository][1]
|
245
|
+
|
246
|
+
|
247
|
+
|
248
|
+
[1]: http://github.com/georgi/shinmun/tree/master
|
249
|
+
[2]: commenting-system-with-lightweight-json-store.html
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/packagetask'
|
7
|
+
require 'rake/gempackagetask'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
spec = Gem::Specification.new do |s|
|
11
|
+
s.name = "shinmun"
|
12
|
+
s.version = `git describe`.strip.sub(/-.*/, '')
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.summary = "a small blog engine"
|
15
|
+
|
16
|
+
s.description = <<-EOF
|
17
|
+
Shinmun is a blog engine, which renders text files using a markup
|
18
|
+
language like Markdown and a set of templates into static web
|
19
|
+
pages. It supports Categories, Archives and RSS Feeds. Commenting can
|
20
|
+
be done with some Javascript, PHP and a flat file JSON store.
|
21
|
+
EOF
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.bindir = 'bin'
|
25
|
+
s.executables << 'shinmun'
|
26
|
+
s.require_path = 'lib'
|
27
|
+
s.add_dependency 'uuid', '>=2.0.0'
|
28
|
+
s.add_dependency 'BlueCloth', '>=1.0.0'
|
29
|
+
s.add_dependency 'rubypants', '>=0.2.0'
|
30
|
+
s.has_rdoc = true
|
31
|
+
s.extra_rdoc_files = ['README.md']
|
32
|
+
|
33
|
+
s.author = 'Matthias Georgi'
|
34
|
+
s.email = 'matti.georgi@gmail.com'
|
35
|
+
s.homepage = 'http://shinmun.rubyforge.org'
|
36
|
+
s.rubyforge_project = 'shinmun'
|
37
|
+
end
|
38
|
+
|
39
|
+
Rake::GemPackageTask.new(spec) do |p|
|
40
|
+
p.gem_spec = spec
|
41
|
+
p.need_tar = false
|
42
|
+
p.need_zip = false
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
desc "Generate RDoc documentation"
|
47
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
48
|
+
rdoc.options << '--line-numbers' << '--inline-source' <<
|
49
|
+
'--main' << 'README' <<
|
50
|
+
'--title' << 'Shinmun Documentation' <<
|
51
|
+
'--charset' << 'utf-8'
|
52
|
+
rdoc.rdoc_dir = "doc"
|
53
|
+
rdoc.rdoc_files.include 'README.md'
|
54
|
+
rdoc.rdoc_files.include('lib/shinmun.rb')
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
task :push => [:rdoc] do
|
59
|
+
sh "rsync -avz doc/ mgeorgi@rack.rubyforge.org:/var/www/gforge-projects/shinmun"
|
60
|
+
end
|
data/bin/shinmun
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
category: Ruby
|
3
|
+
guid: 72ece880-5e32-012b-362f-001a92975b89
|
4
|
+
date: 2008-09-01
|
5
|
+
|
6
|
+
Example post
|
7
|
+
============
|
8
|
+
|
9
|
+
This is the first paragraph. Below is a code example:
|
10
|
+
|
11
|
+
# Return the first paragraph of rendered html.
|
12
|
+
def summary
|
13
|
+
body.split("\n\n")[0]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return the first paragraph of source text.
|
17
|
+
def text_summary
|
18
|
+
src.split("\n\n")[1]
|
19
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<?php
|
2
|
+
|
3
|
+
$guid_pattern = "/^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/";
|
4
|
+
$req = $_REQUEST;
|
5
|
+
$guid = $req['guid'];
|
6
|
+
|
7
|
+
preg_match($guid_pattern, $guid) or die("invalid guid");
|
8
|
+
|
9
|
+
$file = 'comments/' . $guid;
|
10
|
+
|
11
|
+
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
12
|
+
|
13
|
+
// create a comment record
|
14
|
+
$record = array(date('Y-m-d H:i:s'),
|
15
|
+
strip_tags(stripslashes($req['name'])),
|
16
|
+
strip_tags(stripslashes($req['website'])),
|
17
|
+
strip_tags(stripslashes($req['text'])));
|
18
|
+
|
19
|
+
// encode as json string
|
20
|
+
$json = json_encode($record) . "\n";
|
21
|
+
|
22
|
+
// open the comment file for appending
|
23
|
+
$fp = fopen($file, "a");
|
24
|
+
|
25
|
+
// acquire a write lock
|
26
|
+
flock($fp, LOCK_EX);
|
27
|
+
|
28
|
+
// append the json line
|
29
|
+
fwrite($fp, $json);
|
30
|
+
|
31
|
+
// release lock
|
32
|
+
flock($fp, LOCK_UN);
|
33
|
+
|
34
|
+
// close file and release lock
|
35
|
+
fclose($fp);
|
36
|
+
}
|
37
|
+
|
38
|
+
if (file_exists($file)) {
|
39
|
+
|
40
|
+
// open the comment file for reading
|
41
|
+
$fp = fopen($file, "r");
|
42
|
+
|
43
|
+
// acquire a read lock
|
44
|
+
flock($fp, LOCK_SH);
|
45
|
+
|
46
|
+
// read whole file and print it out
|
47
|
+
echo fread($fp, filesize($file));
|
48
|
+
|
49
|
+
// release lock
|
50
|
+
flock($fp, LOCK_UN);
|
51
|
+
|
52
|
+
// close file
|
53
|
+
fclose($fp);
|
54
|
+
}
|
55
|
+
|
56
|
+
?>
|
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
$('.comment-form form').ajaxForm({
|
2
|
+
url: Blog.root + 'controllers/comments.php',
|
3
|
+
type: 'POST',
|
4
|
+
resetForm: true,
|
5
|
+
beforeSubmit: function(values) {
|
6
|
+
if (values[1].value && values[3].value) {
|
7
|
+
$('.comment-form-loading').show();
|
8
|
+
return true;
|
9
|
+
}
|
10
|
+
else {
|
11
|
+
alert('Please enter name and text!');
|
12
|
+
return false;
|
13
|
+
}
|
14
|
+
},
|
15
|
+
success: function(data) {
|
16
|
+
$('.comment-form-loading').hide();
|
17
|
+
renderComments(data);
|
18
|
+
}
|
19
|
+
});
|
20
|
+
|
21
|
+
function renderComments(data) {
|
22
|
+
var converter = new Showdown.converter();
|
23
|
+
var lines = data.split("\n");
|
24
|
+
var comments = [];
|
25
|
+
for (var i = 0; i < lines.length; i++) {
|
26
|
+
var row = eval(lines[i]);
|
27
|
+
if (row) {
|
28
|
+
comments.push({
|
29
|
+
time: row[0],
|
30
|
+
name: row[1],
|
31
|
+
website: row[2],
|
32
|
+
text: converter.makeHtml(row[3])
|
33
|
+
});
|
34
|
+
}
|
35
|
+
}
|
36
|
+
$('.comments-loading').hide();
|
37
|
+
$('.comments').expand(Template.comments, { comment: comments });
|
38
|
+
$('.comments a').prettyDate();
|
39
|
+
}
|
40
|
+
|
41
|
+
function loadComments() {
|
42
|
+
$('.comments-loading').show();
|
43
|
+
$.ajax({
|
44
|
+
type: "GET",
|
45
|
+
url: Blog.root + 'controllers/comments.php',
|
46
|
+
data: {
|
47
|
+
guid: Blog.guid
|
48
|
+
},
|
49
|
+
complete: function(response) {
|
50
|
+
renderComments(response.responseText);
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
$(function() {
|
56
|
+
if ($('.comments').length > 0) {
|
57
|
+
Template.comments = new Template('comments-template');
|
58
|
+
loadComments();
|
59
|
+
}
|
60
|
+
});
|