honey-cms 0.1.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.
data/lib/cms.rb ADDED
@@ -0,0 +1,13 @@
1
+ module CMS
2
+ autoload :Routes, 'cms/routes'
3
+ autoload :Configuration, 'cms/configuration'
4
+ autoload :Type, 'cms/type'
5
+ autoload :Attribute, 'cms/attribute'
6
+ autoload :Helper, 'cms/helper'
7
+ autoload :Orderable, 'cms/orderable'
8
+ autoload :Uploader, 'cms/Uploader'
9
+ autoload :ViewTags, 'cms/view_tags'
10
+ autoload :FormBuilder, 'cms/form_builder'
11
+ end
12
+
13
+ Cms = CMS
@@ -0,0 +1,86 @@
1
+ class CMS::Attribute
2
+ attr_accessor :name, :format, :options
3
+
4
+ def initialize name, format, options
5
+ @name = name
6
+ @format = format
7
+ @options = options
8
+ @attr_options = {
9
+ # null: false
10
+ }
11
+ end
12
+
13
+ def format
14
+ @format_enquirer ||= ActiveSupport::StringInquirer.new(@format)
15
+ end
16
+
17
+ def reference? ; format.reference? end
18
+ def orderable? ; format.orderable? end
19
+ def file? ; format.file? end
20
+
21
+ def has_index?
22
+ false
23
+ end
24
+
25
+ def has_uniq_index?
26
+ false
27
+ end
28
+
29
+ def index_name
30
+ format.reference? ? "#{name}_id" : name
31
+ end
32
+
33
+ def migration_type
34
+ if format.reference?
35
+ 'belongs_to'
36
+ elsif format.orderable?
37
+ 'integer'
38
+ elsif format.file?
39
+ 'string'
40
+ elsif format.html?
41
+ 'text'
42
+ else
43
+ format
44
+ end
45
+ end
46
+
47
+ def form_type
48
+ if format.orderable? || format.reference?
49
+ 'select'
50
+ elsif format.text? or format.html?
51
+ 'text_area'
52
+ elsif format.file?
53
+ 'file_field'
54
+ elsif format.boolean?
55
+ 'check_box'
56
+ else
57
+ 'text_field'
58
+ end
59
+ end
60
+
61
+ def field_name
62
+ if reference?
63
+ name + '_id'
64
+ else
65
+ name
66
+ end
67
+ end
68
+
69
+ def inject_options
70
+ "".tap { |s| @attr_options.each { |k,v| s << ", :#{k} => #{v.inspect}" } }
71
+ end
72
+
73
+ def inject_index_options
74
+ has_uniq_index? ? ", :unique => true" : ''
75
+ end
76
+
77
+ def reference_to
78
+ if reference?
79
+ @reference_to ||= CMS::Configuration.types.find{|t| t.name == @options['reference_to']}
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ name
85
+ end
86
+ end
@@ -0,0 +1,40 @@
1
+ module CMS::Configuration
2
+ def data
3
+ @data = YAML.load(File.read(Rails.root.join 'config/cms.yml'))
4
+ end
5
+
6
+ def scoped_types options
7
+ if options[:only]
8
+ [types.find{|t| options[:only] == t.name}]
9
+ else
10
+ types.reject{|t| options[:except].include?(t.name)}
11
+ end
12
+ end
13
+
14
+ def types
15
+ if defined?(@types) then return @types end
16
+
17
+ @types = data['content_types'].map do |name, config|
18
+ CMS::Type.new(name, config.delete('attributes'), config)
19
+ end
20
+
21
+ @types.each do |type|
22
+ type.attributes = attributes(type.attributes, type)
23
+ end
24
+
25
+ @types
26
+ end
27
+
28
+ def attributes attributes, type
29
+ attributes.map do |args|
30
+ options = args.extract_options!
31
+ name = args.shift
32
+ format = args.pop || options.delete('format')
33
+ attribute = CMS::Attribute.new(name, format, options)
34
+ attribute.reference_to.references << type if attribute.reference?
35
+ attribute
36
+ end
37
+ end
38
+
39
+ extend self
40
+ end
@@ -0,0 +1,3 @@
1
+ class CMS::ControllerStub
2
+
3
+ end
data/lib/cms/engine.rb ADDED
@@ -0,0 +1,5 @@
1
+ module CMS
2
+ class Engine < ::Rails::Engine
3
+ # stubbed for assets.. ?
4
+ end
5
+ end
@@ -0,0 +1,276 @@
1
+ class CMS::FormBuilder < ActionView::Helpers::FormBuilder ; end
2
+
3
+ ActionView::Base.field_error_proc = Proc.new do |html, instance|
4
+ if html =~ /<label/
5
+ html
6
+ else
7
+ message = instance.error_message.map{|m| "#{instance.method_name.humanize} #{m}"}.join(', ')
8
+ "#{html}<div class=\"help-inline\">#{message}</div>".html_safe
9
+ end
10
+ end
11
+
12
+ module CMS::FormBuilder::Fields
13
+ def radio name, *args
14
+ args = _apply_field_defaults(args)
15
+ options = args.extract_options!
16
+ values = args
17
+ field_wrapper :radio, name do
18
+ out = ''.html_safe
19
+ out.concat label(name) if options[:label]
20
+
21
+ value_div = @template.content_tag(:span, class: 'values') do
22
+ values.map do |value|
23
+ @template.content_tag :span, class: 'value' do
24
+ if value.is_a? Array
25
+ radio_button(name, value[1]) + label(name, value[0], value: value[1])
26
+ else
27
+ radio_button(name, value) + label(name, value, value: value)
28
+ end
29
+ end
30
+ end.join("\n").html_safe
31
+ end
32
+ out.concat value_div
33
+ end
34
+ end
35
+
36
+ def location name, options
37
+ autocomplete name, options.merge(prepend: @template.content_tag(:div, '', class: 'geolocate'))
38
+ end
39
+
40
+ def autocomplete name, *args
41
+ args = _apply_field_defaults(args)
42
+ options = args.extract_options!
43
+ options.reverse_merge!(waiting: 'Searching...')
44
+
45
+ option_text = '<div class="options"><div class="inner">'.html_safe
46
+ option_text.concat @template.content_tag(:div, options[:waiting], class: 'waiting')
47
+ option_text.concat '<div class="results"></div>'.html_safe
48
+ option_text.concat '</div></div>'.html_safe
49
+
50
+ field_wrapper(:autocomplete, name) do
51
+ out = ''.html_safe
52
+ if options[:label] == true
53
+ out.concat label(name)
54
+ elsif options[:label]
55
+ out.concat label(name, options[:label])
56
+ end
57
+ out.concat @template.link_to 'learn more', '#', class: 'tipsy', title: send("#{name}_help_text") if options[:help_text]
58
+ options[:help_text] = false
59
+ out.concat string(name, options.merge(autocomplete: false, label: false, append: option_text))
60
+ end
61
+ end
62
+
63
+ def text_with_counter name, *args
64
+ args = _apply_field_defaults(args)
65
+ options = args.extract_options!
66
+
67
+ unless options[:length].blank?
68
+ counter = "<div class=\"counter\"><span class=\"count\">0</span>/<span class=\"maximum\">#{options[:length]}</span></div>".html_safe
69
+ end
70
+
71
+ text(name, options.merge(label: options[:label], append: counter))
72
+ end
73
+
74
+ def boolean *args
75
+ field :boolean, *_apply_default_options(args, label_first: false)
76
+ end
77
+
78
+ def string *args
79
+ field :string, *args
80
+ end
81
+
82
+ def search *args
83
+ field :search, *args
84
+ end
85
+
86
+ def text *args
87
+ field :text, *args
88
+ end
89
+
90
+ def email *args
91
+ field :email, *args
92
+ end
93
+
94
+ def password *args
95
+ field :password, *args
96
+ end
97
+
98
+ def hidden *args
99
+ field :hidden, *_apply_default_options(args, label: false, wrap_field: false)
100
+ end
101
+
102
+ # slider is weird enough that we will not use the default field helper.
103
+ # instead, we will construct our own field that looks like a regular field.
104
+ def slider name, *args
105
+ args = _apply_field_defaults(args)
106
+ options = args.extract_options!
107
+ out = ''.html_safe
108
+
109
+ field_wrapper :slider, name do
110
+ out.concat label(name, options[:label]) if options[:label]
111
+ out.concat @template.content_tag :div, '', class: 'slider-edit'
112
+ out.concat hidden(name)
113
+ end
114
+ end
115
+
116
+ def toggle name, *args
117
+ args = _apply_field_defaults(args)
118
+ options = args.extract_options!
119
+ out = ''.html_safe
120
+
121
+ field_wrapper :toggle, name, :'data-default' => options[:default] do
122
+ out.concat label(name) if options[:label]
123
+ out.concat(@template.content_tag(:div, class: (object.send(name) ? 'visible' : 'hidden')) do
124
+ check_box(name) << @template.label_tag(object.send(name) ? 'visible' : 'hidden')
125
+ end)
126
+ end
127
+ end
128
+
129
+ def actions options = {}
130
+ options.reverse_merge! save: 'Save', saving: 'Saving...', class: 'form-actions'
131
+ @template.content_tag(:div, class: options.delete(:class)) do
132
+ actions = ''.html_safe
133
+ actions << submit(options[:save], disable_with: options[:saving], class: 'btn btn-primary')
134
+ actions << status
135
+ end
136
+ end
137
+
138
+ def modal_actions options = {}
139
+ options.reverse_merge! save: 'Save', saving: 'Saving...', class: 'modal-footer'
140
+ @template.content_tag(:div, class: options.delete(:class)) do
141
+ actions = ''.html_safe
142
+ actions << @template.link_to('Close', '#close', class: 'btn', data: {dismiss: 'modal'})
143
+ actions << submit(options[:save], disable_with: options[:saving], class: 'btn btn-primary')
144
+ end
145
+ end
146
+
147
+ def status options = {}
148
+ options.reverse_merge! success: 'Saved!', error: 'Failed!'
149
+ out = @template.content_tag(:div, class: 'status') do
150
+ status = ''.html_safe
151
+ status << @template.content_tag(:div, '', class: 'spinner')
152
+ # status << @template.content_tag(:div, options[:success], class: 'success')
153
+ # status << @template.content_tag(:div, options[:error], class: 'error')
154
+ end
155
+ end
156
+
157
+ def field_wrapper type, name, options = {}
158
+ classes = "field #{type} #{name.to_s.dasherize} control-group"
159
+ classes << options[:classes] if options[:classes]
160
+ classes << ' error' if object.errors.include? name
161
+ options.merge! class: classes
162
+ @template.content_tag :div, options do
163
+ yield
164
+ end
165
+ end
166
+
167
+ # def _input_options options
168
+ # [:autocomplete, :placeholder]
169
+ # end
170
+
171
+ def field *args, &block
172
+ type, name, options = _extract_field_args(args)
173
+ out = ''.html_safe
174
+
175
+ input_options = {}
176
+
177
+ unless options[:autocomplete].nil?
178
+ options.delete(:autocomplete)
179
+ input_options[:autocomplete] = 'off'
180
+ end
181
+
182
+ unless options[:placeholder].nil?
183
+ input_options[:placeholder] = options.delete(:placeholder)
184
+ end
185
+
186
+ unless options[:hidden].nil?
187
+ input_options[:class] = 'hidden' if options[:hidden] == true
188
+ end
189
+
190
+ unless options[:required].nil?
191
+ input_options[:required] = 'required' if options[:required] == true
192
+ end
193
+
194
+ out.concat options[:prepend] if options[:prepend]
195
+
196
+
197
+ label_html = label(name, options[:label], class: 'control-label')
198
+
199
+ out.concat label_html if options[:label] && options[:label_first]
200
+
201
+ if options[:help_text]
202
+ help_text = send("#{name}_help_text")
203
+ help_html = "<a class=\"tipsy\" title=\"#{help_text}\" href=\"#\">learn more</a>".html_safe
204
+ out.concat help_html
205
+ end
206
+
207
+ out.concat(@template.content_tag(:div, class: 'controls') do
208
+ controls = send(_field_types(type), name, input_options)
209
+ controls.concat @template.content_tag(:div, options[:help_block], class: 'help-block') if options[:help_block].present?
210
+ controls
211
+ end)
212
+
213
+ out.concat label_html if options[:label] && !options[:label_first]
214
+
215
+ out.concat options[:append] if options[:append]
216
+ out.concat yield if block_given?
217
+
218
+ if options[:wrap_field]
219
+ field_wrapper(type, name) { out }
220
+ else
221
+ out
222
+ end
223
+ end
224
+
225
+ # simple helper method for extracting and applying default options.
226
+ def _apply_default_options args, defaults
227
+ options = args.extract_options!
228
+ args << options.reverse_merge!(defaults)
229
+ end
230
+
231
+ # apply the default options for all fields.
232
+ def _apply_field_defaults args
233
+ _apply_default_options args, label: true, wrap_field: true, label_first: true
234
+ end
235
+
236
+ # single use method for parsing options provided by the +field+ helper
237
+ def _extract_field_args args
238
+ args = _apply_field_defaults(args)
239
+ options = args.extract_options!
240
+ name = args.pop
241
+ type = args.pop
242
+ options[:label] = name.to_s.humanize if options[:label].is_a? TrueClass
243
+ [type, name, options]
244
+ end
245
+
246
+ def _field_types(type)
247
+ case type
248
+ when :string, :location
249
+ :text_field
250
+ when :search
251
+ :search_field
252
+ when :text
253
+ :text_area
254
+ when :email
255
+ :email_field
256
+ when :password
257
+ :password_field
258
+ when :hidden, :slider
259
+ :hidden_field
260
+ when :boolean, :radio
261
+ :radio_button
262
+ when :boolean, :check
263
+ :check_box
264
+ end
265
+ end
266
+
267
+ def error_messages
268
+ if object.errors.any?
269
+ @template.render partial: 'shared/form/error_messages', object: object.errors
270
+ end
271
+ end
272
+ end
273
+
274
+ class CMS::FormBuilder
275
+ include CMS::FormBuilder::Fields
276
+ end
data/lib/cms/helper.rb ADDED
@@ -0,0 +1,65 @@
1
+ module CMS::Helper
2
+ def cms_file name, size = false
3
+ if file = CMS::FileUpload.find_by_name(name) then return file end
4
+ opts = {name: name}
5
+ opts[:description] = (size.sub('x', ' by ') << ' pixels')
6
+ CMS::FileUpload.create(opts, without_protection: true)
7
+ end
8
+
9
+ def cms_image name, size = false, width = '', height = ''
10
+ width, height = size.split('x') if size
11
+ image = cms_file(name, size)
12
+
13
+ if image.file?
14
+ image_tag image.file.url, class: 'cms-image', style: "width: #{width}px ; height: #{height}px"
15
+ else
16
+ if current_user && current_user.role.admin?
17
+ link_to(name, edit_cms_file_upload_path(image), class: 'cms-image missing-cms-image', style: "width: #{width}px ; height: #{height}px ")
18
+ else
19
+ content_tag :div, name, class: 'cms-image missing-cms-image', style: "width: #{width}px ; height: #{height}px"
20
+ end
21
+ end
22
+ end
23
+
24
+ def cms_page_area name, &block
25
+ page_area = if area = CMS::PageArea.find_by_name(name) then area else CMS::PageArea.new({name: name}, without_protection: true) end
26
+
27
+ content_tag :div, role: 'html-editor' do
28
+ out = content_tag(:div, class: 'cms-page-area', role: 'display') do
29
+ if page_area.content.present? && !page_area.default
30
+ content = page_area.content
31
+ elsif block_given?
32
+ content = capture(&block)
33
+ page_area.content = ''.concat(content)
34
+ page_area.save!
35
+ end
36
+
37
+ display = ''.html_safe
38
+ display << cms_page_area_edit_link if admin?
39
+ display << content_tag(:div, class: 'content') do
40
+ cms_content_parse(content) if content.present?
41
+ end
42
+ end
43
+
44
+ out << content_tag(:div, role: 'editor') do
45
+ form_for([:cms, page_area], format: 'json', remote: true) do |f|
46
+ form = f.hidden_field(:name)
47
+ form << f.hidden_field(:content, class: 'content')
48
+ form << f.actions(save: 'done')
49
+ end
50
+ end
51
+ end
52
+ rescue Exception => e
53
+ if Rails.env.production? then '' else raise e end
54
+ end
55
+
56
+ def cms_page_area_edit_link
57
+ content_tag :div, class: 'cms-edit-link' do
58
+ link_to('Edit', '#edit')
59
+ end
60
+ end
61
+
62
+ def cms_content_parse content
63
+ CMS::ViewTags.instance.parse content, context: self
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ module CMS::Orderable
2
+ extend ActiveSupport::Concern
3
+
4
+ def order_scope
5
+ self.class
6
+ end
7
+
8
+ module ClassMethods
9
+ def orderable name
10
+ default_scope order(name)
11
+ after_save :"order_#{name}"
12
+
13
+ define_method :"order_#{name}" do
14
+ order_scope.where("#{name} >= #{send(name)}").where("id != #{id}").select(:id).select(name).inject(send(name)) do |i, record|
15
+ record.update_column name, (i += 1) ; i
16
+ end
17
+
18
+ order_scope.all.inject(1) do |i, record|
19
+ record.update_column name, i ; i + 1
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/cms/routes.rb ADDED
@@ -0,0 +1,14 @@
1
+ class CMS::Routes < SimpleDelegator
2
+ def draw
3
+ namespace :cms do
4
+ get 'description' => 'root#description'
5
+ get '' => 'root#index'
6
+
7
+ CMS::Configuration.types.each do |type|
8
+ resources type.model_name.route_key
9
+ end
10
+
11
+ resources :topic_datas, :community_maps, :downtowns
12
+ end
13
+ end
14
+ end
data/lib/cms/type.rb ADDED
@@ -0,0 +1,44 @@
1
+ class CMS::Type
2
+ attr_accessor :name, :attributes, :options, :references
3
+ include ActiveModel::Naming # using include instead of extend on purpose
4
+ def parents ; [] end # quacks like a Module
5
+
6
+ def initialize name, attributes, options = {}
7
+ @name = name
8
+ @attributes = attributes
9
+ @options = options.symbolize_keys.merge(timestamps: true, indexes: true)
10
+ @references = []
11
+ end
12
+
13
+ def accessible_attributes
14
+ attributes
15
+ end
16
+
17
+ def attributes_with_index
18
+ attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) }
19
+ end
20
+
21
+ def orderable_attributes
22
+ attributes.select(&:orderable?)
23
+ end
24
+
25
+ def file_attributes
26
+ attributes.select(&:file?)
27
+ end
28
+
29
+ def orderable?
30
+ !!order_attribute
31
+ end
32
+
33
+ def order_attribute
34
+ orderable_attributes.first
35
+ end
36
+
37
+ def to_s
38
+ name
39
+ end
40
+
41
+ def subject
42
+ options[:subject] || name
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ class CMS::Uploader < CarrierWave::Uploader::Base
2
+ def store_dir
3
+ base = File.join('cms-uploads', model.class.model_name.collection.gsub('_', '-'), model.id.try(:to_s))
4
+ base = File.join('uploads', base) if storage.is_a? CarrierWave::Storage::File
5
+ base
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ class CMS::ViewTags
2
+ attr_accessor :context, :controller
3
+ delegate :current_user, :config, to: :context
4
+
5
+ include Singleton
6
+ include ApplicationHelper
7
+ include ActionView::Helpers::TextHelper
8
+ include ActionView::Helpers::UrlHelper
9
+ include ActionView::Helpers::AssetTagHelper
10
+ include ApplicationHelper
11
+ include CMS::Helper
12
+ include Rails.application.routes.url_helpers
13
+
14
+ def setup opts
15
+ @context = @controller = opts[:context]
16
+ end
17
+
18
+ def parse content, opts = {}
19
+ setup(opts)
20
+ content.gsub(/\{\{image [^}}]+\}\}/) do |tag|
21
+ str, name, size = tag.match(/\{\{image (\w+) (\w+)\}\}/).to_a
22
+ cms_image(name, size)
23
+ end.html_safe
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate cms Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,44 @@
1
+ require 'rails/generators/active_record/migration'
2
+
3
+ class CmsGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+ include Rails::Generators::Migration
6
+ extend ActiveRecord::Generators::Migration
7
+
8
+ class_option :except, type: :array, default: [],
9
+ desc: 'skip certain types.'
10
+
11
+ class_option :only, type: :string, default: false,
12
+ desc: 'run a specific type generator.'
13
+
14
+ class_option :migrate, type: :boolean, default: false,
15
+ desc: 'generate the migration'
16
+
17
+ class_option :controller, type: :boolean, default: false,
18
+ desc: 'generate the controller'
19
+
20
+ def create_migration_file
21
+ if options[:only].present?
22
+ migration_template 'migration.rb', "db/migrate/create_#{options[:only].underscore.pluralize}" if options[:migrate]
23
+ else
24
+ migration_template 'migration.rb', 'db/migrate/create_cms' if options[:migrate]
25
+ end
26
+ end
27
+
28
+ def copy_controller_file
29
+ template 'cms_base_controller.rb', 'app/controllers/cms/base_controller.rb' if options[:controller]
30
+
31
+ empty_directory 'app/controllers/cms'
32
+ empty_directory 'app/models/cms'
33
+
34
+ CMS::Configuration.scoped_types(options).each do |type|
35
+ @name = (@type = type).model_name
36
+ template 'type_controller.rb', "app/controllers/cms/#{@name.collection}_controller.rb"
37
+ template 'type_model.rb', "app/models/cms/#{@name.element}.rb"
38
+
39
+ %w(index new show edit).each do |view|
40
+ template "views/#{view}.html.haml", "app/views/cms/#{@name.collection}/#{view}.html.haml"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,78 @@
1
+ class CMS::BaseController < ApplicationController
2
+ before_filter :admin!
3
+ before_filter :set_active
4
+ layout 'cms'
5
+
6
+ before_filter :find_record, only: [:show, :edit, :update, :destroy]
7
+ before_filter :set_element_variable, only: [:show, :edit, :update, :destroy]
8
+ respond_to :html, :json
9
+
10
+ def index
11
+ @records = if params[:search].blank?
12
+ subject.order('id asc') .page(params[:page]).per(100)
13
+ else
14
+ subject.search(params[:search]).page(params[:page]).per(100)
15
+ end
16
+
17
+ set_collection_variable
18
+ respond_with(@records)
19
+ end
20
+
21
+ def new
22
+ @record = subject.new
23
+ set_element_variable
24
+ respond_with(@record)
25
+ end
26
+
27
+ def create
28
+ @record = subject.create(params[subject.model_name.element])
29
+ set_element_variable
30
+ respond_with @record
31
+ end
32
+
33
+ def show
34
+ respond_with @record
35
+ end
36
+
37
+ def edit
38
+ respond_with @record
39
+ end
40
+
41
+ def update
42
+ @record.update_attributes params[subject.model_name.element]
43
+ respond_with @record
44
+ end
45
+
46
+ def destroy
47
+ @record.destroy
48
+ respond_with @record
49
+ end
50
+
51
+ protected
52
+
53
+ def respond_with object
54
+ super [:cms, object]
55
+ end
56
+
57
+ def find_record
58
+ @record = subject.find(params[:id])
59
+ end
60
+
61
+ def set_collection_variable
62
+ instance_variable_set :"@#{subject.model_name.collection}", @records
63
+ end
64
+
65
+ def set_element_variable
66
+ instance_variable_set :"@#{subject.model_name.element}", @record
67
+ end
68
+
69
+ def admin!
70
+ unless signed_in? && current_user.role.admin?
71
+ auth_failed
72
+ end
73
+ end
74
+
75
+ def set_active
76
+ @active_page = /cms/
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ class CMS::Model < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,19 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def change
3
+ <% CMS::Configuration.scoped_types(options).each do |type| -%>
4
+ create_table :<%= type.model_name.collection %> do |t|
5
+ <% type.attributes.each do |attribute| -%>
6
+ t.<%= attribute.migration_type %> :<%= attribute.name %><%= attribute.inject_options %>
7
+ <% end -%>
8
+ <% if type.options[:timestamps] -%>
9
+ t.timestamps
10
+ <% end -%>
11
+ end
12
+
13
+ <% type.attributes_with_index.each do |attribute| -%>
14
+ add_index :<%= type.model_name.collection %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
15
+ <% end -%>
16
+ <% end -%>
17
+
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ class CMS::<%= @name.pluralize %>Controller < CMS::BaseController
2
+ helper_method :subject
3
+
4
+ protected
5
+
6
+ def subject
7
+ CMS::<%= @name %>
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ class CMS::<%= @name %> < ActiveRecord::Base
2
+ self.table_name = '<%= @name.collection %>'
3
+ <% @type.attributes.select {|attr| attr.reference? }.each do |attribute| -%>
4
+ belongs_to :<%= attribute.name %>, class_name: 'CMS::<%= attribute.reference_to %>'
5
+ <% end -%>
6
+ <% if @type.references.any? -%>
7
+ <% @type.references.each do |type| -%>
8
+ has_many :<%= type.model_name.collection %>, class_name: 'CMS::<%= type %>'
9
+ <% end -%>
10
+ <% end -%>
11
+ attr_accessible <%= @type.accessible_attributes.map {|a| ":#{a.field_name}" }.sort.join(', ') %>
12
+ <% if @type.orderable? -%>
13
+ include CMS::Orderable
14
+ orderable(:<%= @type.order_attribute.name %>)
15
+ <% end -%>
16
+ <% @type.file_attributes.each do |attribute| -%>
17
+ mount_uploader :<%= attribute.name %>, CMS::Uploader
18
+ <% end -%>
19
+
20
+ def self.name
21
+ '<%= @name %>'
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ %h2 Edit <%= @name.human.downcase %>
2
+
3
+ = form_for @<%= @name.element %>, url: cms_<%= @name.element %>_path(@<%= @name.element %>), html: {class: 'form-horizontal'} do |f|
4
+ <% @type.attributes.each do |attribute| -%>
5
+ .control-group
6
+ = f.label :<%= attribute.field_name %>, class: 'control-label'
7
+ <% if attribute.orderable? -%>
8
+ .controls
9
+ = f.<%= attribute.form_type %> :<%= attribute.name %>, 1.upto(CMS::<%= @name %>.count).to_a
10
+ <% elsif attribute.reference? -%>
11
+ .controls
12
+ = f.<%= attribute.form_type %> :<%= attribute.field_name %>, CMS::<%= attribute.reference_to %>.all.collect {|r| [ r.<%= attribute.options['reference_label'] %>, r.id ] }
13
+ <% else -%>
14
+ .controls
15
+ = f.<%= attribute.form_type %> :<%= attribute.name %>
16
+ <% end -%>
17
+ <% end -%>
18
+ .form-actions
19
+ = f.submit 'Save', class: 'btn btn-primary', :'data-disable-with' => 'Saving...'
@@ -0,0 +1,34 @@
1
+ %h2 <%= @name.human.pluralize %>
2
+
3
+ = link_to 'New <%= @name.human.downcase %>', new_cms_<%= @name.element %>_path
4
+
5
+ %table.table
6
+ %thead
7
+ %tr
8
+ %th Id
9
+ <% @type.attributes.each do |attribute| -%>
10
+ %th <%= attribute.name.humanize %>
11
+ <% end -%>
12
+ %th
13
+
14
+ %tbody
15
+ - @<%= @name.collection %>.each do |<%= @name.element %>|
16
+ %tr
17
+ %td= <%= @name.element %>.id
18
+ <% @type.attributes.each do |attribute| -%>
19
+ <% if attribute.reference? -%>
20
+ %td
21
+ - if <%= @name.element %>.<%= attribute.name %>.present?
22
+ = link_to <%= @name.element %>.<%= attribute.name %>.<%= attribute.options['reference_label'] %>, cms_<%= attribute.reference_to.model_name.element %>_path(<%= @name.element %>.<%= attribute.name %>)
23
+ <% elsif attribute.format.file? -%>
24
+ %td
25
+ %img{src: <%= @name.element %>.<%= attribute.name %>}
26
+ <% else -%>
27
+ %td= <%= @name.element %>.<%= attribute.name %>
28
+ <% end -%>
29
+ <% end -%>
30
+ %td
31
+ = link_to 'Edit', edit_cms_<%= @name.element %>_path(<%= @name.element %>)
32
+ = link_to 'Destroy', cms_<%= @name.element %>_path(<%= @name.element %>), confirm: 'are you sure?', method: 'delete'
33
+
34
+ = paginate @<%= @name.collection %>
@@ -0,0 +1,19 @@
1
+ %h2 New <%= @name.human.downcase %>
2
+
3
+ = form_for @<%= @name.element %>, url: cms_<%= @name.collection %>_path, html: {class: 'form-horizontal'} do |f|
4
+ <% @type.attributes.each do |attribute| -%>
5
+ .control-group
6
+ = f.label :<%= attribute.field_name %>, class: 'control-label'
7
+ <% if attribute.orderable? -%>
8
+ .controls
9
+ = f.<%= attribute.form_type %> :<%= attribute.name %>, 1.upto(CMS::<%= @name %>.count + 1).to_a
10
+ <% elsif attribute.reference? -%>
11
+ .controls
12
+ = f.<%= attribute.form_type %> :<%= attribute.field_name %>, CMS::<%= attribute.reference_to %>.all.collect {|r| [ r.<%= attribute.options['reference_label'] %>, r.id ] }
13
+ <% else -%>
14
+ .controls
15
+ = f.<%= attribute.form_type %> :<%= attribute.name %>
16
+ <% end -%>
17
+ <% end -%>
18
+ .form-actions
19
+ = f.submit 'Save', class: 'btn btn-primary', :'data-disable-with' => 'Saving...'
@@ -0,0 +1,13 @@
1
+ %h2== Showing <%= @name.human.downcase %> ##{@<%= @name.element %>.id}
2
+
3
+ %dl
4
+ <% @type.attributes.each do |attribute| -%>
5
+ %dt <%= attribute.name.humanize %>
6
+ <% if attribute.reference? -%>
7
+ %dd= @<%= @name.element %>.<%= attribute.name %>.try(:<%= attribute.options['reference_label'] %>)
8
+ <% elsif attribute.format.text? -%>
9
+ %dd= markdown @<%= @name.element %>.<%= attribute.name %>
10
+ <% else -%>
11
+ %dd= @<%= @name.element %>.<%= attribute.name %>
12
+ <% end -%>
13
+ <% end -%>
data/lib/honey-cms.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'cms'
2
+ require 'cms/engine'
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: honey-cms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Quinn Shanahan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Some CMS functionality
15
+ email: quinn@tastehoneyco.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/cms/attribute.rb
21
+ - lib/cms/configuration.rb
22
+ - lib/cms/controller_stub.rb
23
+ - lib/cms/engine.rb
24
+ - lib/cms/form_builder.rb
25
+ - lib/cms/helper.rb
26
+ - lib/cms/orderable.rb
27
+ - lib/cms/routes.rb
28
+ - lib/cms/type.rb
29
+ - lib/cms/uploader.rb
30
+ - lib/cms/view_tags.rb
31
+ - lib/cms.rb
32
+ - lib/generators/cms/cms_generator.rb
33
+ - lib/generators/cms/templates/cms_base_controller.rb
34
+ - lib/generators/cms/templates/cms_model.rb
35
+ - lib/generators/cms/templates/migration.rb
36
+ - lib/generators/cms/templates/type_controller.rb
37
+ - lib/generators/cms/templates/type_model.rb
38
+ - lib/generators/cms/templates/views/edit.html.haml
39
+ - lib/generators/cms/templates/views/index.html.haml
40
+ - lib/generators/cms/templates/views/new.html.haml
41
+ - lib/generators/cms/templates/views/show.html.haml
42
+ - lib/generators/cms/USAGE
43
+ - lib/honey-cms.rb
44
+ homepage: https://github.com/honeyco/honey-cms
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.11
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: CMS
68
+ test_files: []