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