village 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Gemfile +29 -0
  2. data/Guardfile +9 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +255 -0
  5. data/Rakefile +29 -0
  6. data/app/controllers/village/articles_controller.rb +27 -0
  7. data/app/controllers/village/pages_controller.rb +16 -0
  8. data/app/views/layouts/village.html.haml +22 -0
  9. data/app/views/village/articles/_addthis.html.haml +8 -0
  10. data/app/views/village/articles/_analytics.html.haml +13 -0
  11. data/app/views/village/articles/_article.html.haml +25 -0
  12. data/app/views/village/articles/_comments.html.haml +8 -0
  13. data/app/views/village/articles/_feed_link.html.haml +2 -0
  14. data/app/views/village/articles/_sidebar.html.haml +13 -0
  15. data/app/views/village/articles/index.atom.builder +26 -0
  16. data/app/views/village/articles/index.html.haml +11 -0
  17. data/app/views/village/articles/index.rss.builder +31 -0
  18. data/app/views/village/articles/show.html.haml +9 -0
  19. data/app/views/village/pages/show.html.haml +1 -0
  20. data/lib/generators/base.rb +178 -0
  21. data/lib/generators/village/articles/USAGE +6 -0
  22. data/lib/generators/village/articles/articles_generator.rb +50 -0
  23. data/lib/generators/village/setup/USAGE +5 -0
  24. data/lib/generators/village/setup/setup_generator.rb +67 -0
  25. data/lib/generators/village/setup/templates/2001-01-01-example-article.markdown +8 -0
  26. data/lib/generators/village/setup/templates/example-page.markdown +10 -0
  27. data/lib/generators/village/setup/templates/views/articles/_addthis.html.haml +8 -0
  28. data/lib/generators/village/setup/templates/views/articles/_analytics.html.haml +13 -0
  29. data/lib/generators/village/setup/templates/views/articles/_article.html.haml +25 -0
  30. data/lib/generators/village/setup/templates/views/articles/_comments.html.haml +8 -0
  31. data/lib/generators/village/setup/templates/views/articles/_feed_link.html.haml +2 -0
  32. data/lib/generators/village/setup/templates/views/articles/_sidebar.html.haml +13 -0
  33. data/lib/generators/village/setup/templates/views/articles/index.atom.builder +26 -0
  34. data/lib/generators/village/setup/templates/views/articles/index.html.haml +11 -0
  35. data/lib/generators/village/setup/templates/views/articles/index.rss.builder +31 -0
  36. data/lib/generators/village/setup/templates/views/articles/show.html.haml +9 -0
  37. data/lib/generators/village/setup/templates/views/pages/show.html.haml +1 -0
  38. data/lib/generators/village/setup/templates/views/village.css +72 -0
  39. data/lib/generators/village/setup/templates/views/village.html.haml +22 -0
  40. data/lib/generators/village/setup/templates/village_config.yml +81 -0
  41. data/lib/village.rb +4 -0
  42. data/lib/village/article.rb +125 -0
  43. data/lib/village/attributes.rb +21 -0
  44. data/lib/village/config.rb +53 -0
  45. data/lib/village/engine.rb +11 -0
  46. data/lib/village/file_model.rb +83 -0
  47. data/lib/village/page.rb +10 -0
  48. data/lib/village/routes.rb +16 -0
  49. metadata +158 -0
@@ -0,0 +1,8 @@
1
+ - if Village::Config.disqus_short_name?
2
+ #disqus_thread
3
+ - if ENV['RAILS_ENV'] == :development
4
+ :javascript
5
+ var disqus_developer = true;
6
+ %script{:type => 'text/javascript', :src => "http://#{Village::Config.disqus_short_name}.disqus.com/embed.js", :async => true}
7
+ %noscript
8
+ %a(href="http://#{Village::Config.disqus_short_name}.disqus.com/embed.js?url=ref") View comments.
@@ -0,0 +1,2 @@
1
+ - content_for :head do
2
+ %link{:href => village_articles_path(:format => :atom), :type => 'application/rss+xml', :rel => :alternate, :title => Village::Config.title}
@@ -0,0 +1,13 @@
1
+ %h4
2
+ Categories
3
+ - unless Village::Article.categories.nil?
4
+ %ul
5
+ - Village::Article.categories.each do |category|
6
+ %li= link_to "#{category[0]} (#{category[1]})", village_articles_path(:category => category[0])
7
+
8
+ %h4
9
+ Tags
10
+ - unless Village::Article.tags.nil?
11
+ %ul
12
+ - Village::Article.tags.each do |tag|
13
+ %li= link_to "#{tag[0]} (#{tag[1]})", village_articles_path(:tag => tag[0])
@@ -0,0 +1,26 @@
1
+ xml.instruct!
2
+ xml.feed :xmlns => 'http://www.w3.org/2005/Atom' do
3
+ xml.title Village::Config.title
4
+ xml.link village_articles_url(:format => :atom)
5
+ xml.id village_articles_url
6
+ xml.updated Village::Article.feed_last_modified.xmlschema
7
+
8
+ Village::Article.feed.each do |article|
9
+ xml.entry do
10
+ xml.title article.title, :type => :text
11
+ xml.link :href => village_article_url(article), :rel => :alternate, :type => 'text/html'
12
+ xml.published article.timestamp.xmlschema
13
+ xml.updated article.last_modified.xmlschema
14
+ if article.author?
15
+ xml.author do
16
+ xml.name article.author[:name]
17
+ xml.email article.author[:email]
18
+ end
19
+ end
20
+ xml.id village_article_url(article)
21
+ xml.content :type => :html, 'xml:base' => village_article_url(article) do
22
+ xml.cdata! article.content_html
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ = render 'analytics'
2
+ = render 'feed_link'
3
+ %section#sidebar
4
+ = render 'sidebar'
5
+
6
+ %section#articles
7
+ - if collection.present?
8
+ = render :partial => 'article', :collection => collection, :locals => { :summary => true }
9
+ = paginate collection
10
+ - else
11
+ No articles found.
@@ -0,0 +1,31 @@
1
+ xml.instruct! :xml, :version => "1.0"
2
+ xml.rss :version => "2.0" do
3
+ xml.channel do
4
+ xml.title Village::Config.title
5
+ xml.description Village::Config.subtitle
6
+ xml.link village_articles_url(:format => :rss)
7
+ xml.generator village_articles_url(:format => :rss)
8
+ xml.lastBuildDate Village::Article.feed_last_modified
9
+
10
+ for article in Village::Article.feed
11
+ xml.item do
12
+ xml.title article.title
13
+ xml.description :type => :html, 'xml:base' => village_article_url(article) do
14
+ xml.cdata! article.summary_html
15
+ end
16
+ xml.pubDate article.timestamp.xmlschema
17
+ xml.link :href => village_article_url(article), :rel => :alternate, :type => 'text/html'
18
+ xml.guid village_article_url(article)
19
+ if article.author.present?
20
+ xml.author do
21
+ xml.name article.author[:name]
22
+ xml.email article.author[:email]
23
+ end
24
+ end
25
+ if article.tags?
26
+ xml.category article.tags.join(",")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ = render 'feed_link'
2
+ %section#sidebar
3
+ = render 'sidebar'
4
+
5
+ = render :partial => 'article', :object => resource, :locals => { :summary => false }
6
+
7
+ = render 'addthis'
8
+
9
+ = render 'comments'
@@ -0,0 +1 @@
1
+ ~ @resource.content_html
@@ -0,0 +1,178 @@
1
+ require 'rails/generators/base'
2
+ require 'bundler'
3
+ require 'bundler/dsl'
4
+
5
+ module Village
6
+ module Generators
7
+ class Base < Rails::Generators::Base #:nodoc:
8
+
9
+ def self.source_root
10
+ @_village_source_root = File.expand_path(File.join(File.dirname(__FILE__), 'village', generator_name, 'templates'))
11
+ end
12
+
13
+ def self.banner
14
+ "rails generate village:#{generator_name} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]"
15
+ end
16
+
17
+ protected
18
+
19
+ def root_path(path)
20
+ File.expand_path(File.join(File.dirname(__FILE__), 'village', path))
21
+ end
22
+
23
+ def destination_path(path)
24
+ File.join(destination_root, path)
25
+ end
26
+
27
+ def file_exists?(path)
28
+ File.exist? destination_path(path)
29
+ end
30
+
31
+ def folder_exists?(path)
32
+ File.directory? path
33
+ end
34
+
35
+ def class_exists?(class_name)
36
+ klass = Rails.application.class.parent_name.constantize.const_get(class_name)
37
+ return klass.is_a?(Class)
38
+ rescue NameError
39
+ return false
40
+ end
41
+
42
+ def extract(filepath,destinationpath,foldername)
43
+ begin
44
+ print_notes("Extracting #{filepath}")
45
+ system("tar -C '#{destination_path(destinationpath)}' -xzf '#{root_path(filepath)}' #{foldername}/")
46
+ rescue Exception => e
47
+ raise e
48
+ end
49
+ end
50
+
51
+ def asking(messages,&block)
52
+ opt = ask("=> #{messages} [yes]")
53
+ if opt == "yes" || opt.blank?
54
+ yield
55
+ end
56
+ rescue Exception => e
57
+ raise e
58
+ end
59
+
60
+ def print_notes(message,notes = "notes",color = :yellow)
61
+ unless message.blank?
62
+ puts '', '='*80
63
+ say_status "#{notes}", "#{message}", color
64
+ puts '='*80, ''; sleep 0.5
65
+ else
66
+ puts "\n"
67
+ end
68
+ end
69
+
70
+ def print_usage
71
+ self.class.help(Thor::Base.shell.new)
72
+ exit
73
+ end
74
+
75
+ def install_local_gem(name,version = nil)
76
+ ::Bundler.with_clean_env do
77
+ if version
78
+ `gem install #{name} -v=#{version}`
79
+ else
80
+ `gem install #{name}`
81
+ end
82
+ end
83
+ $? == 0 ? true : false
84
+ rescue Exception => e
85
+ raise e
86
+ end
87
+
88
+ def check_local_gem?(name,version = nil)
89
+ ::Bundler.with_clean_env do
90
+ if version
91
+ `gem list #{name} -i -v=#{version}`
92
+ else
93
+ `gem list #{name} -i`
94
+ end
95
+ end
96
+ $? == 0 ? true : false
97
+ rescue Exception => e
98
+ raise e
99
+ end
100
+
101
+ def refresh_bundle
102
+ ::Bundler.with_clean_env do
103
+ `bundle`
104
+ end
105
+ rescue Exception => e
106
+ raise e
107
+ end
108
+
109
+ def gemfile_included?(name)
110
+ ::Bundler.with_clean_env do
111
+ `bundle show #{name}`
112
+ end
113
+ $?.exitstatus == 0 ? true : false
114
+ rescue Exception => e
115
+ raise e
116
+ end
117
+
118
+ def check_required_gems?(*names)
119
+ names.each do |name|
120
+ return false unless gemfile_included? name
121
+ end
122
+ true
123
+ rescue Exception => e
124
+ raise e
125
+ end
126
+
127
+ def check_some_gems?(*names)
128
+ names.each do |name|
129
+ return true if gemfile_included? name
130
+ end
131
+ false
132
+ rescue Exception => e
133
+ raise e
134
+ end
135
+
136
+ def rails_3_1?
137
+ Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR >= 1
138
+ end
139
+
140
+ def copy_asset(source, *args, &block)
141
+ if rails_3_1?
142
+ if args.first =~ /^public/
143
+ args.first.gsub!(/^public/,"app/assets")
144
+ end
145
+ if args.first.include?("javascripts/application.js") or args.first.include?("stylesheets/application.css")
146
+ last_line = IO.readlines(args.first).last
147
+ content = IO.read(File.expand_path(find_in_source_paths(source.to_s)))
148
+ content.gsub!(/images/,"assets")
149
+ inject_into_file args.first, :after => last_line do
150
+ content
151
+ end
152
+ return
153
+ end
154
+ end
155
+ copy_file(source, *args, &block)
156
+ end
157
+
158
+ def remove_asset(path, config={})
159
+ if rails_3_1?
160
+ if path =~ /^public/
161
+ path.gsub!(/^public/,"app/assets")
162
+ end
163
+ end
164
+ remove_asset(path, config)
165
+ end
166
+
167
+ def rails_app_name
168
+ Rails.application.class.name.split('::')[0..-2].join.titleize
169
+ end
170
+
171
+ def git_config(name)
172
+ value = `git config --get #{name}`.chomp
173
+ value if $?.success?
174
+ end
175
+
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,6 @@
1
+ Description:
2
+ The village:articles will generate article page for you.
3
+
4
+ rails g village:articles test-article.rdoc # => using rdoc
5
+
6
+ rails g village:articles sample-article.md --date=2011-01-01 # => passing date options
@@ -0,0 +1,50 @@
1
+ require 'generators/base'
2
+
3
+ module Village
4
+ module Generators
5
+ class ArticlesGenerator < Base
6
+
7
+ argument :slug, :type => :string, :required => true
8
+ class_option :date, :type => :string, :group => :runtime, :desc => 'Publish date for the article'
9
+
10
+ def check_slug
11
+ unless slug =~ /^[A-Za-z0-9\-\.]+$/
12
+ puts 'Invalid slug - valid characters include letters, digits and dashes.'
13
+ exit
14
+ end
15
+ end
16
+
17
+ def check_date
18
+ if options.date && options.date !~ /^\d{4}-\d{2}-\d{2}$/
19
+ puts 'Invalid date - please use the following format: YYYY-MM-DD, eg. 2011-01-01.'
20
+ exit
21
+ end
22
+ end
23
+
24
+ def generate_article
25
+ @date_str, @slug, @extension = File.basename(filename).match(/^(\d+-\d+-\d+)-(.*)(\.[^.]+)$/).captures
26
+ create_file "app/views/articles/#{@date_str}-#{@slug}#{@extension}" do
27
+ "---\n" +
28
+ "title: #{@slug.titleize}\n" +
29
+ "summary: summary goes here ...\n" +
30
+ "categories: ['category']\n" +
31
+ "tags: ['tag']\n" +
32
+ "---\n\n" +
33
+ "CONTENT GOES HERE ..."
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def filename
40
+ "#{publish_date}-#{slug.downcase}"
41
+ end
42
+
43
+ def publish_date
44
+ date = options.date.present? ? Time.zone.parse(options.date) : Time.zone.now
45
+ date.strftime('%Y-%m-%d')
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ The village:setup will setup village:pages or village:articles
3
+ depending what you need.
4
+
5
+ rails g village:setup
@@ -0,0 +1,67 @@
1
+ require 'generators/base'
2
+
3
+ module Village
4
+ module Generators
5
+ class SetupGenerator < Base #:nodoc:
6
+
7
+ class_option :pages, :desc => 'Setup village:pages for static pages', :type => :boolean, :default => true
8
+ class_option :articles, :desc => 'Setup village:articles for blog engine', :type => :boolean, :default => true
9
+
10
+ def setup
11
+ template 'village_config.yml', 'config/village_config.yml'
12
+ gem "haml-rails"
13
+ refresh_bundle
14
+ setup_pages if options.pages
15
+ setup_articles if options.articles
16
+ setup_markdown
17
+ rescue Exception => e
18
+ print_notes(e.message,"error",:red)
19
+ end
20
+
21
+ private
22
+ def setup_pages
23
+ asking "would you like to setup village:pages for static page?" do
24
+ empty_directory "app/views/pages"
25
+ route "village :pages"
26
+ copy_file 'example-page.markdown', 'app/views/pages/example-page.markdown'
27
+ asking "would you to copy village:pages views application directory?" do
28
+ empty_directory "app/views/village/pages/"
29
+ directory "views/pages", "app/views/village/pages/", :recursive => true
30
+ copy_file 'views/village.html.haml', 'app/views/layouts/village.html.haml', :force => true
31
+ end
32
+ end
33
+ end
34
+
35
+ def setup_articles
36
+ asking "would you like to setup village:articles for blog engine?" do
37
+ empty_directory "app/views/articles"
38
+ copy_asset 'views/village.css', 'public/stylesheets/village.css'
39
+ print_notes "copied default village stylesheets.css you can change it later!"
40
+ copy_file '2001-01-01-example-article.markdown', 'app/views/articles/2001-01-01-example-article.markdown'
41
+ route "village :articles"
42
+ gem "kaminari"
43
+ refresh_bundle
44
+ asking "would you to copy village:articles views directory?" do
45
+ empty_directory "app/views/village/articles/"
46
+ directory "views/articles", "app/views/village/articles/", :recursive => true
47
+ copy_file 'views/village.html.haml', 'app/views/layouts/village.html.haml', :force => true
48
+ end
49
+ end
50
+ end
51
+
52
+ def setup_markdown
53
+ markdown = ["RDiscount", "Redcarpet", "BlueCloth", "Kramdown", "Maruku"]
54
+ unless check_some_gems?(*markdown.map { |m| m.downcase })
55
+ puts "Please choose markdown engine you wish to use:"
56
+ markdown.each_with_index { |value,index| puts "#{index+1}.#{value}" }
57
+ mkd = ask(">")
58
+ markdown.each_with_index do |value,index|
59
+ gem "#{value.downcase}" if (index + 1) == mkd.to_i
60
+ end
61
+ refresh_bundle
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,8 @@
1
+ ---
2
+ title: Example Article
3
+ tags: ["Example", "Markdown"]
4
+ ---
5
+
6
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
7
+
8
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@@ -0,0 +1,10 @@
1
+ ---
2
+ title: "Example Page"
3
+ keywords: ["sooner", "you", "like"]
4
+ ---
5
+
6
+ # Another Header
7
+
8
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
9
+
10
+ [Reference](http://daringfireball.net/projects/markdown/syntax)