postview 0.7.0 → 0.8.0

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 (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)