activeadmin-cms 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +73 -0
  3. data/Rakefile +27 -0
  4. data/lib/active_admin/cms.rb +54 -0
  5. data/lib/active_admin/cms/content.rb +71 -0
  6. data/lib/active_admin/cms/content_type.rb +73 -0
  7. data/lib/active_admin/cms/content_types/image.rb +17 -0
  8. data/lib/active_admin/cms/content_types/large_image.rb +21 -0
  9. data/lib/active_admin/cms/content_types/string.rb +10 -0
  10. data/lib/active_admin/cms/content_types/text.rb +13 -0
  11. data/lib/active_admin/cms/content_types/text_and_image.rb +12 -0
  12. data/lib/active_admin/cms/controller_extensions.rb +27 -0
  13. data/lib/active_admin/cms/helpers/cms_helper.rb +13 -0
  14. data/lib/active_admin/cms/page.rb +77 -0
  15. data/lib/active_admin/cms/recipe.rb +45 -0
  16. data/lib/active_admin/cms/recipe/ingredient.rb +56 -0
  17. data/lib/active_admin/cms/recipe/section.rb +36 -0
  18. data/lib/active_admin/cms/recipes/section_helper.rb +99 -0
  19. data/lib/active_admin/cms/uploaders/content_file_uploader.rb +56 -0
  20. data/lib/active_admin/cms/uploaders/content_image_uploader.rb +62 -0
  21. data/lib/active_admin/cms/uploaders/large_image_uploader.rb +66 -0
  22. data/lib/active_admin/cms/utility/class_level_inheritable_attributes.rb +31 -0
  23. data/lib/activeadmin-cms.rb +6 -0
  24. data/lib/activeadmin-cms/version.rb +3 -0
  25. data/lib/activeadmin/cms.rb +1 -0
  26. data/lib/generators/active_admin/cms/install/install_generator.rb +39 -0
  27. data/lib/generators/active_admin/cms/install/templates/initializer.rb +7 -0
  28. data/lib/generators/active_admin/cms/install/templates/migrations/1_install_aacms.rb +29 -0
  29. data/lib/generators/active_admin/cms/page/page_generator.rb +41 -0
  30. data/lib/generators/active_admin/cms/page/templates/admin/pages.rb.erb +39 -0
  31. data/lib/generators/active_admin/cms/page/templates/migrations/1_create_pages.rb +25 -0
  32. data/lib/generators/active_admin/cms/page/templates/page.rb.erb +3 -0
  33. data/lib/generators/active_admin/cms/page/templates/views/admin/cms/page.html.haml +0 -0
  34. data/lib/generators/active_admin/cms/page/templates/views/admin/cms/pages/_form.html.haml +20 -0
  35. data/lib/generators/active_admin/cms/page/templates/views/admin/cms/pages/_ingredient.html.haml +7 -0
  36. data/lib/generators/active_admin/cms/page/templates/views/admin/cms/pages/_section.html.haml +6 -0
  37. data/lib/generators/active_admin/cms/page/templates/views/admin/cms/pages/_show.html.haml +10 -0
  38. data/lib/generators/active_admin/cms/recipe/recipe_generator.rb +42 -0
  39. data/lib/generators/active_admin/cms/recipe/templates/recipe.rb.erb +20 -0
  40. data/lib/tasks/activeadmin-cms_tasks.rake +20 -0
  41. metadata +432 -0
@@ -0,0 +1,77 @@
1
+ module ActiveAdmin
2
+ module Cms
3
+ class Page < ActiveRecord::Base
4
+ validates :title, :presence => true
5
+ validates :recipe_id, :presence => true
6
+
7
+ belongs_to :recipe
8
+
9
+ has_many :content
10
+ accepts_nested_attributes_for :content
11
+
12
+ class << self
13
+
14
+ def for_url(url)
15
+ where(:url => url).first if where(:url => url).any?
16
+ end
17
+
18
+ end
19
+
20
+ def content_for content_key
21
+ ret = nil
22
+ if recipe
23
+ if recipe.contains_content_key?(content_key)
24
+ ret = Cms::Content.where(:page_id => id, :key => content_key)
25
+ if ret.length == 0
26
+ ret = Cms::Content.new(:page => self, :key => content_key)
27
+ ret.content_type = recipe.ingredient_for(content_key).content_type
28
+ else
29
+ ret = ret[0]
30
+ end
31
+ #else
32
+ #raise Cms::Exceptions::InvalidContentKey
33
+ end
34
+ end
35
+ return ret
36
+ end
37
+
38
+ def meta_data
39
+ data = {}
40
+ if meta_title and !meta_title.blank?
41
+ data[:title] = meta_title
42
+ elsif title and !title.blank?
43
+ data[:title] = "#{Cms::SITE_TITLE} | #{title}"
44
+ else
45
+ data[:title] = Cms::SITE_TITLE
46
+ end
47
+ data[:description] = meta_description || Cms::DEFAULT_META_DESCRIPTION
48
+ data[:keywords] = meta_keywords || Cms::DEFAULT_META_KEYWORDS
49
+ data
50
+ end
51
+
52
+ # Takes a content_key => text hash and sets the text value for each of the content records
53
+ def set_value content_hash
54
+ if content_hash
55
+ content_hash.each do |key, value|
56
+ c = content_for(key)
57
+ #debugger
58
+ if c
59
+ c.set_content value
60
+ c.save
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def set_content content_key, content
67
+ if content.kind_of? Cms::Content
68
+ content.key = content_key
69
+ content.page = self
70
+ content.content_type = recipe.ingredient_for(content_key).content_type
71
+ content.save
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,45 @@
1
+ module ActiveAdmin
2
+ module Cms
3
+ class Recipe < ActiveRecord::Base
4
+
5
+ include Cms::Recipes::SectionHelper::SectionContainer
6
+
7
+ has_many :pages
8
+
9
+ def self.define(&definition_block)
10
+ after_initialize do
11
+ define &definition_block
12
+ end
13
+ end
14
+
15
+ def define(&block)
16
+ self.instance_eval &block
17
+ end
18
+
19
+ def admin_fieldset_title
20
+ 'Content'
21
+ end
22
+
23
+ def contains_content_key? content_key
24
+ !!ingredient_for(content_key)
25
+ end
26
+
27
+ def ingredient_for content_key
28
+ section_keys = content_key.split ':'
29
+ current_section = self
30
+ section_keys.each do |section_id|
31
+ #debugger
32
+ if section_id == section_keys.last
33
+ return current_section.ingredients[section_id.to_sym]
34
+ else
35
+ if current_section.sections[section_id.to_sym]
36
+ current_section = current_section.sections[section_id.to_sym]
37
+ else
38
+ return nil
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,56 @@
1
+ module ActiveAdmin
2
+ module Cms
3
+ class Recipe
4
+ class Ingredient
5
+
6
+ attr_accessor :id, :content_type, :section,
7
+ :title, :description, :options
8
+
9
+ def initialize(id, content_type, opts = {})
10
+ @id = id
11
+ @content_type = content_type
12
+ @options = opts
13
+ end
14
+
15
+ def add_fields_to(formtastic_form)
16
+ page = formtastic_form.object
17
+ content = page.content_for content_key
18
+ #debugger
19
+ fields = formtastic_form.fields_for(content) do |i_form|
20
+ i_form.inputs do
21
+ i_form.input :text
22
+ end
23
+ end
24
+ #debugger
25
+ fields
26
+ end
27
+
28
+ # returns the key to use for storing content
29
+ def content_key
30
+ return "#{section.section_key}:#{id}" if section
31
+ id
32
+ end
33
+
34
+ def input_settings opts = {}
35
+ opts[:prefix]
36
+
37
+ input_options = {:label => title, :input_html => {:name => "content[#{content_key}]", :id => content_key.to_s.gsub(':', '__')}}
38
+
39
+ input_options[:hint] ||= description if description
40
+ input_options[:hint] ||= content_type.description if !description and !content_type.description.blank?
41
+ input_options.merge! @options if @options
42
+ #debugger
43
+ [
44
+ content_type.input_field,
45
+ input_options.merge(content_type.input_opts)
46
+ ]
47
+ end
48
+
49
+ def title
50
+ @title ||= id.to_s.humanize
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ module ActiveAdmin
2
+ module Cms
3
+ class Recipe
4
+ class Section
5
+
6
+ include ActiveAdmin::Cms::Recipes::SectionHelper::SectionContainer
7
+
8
+ attr_accessor :id, :options
9
+
10
+ @content = {}
11
+
12
+ def initialize(id, opts={}, &block)
13
+
14
+ #debugger
15
+
16
+ opts[:partial] ||= 'cms/recipes/section'
17
+ opts[:class] ||= ''
18
+
19
+ @id = id
20
+ @options = opts
21
+
22
+ if block
23
+ self.instance_eval &block
24
+ end
25
+ end
26
+
27
+ def section(id, opts={}, &block)
28
+ #super(id, opts)
29
+ super
30
+ sections[id].parent = self
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,99 @@
1
+ require 'active_admin/cms/recipe/ingredient'
2
+ require 'active_admin/cms/recipe/section'
3
+
4
+ module ActiveAdmin
5
+ module Cms
6
+ module Recipes
7
+ module SectionHelper
8
+ module SectionContainer
9
+
10
+ class Ingredient < ActiveAdmin::Cms::Recipe::Ingredient; end
11
+ class Section < ActiveAdmin::Cms::Recipe::Section; end
12
+
13
+ attr_accessor :parent
14
+
15
+ def method_missing(method, *args, &block)
16
+
17
+ begin
18
+ klass = "ActiveAdmin::Cms::ContentTypes::#{method.to_s.camelcase}".constantize
19
+ rescue NameError
20
+ end
21
+
22
+ begin
23
+ klass = "::ContentTypes::#{method.to_s.camelcase}".constantize
24
+ rescue NameError
25
+ end
26
+
27
+ if klass && klass.new.kind_of?(ActiveAdmin::Cms::ContentType)
28
+ args[2] = args[1]
29
+ args[1] = klass
30
+ ingredient *args
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ # Adds formatastic fields to the specified form
37
+ def add_fields_to(formtastic_form)
38
+ fields = {}
39
+ formtastic_form.inputs admin_fieldset_title do
40
+ ingredients.each do |i_id, i|
41
+ page = formtastic_form.object
42
+ content = page.content_for i.content_key
43
+ #debugger
44
+ fields[i.content_key] = formtastic_form.fields_for(content) do |i_form|
45
+ i_form.input :text
46
+ end
47
+ #i.add_fields_to(formtastic_form) if i.kind_of? ActiveAdmin::Cms::Recipe::Ingredient
48
+ end
49
+ end
50
+ sections.each do |s_id, s|
51
+ fields[s_id] = s.add_fields_to(formtastic_form) if s.kind_of? ActiveAdmin::Cms::Recipe::Section
52
+ end
53
+
54
+ #debugger
55
+
56
+ formtastic_form.inputs
57
+
58
+ end
59
+
60
+ def admin_fieldset_title
61
+ section_id.to_s.humanize
62
+ end
63
+
64
+ def ingredient(ingredient_id, type, opts={})
65
+ @ingredients ||= {}
66
+ @ingredients[ingredient_id] = Ingredient.new(ingredient_id, type, opts)
67
+ @ingredients[ingredient_id].section = self
68
+ @ingredients[ingredient_id]
69
+ end
70
+
71
+ def ingredients
72
+ @ingredients ||= {}
73
+ end
74
+
75
+ def section(section_id, opts={}, &block)
76
+
77
+ s = Section.new(section_id, opts, &block)
78
+ @sections ||= {}
79
+ @sections[section_id] = s
80
+ s
81
+ end
82
+
83
+ def sections
84
+ @sections ||= {}
85
+ end
86
+
87
+ def section_id
88
+ self.id
89
+ end
90
+
91
+ def section_key
92
+ return "#{@parent.section_key}:#{section_id.to_s}" if @parent
93
+ section_id.to_s
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ module ActiveAdmin
3
+ module Cms
4
+ module Uploaders
5
+ class ContentFileUploader < CarrierWave::Uploader::Base
6
+
7
+ include ::CarrierWave::Backgrounder::Delay
8
+
9
+ # Include RMagick or MiniMagick support:
10
+ # include CarrierWave::RMagick
11
+ include CarrierWave::MiniMagick
12
+
13
+ # Choose what kind of storage to use for this uploader:
14
+ # storage :file
15
+ storage :fog
16
+
17
+ # Override the directory where uploaded files will be stored.
18
+ # This is a sensible default for uploaders that are meant to be mounted:
19
+ def store_dir
20
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
21
+ end
22
+
23
+ # Provide a default URL as a default if there hasn't been a file uploaded:
24
+ # def default_url
25
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
26
+ # end
27
+
28
+ # Process files as they are uploaded:
29
+ # process :scale => [200, 300]
30
+ #
31
+ # def scale(width, height)
32
+ # # do something
33
+ # end
34
+
35
+ # Create different versions of your uploaded files:
36
+ # version :thumb do
37
+ # process :scale => [50, 50]
38
+ # end
39
+
40
+ # Add a white list of extensions which are allowed to be uploaded.
41
+ # For images you might use something like this:
42
+ # def extension_white_list
43
+ # %w(jpg jpeg gif png)
44
+ # end
45
+
46
+ # Override the filename of the uploaded files:
47
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
48
+ # def filename
49
+ # "something.jpg" if original_filename
50
+ # end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ module ActiveAdmin
3
+ module Cms
4
+ module Uploaders
5
+ class ContentImageUploader < CarrierWave::Uploader::Base
6
+
7
+ include ::CarrierWave::Backgrounder::Delay
8
+
9
+ # Include RMagick or MiniMagick support:
10
+ # include CarrierWave::RMagick
11
+ include CarrierWave::MiniMagick
12
+
13
+ # Choose what kind of storage to use for this uploader:
14
+ # storage :file
15
+ storage :fog
16
+
17
+ # Override the directory where uploaded files will be stored.
18
+ # This is a sensible default for uploaders that are meant to be mounted:
19
+ def store_dir
20
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
21
+ end
22
+
23
+ # Provide a default URL as a default if there hasn't been a file uploaded:
24
+ # def default_url
25
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
26
+ # end
27
+ def default_url
28
+ '/shared/missing.png'
29
+ end
30
+
31
+ # Process files as they are uploaded:
32
+ # process :scale => [200, 300]
33
+ #
34
+ # def scale(width, height)
35
+ # # do something
36
+ # end
37
+
38
+ # Create different versions of your uploaded files:
39
+ version :small do
40
+ process :resize_to_fit => [155, nil]
41
+ end
42
+
43
+ version :thumb do
44
+ process :resize_to_fit => [55, nil]
45
+ end
46
+
47
+ # Add a white list of extensions which are allowed to be uploaded.
48
+ # For images you might use something like this:
49
+ def extension_white_list
50
+ %w(jpg jpeg gif png)
51
+ end
52
+
53
+ # Override the filename of the uploaded files:
54
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
55
+ # def filename
56
+ # "something.jpg" if original_filename
57
+ # end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module ActiveAdmin
3
+ module Cms
4
+ module Uploaders
5
+ class LargeImageUploader < CarrierWave::Uploader::Base
6
+
7
+ include ::CarrierWave::Backgrounder::Delay
8
+
9
+ # Include RMagick or MiniMagick support:
10
+ # include CarrierWave::RMagick
11
+ include CarrierWave::MiniMagick
12
+
13
+ # Choose what kind of storage to use for this uploader:
14
+ # storage :file
15
+ storage :fog
16
+
17
+ # Override the directory where uploaded files will be stored.
18
+ # This is a sensible default for uploaders that are meant to be mounted:
19
+ def store_dir
20
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
21
+ end
22
+
23
+ # Provide a default URL as a default if there hasn't been a file uploaded:
24
+ # def default_url
25
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
26
+ # end
27
+ def default_url
28
+ '/shared/missing.png'
29
+ end
30
+
31
+ # Process files as they are uploaded:
32
+ # process :scale => [200, 300]
33
+ #
34
+ # def scale(width, height)
35
+ # # do something
36
+ # end
37
+
38
+ # Create different versions of your uploaded files:
39
+ version :small do
40
+ process :resize_to_fit => [155, nil]
41
+ end
42
+
43
+ version :thumb do
44
+ process :resize_to_fit => [55, nil]
45
+ end
46
+
47
+ version :large do
48
+ process :resize_to_fit => [500, nil]
49
+ end
50
+
51
+ # Add a white list of extensions which are allowed to be uploaded.
52
+ # For images you might use something like this:
53
+ def extension_white_list
54
+ %w(jpg jpeg gif png)
55
+ end
56
+
57
+ # Override the filename of the uploaded files:
58
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
59
+ # def filename
60
+ # "something.jpg" if original_filename
61
+ # end
62
+
63
+ end
64
+ end
65
+ end
66
+ end