postview 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/HISTORY +67 -0
  2. data/INFO +14 -0
  3. data/LICENSE +0 -0
  4. data/README.rdoc +103 -0
  5. data/Rakefile +174 -0
  6. data/VERSION +8 -0
  7. data/bin/postview +51 -0
  8. data/lib/postview.rb +68 -0
  9. data/lib/postview/about.rb +34 -0
  10. data/lib/postview/application.rb +130 -0
  11. data/lib/postview/cli.rb +71 -0
  12. data/lib/postview/cli/create_command.rb +362 -0
  13. data/lib/postview/cli/server_command.rb +115 -0
  14. data/lib/postview/helpers.rb +21 -0
  15. data/lib/postview/patches.rb +11 -0
  16. data/lib/postview/settings.rb +107 -0
  17. data/lib/postview/site.rb +51 -0
  18. data/lib/postview/version.rb +27 -0
  19. data/tasks/documentation.rake +21 -0
  20. data/tasks/history.rake +7 -0
  21. data/tasks/homepage.rake +10 -0
  22. data/tasks/package.rake +11 -0
  23. data/tasks/version.rake +56 -0
  24. data/test/application_test.rb +122 -0
  25. data/test/extensions.rb +23 -0
  26. data/test/fixtures/application/config.ru +6 -0
  27. data/test/fixtures/application/config/settings.yml +22 -0
  28. data/test/fixtures/application/empty.yml +0 -0
  29. data/test/fixtures/application/posts/20090529-postview_blogware.ruby.sinatra.mkd +4 -0
  30. data/test/fixtures/application/posts/20090602-postview_blogware.ruby.sinatra.mkd +4 -0
  31. data/test/fixtures/application/posts/archive/20080529-postview_blogware.ruby.sinatra.mkd +4 -0
  32. data/test/fixtures/application/posts/archive/20080602-postview_blogware.ruby.sinatra.mkd +4 -0
  33. data/test/fixtures/application/posts/drafts/20090730-draft_postview_blogware.ruby.sinatra.mkd +4 -0
  34. data/test/fixtures/application/themes/gemstone/about.erb +0 -0
  35. data/test/fixtures/application/themes/gemstone/archive/index.erb +0 -0
  36. data/test/fixtures/application/themes/gemstone/archive/show.erb +17 -0
  37. data/test/fixtures/application/themes/gemstone/images/banners/banner.jpg +0 -0
  38. data/test/fixtures/application/themes/gemstone/images/favicon.ico +0 -0
  39. data/test/fixtures/application/themes/gemstone/images/trojan.com +0 -0
  40. data/test/fixtures/application/themes/gemstone/index.erb +0 -0
  41. data/test/fixtures/application/themes/gemstone/javascripts/gemstone.js +1 -0
  42. data/test/fixtures/application/themes/gemstone/layout.erb +0 -0
  43. data/test/fixtures/application/themes/gemstone/posts/index.erb +0 -0
  44. data/test/fixtures/application/themes/gemstone/posts/show.erb +0 -0
  45. data/test/fixtures/application/themes/gemstone/search.erb +0 -0
  46. data/test/fixtures/application/themes/gemstone/stylesheets/gemstone.css +1 -0
  47. data/test/fixtures/application/themes/gemstone/tags/index.erb +0 -0
  48. data/test/fixtures/application/themes/gemstone/tags/show.erb +0 -0
  49. data/test/helper.rb +9 -0
  50. data/test/settings_test.rb +72 -0
  51. data/test/site_test.rb +62 -0
  52. data/themes/default/about.erb +24 -0
  53. data/themes/default/archive/index.erb +21 -0
  54. data/themes/default/archive/show.erb +17 -0
  55. data/themes/default/error.erb +0 -0
  56. data/themes/default/images/favicon.ico +0 -0
  57. data/themes/default/images/logo.png +0 -0
  58. data/themes/default/images/navigation-bar.gif +0 -0
  59. data/themes/default/images/postview.png +0 -0
  60. data/themes/default/images/rack.png +0 -0
  61. data/themes/default/images/ruby.png +0 -0
  62. data/themes/default/images/sinatra.png +0 -0
  63. data/themes/default/index.erb +38 -0
  64. data/themes/default/layout.erb +117 -0
  65. data/themes/default/posts/index.erb +21 -0
  66. data/themes/default/posts/show.erb +17 -0
  67. data/themes/default/search.erb +40 -0
  68. data/themes/default/stylesheets/postview.css +238 -0
  69. data/themes/default/tags/index.erb +12 -0
  70. data/themes/default/tags/show.erb +40 -0
  71. metadata +158 -0
@@ -0,0 +1,34 @@
1
+ module Postview
2
+
3
+ # Copyright (c) Hallison Batista
4
+ module About #:nodoc: all
5
+
6
+ class << self
7
+
8
+ def info
9
+ @about ||= OpenStruct.new(YAML.load_file(File.join(ROOT, "INFO")))
10
+ end
11
+
12
+ def to_s
13
+ <<-end_info.gsub(/ /,'')
14
+ #{Version}
15
+
16
+ Copyright (c) #{Version.info.timestamp.year} #{info.authors.join(', ')}
17
+
18
+ #{info.description}
19
+
20
+ For more information, please see the project homepage <#{info.homepage}>.
21
+ Bugs, enhancements and improvements, please send message to <#{info.email}>.
22
+ end_info
23
+ end
24
+
25
+ def to_html
26
+ Maruku.new(to_s).to_html
27
+ end
28
+
29
+ end
30
+
31
+ end # module About
32
+
33
+ end # module Postview
34
+
@@ -0,0 +1,130 @@
1
+ module Postview
2
+
3
+ # Copyright (c) 2009 Hallison Batista
4
+ class Application < Sinatra::Base #:nodoc: all
5
+
6
+ register Sinatra::Mapping
7
+
8
+ configure do
9
+ set :settings, Postview::Settings.load
10
+ set :site, settings.build_site
11
+ set :page, settings.build_page
12
+
13
+ set :static, true
14
+
15
+ set :root, Postview::PATH
16
+ set :public, Postview::PATH.join("public")
17
+ set :views, Postview::PATH.join("themes", site.theme)
18
+
19
+ map :theme, "/"
20
+
21
+ mapping settings.sections
22
+ end
23
+
24
+ before do
25
+ @settings = options.settings
26
+ @site = options.site
27
+ @page = options.page
28
+ @tags = @site.find_all_tags
29
+ @posts = @site.find.all_posts.reverse
30
+ @archive = @site.find_archived.all_posts.reverse
31
+ end
32
+
33
+ helpers Postview::Helpers
34
+
35
+ # Get theme resources
36
+ # TOFIX: Check security and other problems
37
+ get theme_path "/:resource/*.*" do |resource, file, ext|
38
+ send_file options.views.join(resource, "#{file}.#{ext}")
39
+ end
40
+
41
+ # Show only the last 5 posts.
42
+ get root_path do
43
+ @posts = @site.find.all_posts.limit(5).reverse
44
+ @page.title, @page.keywords = @site.subtitle, "posts"
45
+ show :index, :posts_path => :posts, :tags_path => :tags
46
+ end
47
+
48
+ # Show all posts.
49
+ get posts_path do
50
+ @page.title, @page.keywords = title_path(:posts), @tags.join(' ')
51
+ show :"posts/index", :posts_path => :posts, :tags_path => :tags
52
+ end
53
+
54
+ # Show selected post.
55
+ get posts_path "/:year/:month/:day/:name" do |year, month, day, name|
56
+ @post = @site.find.post(year, month, day, name)
57
+ @page.title, @page.keywords = @post.title, @post.tags.join(' ')
58
+ show :"posts/show", :posts_path => :posts, :tags_path => :tags
59
+ end
60
+
61
+ # Show all tags.
62
+ get tags_path do
63
+ @page.title, @page.keywords = title_path(:tags), @tags.join(' ')
64
+ show :"tags/index", :posts_path => :posts, :tags_path => :tags
65
+ end
66
+
67
+ # Show all posts by selected tag.
68
+ get tags_path "/:tag" do |tag|
69
+ @tag = @site.find_tag(tag)
70
+ @posts = @site.find.all_posts_by_tag(tag)
71
+ @archive = @site.find_archived.all_posts_by_tag(tag)
72
+ @page.title, @page.keywords = "#{title_path(:tags)} - #{@tag.capitalize}", "posts #{@tag}" unless @posts.empty?
73
+ show :"tags/show", :posts_path => :posts, :archive_path => :archive, :tags_path => :tags
74
+ end
75
+
76
+ # Show archives grouped by year.
77
+ get archive_path do
78
+ @posts = @site.find_archived.all_posts.reverse
79
+ @page.title, @page.keywords = title_path(:archive), @tags.join(' ')
80
+ show :"archive/index", :archive_path => :archive, :posts_path => :archive, :tags_path => :tags
81
+ end
82
+
83
+ # Show selected post in archive.
84
+ get archive_path "/:year/:month/:day/:name" do |year, month, day, name|
85
+ @post = @site.find_archived.post(year, month, day, name)
86
+ @posts = @site.find_archived.all_posts.reverse
87
+ @tags = @site.find_archived.all_tags
88
+ @page.title, @page.keywords = @post.title, @post.tags.join(' ')
89
+ show :"archive/show", :posts_path => :archive, :tags_path => :tags
90
+ end
91
+
92
+ # Show all drafts.
93
+ get drafts_path do
94
+ @posts = @site.find_drafted.all_posts.reverse
95
+ @tags = @site.find_drafted.all_tags.sort
96
+ @page.title, @page.keywords = title_path(:drafts), "drafts #{@tags.join(' ')}"
97
+ show :"posts/index", :posts_path => :drafts, :tags_path => [:drafts, :tags]
98
+ end
99
+
100
+ # Show selected drafted post.
101
+ get drafts_path "/:year/:month/:day/:name" do |year, month, day, name|
102
+ @post = @site.find_drafted.post(year, month, day, name)
103
+ @posts = @site.find_drafted.all_posts.reverse
104
+ @tags = @site.find_drafted.all_tags.sort
105
+ @page.title, @page.keywords = @post.title, @post.tags.join(' ')
106
+ show :"posts/show", :posts_path => :drafts, :tags_path => [:drafts, :tags]
107
+ end
108
+
109
+ # Show information site.
110
+ get about_path do
111
+ show :about, :about_path => :about, :posts_path => :posts, :tags_path => :tags
112
+ end
113
+
114
+ # Search posts by title or match file name.
115
+ get search_path do
116
+ @posts = @site.find.posts(*params.values)
117
+ @archive = @site.find_archived.posts(*params.values)
118
+ @page.title, @page.keywords = title_path(:search), @tags.join(' ')
119
+ show :search, :posts_path => :posts, :tags_path => :tags, :archive_path => :archive, :search_path => :search
120
+ end
121
+
122
+ def show(template, locals = {}, options = {})
123
+ erb template, options.update(:locals => locals)
124
+ end
125
+ private :show
126
+
127
+ end # class Application
128
+
129
+ end # module Postview
130
+
@@ -0,0 +1,71 @@
1
+ module Postview
2
+
3
+ # Copyright (c) 2009 Hallison Batista
4
+ module CLI
5
+
6
+ autoload :CreateCommand, 'postview/cli/create_command'
7
+ autoload :ServerCommand, 'postview/cli/server_command'
8
+
9
+ def self.commands
10
+ constants.select do |constant|
11
+ constant =~ /.Command/
12
+ end.map do |constant|
13
+ constant.sub(/Command/,'').downcase
14
+ end.sort
15
+ end
16
+
17
+ def self.run(command, args)
18
+ const_get("#{command.capitalize}Command").run(args)
19
+ end
20
+
21
+ module Command #:nodoc: all
22
+
23
+ # Prompt for values.
24
+ def prompt label, default = nil, regexp = nil
25
+ while true
26
+ message = if default
27
+ [ "%1$s %2$s [%3$s]: ", " "*2, label, "#{default}" ]
28
+ else
29
+ [ "%1$s %2$s: ", " "*2, "#{label}" ]
30
+ end
31
+ printf *message
32
+ value = $stdin.readline.chomp.strip
33
+ value = default if value.empty?
34
+ if regexp && !value.match(regexp)
35
+ printf "!! Invalid value, please try again."
36
+ value = nil
37
+ end
38
+ return value unless value.nil? || value.to_s.empty?
39
+ end
40
+ end
41
+
42
+ def start process, &block
43
+ printf "%1$s %2$s ", ">"*2, process
44
+ if block_given?
45
+ result = yield
46
+ printf " %s\n", (result ? "done" : "fail")
47
+ end
48
+ rescue Exception => error
49
+ printf " error\n"
50
+ abort format("%1$s %2$s \n", ">"*2, error)
51
+ end
52
+
53
+ def init process, &block
54
+ printf "%1$s %2$s ...\n", ">"*2, process
55
+ yield Hash.new
56
+ end
57
+
58
+ def step &block
59
+ if block_given?
60
+ result = yield
61
+ printf "%s", (result ? "." : "!")
62
+ result
63
+ end
64
+ end
65
+
66
+ end # module Command
67
+
68
+ end # module CLI
69
+
70
+ end # module Postview
71
+
@@ -0,0 +1,362 @@
1
+ module Postview
2
+
3
+ module CLI
4
+
5
+ # Copying (c) 2009 Hallison Batista
6
+ class CreateCommand #:nodoc: all
7
+
8
+ include Command
9
+
10
+ def initialize(path, arguments)
11
+ @path, @arguments, @options = path, arguments, {}
12
+ end
13
+
14
+ def run
15
+ parse_arguments
16
+ load_default_settings
17
+ build_settings
18
+ end
19
+
20
+ def self.run args
21
+ if args.first =~ /^\w.*|^\/\w.*/
22
+ new(args.shift, args.options).run
23
+ else
24
+ new(".", args.options).run
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ # Options for arguments.
31
+ def options_for(name)
32
+ { :help => [ "-h", "--help", nil,
33
+ "Show this message." ],
34
+ :prompt => [ "-p", "--prompt-values", nil,
35
+ "Enable ask for values." ]
36
+ }[name]
37
+ end
38
+
39
+ def parse_arguments
40
+ @arguments.summary_indent = " "
41
+ @arguments.summary_width = 24
42
+ @arguments.banner = <<-end_banner.gsub(/^[ ]{6}/, '')
43
+ #{Postview::Version}
44
+
45
+ Usage:
46
+ #{Postview.name.downcase} create <path>
47
+
48
+ end_banner
49
+
50
+ @arguments.separator "Create options:"
51
+
52
+ @arguments.on(*options_for(:help)) { puts @arguments; exit 0 }
53
+ @arguments.on(*options_for(:prompt)) { @options[:prompt] = true }
54
+
55
+ @arguments.separator ""
56
+
57
+ begin
58
+ @arguments.parse!
59
+ rescue => error
60
+ puts error
61
+ puts @arguments
62
+ end
63
+ puts "#{Postview::Version}\n\n"
64
+ end
65
+
66
+ def build_settings
67
+ create_path
68
+ if @options[:prompt]
69
+ prompt_for_site_settings
70
+ prompt_for_directories_settings
71
+ prompt_for_sections_settings
72
+ end
73
+ create_settings
74
+ create_directories
75
+ create_default_theme
76
+ create_rackup
77
+ create_rakefile
78
+ end
79
+
80
+ def load_default_settings
81
+ start "Loading default settings" do
82
+ step { @settings = Postview::Settings.load }
83
+ step { @site = @settings.site }
84
+ step { @directories = @settings.directories }
85
+ step { @sections = @settings.sections }
86
+ step { @theme_default = Postview::ROOT.join("themes", "default") }
87
+ end
88
+ end
89
+
90
+ def create_path
91
+ start "Creating #{@path} path" do
92
+ step { @path = Pathname.new(@path) }
93
+ step { @path.exist? ? raise("Path #{@path} exist") : true }
94
+ step { @path.mkpath; true }
95
+ step { @theme = @path.join("themes", "default") }
96
+ end
97
+ end
98
+
99
+ def create_settings
100
+ file = @path.join(Settings::FILE_DIR, Settings::FILE_NAME)
101
+ start "Creating #{file}" do
102
+ step { file.dirname.mkpath; true }
103
+ step { file.dirname.exist? }
104
+ file.open "w+" do |settings_file|
105
+ settings = {}
106
+ step { settings[:site] = @site }
107
+ step { settings[:directories] = @directories }
108
+ step { settings[:sections] = @sections }
109
+ step { settings_file << settings.to_yaml }
110
+ end
111
+ step { file.exist? }
112
+ end
113
+ end
114
+
115
+ def create_directories
116
+ create = lambda do |path|
117
+ start "Creating #{path}" do
118
+ # step { path.exist? ? raise("Directory path #{path} exist") : true } if check
119
+ step { path.mkpath; true }
120
+ step { path.exist? }
121
+ end
122
+ end
123
+
124
+ @directories.keys.each do |dirname|
125
+ create.call @path.join(@settings.directories[dirname])
126
+ end
127
+
128
+ %w{public tmp}.each do |dirname|
129
+ create.call @path.join(dirname)
130
+ end
131
+ end
132
+
133
+ def create_default_theme
134
+ create = lambda do |path|
135
+ start "Creating #{path}" do
136
+ step { path.exist? ? raise("Theme path #{path} exist") : true }
137
+ step { path.mkpath; true }
138
+ step { path.exist? }
139
+ end
140
+ end
141
+
142
+ copy = lambda do |origin, destination|
143
+ start "Creating #{destination}" do
144
+ step { destination.exist? ? raise("Theme file #{destination} exist") : true }
145
+ step { FileUtils.copy(origin, destination); true }
146
+ step { destination.exist? }
147
+ end
148
+ end
149
+
150
+ create.call @theme
151
+
152
+ @theme_default.children.map do |origin|
153
+ if origin.directory?
154
+ path = @theme.join origin.basename
155
+ create.call path
156
+ origin.children.map do |file|
157
+ copy.call file, path.join(file.basename)
158
+ end
159
+ else
160
+ copy.call origin, @theme.join(origin.basename)
161
+ end
162
+ end
163
+ end
164
+
165
+ def create_rackup
166
+ config = @path.join("config.ru")
167
+ start "Creating #{config} file" do
168
+ config.open("w+") do |rackup|
169
+ step { rackup << "require 'rubygems'\n" }
170
+ step { rackup << "require 'postview'\n" }
171
+ #step { rackup << "log = File.open(\"tmp/postview.log\", \"a+\")\n" }
172
+ #step { rackup << "$stdout.reopen(log)\n" }
173
+ #step { rackup << "$stderr.reopen(log)\n" }
174
+ step { rackup << "run Postview::Application\n" }
175
+ end
176
+ end
177
+ end
178
+
179
+ def create_rakefile
180
+ rakefile = @path.join("rakefile")
181
+ start "Creating #{rakefile}" do
182
+ rakefile.open("w+") do |file|
183
+ content = []
184
+ content << "require 'postview'\n"
185
+ content << <<-'end_def'.gsub(/^[ ]{10}/, '')
186
+ # Build default settings file and load.
187
+ def settings
188
+ #Postview::Settings.build_default_file
189
+ Postview::Settings.load
190
+ end
191
+ end_def
192
+
193
+ content << <<-'end_def'.gsub(/^[ ]{10}/, '')
194
+ # Build and load the resource file for FTP connection.
195
+ def netrc
196
+ begin
197
+ @netrc ||= File.readlines(File.join(ENV['HOME'],".netrc"))
198
+ rescue Errno::ENOENT => message
199
+ puts <<-end_message.gsub(/^[ ]{6}/,'')
200
+ #{message}.
201
+ Please create the .netrc file in your home.
202
+ echo "\
203
+ machine #{settings.site[:domain]}
204
+ login <username>
205
+ password <password>
206
+ " >> #{ENV['HOME']}/.netrc
207
+ end_message
208
+ exit 1
209
+ end
210
+ match ||= @netrc.to_s.match(/machine (.*?)[\n ]login (.*?)[\n ]password (.*?)[\n ].*?/m)
211
+ { :machine => match[1].strip, :login => match[2].strip, :password => match[3].strip }
212
+ end
213
+ end_def
214
+
215
+ content << <<-'end_def'.gsub(/^[ ]{10}/, '')
216
+ # Synchronize directory
217
+ def ftp(directory, destination = nil)
218
+ origin = settings.directories[directory]
219
+ destination ||= File.join(settings.site[:directory], settings.directories[directory])
220
+ posts = settings.build_finder_for(directory).all_posts
221
+
222
+ $stdout.puts ">> Connecting to #{netrc[:machine]} ..."
223
+
224
+ Net::FTP.open(netrc[:machine]) do |ftp|
225
+ ftp.login netrc[:login], netrc[:password]
226
+
227
+ $stdout.puts ">> Logged as #{netrc[:login]} ..."
228
+
229
+ $stdout.puts ">> Accessing #{destination} ..."
230
+
231
+ ftp.chdir destination
232
+
233
+ posts.each do |post|
234
+ $stdout.puts ">> Copying #{post} ..."
235
+ ftp.putbinaryfile(File.join(origin, post.file))
236
+ end
237
+
238
+ $stdout.puts ">> Synchronization for #{directory} is done."
239
+ end
240
+ end
241
+ end_def
242
+
243
+ content << <<-'end_task'.gsub(/^[ ]{10}/, '')
244
+ desc <<-end_desc.gsub(/^[ ]{2}/,'')
245
+ Create new post in #{settings.directory_for(:posts)}.
246
+ For edit posts, set environment variable EDITOR or VISUAL. Otherwise,
247
+ pass editor="<your favorite editor command and arguments>".
248
+
249
+ Example:
250
+
251
+ $ rake post editor="gvim -f"
252
+
253
+ Or use directory argument for create a post in other directory.
254
+
255
+ $ rake post[other/path/for/new/post]
256
+ end_desc
257
+ task :post, [:directory] do |spec, args|
258
+ banner "New post. Type all attributes for new post.\n"
259
+ path = if args.directory
260
+ if settings.directories.has_key? args.directory.to_sym
261
+ settings.directory_for(args.directory.to_sym)
262
+ else
263
+ args.directory
264
+ end
265
+ else
266
+ settings.directory_for(:drafts)
267
+ end
268
+ post = Postage::Post.new :title => prompt("Post title"),
269
+ :publish_date => prompt("Publish date", Date.today),
270
+ :tags => prompt("Tags separated by spaces").split(' '),
271
+ :filter => :markdown,
272
+ :content => <<-end_content.gsub(/^[ ]{29}/,'')
273
+ Tanks for use #{Postview}.
274
+ Input here the content of your post.
275
+ end_content
276
+
277
+ begin
278
+ post.build_file
279
+ post.create_into(path)
280
+ rescue Errno::ENOENT => message
281
+ $stderr.puts message
282
+ $stderr.puts "Try create path #{args.directory}."
283
+ exit 1
284
+ end
285
+
286
+ printf "%s\n", "The post '#{post.title}' was created in '#{path}/#{post.file}'."
287
+
288
+ editor = ENV['editor'] || ENV['EDITOR'] || ENV['VISUAL'] || 'none'
289
+ if prompt("Edit post using '#{editor}'?", "y") =~ /y/i
290
+ if editor
291
+ sh "#{editor} #{path}/#{post.file}"
292
+ else
293
+ printf "%s", "Editor not specified."
294
+ end
295
+ end
296
+
297
+ $stdout.puts ">> Post done."
298
+ end
299
+ end_task
300
+
301
+ content << <<-'end_task'.gsub(/^[ ]{10}/, '')
302
+ namespace :sync do
303
+ settings.directories.keys.each do |dirname|
304
+ desc "Synchronize #{dirname}."
305
+ task dirname, [:destination] do |spec,args|
306
+ banner "Synchronize #{dirname} directory."
307
+ ftp(dirname, args.destination)
308
+ end
309
+ end
310
+
311
+ desc "Synchronize all directories."
312
+ task :all => settings.directories.keys
313
+ end
314
+ end_task
315
+
316
+ content.each do |method|
317
+ step { file << "#{method}\n" }
318
+ end
319
+ end
320
+ end
321
+ end
322
+
323
+ def prompt_for_site_settings
324
+ init "Settings for site information" do |site|
325
+ site[:title] = prompt "Title", @settings.site[:title]
326
+ site[:subtitle] = prompt "Subtitle", @settings.site[:subtitle]
327
+ site[:author] = prompt "Author name", @settings.site[:author]
328
+ site[:email] = prompt "Email", @settings.site[:email], %r{.*?@.*?\..*}
329
+ site[:domain] = prompt "Domain", @settings.site[:domain], %r{.*\..*}
330
+ site[:directory] = prompt "Directory", @settings.site[:directory]
331
+ @site.update site
332
+ end
333
+ end
334
+
335
+ def prompt_for_directories_settings
336
+ init "Settings for directories" do |directories|
337
+ directories[:posts] = prompt "Posts", @settings.directories[:posts]
338
+ directories[:archive] = prompt "Archive", @settings.directories[:archive]
339
+ directories[:drafts] = prompt "Drafts", @settings.directories[:drafts]
340
+ @directories.update directories
341
+ end
342
+ end
343
+
344
+ def prompt_for_sections_settings
345
+ init "Settings for sections" do |sections|
346
+ sections[:root] = prompt "Root", @settings.sections[:root]
347
+ sections[:posts] = prompt "Posts", @settings.sections[:posts]
348
+ sections[:tags] = prompt "Tags", @settings.sections[:tags]
349
+ sections[:archive] = prompt "Archive", @settings.sections[:archive]
350
+ sections[:drafts] = prompt "Drafts", @settings.sections[:drafts]
351
+ sections[:search] = prompt "Search", @settings.sections[:search]
352
+ sections[:about] = prompt "About", @settings.sections[:about]
353
+ @sections.update sections
354
+ end
355
+ end
356
+
357
+ end # class SetupCommand
358
+
359
+ end # module CLI
360
+
361
+ end # module Postview
362
+