contentator 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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