postview 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/HISTORY +34 -9
  2. data/README.rdoc +11 -7
  3. data/Rakefile +4 -0
  4. data/VERSION +4 -4
  5. data/lib/postview.rb +6 -1
  6. data/lib/postview/application.rb +26 -33
  7. data/lib/postview/cli.rb +2 -0
  8. data/lib/postview/extensions.rb +8 -0
  9. data/lib/postview/helpers.rb +67 -9
  10. data/lib/postview/patches.rb +2 -0
  11. data/lib/postview/settings.rb +19 -3
  12. data/lib/postview/site.rb +19 -4
  13. data/tasks/history.rake +2 -2
  14. data/test/application_test.rb +12 -12
  15. data/test/extensions.rb +3 -3
  16. data/test/fixtures/application/posts/{20090529-postview_blogware.ruby.sinatra.mkd → 20090529-third_article.t1.t2.t3.mkd} +0 -0
  17. data/test/fixtures/application/posts/{20090602-postview_blogware.ruby.sinatra.mkd → 20090602-fourth_article.t1.t2.t3.t4.mkd} +0 -0
  18. data/test/fixtures/application/posts/archive/{20080529-postview_blogware.ruby.sinatra.mkd → 20080529-first_article.t1.mkd} +0 -0
  19. data/test/fixtures/application/posts/archive/{20080602-postview_blogware.ruby.sinatra.mkd → 20080602-second_article.t1.t2.mkd} +0 -0
  20. data/test/fixtures/application/posts/drafts/{20090730-draft_postview_blogware.ruby.sinatra.mkd → 20090730-fifth_article.t1.t2.t3.t4.t5.mkd} +0 -0
  21. data/test/fixtures/application/themes/gemstone/about.erb +22 -0
  22. data/test/fixtures/application/themes/gemstone/archive/index.erb +21 -0
  23. data/test/fixtures/application/themes/gemstone/archive/show.erb +4 -4
  24. data/test/fixtures/application/themes/gemstone/error.erb +0 -0
  25. data/test/fixtures/application/themes/gemstone/images/logo.png +0 -0
  26. data/test/fixtures/application/themes/gemstone/images/navigation-bar.gif +0 -0
  27. data/test/fixtures/application/themes/gemstone/images/postview.png +0 -0
  28. data/test/fixtures/application/themes/gemstone/images/rack.png +0 -0
  29. data/test/fixtures/application/themes/gemstone/images/ruby.png +0 -0
  30. data/test/fixtures/application/themes/gemstone/images/sinatra.png +0 -0
  31. data/test/fixtures/application/themes/gemstone/index.erb +38 -0
  32. data/test/fixtures/application/themes/gemstone/layout.erb +124 -0
  33. data/test/fixtures/application/themes/gemstone/posts/index.erb +21 -0
  34. data/test/fixtures/application/themes/gemstone/posts/show.erb +17 -0
  35. data/test/fixtures/application/themes/gemstone/search.erb +40 -0
  36. data/test/fixtures/application/themes/gemstone/stylesheets/postview.css +238 -0
  37. data/test/fixtures/application/themes/gemstone/tags/index.erb +12 -0
  38. data/test/fixtures/application/themes/gemstone/tags/show.erb +40 -0
  39. data/test/helpers_test.rb +70 -0
  40. data/test/settings_test.rb +2 -2
  41. data/test/site_test.rb +15 -14
  42. data/themes/default/about.erb +3 -5
  43. data/themes/default/archive/index.erb +1 -1
  44. data/themes/default/archive/show.erb +4 -4
  45. data/themes/default/index.erb +2 -2
  46. data/themes/default/layout.erb +20 -7
  47. data/themes/default/posts/index.erb +1 -1
  48. data/themes/default/posts/show.erb +4 -4
  49. data/themes/default/search.erb +5 -5
  50. data/themes/default/tags/index.erb +1 -1
  51. data/themes/default/tags/show.erb +6 -6
  52. metadata +27 -8
data/HISTORY CHANGED
@@ -1,12 +1,37 @@
1
- [0.7.0 - not released - Features]
2
- * The project is a Gem package.
3
- * Postview command for create a new directory structure.
4
- * Added CLI commands.
5
- * Added basic classes for version and information about project.
6
- * Added basic files for versioning and informations.
7
- * Updated methods and constants to path of directories.
8
- * Updated default views.
9
- * Support to themes using ERB.
1
+ [0.8.0 - 2009-09-15 - Improvements]
2
+ * Added helper methods for improves all theme views source.
3
+ * Added core extensions.
4
+
5
+ [0.7.0 - 2009-09-10 - Features, enhancements and improvements]
6
+ New features and enhancements for version 0.7.0.
7
+
8
+ * Features
9
+ * Postview is a RubyGems project.
10
+ * Added executable for creates new Postview blogs.
11
+ * Added support to themes.
12
+ * CLI and commands have been added in application libraries.
13
+
14
+ * Enhancements
15
+ * Added basic classes and files for version and information about project.
16
+ * Support to creates default Postview theme have been added.
17
+ * Default views have been updated to default theme.
18
+ * Added new images and logos in default theme.
19
+ * The helper methods have been separated from application.
20
+ * The method "mapping" has been renamed to "sections".
21
+ * Added patches for Ruby v1.8.5.
22
+ * Added creation of Rakefile in new Postview blogs.
23
+ * Fixes for new features of the Postage API.
24
+
25
+ * Improvements
26
+ * Updates in application class to new features of the Sinatra::Mapping.
27
+ * Updates in CLI commands. Need fix to load the production environment.
28
+ * Updated method for synchronize.
29
+ * Removed archive tags path.
30
+ * Change host attribute name.
31
+ * Updated methods and constants to path of directories.
32
+ * Updates all tests to new features.
33
+ * Improvements in method that creates config.ru file.
34
+ * Updates in the settings and site classes.
10
35
 
11
36
  [0.6.0 - 2009-07-31 - Features and enhancements]
12
37
  * Added task for build settings file.
data/README.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Just write your posts ... and view!
4
4
 
5
- Postview is a simple blogware written in Ruby using Sinatra DSL that
5
+ Postview is a simple blogware written in Ruby using Sinatra DSL and
6
6
  renders files written in Markdown.
7
7
 
8
8
  * Easy to configure.
@@ -14,14 +14,12 @@ Install {Ruby}[http://www.ruby-lang.org/] Gem package and try.
14
14
 
15
15
  The Postview requires the following gems:
16
16
 
17
- * {Rack}[http://rack.rubyforge.org/]
18
- * {Rack-Test}[http://github.com/brynary/rack-test]
19
17
  * {Sinatra}[http://www.sinatrarb.com/]
20
18
  * {Sinatra-Mapping}[http://sinatra-mapping.rubyforge.org/]
21
- * {Maruku}[http://maruku.rubyforge.org/]
22
19
  * {Postage}[http://postage.rubyforge.org/]
23
20
 
24
- Install stable gem from {RubyForge.org}[http://rubyforge.org/].
21
+ Install stable gem from {RubyForge.org}[http://rubyforge.org/] or
22
+ {GemCutter.org}[http://gemcutter.org/].
25
23
 
26
24
  $ sudo gem install postview
27
25
 
@@ -33,6 +31,10 @@ So, run command for create and setup a new Postview directory structure.
33
31
 
34
32
  $ postview create path/to/website
35
33
 
34
+ Or run using +--prompt-values+.
35
+
36
+ $ postview create --prompt-values
37
+
36
38
  After setup, run server with command:
37
39
 
38
40
  $ RACK_ENV=production postview server
@@ -40,7 +42,7 @@ After setup, run server with command:
40
42
  NOTE: Inopportunely, Postview not run server using production environment,
41
43
  yet.
42
44
 
43
- In your browser, access http://localhost:9000/.
45
+ In your browser, access http://127.0.0.1:9000/.
44
46
 
45
47
  == Create new post
46
48
 
@@ -50,7 +52,7 @@ New post can be created by using the task `post`:
50
52
  $ rake post
51
53
 
52
54
  Following all instructions. Please, set environment variable +EDITOR+
53
- or +VISUAL+ for editing your posts. Ether else, run:
55
+ or +VISUAL+ for editing your posts. Other else, run:
54
56
 
55
57
  $ cd path/to/postview
56
58
  $ EDITOR=<your favorite editor> rake post
@@ -101,3 +103,5 @@ Example:
101
103
  # To synchronize all
102
104
  $ rake sync:all
103
105
 
106
+ NOTE: Will added new enhancements for this feature.
107
+
data/Rakefile CHANGED
@@ -168,6 +168,10 @@ namespace :sync do
168
168
  task :all => settings.directories.keys
169
169
  end
170
170
 
171
+ Rake::TestTask.new do |spec|
172
+ spec.test_files = FileList["test/*_test.rb"]
173
+ end
174
+
171
175
  Dir["tasks/**.rake"].each do |task_file|
172
176
  load task_file
173
177
  end
data/VERSION CHANGED
@@ -1,8 +1,8 @@
1
1
  ---
2
- :major: 0
3
2
  :release:
4
- :minor: 7
5
3
  :cycle: Beta release
6
- :patch: 0
7
- :date: 2009-09-10
8
4
  :timestamp: 2009-08-24 07:46:28 -04:00
5
+ :major: 0
6
+ :date: 2009-09-15
7
+ :minor: 8
8
+ :patch: 0
data/lib/postview.rb CHANGED
@@ -31,7 +31,7 @@ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))
31
31
  # == Themes
32
32
  #
33
33
  # Default theme is generated in <tt>themes/default</tt>. Change or migrate your favorite
34
- # theme.
34
+ # theme. To help for this, read Helpers for more informations.
35
35
  #
36
36
  module Postview
37
37
 
@@ -44,14 +44,19 @@ module Postview
44
44
  require 'ostruct'
45
45
 
46
46
  # 3rd part libraries/projects.
47
+ require 'rack'
47
48
  require 'sinatra/base' unless defined? ::Sinatra::Base
48
49
  require 'sinatra/mapping' unless defined? ::Sinatra::Mapping
49
50
  require 'postage' unless defined? ::Postage
50
51
 
51
52
  # Internal requires
52
53
  require 'postview/patches' if RUBY_VERSION < "1.8.7"
54
+ require 'postview/extensions'
53
55
 
56
+ # Root path for Postview source.
54
57
  ROOT = Pathname.new("#{File.dirname(__FILE__)}/..").expand_path
58
+
59
+ # Current path.
55
60
  PATH = Pathname.new(".").expand_path
56
61
 
57
62
  # Auto-load all internal requires.
@@ -22,12 +22,14 @@ class Application < Sinatra::Base #:nodoc: all
22
22
  end
23
23
 
24
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
25
+ @page = options.page
26
+ @settings ||= options.settings
27
+ @site ||= options.site
28
+ @all_tags ||= @site.find_all_tags
29
+ @all_posts ||= @site.find.all_posts.reverse
30
+ @all_archived_posts ||= @site.find_in_archive.all_posts.reverse
31
+ @all_drafted_posts ||= @site.find_in_drafts.all_posts.reverse
32
+ @current_post ||= @all_posts.last
31
33
  end
32
34
 
33
35
  helpers Postview::Helpers
@@ -38,71 +40,63 @@ class Application < Sinatra::Base #:nodoc: all
38
40
  send_file options.views.join(resource, "#{file}.#{ext}")
39
41
  end
40
42
 
41
- # Show only the last 5 posts.
43
+ # Show all information for site.
42
44
  get root_path do
43
- @posts = @site.find.all_posts.limit(5).reverse
44
45
  @page.title, @page.keywords = @site.subtitle, "posts"
45
- show :index, :posts_path => :posts, :tags_path => :tags
46
+ show :index, :posts_path => :posts, :archive_path => :archive, :tags_path => :tags
46
47
  end
47
48
 
48
49
  # Show all posts.
49
50
  get posts_path do
50
- @page.title, @page.keywords = title_path(:posts), @tags.join(' ')
51
+ @page.title, @page.keywords = title_path(:posts), @all_tags.join(' ')
51
52
  show :"posts/index", :posts_path => :posts, :tags_path => :tags
52
53
  end
53
54
 
54
55
  # Show selected post.
55
56
  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(' ')
57
+ @current_post = @site.find.post(year, month, day, name)
58
+ @page.title, @page.keywords = @current_post.title, @current_post.tags.join(' ')
58
59
  show :"posts/show", :posts_path => :posts, :tags_path => :tags
59
60
  end
60
61
 
61
62
  # Show all tags.
62
63
  get tags_path do
63
- @page.title, @page.keywords = title_path(:tags), @tags.join(' ')
64
+ @page.title, @page.keywords = title_path(:tags), @all_tags.join(' ')
64
65
  show :"tags/index", :posts_path => :posts, :tags_path => :tags
65
66
  end
66
67
 
67
68
  # Show all posts by selected tag.
68
69
  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?
70
+ @current_tag = @site.find_tag(tag)
71
+ @posts_found, @archived_posts_found = @site.find_all_posts_tagged_with(tag)
72
+ @page.title, @page.keywords = "#{title_path(:tags)} - #{@current_tag.capitalize}", "posts #{@current_tag}"
73
73
  show :"tags/show", :posts_path => :posts, :archive_path => :archive, :tags_path => :tags
74
74
  end
75
75
 
76
76
  # Show archives grouped by year.
77
77
  get archive_path do
78
- @posts = @site.find_archived.all_posts.reverse
79
- @page.title, @page.keywords = title_path(:archive), @tags.join(' ')
78
+ @page.title, @page.keywords = title_path(:archive), @all_tags.join(' ')
80
79
  show :"archive/index", :archive_path => :archive, :posts_path => :archive, :tags_path => :tags
81
80
  end
82
81
 
83
82
  # Show selected post in archive.
84
83
  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(' ')
84
+ @current_post = @site.find_in_archive.post(year, month, day, name)
85
+ @page.title, @page.keywords = @current_post.title, @current_post.tags.join(' ')
89
86
  show :"archive/show", :posts_path => :archive, :tags_path => :tags
90
87
  end
91
88
 
92
89
  # Show all drafts.
93
90
  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(' ')}"
91
+ @page.title, @page.keywords = title_path(:drafts), "drafts #{@all_tags.join(' ')}"
97
92
  show :"posts/index", :posts_path => :drafts, :tags_path => [:drafts, :tags]
98
93
  end
99
94
 
100
95
  # Show selected drafted post.
101
96
  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(' ')
97
+ @current_post = @site.find_in_drafts.post(year, month, day, name)
98
+ @all_tags ||= @site.find_in_drafts.all_tags.sort
99
+ @page.title, @page.keywords = @current_post.title, @current_post.tags.join(' ')
106
100
  show :"posts/show", :posts_path => :drafts, :tags_path => [:drafts, :tags]
107
101
  end
108
102
 
@@ -113,9 +107,8 @@ class Application < Sinatra::Base #:nodoc: all
113
107
 
114
108
  # Search posts by title or match file name.
115
109
  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(' ')
110
+ @posts_found, @archived_posts_found = @site.search_posts(*params.values)
111
+ @page.title, @page.keywords = title_path(:search), @all_tags.join(' ')
119
112
  show :search, :posts_path => :posts, :tags_path => :tags, :archive_path => :archive, :search_path => :search
120
113
  end
121
114
 
data/lib/postview/cli.rb CHANGED
@@ -6,6 +6,7 @@ module CLI
6
6
  autoload :CreateCommand, 'postview/cli/create_command'
7
7
  autoload :ServerCommand, 'postview/cli/server_command'
8
8
 
9
+ # List all commands for CLI options.
9
10
  def self.commands
10
11
  constants.select do |constant|
11
12
  constant =~ /.Command/
@@ -14,6 +15,7 @@ module CLI
14
15
  end.sort
15
16
  end
16
17
 
18
+ # Run!
17
19
  def self.run(command, args)
18
20
  const_get("#{command.capitalize}Command").run(args)
19
21
  end
@@ -0,0 +1,8 @@
1
+ class Array
2
+
3
+ # Returns elements between first and the specific limit.
4
+ def limit(size)
5
+ self[0..size - 1]
6
+ end
7
+
8
+ end
@@ -3,16 +3,74 @@ module Postview
3
3
  # Copyright (c) 2009 Hallison Batista
4
4
  module Helpers
5
5
 
6
- attr_reader :site, :page
7
- attr_reader :post, :posts, :archive, :tag, :tags
8
-
9
- # ...
10
- def count_posts_by_tag(tagname)
11
- @count_posts_by_tag ||= @tags.inject({}) do |hash, tag|
12
- hash[tag] = (@site.find.all_posts + @site.find_archived.all_posts).count{ |post| post.tags.include? tag }
13
- hash
6
+ # Site information.
7
+ attr_reader :site
8
+
9
+ # Current page.
10
+ attr_reader :page
11
+
12
+ # Current post.
13
+ attr_reader :current_post
14
+
15
+ # Current tag.
16
+ attr_reader :current_tag
17
+
18
+ # All tags used in posts and archived posts.
19
+ attr_reader :all_tags
20
+
21
+ # All posts
22
+ attr_reader :all_posts
23
+
24
+ # All archived posts.
25
+ attr_reader :all_archived_posts
26
+
27
+ # All posts found by search.
28
+ attr_reader :posts_found
29
+
30
+ # All archived posts found by search.
31
+ attr_reader :archived_posts_found
32
+
33
+ # Returns latest posts.
34
+ def latest_posts(limit = 5)
35
+ @all_posts.limit(limit) || []
36
+ end
37
+
38
+ # Returns all posts related to any post.
39
+ def related_posts_in(folder = :posts)
40
+ posts = case folder
41
+ when :posts
42
+ all_posts
43
+ when :archive
44
+ all_archived_posts
45
+ when :drafts
46
+ all_drafted_posts
47
+ else
48
+ return nil
49
+ end
50
+ posts.reject do |post|
51
+ (post.tags & current_post.tags).empty? || post == current_post
52
+ end
53
+ end
54
+
55
+ # Returns all tags related with a post tags.
56
+ def related_tags_in(folder = :posts)
57
+ (related_posts_in(folder) << current_post).map{ |post| post.tags }.flatten.uniq.sort
58
+ end
59
+
60
+ # Returns all tags related with a post tags.
61
+ def all_related_tags
62
+ (all_posts + all_archived_posts).reject do |post|
63
+ (post.tags & current_post.tags).empty?
64
+ end.map{ |post| post.tags }.flatten.uniq.sort
65
+ end
66
+
67
+ # Count posts by tag name.
68
+ def count_posts_by_tag(name)
69
+ @count_posts_by_tag ||= all_tags.inject({}) do |count, tag|
70
+ count[tag] = (all_posts + all_archived_posts).count{ |post| post.tags.include? tag }
71
+ count
14
72
  end
15
- @count_posts_by_tag[tagname]
73
+ @count_posts_by_tag[name]
16
74
  end
17
75
 
18
76
  end # module Helpers
@@ -1,4 +1,5 @@
1
1
  class Array
2
+
2
3
  # Count objects in elements.
3
4
  def count(obj = nil)
4
5
  if block_given?
@@ -7,5 +8,6 @@ class Array
7
8
  select { |item| item == obj }.size
8
9
  end
9
10
  end
11
+
10
12
  end
11
13
 
@@ -34,35 +34,45 @@ class Settings
34
34
 
35
35
  attr_reader :site, :theme, :directories, :sections
36
36
 
37
+ # Initialize the settings using attributes passed by arguments.
38
+ # Only attributes valid are read. See DEFAULTS.
37
39
  def initialize(attributes = {})
38
40
  attributes.symbolize_keys.merge(DEFAULTS) do |key, value, default|
39
41
  value || default
40
42
  end.instance_variables_set_to(self)
41
43
  end
42
44
 
45
+ # Build site using attributes found in +site+ key.
43
46
  def build_site
44
47
  build_all_finders_for(Site.new(site))
45
48
  end
46
49
 
50
+ # Build a simple structure for pages.
47
51
  def build_page
48
52
  OpenStruct.new(:title => "", :keywords => [])
49
53
  end
50
54
 
55
+ # Build finders for site. The finders load all post files
56
+ # placed in directories setted in +directories+ values.
51
57
  def build_all_finders_for(site)
52
- site.find = build_finder_for(:posts)
53
- site.find_archived = build_finder_for(:archive)
54
- site.find_drafted = build_finder_for(:drafts)
58
+ site.find = build_finder_for(:posts)
59
+ site.find_in_archive = build_finder_for(:archive)
60
+ site.find_in_drafts = build_finder_for(:drafts)
55
61
  site
56
62
  end
57
63
 
64
+ # Build a specific finder for directory.
58
65
  def build_finder_for(directory)
59
66
  Postage::Finder.new(directory_for(directory))
60
67
  end
61
68
 
69
+ # Load a default settings values from file placed in +config/settings.yml+.
62
70
  def self.load
63
71
  load_file(FILE)
64
72
  end
65
73
 
74
+ # Load a specific settings file.
75
+ # Returns default values for attributes not found.
66
76
  def self.load_file(file_name)
67
77
  begin
68
78
  new(YAML.load_file(file_name) || DEFAULTS)
@@ -71,30 +81,36 @@ class Settings
71
81
  end
72
82
  end
73
83
 
84
+ # Load file from a path.
74
85
  def self.load_file_from(path)
75
86
  file = Pathname.new(path).join(FILE_DIR, FILE_NAME)
76
87
  new(YAML.load_file(file))
77
88
  end
78
89
 
90
+ # Build settings file using DEFAULTS.
79
91
  def self.build_default_file
80
92
  FILE.open "w+" do |file|
81
93
  file << DEFAULTS.to_yaml
82
94
  end unless FILE.exist?
83
95
  end
84
96
 
97
+ # Returns settings file.
85
98
  def file
86
99
  FILE
87
100
  end
88
101
 
102
+ # Check directory and returns file that matches with a pattern.
89
103
  def file_names_for(directory, pattern = "**.*")
90
104
  directory_for(directory, pattern)
91
105
  end
92
106
 
107
+ # Returns a valid directory loaded from settings file.
93
108
  def directory_for(name, *paths)
94
109
  return Pathname.new(directories[name], *paths) if directories[name].match(%r{^/.*})
95
110
  PATH.join(directories[name], *paths)
96
111
  end
97
112
 
113
+ # Parse all attributes to hash.
98
114
  def to_hash
99
115
  DEFAULTS.keys.inject({}) do |hash, method|
100
116
  hash[method] = send(method)