contentator 0.2.0 → 0.2.1

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 (101) hide show
  1. data/README.rdoc +2 -2
  2. data/Rakefile +26 -0
  3. data/VERSION +1 -0
  4. data/app/controllers/application_controller.rb +35 -0
  5. data/app/controllers/cms/admin/admin_controller.rb +3 -0
  6. data/app/controllers/cms/admin/file_attachments_controller.rb +53 -0
  7. data/app/controllers/cms/admin/page_content_blocks_controller.rb +77 -0
  8. data/app/controllers/cms/admin/pages_controller.rb +68 -0
  9. data/app/controllers/cms/content_controller.rb +25 -0
  10. data/app/helpers/application_helper.rb +29 -0
  11. data/app/helpers/cms/admin/pages_helper.rb +34 -0
  12. data/app/models/file_attachment.rb +4 -0
  13. data/app/models/page.rb +71 -0
  14. data/app/models/page_content_block.rb +10 -0
  15. data/app/views/cms/admin/_admin_toolbar.html.haml +10 -0
  16. data/app/views/cms/admin/file_attachments/_form.html.haml +17 -0
  17. data/app/views/cms/admin/page_content_blocks/_form.html.haml +23 -0
  18. data/app/views/cms/admin/pages/_form.html.haml +22 -0
  19. data/app/views/cms/admin/pages/edit.html.haml +10 -0
  20. data/app/views/cms/admin/pages/index.html.haml +13 -0
  21. data/app/views/cms/admin/pages/new.html.haml +7 -0
  22. data/app/views/cms/content/_file_attachment.html.haml +9 -0
  23. data/app/views/cms/content/_file_attachments_container.html.haml +16 -0
  24. data/app/views/cms/content/_page_content_block.html.haml +14 -0
  25. data/app/views/cms/content/_page_content_blocks_container.html.haml +15 -0
  26. data/app/views/cms/content/content.html.haml +4 -0
  27. data/app/views/cms/content/gallery.html.haml +4 -0
  28. data/app/views/cms/content/home.html.haml +4 -0
  29. data/app/views/layouts/application.html.haml +22 -0
  30. data/app/views/layouts/cms/admin/application.html.haml +44 -0
  31. data/config/boot.rb +110 -0
  32. data/config/environment.rb +54 -0
  33. data/config/environments/development.rb +17 -0
  34. data/config/environments/production.rb +28 -0
  35. data/config/environments/test.rb +28 -0
  36. data/config/geminstaller.local.yml +21 -0
  37. data/config/geminstaller.yml +22 -0
  38. data/config/initializers/backtrace_silencers.rb +7 -0
  39. data/config/initializers/inflections.rb +10 -0
  40. data/config/initializers/mime_types.rb +5 -0
  41. data/config/initializers/new_rails_defaults.rb +19 -0
  42. data/config/initializers/session_store.rb +15 -0
  43. data/config/locales/de.yml +49 -0
  44. data/config/locales/en.yml +49 -0
  45. data/config/routes.rb +13 -0
  46. data/contentator.gemspec +160 -0
  47. data/db/migrate/20091002165818_create_pages.rb +22 -0
  48. data/db/migrate/20091002211930_create_home_page.rb +10 -0
  49. data/db/migrate/20091007222703_create_page_content_blocks.rb +22 -0
  50. data/db/migrate/20091029204950_create_file_attachments.rb +17 -0
  51. data/lib/contentator.rb +2 -0
  52. data/lib/generators/content/content_generator.rb +118 -0
  53. data/lib/generators/content/templates/container.rb +16 -0
  54. data/lib/generators/content/templates/controller.rb +63 -0
  55. data/lib/generators/content/templates/factories.rb +6 -0
  56. data/lib/generators/content/templates/form.rb +12 -0
  57. data/lib/generators/content/templates/functional_test.rb +140 -0
  58. data/lib/generators/content/templates/item.rb +11 -0
  59. data/lib/generators/content/templates/migration.rb +17 -0
  60. data/lib/generators/content/templates/model.rb +5 -0
  61. data/lib/generators/content/templates/unit_test.rb +8 -0
  62. data/lib/generators/content/templates/view.rb +0 -0
  63. data/lib/template.rb +10 -0
  64. data/public/404.html +30 -0
  65. data/public/422.html +30 -0
  66. data/public/500.html +30 -0
  67. data/public/favicon.ico +0 -0
  68. data/public/images/admin_standard/content-header-bg.png +0 -0
  69. data/public/images/admin_standard/context-arrow.png +0 -0
  70. data/public/images/admin_standard/context-bg.png +0 -0
  71. data/public/images/admin_standard/crumb-bg-current.gif +0 -0
  72. data/public/images/admin_standard/crumb-bg.gif +0 -0
  73. data/public/images/admin_standard/crumb-divide-current.gif +0 -0
  74. data/public/images/admin_standard/crumb-divide.gif +0 -0
  75. data/public/images/admin_standard/drawer-end.png +0 -0
  76. data/public/images/admin_standard/drawer-middle.png +0 -0
  77. data/public/images/admin_standard/drawer-start.png +0 -0
  78. data/public/images/admin_standard/form-error.png +0 -0
  79. data/public/images/admin_standard/input-background.gif +0 -0
  80. data/public/images/admin_standard/shadow-bottom.png +0 -0
  81. data/public/images/admin_standard/shadow-right.png +0 -0
  82. data/public/images/admin_standard/subnavigation-bullet-1.png +0 -0
  83. data/public/images/admin_standard/subnavigation-bullet-2.png +0 -0
  84. data/public/images/admin_standard/tab-active-cap.png +0 -0
  85. data/public/images/admin_standard/tab-active.png +0 -0
  86. data/public/images/admin_standard/tab-inactive-cap.png +0 -0
  87. data/public/images/admin_standard/tab-inactive.png +0 -0
  88. data/public/images/blank.gif +0 -0
  89. data/public/images/icons/add.png +0 -0
  90. data/public/images/icons/cancel.png +0 -0
  91. data/public/images/icons/delete.png +0 -0
  92. data/public/images/icons/edit.png +0 -0
  93. data/public/images/icons/folder.png +0 -0
  94. data/public/images/icons/move.png +0 -0
  95. data/public/images/rails.png +0 -0
  96. data/public/robots.txt +5 -0
  97. data/public/stylesheets/admin_standard.css +877 -0
  98. data/public/stylesheets/application.css +33 -0
  99. data/rails_generators/contentator_files/contentator_files_generator.rb +127 -0
  100. data/rails_generators/contentator_files/templates/application.rb +5 -0
  101. metadata +111 -2
@@ -4,13 +4,13 @@ Contentator is designed to be a flexible, light cms. Hopefully it won't get in
4
4
 
5
5
  == Install
6
6
 
7
- For now build and install the gem with jeweler. It will be on gemcutter eventually
7
+ gem install contentator
8
8
 
9
9
  == Usage
10
10
 
11
11
  Create a new rails app with the contentator template
12
12
 
13
- rails MY_APP -m YOUR_GEM_PATH/lib/template.rb
13
+ rails MY_APP -m GEM_PATH/lib/template.rb
14
14
 
15
15
  Then drop in a database.yml and fire up the database
16
16
 
@@ -0,0 +1,26 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+ require 'tasks/rails'
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "contentator"
15
+ gem.summary = %q{A lightweight cms that focuses on in place editing.}
16
+ gem.description = %q{A lightweight cms that focuses on in place editing.}
17
+ gem.email = "cpartin@gmail.com"
18
+ gem.homepage = "http://github.com/cpartin/contentator"
19
+ gem.authors = ["Craig Partin"]
20
+ gem.add_dependency('haml', '>= 2.2.6')
21
+ gem.files.exclude('.DS_Store', '.gitignore', 'pkg', 'vendor', 'public/javascripts', 'script')
22
+ end
23
+
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
26
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,35 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ before_filter :set_locale
6
+
7
+ helper :all # include all helpers, all the time
8
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
9
+
10
+ # Scrub sensitive parameters from your log
11
+ # filter_parameter_logging :password
12
+
13
+ uses_tiny_mce :options => {
14
+ :width => 400,
15
+ :theme => 'advanced',
16
+ :theme_advanced_disable => "anchor,blockquote,outdent,indent,image,cleanup,help,code,separator,hr,quote,removeformat,formatselect,fontselect,fontsizeselect,styleselect,sub, sup,forecolor,backcolor,forecolorpicker,backcolorpicker,charmap,visualaid"
17
+ }
18
+
19
+ helper_method :current_user
20
+
21
+ private
22
+ def current_user
23
+ return true
24
+ end
25
+
26
+ def set_locale
27
+ I18n.locale = extract_locale_from_subdomain
28
+ end
29
+
30
+ def extract_locale_from_subdomain
31
+ parsed_locale = request.host.split('.').first
32
+ (I18n.available_locales.include? parsed_locale.to_sym) ? parsed_locale : nil
33
+ end
34
+
35
+ end
@@ -0,0 +1,3 @@
1
+ class Cms::Admin::AdminController < ApplicationController
2
+ layout 'cms/admin/application'
3
+ end
@@ -0,0 +1,53 @@
1
+ class Cms::Admin::FileAttachmentsController < Cms::Admin::AdminController
2
+
3
+ def new
4
+ @page = Page.find(params[:page_id])
5
+ @file_attachment = FileAttachment.new
6
+ render :partial => 'cms/admin/file_attachments/form'
7
+ end
8
+
9
+ def create
10
+ @page = Page.find(params[:file_attachment].delete('page_id'))
11
+
12
+ @owner = params[:file_attachment][:owner_type].constantize.find(params[:file_attachment][:owner_id])
13
+ @file_attachment = @owner.file_attachments.new(params[:file_attachment])
14
+
15
+ if @file_attachment.save
16
+ responds_to_parent do
17
+ render :update do |page|
18
+ page.replace_html 'new_file_attachment', ''
19
+ page.replace_html 'file_attachments_container', :partial => 'cms/content/file_attachments_container'
20
+ end
21
+ end
22
+ else
23
+ responds_to_parent do
24
+ render :update do |page|
25
+ page.replace_html "file_attachment_", :partial => 'cms/admin/file_attachments/form'
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def destroy
32
+ @page = Page.find(params[:page_id])
33
+ @file_attachment = FileAttachment.find(params[:id])
34
+ @file_attachment.destroy
35
+ render :update do |page|
36
+ page.replace_html 'file_attachments_container', :partial => 'cms/content/file_attachments_container'
37
+ end
38
+ end
39
+
40
+ def sort
41
+ @page = Page.find(params[:page_id])
42
+ if params[:file_attachment]
43
+ position = 0
44
+ params[:file_attachment].each do |id|
45
+ file_attachment = FileAttachment.find(id)
46
+ file_attachment.update_attributes(:position => position)
47
+ position += 1
48
+ end
49
+ end
50
+ render :nothing => true, :layout => false
51
+ end
52
+
53
+ end
@@ -0,0 +1,77 @@
1
+ class Cms::Admin::PageContentBlocksController < ApplicationController
2
+
3
+ def new
4
+ @page = Page.find(params[:page_id])
5
+ @page_content_block = @page.page_content_blocks.new
6
+ render :partial => 'cms/admin/page_content_blocks/form'
7
+ end
8
+
9
+ def edit
10
+ @page_content_block = PageContentBlock.find(params[:id])
11
+ @page = Page.find(@page_content_block.page_id)
12
+ render :partial => 'cms/admin/page_content_blocks/form'
13
+ end
14
+
15
+ def create
16
+ @page = Page.find(params[:page_content_block][:page_id])
17
+ @page_content_block = @page.page_content_blocks.new(params[:page_content_block])
18
+
19
+ if @page_content_block.save
20
+ responds_to_parent do
21
+ render :update do |page|
22
+ page.replace_html 'new_page_content_block', ''
23
+ page.replace_html 'page_content_blocks_container', :partial => 'cms/content/page_content_blocks_container'
24
+ end
25
+ end
26
+ else
27
+ responds_to_parent do
28
+ render :update do |page|
29
+ page.replace_html "page_content_block_", :partial => 'cms/admin/page_content_blocks/form'
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def update
36
+ @page_content_block = PageContentBlock.find(params[:id])
37
+ @page = Page.find(@page_content_block.page_id)
38
+
39
+ @page_content_block.photo = nil if params[:remove_image]
40
+
41
+ if @page_content_block.update_attributes(params[:page_content_block])
42
+ responds_to_parent do
43
+ render :update do |page|
44
+ page.replace_html 'page_content_blocks_container', :partial => 'cms/content/page_content_blocks_container'
45
+ end
46
+ end
47
+ else
48
+ responds_to_parent do
49
+ render :update do |page|
50
+ page.replace_html "page_content_block_", :partial => 'cms/admin/page_content_blocks/form'
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def destroy
57
+ @page_content_block = PageContentBlock.find(params[:id])
58
+ @page = Page.find(@page_content_block.page_id)
59
+ @page_content_block.destroy
60
+ render :update do |page|
61
+ page.replace_html 'page_content_blocks_container', :partial => 'cms/content/page_content_blocks_container'
62
+ end
63
+ end
64
+
65
+ def sort
66
+ @page = Page.find(params[:page_id])
67
+ if params[:page_content_block]
68
+ position = 0
69
+ params[:page_content_block].each do |id|
70
+ page_content_block = @page.page_content_blocks.find(id)
71
+ page_content_block.update_attributes(:position => position)
72
+ position += 1
73
+ end
74
+ end
75
+ render :nothing => true, :layout => false
76
+ end
77
+ end
@@ -0,0 +1,68 @@
1
+ class Cms::Admin::PagesController < Cms::Admin::AdminController
2
+
3
+ def index
4
+ @pages = Page.ordered
5
+ end
6
+
7
+ def new
8
+ @page = Page.new
9
+ @pages = Page.ordered
10
+ end
11
+
12
+ def edit
13
+ @page = Page.find(params[:id])
14
+ @pages = Page.ordered
15
+ end
16
+
17
+ def create
18
+ @page = Page.new(params[:page])
19
+ @pages = Page.ordered
20
+
21
+ if @page.save
22
+ flash[:notice] = t('cms.admin.pages.flash_create')
23
+ redirect_to(cms_admin_pages_path)
24
+ else
25
+ render :action => "new"
26
+ end
27
+ end
28
+
29
+ def update
30
+ @page = Page.find(params[:id])
31
+ @pages = Page.ordered
32
+
33
+ if @page.update_attributes(params[:page])
34
+ flash[:notice] = t('cms.admin.pages.flash_update')
35
+ redirect_to( cms_admin_pages_path )
36
+ else
37
+ render :action => "edit"
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ @page = Page.find(params[:id])
43
+ @page.destroy
44
+ flash[:notice] = @page ? @page.errors.on_base : flash[:notice] = t('cms.admin.pages.flash_delete')
45
+ redirect_to(cms_admin_pages_path)
46
+ end
47
+
48
+ def update_page_tree
49
+ position = -1
50
+ params[:tree_root].sort.each do |id, pos|
51
+ save_tree params[:tree_root][id], nil, position += 1
52
+ end
53
+ render :nothing => true
54
+ end
55
+
56
+ private
57
+ # saves the tree structure and positions when updated
58
+ def save_tree(node, parent_id, pos)
59
+ id = node["id"]
60
+ Page.update(id, :position => pos += 1, :parent_id => parent_id)
61
+
62
+ node.delete("id")
63
+ node.sort.each do |child|
64
+ pos = save_tree(child[1], id, pos)
65
+ end if node.length
66
+ pos
67
+ end
68
+ end
@@ -0,0 +1,25 @@
1
+ class Cms::ContentController < ApplicationController
2
+
3
+ def show
4
+ @page = Page.find_from_path(params[:path])
5
+
6
+ if @page
7
+ send @page.template_name if @page
8
+ render :action => @page.template_name
9
+ else
10
+ respond_to do |format|
11
+ format.all { render :file => "#{RAILS_ROOT}/public/404.html", :status => 404 }
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+ def home
18
+ end
19
+
20
+ def content
21
+ end
22
+
23
+ def gallery
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ def flash_messages
4
+ messages = ''
5
+ %w{ notice success warning error }.each do |type|
6
+ messages += content_tag(:div,
7
+ content_tag(:div, flash[type.to_sym] || flash.now[type.to_sym]),
8
+ :class => type + ' message'
9
+ ) if flash[type.to_sym] || flash.now[type.to_sym]
10
+ end
11
+ messages.blank? ? '' : content_tag(:div, messages, :class => 'flash-messages', :id => 'flash_messages')
12
+ end
13
+
14
+ def edit_link(update, url)
15
+ return unless current_user
16
+ link_to_remote(image_tag('icons/edit.png', :class => 'edit_button'), :update => update, :url => url, :method => :get)
17
+ end
18
+
19
+ def delete_link(update, url)
20
+ return unless current_user
21
+ link_to_remote(image_tag('icons/delete.png', :class => 'delete_button'), :update => update, :url => url, :method => :delete, :confirm => t('form_global.delete_warning'))
22
+ end
23
+
24
+ def sort_field(field_name, pos)
25
+ return unless current_user
26
+ text_field_tag field_name, pos, :class => 'position_text_box'
27
+ end
28
+
29
+ end
@@ -0,0 +1,34 @@
1
+ module Cms::Admin::PagesHelper
2
+
3
+ def sortable_tree(collection, model)
4
+ make_tree_recursive(collection) do |item|
5
+ controls = %{
6
+ #{link_to('', send("edit_cms_admin_#{model}_path", item), {:class => 'edit'} )}
7
+ #{link_to('', send("cms_admin_#{model}_path", item), {:method => :delete, :confirm => t('form_global.delete_warning'), :class => 'delete'})}
8
+ }
9
+ toggle = item.children.empty? ? '<span class="spacer">&nbsp;</span>': link_to_function(image_tag('icons/folder.png'), "$(this).next('ul').toggle()")
10
+
11
+ buffer = <<-"end;"
12
+ #{toggle}
13
+ <span class="tree-controls">#{controls}<a class="move">t('form_global.delete_warning')</a></span>
14
+ <span>#{item.title} (/#{item.path})</span>
15
+ end;
16
+
17
+ end
18
+ end
19
+
20
+ def make_tree_recursive(tree, parent_id=nil, nested=false)
21
+ ret = "<ul id=\"tree_#{parent_id || 'root'}\" class=\"#{parent_id ? '' : 'tree'}\">"
22
+ tree.each do |node|
23
+ if node.parent_id == parent_id
24
+ ret += "<li id=\"nav_#{node.id}\">"
25
+ ret += yield node
26
+ ret += node.children.empty? ? '' : make_tree_recursive(tree, node.id, true) {|n| yield n}
27
+ ret += '</li>'
28
+ end
29
+ end
30
+ ret += '</ul>'
31
+ ret
32
+ end
33
+
34
+ end
@@ -0,0 +1,4 @@
1
+ class FileAttachment < ActiveRecord::Base
2
+ belongs_to :owner, :polymorphic => true
3
+ has_attached_file :file, :url => "/images/:attachment/:id/:style_:basename.:extension", :path => ":rails_root/public/images/:attachment/:id/:style_:basename.:extension"
4
+ end
@@ -0,0 +1,71 @@
1
+ class Page < ActiveRecord::Base
2
+ TEMPLATES = I18n.t('cms.admin.pages.templates').collect{|k,v| v}
3
+
4
+ translates :title, :subtitle, :template_name
5
+
6
+ acts_as_tree :order => 'position'
7
+ has_permalink :title, :slug, :scope => :parent_id
8
+
9
+ has_many :page_content_blocks, :order => :position
10
+ has_many :file_attachments, :as => :owner, :dependent => :destroy, :order => :position
11
+
12
+ validates_presence_of :title
13
+ validates_length_of :title, :within => 1..255, :message => I18n.t('cms.admin.pages.error_length')
14
+ validates_presence_of :slug
15
+ validates_uniqueness_of :slug, :scope => :parent_id, :message => I18n.t('cms.admin.pages.error_slug_unique')
16
+ validates_length_of :slug, :within => 1..255, :message => I18n.t('cms.admin.pages.error_length')
17
+ validates_format_of :slug, :with => /^[a-z\d\-]+$/, :message => I18n.t('cms.admin.pages.error_lowercase')
18
+ # validates_associated :parent
19
+
20
+ before_save :create_full_path
21
+ before_save :check_parent
22
+
23
+ named_scope :ordered, :order => :position
24
+ named_scope :visible, :conditions => "visible = 1"
25
+
26
+ def self.find_from_path(path)
27
+ path = path.join("/")
28
+ page = path.blank? ? Page.home_page : find_by_path(path)
29
+ end
30
+
31
+ def self.home_page
32
+ Page.find_by_slug('home')
33
+ end
34
+
35
+ def destroy
36
+ if self == Page.home_page
37
+ self.errors.add_to_base I18n.t('cms.admin.pages.error_delete_home')
38
+ return
39
+ end
40
+ unless self.children.empty?
41
+ self.errors.add_to_base I18n.t('cms.admin.pages.error_delete_children')
42
+ return
43
+ end
44
+ super
45
+ end
46
+
47
+ protected
48
+ def check_parent
49
+ if self == Page.home_page
50
+ self.parent_id = nil
51
+ return
52
+ end
53
+ self.parent_id = 1 if self.parent_id.nil?
54
+ end
55
+
56
+ #Creates a URI path based on the Page tree
57
+ def create_full_path
58
+ return if self == Page.home_page
59
+
60
+ self.parent.reload if self.parent
61
+ if parent_node = self.parent
62
+ # Build URI Path
63
+ path = "#{parent_node.path}/#{self.slug}"
64
+ # strip leading space, if there is one...
65
+ path = path[1..-1] if path.starts_with? "/"
66
+ self[:path] = path || ""
67
+ else
68
+ self[:path] = self.slug
69
+ end
70
+ end
71
+ end