village 2.1.2

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 (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
data/Gemfile ADDED
@@ -0,0 +1,29 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify any dependencies in the gemspec
4
+ gemspec
5
+
6
+ ## PLEASE UNBLOCK ME IF YOU WANT TO RUN TEST
7
+ ## WITH SPORK AND GUARD
8
+ # group :development, :test do
9
+ # gem 'rails', '3.0.10'
10
+ # # load
11
+ # require 'rails'
12
+ # require 'action_view'
13
+ # require 'action_controller/vendor/html-scanner/html/sanitizer'
14
+ #
15
+ # # test gems
16
+ # gem 'rspec-rails', '~> 2.5'
17
+ # gem 'guard-rspec'
18
+ # gem 'capybara', '~> 1.0.0.beta'
19
+ # gem 'delorean', '>= 0.2'
20
+ # gem 'rb-fsevent', :require => false
21
+ # gem 'growl'
22
+ #
23
+ # # other
24
+ # gem 'haml-rails'
25
+ # gem 'sqlite3'
26
+ # gem 'kaminari'
27
+ # gem 'redcarpet'
28
+ # gem 'rdoc'
29
+ # end
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, :all_after_pass => false do
5
+ watch(%r{^app/.+\.(rb|erb|haml|builder)$}) { "spec" }
6
+ watch(%r{^spec/.+\.(rb|erb|haml|markdown|md|mkd|rdoc|yml|builder)$}) { "spec" }
7
+ watch(%r{^lib/.+\.rb$}) { "spec" }
8
+ watch('spec/spec_helper.rb') { "spec" }
9
+ end
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Fajri Fachriansyah
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,255 @@
1
+ # Village
2
+
3
+ A simple static content pages and blog engine for Rails 3.x
4
+
5
+ Village are inspired by [high_voltage](https://github.com/thoughtbot/high_voltage) and [postmarkdown](https://github.com/ennova/postmarkdown) gems, for creating static content page and
6
+ mini blog engine inside your Rails 3 application.
7
+
8
+ So Village are the combination of it, combination of all unnecessary files, nasty that you definitely don't want
9
+ to be stored into the database, rather than just read from the disk and just use `http_caching`, `memcached`
10
+ or whatever caching mechanism you wish to use in your production mode.
11
+
12
+ Village is compatible with Rails 3 only and the gem is hosted on [RubyGems.org](https://rubygems.org/gems/village).
13
+
14
+ ## Features
15
+
16
+ * Using various template engines such as markdown, textile, erb, etc. (whatever that `tilt` support)
17
+ * No database and administering page (update your content using git only)
18
+ * RSS Feed / Atom
19
+ * Customizable Routes
20
+ * HTML5 support
21
+ * Rails engine (so you can override views, controllers, etc)
22
+ * Easily customized
23
+ * Commenting via discuss
24
+ * Google analytics
25
+ * Support for tags / categories for articles
26
+ * Paginated article using `kaminari`
27
+ * Gravatar support using `gravtastic`
28
+ * `add-this` button support
29
+
30
+ ## Installation
31
+
32
+ Simply add Village to your Gemfile and bundle it up:
33
+
34
+ gem 'village'
35
+
36
+ Static pages and blog engine are managed under the named `village:pages` and `village:articles` respectively.
37
+ To setup both, run the generator to setup Village for your application:
38
+
39
+ $ rails generate village:setup
40
+
41
+ The above command will setup all necessary files and folders, routes, views directory required by `village:pages` and `village:articles`,
42
+ you can pass `--skip` optional parameter if want to skip some of the functionality.
43
+ (e.g you don't want to install `village:pages` then pass `--skip-pages`)
44
+
45
+ By default Village are using `tilt` to render every contents, so it is required you to install some of the template
46
+ engine you wish to use with Village, for example `redcarpet` for markdown then add `gem 'redcarpet'` in your `Gemfile`
47
+ or `RedCloth` for textile, etc.
48
+
49
+ all the configuration settings are managed in YAML file `config/village_config.yml`, you can customize it later depending your needs.
50
+
51
+ ## Village:Pages
52
+
53
+ Your static content pages are lived under `app/views/pages` directory, you can have many nested folder with pages in here!
54
+
55
+ you can access your static pages using route helper method `village_page_path`, for example:
56
+
57
+ <%= link_to "My Page", village_page_path('to/my/page') %>
58
+
59
+ if you setup `village:pages` properly, you will have some example page `app/views/pages/example-page.markdown`
60
+ to tested it, open `http://localhost:3000/example-page` in your browser and you should be able to navigate to your static page.
61
+
62
+ ## Village:Articles
63
+
64
+ This is a mini blog engine for your Rails app, all the articles are managed under `app/views/articles` directory
65
+ and the views files after you run the setup are copied into `app/views/village/articles` directory.
66
+
67
+ ### Generate a new Article
68
+
69
+ Here's an example of how to generate a new article using a slug and publish date:
70
+
71
+ $ rails generate village:articles test-post.md --date=2011-01-01
72
+
73
+ The above command will create the file `app/articles/2011-01-01-test-post.md`, which you can edit and add content to.
74
+
75
+ ### View the Articles
76
+
77
+ Open `http://localhost:3000/articles` in your browser and you should be able to navigate to your index articles page.
78
+ The URL for your new article is `http://localhost:3000/articles/2011/01/01/test-post`.
79
+
80
+ ### Article metadata
81
+
82
+ Metadata are stored inside the generated article using YAML front-matter `---`
83
+
84
+ ---
85
+ title: My First Article
86
+ author:
87
+ name: Fajri Fachriansyah
88
+ uri: https://github.com/fajrif
89
+ email: fajri82@gmail.com
90
+ summary: This is another article with custom metadata & summary.
91
+ tags: ["Ruby","Rails"]
92
+ ---
93
+
94
+ Village are implementing `method_missing`, so you are able to add any others metadata attributes
95
+ inside this kind of block and use it inside your views. For example :
96
+
97
+ ---
98
+ title: My First Article
99
+ summary: This is another article with custom metadata & summary.
100
+ sub_summary: this is the sub-summary i want to use in my views.
101
+ ---
102
+
103
+ notice that `sub_summary` are not required by `village:articles`, but you still able to add it
104
+ and use it inside your views like this line:
105
+
106
+ article.sub_summary if article.sub_summary?
107
+
108
+ ### RSS Feed
109
+
110
+ Village:Articles comes prepared with a fully functional RSS feed / Atom.
111
+
112
+ You can take advantage of the built-in feed by adding the feed link to your HTML head tag. For example, simply add the following to your default layout:
113
+
114
+ <head>
115
+ <!-- include your stylesheets and javascript here... -->
116
+ <%= yield :head %>
117
+ </head>
118
+
119
+ To link to the feed in your app, simply use the route helper: `<%= link_to 'RSS Feed', village_articles_path(:rss) %>`
120
+ or if you like to use Atom: `village_articles_path(:atom)`
121
+
122
+ ## Customizing Routes
123
+
124
+ By default Village will setup all article routes to go through the `/articles/*` path
125
+ while static pages go through root path (/)
126
+
127
+ For example:
128
+
129
+ http://localhost:3000/articles # lists all articles
130
+ http://localhost:3000/articles/2011 # lists all articles from 2011
131
+ http://localhost:3000/articles/2011/01 # lists all articles from January 2011
132
+ http://localhost:3000/articles/2011/01/01 # lists all articles from the 1st of January 2011
133
+ http://localhost:3000/articles/tags/ruby # lists all articles tagged with ruby
134
+ http://localhost:3000/articles/2011/01/01/test-post # show the specified article
135
+ http://localhost:3000/pages/home # show the specified static page
136
+
137
+ You can change the default route path by modifying the 'village' line in `routes.rb`. For example:
138
+
139
+ village :articles, :as => :blog
140
+ village :pages, :as => :content
141
+
142
+ This will produce the following routes:
143
+
144
+ http://localhost:3000/blog # lists all articles
145
+ http://localhost:3000/blog/2011 # lists all articles from 2011
146
+ http://localhost:3000/blog/2011/01 # lists all articles from January 2011
147
+ http://localhost:3000/blog/2011/01/01 # lists all articles from the 1st of January 2011
148
+ http://localhost:3000/blog/tags/ruby # lists all articles tagged with ruby
149
+ http://localhost:3000/blog/2011/01/01/test-post # show the specified article
150
+ http://localhost:3000/content/home # show the specified static page
151
+
152
+ You can also customize the `articles#show` route for `village:articles` via the `:permalink_format` option:
153
+
154
+ village :articles, :as => :blog, :permalink_format => :day # URL: http://localhost:3000/blog/2011/01/01/test-post
155
+ village :articles, :as => :blog, :permalink_format => :month # URL: http://localhost:3000/blog/2011/01/test-post
156
+ village :articles, :as => :blog, :permalink_format => :year # URL: http://localhost:3000/blog/2011/test-post
157
+ village :articles, :as => :blog, :permalink_format => :slug # URL: http://localhost:3000/blog/test-post
158
+
159
+ What about mapping `village:articles` / `village:pages` to root? We got you covered:
160
+
161
+ village :articles
162
+ root :to => 'village/articles#index'
163
+
164
+ or redirect root_path to some static pages in this case `home.erb`:
165
+
166
+ village :pages
167
+ root :to => 'village/pages#show', :id => 'home'
168
+
169
+ ## Default Directory Structure
170
+
171
+ ├── app
172
+ │ ├── controllers
173
+ │ ├── helpers
174
+ │ ├── mailers
175
+ │ ├── models
176
+ │ └── views
177
+ │ └── village (overrideable views)
178
+ │ └── articles (customizable)
179
+ │ ├── _article.html.haml
180
+ │ ├── _sidebar.html.haml
181
+ │ ├── ...
182
+ │ └── show.html.haml
183
+ │ ├── articles (where your article files live)
184
+ │ │ ├── 2011-04-01-example-1.markdown
185
+ │ │ ├── ...
186
+ │ │ ├── 2011-04-04-example-4.markdown
187
+ │ └── pages (where your static page files live)
188
+ │ ├── home.haml
189
+ │ ├── FAQ_FOLDERS
190
+ │ └── how-to.markdown
191
+ │ ├── ...
192
+ │ └── user_guides.rdoc
193
+
194
+ ## Override Village Controller
195
+
196
+ Most common reasons to override?
197
+
198
+ * You need authentication around the pages or articles to make sure a user is signed in.
199
+ * Or you need to skip authentication for some pages if you defined authentication filter on `ApplicationController`
200
+ * You need to render different layouts for different pages.
201
+
202
+ In this case I will show you how to override `village:pages` to add skip authentication generated by `Devise`,
203
+ let's assume that you have `before_filter: authenticate_user!` in your `ApplicationController`.
204
+
205
+ You have to create a PagesController of your own:
206
+
207
+ $ rails generate controller pages
208
+
209
+ Then modify your new `PagesController` it to inherit from Village::PagesController, adding whatever you need:
210
+
211
+ class PagesController < Village::PagesController
212
+ before_filter: authenticate_user!
213
+ end
214
+
215
+ And then change the default `village:pages` route to route to your new controller:
216
+
217
+ # in config/routes.rb
218
+ village :pages, :controller => "pages"
219
+
220
+ ## Supported Template Engine
221
+
222
+ According from [tilt](https://github.com/rtomayko/tilt) Village will support for these template engines:
223
+
224
+ ENGINE FILE EXTENSIONS REQUIRED LIBRARIES
225
+ -------------------------- ----------------------- ----------------------------
226
+ ERB .erb, .rhtml none (included ruby stdlib)
227
+ Erubis .erb, .rhtml, .erubis erubis
228
+ Haml .haml haml
229
+ Builder .builder builder
230
+ Liquid .liquid liquid
231
+ RDiscount .markdown, .mkd, .md rdiscount
232
+ Redcarpet .markdown, .mkd, .md redcarpet
233
+ BlueCloth .markdown, .mkd, .md bluecloth
234
+ Kramdown .markdown, .mkd, .md kramdown
235
+ Maruku .markdown, .mkd, .md maruku
236
+ RedCloth .textile redcloth
237
+ RDoc .rdoc rdoc
238
+ Radius .radius radius
239
+ Markaby .mab markaby
240
+ Creole (Wiki markup) .wiki, .creole creole
241
+ WikiCloth (Wiki markup) .wiki, .mediawiki, .mw wikicloth
242
+ Yajl .yajl yajl-ruby
243
+
244
+
245
+ this handlers are configurable inside generated `config/initializers/init_village.rb` file after you run the `village:setup`,
246
+ you are able to edit this file, if you wish not to use all these handlers!
247
+
248
+ ## FOUND A BUG
249
+
250
+ don't hesitate to post your issues in [here](https://github.com/fajrif/village/issues)
251
+
252
+ ## LICENSE
253
+
254
+ Village is Copyright (c) 2011 [Fajri Fachriansyah](https://github.com/fajrif) and
255
+ distributed under the MIT license.
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ Bundler.require(:default, :test)
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ require 'rake'
14
+ require 'rdoc/task'
15
+
16
+ require 'rspec/core'
17
+ require 'rspec/core/rake_task'
18
+
19
+ RSpec::Core::RakeTask.new(:spec)
20
+
21
+ task :default => :spec
22
+
23
+ Rake::RDocTask.new(:rdoc) do |rdoc|
24
+ rdoc.rdoc_dir = 'rdoc'
25
+ rdoc.title = 'ContactForm'
26
+ rdoc.options << '--line-numbers' << '--inline-source'
27
+ rdoc.rdoc_files.include('README.md')
28
+ rdoc.rdoc_files.include('lib/**/*.rb')
29
+ end
@@ -0,0 +1,27 @@
1
+ module Village
2
+ class ArticlesController < ApplicationController
3
+
4
+ def index
5
+ render :layout => Village::Config.layout
6
+ end
7
+
8
+ def show
9
+ resource
10
+ render :layout => Village::Config.layout
11
+ end
12
+
13
+ protected
14
+
15
+ def resource
16
+ @resource ||= Article.find(params[:id])
17
+ end
18
+ helper_method :resource
19
+
20
+ def collection
21
+ @collection ||= Article.where(params.slice(:year, :month, :day, :tag, :category))
22
+ Kaminari.paginate_array(@collection).page(params[:page]).per(Village::Config.page_size)
23
+ end
24
+ helper_method :collection
25
+
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ module Village
2
+ class PagesController < ApplicationController
3
+ rescue_from ActionView::MissingTemplate do |exception|
4
+ if exception.message =~ %r{Missing template "#{params[:id]}"}
5
+ raise ActionController::RoutingError, "No such page: #{params[:id]}"
6
+ else
7
+ raise exception
8
+ end
9
+ end
10
+
11
+ def show
12
+ @resource = Page.find(params[:id])
13
+ render :layout => Village::Config.layout
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title= Village::Config.title
5
+ = stylesheet_link_tag 'village'
6
+ = yield :head
7
+ %body
8
+ %header#header
9
+ %h1= link_to Village::Config.title, '/'
10
+ %p
11
+ = Village::Config.subtitle
12
+ %section#content
13
+ = yield
14
+ %footer
15
+ %small
16
+ - if Village::Config.author?
17
+ A #{link_to 'village', Village::Config.author[:url]} blog
18
+ = "by #{Village::Config.author[:name]}"
19
+ = "Copyright &copy; #{Date.today.year}".html_safe
20
+ = link_to 'rss', village_articles_path(:rss)
21
+ |
22
+ = link_to 'atom', village_articles_path(:atom)
@@ -0,0 +1,8 @@
1
+ / AddThis Button BEGIN
2
+ .addthis_toolbox.addthis_default_style
3
+ %a.addthis_button_facebook_like{"fb:like:layout" => "button_count"}
4
+ %a.addthis_button_tweet
5
+ %a.addthis_button_google_plusone{"g:plusone:size" => "medium"}
6
+ %a.addthis_counter.addthis_pill_style
7
+ %script{:src => "http://s7.addthis.com/js/250/addthis_widget.js#pubid=ra-4eade9351b25746b", :type => "text/javascript"}
8
+ / AddThis Button END
@@ -0,0 +1,13 @@
1
+ - content_for :head do
2
+ - if Village::Config.google_analytics_code?
3
+ :plain
4
+ <script type="text/javascript">
5
+ var _gaq = _gaq || [];
6
+ _gaq.push(['_setAccount', '#{Village::Config.google_analytics_code}']);
7
+ _gaq.push(['_trackPageview']);
8
+ (function() {
9
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
10
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
11
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
12
+ })();
13
+ </script>
@@ -0,0 +1,25 @@
1
+ = content_tag_for :article, article do
2
+ %header
3
+ %h1= link_to article.title, article
4
+ = image_tag article.gravatar_url(:size => 32, :default => 'identicon'), :height => 32, :width => 32
5
+ .meta
6
+ %time{:pubdate => 'true', :datetime => article.timestamp.iso8601}
7
+ Posted on #{article.date.strftime '%e %B %Y'}
8
+ %span
9
+ by
10
+ = article.author[:name]
11
+ %p
12
+ - if article.categories?
13
+ Categories on:
14
+ - article.categories.each do |category|
15
+ = link_to category, village_articles_path(:category => category)
16
+ %p
17
+ - if article.tags?
18
+ Tags on:
19
+ - article.tags.each do |tag|
20
+ = link_to tag, village_articles_path(:tag => tag)
21
+ - if summary
22
+ = article.summary_html
23
+ %p.more= link_to 'Read more&hellip;'.html_safe, article
24
+ - else
25
+ ~ article.content_html