spokes_blog 0.0.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 (25) hide show
  1. checksums.yaml +7 -0
  2. data/lib/generators/spokes_blog/USAGE +22 -0
  3. data/lib/generators/spokes_blog/spokes_blog_generator.rb +122 -0
  4. data/lib/generators/spokes_blog/templates/controllers/admin/posts_controller.rb +53 -0
  5. data/lib/generators/spokes_blog/templates/controllers/posts_controller.rb +17 -0
  6. data/lib/generators/spokes_blog/templates/migrations/block_migration.rb +12 -0
  7. data/lib/generators/spokes_blog/templates/migrations/post_migration.rb +17 -0
  8. data/lib/generators/spokes_blog/templates/migrations/seo_meta_migration.rb +14 -0
  9. data/lib/generators/spokes_blog/templates/models/block.rb +7 -0
  10. data/lib/generators/spokes_blog/templates/models/concerns/pageable.rb +37 -0
  11. data/lib/generators/spokes_blog/templates/models/post.rb +17 -0
  12. data/lib/generators/spokes_blog/templates/models/seo_meta.rb +5 -0
  13. data/lib/generators/spokes_blog/templates/models/user.rb +5 -0
  14. data/lib/generators/spokes_blog/templates/presenters/post_presenter.rb +24 -0
  15. data/lib/generators/spokes_blog/templates/presenters/presenter.rb +9 -0
  16. data/lib/generators/spokes_blog/templates/views/admin/_block_content_form.html.haml +4 -0
  17. data/lib/generators/spokes_blog/templates/views/admin/_form.html.haml +18 -0
  18. data/lib/generators/spokes_blog/templates/views/admin/index.html.haml +26 -0
  19. data/lib/generators/spokes_blog/templates/views/admin/index.json.jbuilder +11 -0
  20. data/lib/generators/spokes_blog/templates/views/admin/new.html.haml +1 -0
  21. data/lib/generators/spokes_blog/templates/views/index.html.haml +11 -0
  22. data/lib/generators/spokes_blog/templates/views/show.html.haml +6 -0
  23. data/lib/spokes_blog/version.rb +3 -0
  24. data/lib/spokes_blog.rb +5 -0
  25. metadata +154 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6fe259d812ee077303d0c8568d0a53924a821b3e
4
+ data.tar.gz: 2f80615157378e1ac24d23f6511fac08291bcb01
5
+ SHA512:
6
+ metadata.gz: c11e7fcfae26f4703f72477d5966274f90ccc87af915a5e5a610ec68650fe031ea033837196cfb25aed008fd93d1ac4b79a5016abc1e11bd85dfc6212ef868a7
7
+ data.tar.gz: 0f1e23c806718d6e84eb4b20d6f082100bfd0fda023ceb1e3700b9028ed88ba2350fb0e713f56b99fc7a91c1c21595c6f082c03f4844580a548a2171ec2ff187
@@ -0,0 +1,22 @@
1
+ Description:
2
+ This sets up a basic blog structure. Make sure to run migrations afterwards!
3
+
4
+ Example:
5
+ rails generate spokes_blog
6
+
7
+ This will create:
8
+ Controllers:
9
+ admin/spokes_blog/posts_controller.rb - admin ctrl
10
+ spokes_blog/posts_controller.rb - public ctrl
11
+ Models:
12
+ spokes_blog/ - post, block, seo_meta
13
+ spokes_blog/concerns - pageable
14
+ Views (empty, mainly as api documentation)
15
+ admin/spokes_blog/posts
16
+ spokes_blog/posts
17
+ Presenters
18
+ presenters/presenter.rb - base presenter class
19
+ presenters/post_presenter.rb
20
+ Migrations
21
+ It will also update routes.rb and application rb.
22
+
@@ -0,0 +1,122 @@
1
+ require 'rails/generators'
2
+ module SpokesBlog
3
+ module Generators
4
+ class SpokesBlogGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+ argument :layout_name, type: :string, default: "application"
7
+
8
+ def take_care_of_acts_as_taggable_on_migration
9
+ generate "acts_as_taggable_on:migration"
10
+ end
11
+
12
+ def generate_files
13
+ #models and concerns
14
+ copy_file "models/block.rb", "app/models/spokes_blog/block.rb"
15
+ copy_file "models/post.rb", "app/models/spokes_blog/post.rb"
16
+ copy_file "models/seo_meta.rb", "app/models/spokes_blog/seo_meta.rb"
17
+ copy_file "models/concerns/pageable.rb", "app/models/spokes_blog/concerns/pageable.rb"
18
+
19
+
20
+ #controllers
21
+ copy_file "controllers/admin/posts_controller.rb", "app/controllers/admin/spokes_blog/posts_controller.rb"
22
+ copy_file "controllers/posts_controller.rb", "app/controllers/spokes_blog/posts_controller.rb"
23
+
24
+ #admin views
25
+ copy_file "views/admin/index.html.haml", "app/views/admin/spokes_blog/posts/index.html.haml"
26
+ copy_file "views/admin/index.json.jbuilder", "app/views/admin/spokes_blog/posts/index.json.jbuilder"
27
+ copy_file "views/admin/new.html.haml", "app/views/admin/spokes_blog/posts/new.html.haml"
28
+ copy_file "views/admin/_form.html.haml", "app/views/admin/spokes_blog/posts/_form.html.haml"
29
+ copy_file "views/admin/_block_content_form.html.haml", "app/views/admin/spokes_blog/posts/_block_content_form.html.haml"
30
+
31
+ #user_views
32
+ copy_file "views/index.html.haml", "app/views/spokes_blog/posts/index.html.haml"
33
+ copy_file "views/show.html.haml", "app/views/spokes_blog/posts/show.html.haml"
34
+
35
+
36
+ #presenters
37
+ copy_file "presenters/presenter.rb", "app/presenters/spokes_blog/presenter.rb"
38
+ copy_file "presenters/post_presenter.rb", "app/presenters/spokes_blog/post_presenter.rb"
39
+
40
+ #modify or create user model
41
+ if File.exist?(Rails.root.join('app', 'models', 'user.rb')) and
42
+ File.readlines(Rails.root.join('app', 'models', 'user.rb')).grep(/authored_posts/).size == 0
43
+ line = "class User < ActiveRecord::Base"
44
+ gsub_file "app/models/user.rb", /(#{Regexp.escape(line)})/mi do |match|
45
+ "#{match}\n has_many :authored_posts, class_name: :'SpokesBlog::Post', foreign_key: :author_id\n has_many :created_posts, class_name: :'SpokesBlog::Post', foreign_key: :created_by_id"
46
+ end
47
+ else
48
+ copy_file "models/user.rb", "app/models/user.rb"
49
+ end
50
+
51
+ #modify routes file using default routes
52
+ if File.readlines(Rails.root.join('config', 'routes.rb')).grep(/spokes_blog/).size == 0
53
+ line = "::Application.routes.draw do"
54
+ gsub_file Rails.root.join('config', 'routes.rb'), /(#{Regexp.escape(line)})/mi do |match|
55
+ %{#{match}
56
+ namespace :admin do
57
+ scope module: 'spokes_blog' do
58
+ resources :posts
59
+ end
60
+ end
61
+
62
+ scope module: 'spokes_blog' do
63
+ resources :posts
64
+ end}
65
+ end
66
+ end
67
+
68
+ #modify application.rb ot add models and concerns to load path
69
+ if File.readlines(Rails.root.join("config", "application.rb")).grep(/spokes_blog config/).size == 0
70
+ line = "class Application < Rails::Application"
71
+ gsub_file Rails.root.join("config", "application.rb"), /(#{Regexp.escape(line)})/mi do |match|
72
+ %{#{match}
73
+ # spokes_blog config
74
+ config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**/}')]}
75
+ end
76
+ end
77
+
78
+ #add acts-as-taggable-on to gemfile
79
+ add_gem_entry_to_gemfile("acts-as-taggable-on")
80
+ add_gem_entry_to_gemfile("haml")
81
+ add_gem_entry_to_gemfile("kaminari")
82
+
83
+ #migrations for posts and blocks
84
+ if Dir.glob("db/migrate/*_create_post.rb").empty?
85
+ sleep(1)
86
+ copy_file "migrations/post_migration.rb", "db/migrate/#{migration_timestamp}_create_post.rb"
87
+ end
88
+ if Dir.glob("db/migrate/*_create_block.rb").empty?
89
+ sleep(1)
90
+ copy_file "migrations/block_migration.rb", "db/migrate/#{migration_timestamp}_create_block.rb"
91
+ end
92
+ if Dir.glob("db/migrate/*_create_seo_meta.rb").empty?
93
+ sleep(1)
94
+ copy_file "migrations/seo_meta_migration.rb", "db/migrate/#{migration_timestamp}_create_seo_meta.rb"
95
+ end
96
+
97
+ end
98
+
99
+ private
100
+
101
+ def migration_timestamp
102
+ migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
103
+ migration_number += 1
104
+ migration_number.to_s
105
+ end
106
+
107
+ def add_gem_entry_to_gemfile(gemname)
108
+ if File.readlines(Rails.root.join("Gemfile")).grep(/#{gemname}/).size == 0
109
+ line = "rubygems.org'"
110
+ gsub_file Rails.root.join("Gemfile"), /(#{Regexp.escape(line)})/mi do |match|
111
+ %{#{match}
112
+
113
+ gem '#{gemname}'
114
+ }
115
+ end
116
+ end
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,53 @@
1
+ class Admin::SpokesBlog::PostsController < ApplicationController
2
+
3
+ def index
4
+ @posts = SpokesBlog::Post.all
5
+ end
6
+
7
+ def new
8
+ @post = SpokesBlog::Post.new
9
+ @post.blocks << SpokesBlog::Block.new
10
+ end
11
+
12
+ def create
13
+ @post = SpokesBlog::Post.new(post_params)
14
+
15
+ @post.created_by_id = current_user.id
16
+
17
+ if @post.save
18
+ redirect_to edit_admin_post_path(@post)
19
+ else
20
+ render :new
21
+ end
22
+ end
23
+
24
+ def edit
25
+ @post = SpokesBlog::Post.find(params[:id])
26
+ end
27
+
28
+ def update
29
+ @post = SpokesBlog::Post.find(params[:id])
30
+
31
+ if @post.update_attributes(post_params)
32
+ redirect_to edit_admin_post_path(@post)
33
+ else
34
+ render :edit
35
+ end
36
+ end
37
+
38
+ def destroy
39
+ @post = SpokesBlog::Post.find(params[:id])
40
+
41
+ @post.destroy
42
+
43
+ redirect_to admin_posts_path
44
+ end
45
+
46
+ private
47
+
48
+ def post_params
49
+ params.require(:spokes_blog_post).permit(:title, :slug, :description, :tag_list,
50
+ :author_id, blocks_attributes: [:content, :id])
51
+ end
52
+ end
53
+
@@ -0,0 +1,17 @@
1
+ class SpokesBlog::PostsController < ApplicationController
2
+
3
+ def index
4
+ @posts = SpokesBlog::Post.published.page(params[:page]).per(10)
5
+ end
6
+
7
+ def show
8
+ @presenter = post_presenter.single_post(slug: params[:slug])
9
+ end
10
+
11
+ private
12
+
13
+ def post_presenter
14
+ @post_presenter || @post_presenter = PostPresenter.new
15
+ end
16
+ end
17
+
@@ -0,0 +1,12 @@
1
+ class CreateBlock < ActiveRecord::Migration
2
+ def change
3
+ create_table :spokes_blog_blocks do |t|
4
+ t.text :content
5
+ t.integer :position
6
+ t.integer :post_id
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,17 @@
1
+ class CreatePost < ActiveRecord::Migration
2
+ def change
3
+ create_table :spokes_blog_posts do |t|
4
+ t.string :template
5
+ t.text :description
6
+ t.string :title
7
+ t.string :slug, index: true, unique: true
8
+ t.text :excerpt
9
+ t.integer :state
10
+ t.references :created_by, index: true
11
+ t.references :author, index: true
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,14 @@
1
+ class CreateSeoMeta < ActiveRecord::Migration
2
+ def change
3
+ create_table :seo_meta do |t|
4
+ t.string :browser_title
5
+ t.string :meta_description
6
+ t.integer :seo_meta_id
7
+ t.string :seo_meta_type
8
+
9
+ t.timestamps
10
+ end
11
+ add_index :seo_meta, [:seo_meta_id, :seo_meta_type]
12
+ end
13
+ end
14
+
@@ -0,0 +1,7 @@
1
+ class SpokesBlog::Block < ActiveRecord::Base
2
+ self.table_name_prefix = "spokes_blog_"
3
+ belongs_to :post, class_name: :'SpokesBlog::Post'
4
+
5
+ validates_presence_of :content
6
+
7
+ end
@@ -0,0 +1,37 @@
1
+ require 'active_support/concern'
2
+
3
+ module Pageable
4
+ extend ActiveSupport::Concern
5
+
6
+ STATES = {
7
+ draft: 0,
8
+ published: 1,
9
+ archived: 2
10
+ }
11
+
12
+ included do
13
+ has_one :seo_meta, as: :seo_meta
14
+
15
+ scope :published, -> { where(state: STATES[:published]) }
16
+ scope :draft, -> { where(state: STATES[:draft]) }
17
+ end
18
+
19
+ def draft?
20
+ self.state == 0
21
+ end
22
+
23
+ def published?
24
+ self.state == 1
25
+ end
26
+
27
+ module ClassMethods
28
+ def by_slug(slug)
29
+ self.find_by(slug: slug)
30
+ end
31
+
32
+ def by_template(template)
33
+ self.where(template: template).first
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,17 @@
1
+ class SpokesBlog::Post < ActiveRecord::Base
2
+ self.table_name_prefix = "spokes_blog_"
3
+ include Pageable
4
+ acts_as_taggable
5
+
6
+ belongs_to :created_by, class_name: User
7
+ belongs_to :author, class_name: User
8
+ has_many :blocks, class_name: :'SpokesBlog::Block'
9
+
10
+ accepts_nested_attributes_for :blocks,
11
+ reject_if: lambda { |attrs| attrs['content'].blank? }
12
+
13
+ validates_presence_of :title, :slug
14
+
15
+ validates_format_of :slug, with: /\A[a-zA-Z0-9-]+\z/
16
+
17
+ end
@@ -0,0 +1,5 @@
1
+ class SeoMeta < ActiveRecord::Base
2
+ belongs_to :seo_meta, polymorphic: true
3
+
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :authored_posts, class_name: :'SpokesBlog::Post', foreign_key: :author_id
3
+ has_many :created_posts, class_name: :'SpokesBlog::Post', foreign_key: :created_by_id
4
+
5
+ end
@@ -0,0 +1,24 @@
1
+ class SpokesBlog::PostPresenter < Presenter
2
+
3
+ def single_post(params = {})
4
+ @post = Post.includes(:author).includes(:blocks).by_slug(params[:slug])
5
+ self
6
+ end
7
+
8
+ def title
9
+ @post.title
10
+ end
11
+
12
+ def author
13
+ @post.author.full_name
14
+ end
15
+
16
+ def content
17
+ @post.blocks
18
+ end
19
+
20
+ def published_at
21
+ @post.updated_at.strftime("%A, %b %d, %Y")
22
+ end
23
+ end
24
+
@@ -0,0 +1,9 @@
1
+ class Presenter
2
+ def initialize args = {}
3
+ args.each do |k,v|
4
+ args.each do |k,v|
5
+ instance_variable_set("@#{k}", v) unless v.nil?
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ = f.fields_for :blocks do |block_form|
2
+ = block_form.label :content
3
+ = block_form.text_area
4
+
@@ -0,0 +1,18 @@
1
+ = form_for [:admin, @post] do |f|
2
+ %fieldset
3
+ = f.label :title
4
+ = f.text_field :title
5
+
6
+ = f.label :slug
7
+ = f.text_field :slug
8
+
9
+ = f.label :description
10
+ = f.text_area :description
11
+
12
+ = render "block_content_form", { f: f }
13
+
14
+ = f.label :tags
15
+ = f.text_field :tag_list
16
+
17
+ = f.submit "Submit"
18
+
@@ -0,0 +1,26 @@
1
+ %h1 Posts
2
+ %table.table
3
+ %thead
4
+ %tr
5
+ %th Name
6
+ %th Author
7
+ %th Created by
8
+ %th Template
9
+ %th Tags
10
+ %th Updated at
11
+ %tbody
12
+
13
+ :javascript
14
+ $(document).ready(function() {
15
+ $('.table').dataTable({
16
+ "bProcessing": true,
17
+ "sAjaxSource": "/admin/spokes_blog/posts.json",
18
+ "sDom": "<'row-fluid'<'span6'l><'span6'f>r>t<'row-fluid'<'span6'i><'span6'p>>",
19
+ "sPaginationType": "bootstrap"
20
+ });
21
+
22
+ $.extend($.fin.dataTableExt.oStdClasses, {
23
+ "sWrapper": "dataTables_wrapper form-inline"
24
+ });
25
+ });
26
+
@@ -0,0 +1,11 @@
1
+ json.aaData do
2
+ json.array!(@posts) do |post|
3
+ json.array! [link_to(post.title, edit_admin_post_path(post)),
4
+ post.author.full_name,
5
+ post.created_by.full_name,
6
+ post.template,
7
+ post.tag_list,
8
+ post.updated_at.strftime("%-m/%d/%y on %-I:%M %p")]
9
+ end
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ - @posts.each do |post|
2
+ = post.title
3
+ = post.updated_at
4
+ = post.author.full_name
5
+ - if post.excerpt.blank? || post.excerpt.length > 500
6
+ = post.blocks.first.content.truncate(500)
7
+ - else
8
+ = post.excerpt
9
+
10
+ = paginate @posts
11
+
@@ -0,0 +1,6 @@
1
+ = @presenter.title
2
+ = @presenter.published_at
3
+ = @presenter.author
4
+ - @presenter.blocks.each do |block|
5
+ = block.content.html_safe
6
+
@@ -0,0 +1,3 @@
1
+ module SpokesBlog
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "spokes_blog/version"
2
+
3
+ module SpokesBlog
4
+ # Your code goes here...
5
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spokes_blog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Matt Obarzanek
8
+ - Ryan Fischer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rails
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: acts-as-taggable-on
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: haml
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: kaminari
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description: Simple blog scaffolding that can be added to almost any existing Rails
99
+ site.
100
+ email:
101
+ - matt.obarzanek@20spokes.com
102
+ - ryan.fischer@20spokes.com
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - lib/spokes_blog/version.rb
108
+ - lib/spokes_blog.rb
109
+ - lib/generators/spokes_blog/spokes_blog_generator.rb
110
+ - lib/generators/spokes_blog/USAGE
111
+ - lib/generators/spokes_blog/templates/models/seo_meta.rb
112
+ - lib/generators/spokes_blog/templates/models/user.rb
113
+ - lib/generators/spokes_blog/templates/models/post.rb
114
+ - lib/generators/spokes_blog/templates/models/block.rb
115
+ - lib/generators/spokes_blog/templates/models/concerns/pageable.rb
116
+ - lib/generators/spokes_blog/templates/migrations/block_migration.rb
117
+ - lib/generators/spokes_blog/templates/migrations/seo_meta_migration.rb
118
+ - lib/generators/spokes_blog/templates/migrations/post_migration.rb
119
+ - lib/generators/spokes_blog/templates/presenters/presenter.rb
120
+ - lib/generators/spokes_blog/templates/presenters/post_presenter.rb
121
+ - lib/generators/spokes_blog/templates/views/admin/index.json.jbuilder
122
+ - lib/generators/spokes_blog/templates/views/admin/_block_content_form.html.haml
123
+ - lib/generators/spokes_blog/templates/views/admin/new.html.haml
124
+ - lib/generators/spokes_blog/templates/views/admin/index.html.haml
125
+ - lib/generators/spokes_blog/templates/views/admin/_form.html.haml
126
+ - lib/generators/spokes_blog/templates/views/show.html.haml
127
+ - lib/generators/spokes_blog/templates/views/index.html.haml
128
+ - lib/generators/spokes_blog/templates/controllers/admin/posts_controller.rb
129
+ - lib/generators/spokes_blog/templates/controllers/posts_controller.rb
130
+ homepage: https://github.com/20spokes/spokes_blog
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.1.11
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Setups basic blog structure for rails
154
+ test_files: []