lucy_cms 0.0.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 (245) hide show
  1. data/Gemfile +19 -0
  2. data/Gemfile.lock +88 -0
  3. data/LICENSE +24 -0
  4. data/README.md +161 -0
  5. data/Rakefile +26 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/application_controller.rb +5 -0
  8. data/app/controllers/cms_admin/base_controller.rb +43 -0
  9. data/app/controllers/cms_admin/layouts_controller.rb +66 -0
  10. data/app/controllers/cms_admin/pages_controller.rb +111 -0
  11. data/app/controllers/cms_admin/sessions_controller.rb +25 -0
  12. data/app/controllers/cms_admin/sites_controller.rb +69 -0
  13. data/app/controllers/cms_admin/snippets_controller.rb +62 -0
  14. data/app/controllers/cms_admin/upload_dirs_controller.rb +79 -0
  15. data/app/controllers/cms_admin/users_controller.rb +129 -0
  16. data/app/controllers/cms_content_controller.rb +51 -0
  17. data/app/models/cms_block.rb +28 -0
  18. data/app/models/cms_layout.rb +118 -0
  19. data/app/models/cms_page.rb +163 -0
  20. data/app/models/cms_site.rb +38 -0
  21. data/app/models/cms_snippet.rb +70 -0
  22. data/app/models/cms_upload.rb +19 -0
  23. data/app/models/cms_upload_dir.rb +11 -0
  24. data/app/models/cms_user.rb +93 -0
  25. data/app/views/cms_admin/layouts/_form.html.erb +10 -0
  26. data/app/views/cms_admin/layouts/_index_branch.html.erb +24 -0
  27. data/app/views/cms_admin/layouts/edit.html.erb +6 -0
  28. data/app/views/cms_admin/layouts/index.html.erb +6 -0
  29. data/app/views/cms_admin/layouts/new.html.erb +6 -0
  30. data/app/views/cms_admin/pages/_form.html.erb +37 -0
  31. data/app/views/cms_admin/pages/_form_blocks.html.erb +7 -0
  32. data/app/views/cms_admin/pages/_index_branch.html.erb +40 -0
  33. data/app/views/cms_admin/pages/edit.html.erb +5 -0
  34. data/app/views/cms_admin/pages/form_blocks.js.erb +2 -0
  35. data/app/views/cms_admin/pages/index.html.erb +6 -0
  36. data/app/views/cms_admin/pages/new.html.erb +5 -0
  37. data/app/views/cms_admin/pages/toggle_branch.js.erb +11 -0
  38. data/app/views/cms_admin/sessions/new.html.erb +12 -0
  39. data/app/views/cms_admin/sites/_form.html.erb +16 -0
  40. data/app/views/cms_admin/sites/edit.html.erb +6 -0
  41. data/app/views/cms_admin/sites/new.html.erb +6 -0
  42. data/app/views/cms_admin/sites/setup.html.erb +16 -0
  43. data/app/views/cms_admin/snippets/_form.html.erb +4 -0
  44. data/app/views/cms_admin/snippets/edit.html.erb +6 -0
  45. data/app/views/cms_admin/snippets/index.html.erb +23 -0
  46. data/app/views/cms_admin/snippets/new.html.erb +6 -0
  47. data/app/views/cms_admin/upload_dirs/_file.html.erb +15 -0
  48. data/app/views/cms_admin/upload_dirs/_form.html.erb +2 -0
  49. data/app/views/cms_admin/upload_dirs/conflict.html.erb +12 -0
  50. data/app/views/cms_admin/upload_dirs/index.html.erb +23 -0
  51. data/app/views/cms_admin/upload_dirs/new.html.erb +6 -0
  52. data/app/views/cms_admin/upload_dirs/show.html.erb +26 -0
  53. data/app/views/cms_admin/upload_dirs/uploads_destroy.js.erb +3 -0
  54. data/app/views/cms_admin/users/_form.html.erb +9 -0
  55. data/app/views/cms_admin/users/_index_branch.html.erb +16 -0
  56. data/app/views/cms_admin/users/change_password.html.erb +14 -0
  57. data/app/views/cms_admin/users/edit.html.erb +17 -0
  58. data/app/views/cms_admin/users/index.html.erb +6 -0
  59. data/app/views/cms_admin/users/new.html.erb +14 -0
  60. data/app/views/layouts/cms_admin.html.erb +52 -0
  61. data/config/application.rb +48 -0
  62. data/config/boot.rb +13 -0
  63. data/config/database.yml +22 -0
  64. data/config/environment.rb +5 -0
  65. data/config/environments/development.rb +22 -0
  66. data/config/environments/production.rb +49 -0
  67. data/config/environments/test.rb +35 -0
  68. data/config/initializers/LucyCMS.rb +37 -0
  69. data/config/initializers/mime_types.rb +5 -0
  70. data/config/locales/en.yml +5 -0
  71. data/config/routes.rb +45 -0
  72. data/config.ru +4 -0
  73. data/db/cms_seeds/example.local/layouts/default.yml +8 -0
  74. data/db/cms_seeds/example.local/layouts/nested.yml +6 -0
  75. data/db/cms_seeds/example.local/pages/child/subchild.yml +14 -0
  76. data/db/cms_seeds/example.local/pages/child.yml +10 -0
  77. data/db/cms_seeds/example.local/pages/index.yml +11 -0
  78. data/db/cms_seeds/example.local/snippets/example.yml +4 -0
  79. data/db/migrate/01_create_cms.rb +114 -0
  80. data/db/seeds.rb +7 -0
  81. data/lib/LucyCMS/acts_as_tree.rb +102 -0
  82. data/lib/LucyCMS/cms_tag/field_datetime.rb +26 -0
  83. data/lib/LucyCMS/cms_tag/field_integer.rb +26 -0
  84. data/lib/LucyCMS/cms_tag/field_string.rb +26 -0
  85. data/lib/LucyCMS/cms_tag/field_text.rb +26 -0
  86. data/lib/LucyCMS/cms_tag/helper.rb +20 -0
  87. data/lib/LucyCMS/cms_tag/page_datetime.rb +22 -0
  88. data/lib/LucyCMS/cms_tag/page_integer.rb +22 -0
  89. data/lib/LucyCMS/cms_tag/page_rich_text.rb +22 -0
  90. data/lib/LucyCMS/cms_tag/page_string.rb +22 -0
  91. data/lib/LucyCMS/cms_tag/page_text.rb +22 -0
  92. data/lib/LucyCMS/cms_tag/partial.rb +21 -0
  93. data/lib/LucyCMS/cms_tag/snippet.rb +22 -0
  94. data/lib/LucyCMS/cms_tag.rb +119 -0
  95. data/lib/LucyCMS/configuration.rb +36 -0
  96. data/lib/LucyCMS/controller_methods.rb +42 -0
  97. data/lib/LucyCMS/engine.rb +12 -0
  98. data/lib/LucyCMS/form_builder.rb +129 -0
  99. data/lib/LucyCMS/rails_extensions.rb +22 -0
  100. data/lib/LucyCMS/site_form_builder.rb +129 -0
  101. data/lib/LucyCMS/view_hooks.rb +30 -0
  102. data/lib/LucyCMS/view_methods.rb +68 -0
  103. data/lib/LucyCMS.rb +40 -0
  104. data/lib/generators/README +17 -0
  105. data/lib/generators/cms_generator.rb +44 -0
  106. data/lib/tasks/LucyCMS.rake +283 -0
  107. data/lucy_cms.gemspec +100 -0
  108. data/public/404.html +26 -0
  109. data/public/422.html +26 -0
  110. data/public/500.html +26 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/images/LucyCMS/arrow_bottom.gif +0 -0
  113. data/public/images/LucyCMS/arrow_right.gif +0 -0
  114. data/public/images/LucyCMS/icon_folder.png +0 -0
  115. data/public/images/LucyCMS/icon_layout.gif +0 -0
  116. data/public/images/LucyCMS/icon_move.gif +0 -0
  117. data/public/images/LucyCMS/icon_regular.gif +0 -0
  118. data/public/images/LucyCMS/icon_snippet.gif +0 -0
  119. data/public/images/LucyCMS/icon_upload.png +0 -0
  120. data/public/images/LucyCMS/icon_user.jpg +0 -0
  121. data/public/javascripts/LucyCMS/cms.js +204 -0
  122. data/public/javascripts/LucyCMS/codemirror/codemirror.css +102 -0
  123. data/public/javascripts/LucyCMS/codemirror/codemirror.js +23 -0
  124. data/public/javascripts/LucyCMS/codemirror/codemirror_base.js +88 -0
  125. data/public/javascripts/LucyCMS/codemirror/parse_css.js +4 -0
  126. data/public/javascripts/LucyCMS/codemirror/parse_html_mixed.js +3 -0
  127. data/public/javascripts/LucyCMS/codemirror/parse_js.js +12 -0
  128. data/public/javascripts/LucyCMS/codemirror/parse_xml.js +7 -0
  129. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  130. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  131. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  132. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  133. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  134. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  135. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  136. data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  137. data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
  138. data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_2e83ff_256x240.png +0 -0
  139. data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_454545_256x240.png +0 -0
  140. data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_888888_256x240.png +0 -0
  141. data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_cd0a0a_256x240.png +0 -0
  142. data/public/javascripts/LucyCMS/jquery-ui/jquery-ui.css +362 -0
  143. data/public/javascripts/LucyCMS/jquery-ui/jquery-ui.js +190 -0
  144. data/public/javascripts/LucyCMS/jquery.js +154 -0
  145. data/public/javascripts/LucyCMS/plupload/plupload.full.min.js +1 -0
  146. data/public/javascripts/LucyCMS/plupload/plupload.html5.min.js +1 -0
  147. data/public/javascripts/LucyCMS/plupload/plupload.min.js +1 -0
  148. data/public/javascripts/LucyCMS/rails.js +132 -0
  149. data/public/javascripts/LucyCMS/tiny_mce/jquery.tinymce.js +1 -0
  150. data/public/javascripts/LucyCMS/tiny_mce/langs/en.js +170 -0
  151. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/about.htm +54 -0
  152. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/anchor.htm +26 -0
  153. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/charmap.htm +52 -0
  154. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/color_picker.htm +73 -0
  155. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/editor_template.js +1 -0
  156. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/image.htm +80 -0
  157. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
  158. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/img/icons.gif +0 -0
  159. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/about.js +72 -0
  160. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/anchor.js +37 -0
  161. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/charmap.js +335 -0
  162. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/color_picker.js +253 -0
  163. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/image.js +245 -0
  164. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/link.js +156 -0
  165. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/source_editor.js +56 -0
  166. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/langs/en.js +62 -0
  167. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/langs/en_dlg.js +51 -0
  168. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/link.htm +58 -0
  169. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/content.css +36 -0
  170. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/dialog.css +117 -0
  171. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  172. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  173. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  174. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  175. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  176. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  177. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/ui.css +213 -0
  178. data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/source_editor.htm +25 -0
  179. data/public/javascripts/LucyCMS/tiny_mce/tiny_mce.js +1 -0
  180. data/public/javascripts/LucyCMS/tiny_mce/tiny_mce_popup.js +5 -0
  181. data/public/robots.txt +5 -0
  182. data/public/stylesheets/LucyCMS/content.css +196 -0
  183. data/public/stylesheets/LucyCMS/form.css +125 -0
  184. data/public/stylesheets/LucyCMS/reset.css +1 -0
  185. data/public/stylesheets/LucyCMS/site_form.css +82 -0
  186. data/public/stylesheets/LucyCMS/structure.css +125 -0
  187. data/public/stylesheets/LucyCMS/typography.css +25 -0
  188. data/script/rails +6 -0
  189. data/test/cms_seeds/test.host/layouts/broken.yml +1 -0
  190. data/test/cms_seeds/test.host/layouts/default.yml +3 -0
  191. data/test/cms_seeds/test.host/layouts/nested.yml +4 -0
  192. data/test/cms_seeds/test.host/pages/broken.yml +1 -0
  193. data/test/cms_seeds/test.host/pages/child/subchild.yml +10 -0
  194. data/test/cms_seeds/test.host/pages/child.yml +10 -0
  195. data/test/cms_seeds/test.host/pages/index.yml +10 -0
  196. data/test/cms_seeds/test.host/snippets/broken.yml +1 -0
  197. data/test/cms_seeds/test.host/snippets/default.yml +3 -0
  198. data/test/fixtures/cms_blocks.yml +12 -0
  199. data/test/fixtures/cms_layouts.yml +36 -0
  200. data/test/fixtures/cms_pages.yml +39 -0
  201. data/test/fixtures/cms_sites.yml +3 -0
  202. data/test/fixtures/cms_snippets.yml +5 -0
  203. data/test/fixtures/cms_upload_dirs.yml +9 -0
  204. data/test/fixtures/cms_uploads.yml +4 -0
  205. data/test/fixtures/cms_users.yml +11 -0
  206. data/test/fixtures/files/invalid_file.gif +9 -0
  207. data/test/fixtures/files/valid_image.jpg +0 -0
  208. data/test/fixtures/views/_nav_hook.html.erb +1 -0
  209. data/test/fixtures/views/_nav_hook_2.html.erb +1 -0
  210. data/test/functional/cms_admin/layouts_controller_test.rb +103 -0
  211. data/test/functional/cms_admin/pages_controller_test.rb +334 -0
  212. data/test/functional/cms_admin/sites_controller_test.rb +99 -0
  213. data/test/functional/cms_admin/snippets_controller_test.rb +102 -0
  214. data/test/functional/cms_admin/uploads_controller_test.rb +26 -0
  215. data/test/functional/cms_content_controller_test.rb +134 -0
  216. data/test/integration/rake_tasks_test.rb +65 -0
  217. data/test/integration/render_cms_seed_test.rb +34 -0
  218. data/test/integration/render_cms_test.rb +81 -0
  219. data/test/integration/sites_test.rb +63 -0
  220. data/test/integration/view_hooks_test.rb +33 -0
  221. data/test/test_helper.rb +86 -0
  222. data/test/unit/cms_block_test.rb +43 -0
  223. data/test/unit/cms_configuration_test.rb +17 -0
  224. data/test/unit/cms_layout_test.rb +146 -0
  225. data/test/unit/cms_page_test.rb +257 -0
  226. data/test/unit/cms_site_test.rb +41 -0
  227. data/test/unit/cms_snippet_test.rb +77 -0
  228. data/test/unit/cms_tag_test.rb +206 -0
  229. data/test/unit/cms_tags/field_datetime_test.rb +34 -0
  230. data/test/unit/cms_tags/field_integer_test.rb +33 -0
  231. data/test/unit/cms_tags/field_string_test.rb +34 -0
  232. data/test/unit/cms_tags/field_text_test.rb +32 -0
  233. data/test/unit/cms_tags/helper_test.rb +38 -0
  234. data/test/unit/cms_tags/page_datetime_test.rb +34 -0
  235. data/test/unit/cms_tags/page_integer_test.rb +33 -0
  236. data/test/unit/cms_tags/page_rich_text.rb +33 -0
  237. data/test/unit/cms_tags/page_string_test.rb +33 -0
  238. data/test/unit/cms_tags/page_text_test.rb +34 -0
  239. data/test/unit/cms_tags/partial_test.rb +44 -0
  240. data/test/unit/cms_tags/snippet_test.rb +33 -0
  241. data/test/unit/cms_upload_dir_test.rb +8 -0
  242. data/test/unit/cms_upload_test.rb +26 -0
  243. data/test/unit/cms_user_test.rb +8 -0
  244. data/test/unit/view_methods_test.rb +21 -0
  245. metadata +488 -0
@@ -0,0 +1,62 @@
1
+ class CmsAdmin::SnippetsController < CmsAdmin::BaseController
2
+
3
+ before_filter :check_for_admin
4
+ before_filter :build_cms_snippet, :only => [:new, :create]
5
+ before_filter :load_cms_snippet, :only => [:edit, :update, :destroy]
6
+
7
+ def index
8
+ return redirect_to :action => :new if @cms_site.cms_snippets.count == 0
9
+ @cms_snippets = @cms_site.cms_snippets.all(:order => 'label')
10
+ end
11
+
12
+ def new
13
+ render
14
+ end
15
+
16
+ def edit
17
+ render
18
+ end
19
+
20
+ def create
21
+ @cms_snippet.save!
22
+ flash[:notice] = 'Snippet created'
23
+ redirect_to :action => :index
24
+ rescue ActiveRecord::RecordInvalid
25
+ flash.now[:error] = 'Failed to create snippet'
26
+ render :action => :new
27
+ end
28
+
29
+ def update
30
+ @cms_snippet.update_attributes!(params[:cms_snippet])
31
+ flash[:notice] = 'Snippet updated'
32
+ redirect_to :action => :index
33
+ rescue ActiveRecord::RecordInvalid
34
+ flash.now[:error] = 'Failed to update snippet'
35
+ render :action => :edit
36
+ end
37
+
38
+ def destroy
39
+ @cms_snippet.destroy
40
+ flash[:notice] = 'Snippet deleted'
41
+ redirect_to :action => :index
42
+ end
43
+
44
+ protected
45
+ def check_for_admin
46
+ if CmsUser.find_by_admin_and_disabled(true,false).nil?
47
+ flash[:error] = 'You must create one Active Admin User to continue'
48
+ redirect_to new_cms_admin_user_path
49
+ end
50
+ end
51
+
52
+ def build_cms_snippet
53
+ @cms_snippet = @cms_site.cms_snippets.new(params[:cms_snippet])
54
+ end
55
+
56
+ def load_cms_snippet
57
+ @cms_snippet = @cms_site.cms_snippets.find(params[:id])
58
+ rescue ActiveRecord::RecordNotFound
59
+ flash[:error] = 'Snippet not found'
60
+ redirect_to :action => :index
61
+ end
62
+ end
@@ -0,0 +1,79 @@
1
+ class CmsAdmin::UploadDirsController < CmsAdmin::BaseController
2
+
3
+ before_filter :check_and_set_base_dir, :except => :conflict
4
+
5
+ def index
6
+ return redirect_to :action => :new if @cms_site.cms_upload_dirs.count == 0
7
+ @cms_upload_dirs = @cms_site.cms_upload_dirs.all(:order => 'label')
8
+ end
9
+
10
+ def new
11
+ @cms_upload_dir = @cms_site.cms_upload_dirs.new
12
+ render
13
+ end
14
+
15
+ def create
16
+ @cms_upload_dir = @cms_site.cms_upload_dirs.new(params[:cms_upload_dir])
17
+ if File::exists?(File.join(@base_dir, @cms_upload_dir.label))
18
+ flash[:error] = 'There is already a directory named ' + @cms_upload_dir.label
19
+ render :action => :new
20
+ else
21
+ if @cms_upload_dir.save
22
+ FileUtils.mkdir_p(File.join(@base_dir, @cms_upload_dir.label))
23
+ flash[:notice] = 'Directory created'
24
+ redirect_to :action => :index
25
+ else
26
+ flash[:error] = 'Not able to create directory'
27
+ render :action => :new
28
+ end
29
+ end
30
+ end
31
+
32
+ def show
33
+ @cms_upload_dir = @cms_site.cms_upload_dirs.find(params[:id])
34
+ @cms_uploads = @cms_upload_dir.cms_uploads.find_all_by_cms_upload_dir_id( params[:id])
35
+ end
36
+
37
+ def uploads
38
+ @cms_upload_dir = @cms_site.cms_upload_dirs.find(params[:id])
39
+ @cms_upload_check = @cms_upload_dir.cms_uploads.find_by_cms_upload_dir_id_and_file_file_name( params[:id], params[:file].original_filename)
40
+ unless @cms_upload_check.nil?
41
+ @cms_upload_check.destroy
42
+ end
43
+ @cms_upload = @cms_upload_dir.cms_uploads.create!(:file => params[:file], :cms_upload_dir_label => @cms_upload_dir.label, :cms_user_id => @cms_current_user.id)
44
+ render :partial => 'file', :object => @cms_upload
45
+ rescue ActiveRecord::RecordInvalid
46
+ render :nothing => true, :status => :bad_request
47
+ end
48
+
49
+ def uploads_destroy
50
+ @cms_upload = CmsUpload.find( params[:id])
51
+ @cms_upload.destroy
52
+ end
53
+
54
+
55
+ def destroy
56
+ @cms_upload_dir = @cms_site.cms_upload_dirs.find(params[:id])
57
+ @cms_upload_dir.destroy
58
+ if File::exists?(File.join(@base_dir, @cms_upload_dir.label)) && File::directory?(File.join(@base_dir, @cms_upload_dir.label))
59
+ FileUtils.remove_dir(File.join(@base_dir, @cms_upload_dir.label))
60
+ end
61
+ flash[:notice] = 'Directory deleted'
62
+ redirect_to :action => :index
63
+ end
64
+
65
+ def confilct
66
+ render
67
+ end
68
+
69
+ protected
70
+
71
+ def check_and_set_base_dir
72
+ @base_dir = File.join(Rails.public_path,LucyCMS.config.cms_upload_directory)
73
+ if File::exists?(@base_dir) && !File::directory?(@base_dir)
74
+ flash[:error] = 'File conflict'
75
+ redirect_to :action => :conflict
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,129 @@
1
+ class CmsAdmin::UsersController < CmsAdmin::BaseController
2
+
3
+ before_filter :check_for_admin, :only => :index
4
+ before_filter :check_admin, :except => :index
5
+
6
+ def index
7
+ @cms_users = CmsUser.find(:all, :order => 'last_name ASC')
8
+ end
9
+
10
+ def new
11
+ @cms_user = CmsUser.new
12
+ end
13
+
14
+ def create
15
+ @cms_user = CmsUser.new(params[:cms_user])
16
+ if @cms_site.authentication == 'LDAP'
17
+ username = @cms_user.login
18
+ ldap = Net::LDAP.new(:host => @cms_site.ldap_hostname, :base => @cms_site.ldap_base_DN)
19
+ filter = Net::LDAP::Filter.eq(@cms_site.ldap_uid, username)
20
+ ldap.search(:filter => filter) do |entry|
21
+ username = entry.dn
22
+ end
23
+ if username == @cms_user.login
24
+ flash[:error] = "Username not in LDAP"
25
+ render :action => 'new'
26
+ return
27
+ end
28
+ end
29
+ if CmsUser.find_by_admin_and_disabled(true,false).nil?
30
+ if @cms_user.admin == false || @cms_user.disabled == true
31
+ flash[:error] = 'The first user you create must be an Active Admin'
32
+ render :action => 'new'
33
+ else
34
+ if @cms_user.save
35
+ flash[:notice] = 'User Created'
36
+ redirect_to cms_admin_users_path
37
+ else
38
+ flash[:error] = 'User could not be created'
39
+ render :action => 'new'
40
+ end
41
+ end
42
+ else
43
+ if @cms_user.save
44
+ flash[:notice] = 'User Created'
45
+ redirect_to cms_admin_users_path
46
+ else
47
+ flash[:error] = 'User could not be created'
48
+ render :action => 'new'
49
+ end
50
+ end
51
+ end
52
+
53
+ def edit
54
+ @cms_user = CmsUser.find_by_id(params[:id])
55
+ end
56
+
57
+ def update
58
+ @cms_user = CmsUser.find(params[:id])
59
+ @cms_user.attributes = params[:cms_user]
60
+ if @cms_site.authentication == 'LDAP'
61
+ username = @cms_user.login
62
+ ldap = Net::LDAP.new(:host => @cms_site.ldap_hostname, :base => @cms_site.ldap_base_DN)
63
+ filter = Net::LDAP::Filter.eq(@cms_site.ldap_uid, username)
64
+ ldap.search(:filter => filter) do |entry|
65
+ username = entry.dn
66
+ end
67
+ if username == @cms_user.login
68
+ flash[:error] = "Username not in LDAP"
69
+ render :action => 'edit'
70
+ return
71
+ end
72
+ end
73
+ if @cms_user.disabled == true && CmsUser.find(:all, :conditions => {:admin => true, :disabled => false}).count == 1 && CmsUser.find(:all, :conditions => {:admin => true, :disabled => false}).first.id == @cms_user.id
74
+ flash[:error] = "You can not disable the only Admin"
75
+ render :action => 'edit'
76
+ else
77
+ if @cms_user.admin == false && CmsUser.find(:all, :conditions => {:admin => true, :disabled => false}).count == 1 && CmsUser.find(:all, :conditions => {:admin => true, :disabled => false}).first.id == @cms_user.id
78
+ flash[:error] = "You must have one Active Admin User"
79
+ render :action => 'edit'
80
+ else
81
+ if @cms_user.save
82
+ flash[:notice] = "User was updated"
83
+ redirect_to cms_admin_users_path
84
+ else
85
+ flash[:error] = 'User could not be updated'
86
+ render :action => 'edit'
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def change_password
93
+ @cms_user = CmsUser.find_by_id(params[:id])
94
+ end
95
+
96
+ def update_password
97
+ @cms_user = CmsUser.find_by_id(params[:id])
98
+ @cms_user.attributes = params[:cms_user]
99
+ if @cms_user.password.nil? || @cms_user.password.empty?
100
+ flash[:error] = 'Password can not be blank'
101
+ render :action => 'change_password'
102
+ return
103
+ end
104
+ if @cms_user.save
105
+ flash[:notice] = "Password was updated"
106
+ redirect_to cms_admin_users_path
107
+ else
108
+ flash[:error] = 'User could not be updated'
109
+ render :action => 'change_password'
110
+ end
111
+ end
112
+
113
+ protected
114
+
115
+ def check_for_admin
116
+ if CmsUser.find_by_admin_and_disabled(true,false).nil?
117
+ flash[:error] = 'You must create one Active Admin User to continue'
118
+ redirect_to new_cms_admin_user_path
119
+ end
120
+ end
121
+
122
+ def check_admin
123
+ if CmsUser.count > 0 and !CmsUser.find_by_id(session[:cms_user_id]).admin?
124
+ flash[:error] = 'You must be an Admin to Create or Edit Users'
125
+ redirect_to :action => 'index'
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,51 @@
1
+ class CmsContentController < ApplicationController
2
+
3
+ before_filter :load_cms_site
4
+ before_filter :load_cms_page, :only => :render_html
5
+ before_filter :load_cms_layout, :only => [:render_css, :render_js]
6
+
7
+ caches_page :render_css, :render_js, :if => LucyCMS.config.enable_caching
8
+
9
+ def render_html(status = 200)
10
+ layout = @cms_page.cms_layout.app_layout.blank?? false : @cms_page.cms_layout.app_layout
11
+ render :inline => @cms_page.content, :layout => layout, :status => status
12
+ end
13
+
14
+ def render_css
15
+ render :text => @cms_layout.css, :content_type => 'text/css'
16
+ end
17
+
18
+ def render_js
19
+ render :text => @cms_layout.js, :content_type => 'text/javascript'
20
+ end
21
+
22
+ protected
23
+
24
+ def load_cms_site
25
+ @cms_site = CmsSite.first
26
+ if @cms_site.nil?
27
+ redirect_to new_cms_admin_site_path
28
+ flash[:error] = 'To start you must setup your site'
29
+ return
30
+ end
31
+ end
32
+
33
+ def load_cms_page
34
+ @cms_page = CmsPage.published.load_for_full_path!(@cms_site, "/#{params[:cms_path]}")
35
+ return redirect_to(@cms_page.target_page.full_path) if @cms_page.target_page
36
+
37
+ rescue ActiveRecord::RecordNotFound
38
+ if @cms_page = CmsPage.published.load_for_full_path(@cms_site, '/404')
39
+ render_html(404)
40
+ else
41
+ render :text => 'Page Not Found', :status => 404
42
+ end
43
+ end
44
+
45
+ def load_cms_layout
46
+ @cms_layout = CmsLayout.load_for_slug!(@cms_site, params[:id])
47
+ rescue ActiveRecord::RecordNotFound
48
+ render :nothing => true, :status => 404
49
+ end
50
+
51
+ end
@@ -0,0 +1,28 @@
1
+ class CmsBlock < ActiveRecord::Base
2
+
3
+ # -- Relationships --------------------------------------------------------
4
+ belongs_to :cms_page
5
+
6
+ # -- Validations ----------------------------------------------------------
7
+ validates :label,
8
+ :presence => true,
9
+ :uniqueness => { :scope => :cms_page_id }
10
+
11
+ # -- Class Methods --------------------------------------------------------
12
+ def self.initialize_or_find(cms_page, label)
13
+ if block = cms_page.cms_blocks.detect{ |b| b.label == label.to_s }
14
+ self.new(
15
+ :record_id => block.id,
16
+ :cms_page => cms_page,
17
+ :label => block.label,
18
+ :content => block.content
19
+ )
20
+ else
21
+ self.new(
22
+ :label => label.to_s,
23
+ :cms_page => cms_page
24
+ )
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,118 @@
1
+ class CmsLayout < ActiveRecord::Base
2
+
3
+ acts_as_tree
4
+
5
+ # -- Relationships --------------------------------------------------------
6
+ belongs_to :cms_site
7
+ has_many :cms_pages, :dependent => :nullify
8
+ belongs_to :cms_user
9
+
10
+ # -- Callbacks ------------------------------------------------------------
11
+ after_save :clear_cache, :clear_cached_page_content
12
+ after_destroy :clear_cache, :clear_cached_page_content
13
+
14
+ # -- Validations ----------------------------------------------------------
15
+ validates :cms_site_id,
16
+ :presence => true
17
+ validates :label,
18
+ :presence => true
19
+ validates :slug,
20
+ :presence => true,
21
+ :uniqueness => { :scope => :cms_site_id },
22
+ :format => { :with => /^\w[a-z0-9_-]*$/i }
23
+ validates :content,
24
+ :presence => true
25
+ validate :check_content_tag_presence
26
+
27
+ # -- Class Methods --------------------------------------------------------
28
+ # Tree-like structure for layouts
29
+ def self.options_for_select(cms_site, cms_layout = nil, current_layout = nil, depth = 0, spacer = '. . ')
30
+ out = []
31
+ [current_layout || cms_site.cms_layouts.roots].flatten.each do |layout|
32
+ next if cms_layout == layout
33
+ out << [ "#{spacer*depth}#{layout.label}", layout.id ]
34
+ layout.children.each do |child|
35
+ out += options_for_select(cms_site, cms_layout, child, depth + 1, spacer)
36
+ end
37
+ end
38
+ return out.compact
39
+ end
40
+
41
+ # List of available application layouts
42
+ def self.app_layouts_for_select
43
+ Dir.glob(File.expand_path('app/views/layouts/*.html.*', Rails.root)).collect do |filename|
44
+ match = filename.match(/\w*.html.\w*$/)
45
+ app_layout = match && match[0]
46
+ app_layout.to_s[0...1] == '_' ? nil : app_layout
47
+ end.compact
48
+ end
49
+
50
+ # Attempting to initialize layout object from yaml file that is found in config.seed_data_path
51
+ def self.load_from_file(site, slug)
52
+ return nil if LucyCMS.config.seed_data_path.blank?
53
+ file_path = "#{LucyCMS.config.seed_data_path}/#{site.hostname}/layouts/#{slug}.yml"
54
+ return nil unless File.exists?(file_path)
55
+ attributes = YAML.load_file(file_path).symbolize_keys!
56
+ attributes[:parent] = CmsLayout.load_from_file(site, attributes[:parent])
57
+ attributes[:cms_site] = site
58
+ new(attributes)
59
+ rescue
60
+ raise "Failed to load from #{file_path}"
61
+ end
62
+
63
+ # Wrapper around load_from_file and find_by_slug
64
+ # returns layout object if loaded / found
65
+ def self.load_for_slug!(site, slug)
66
+ if LucyCMS.configuration.seed_data_path
67
+ load_from_file(site, slug)
68
+ else
69
+ site.cms_layouts.find_by_slug(slug)
70
+ end || raise(ActiveRecord::RecordNotFound, "CmsLayout with slug: #{slug} cannot be found")
71
+ end
72
+
73
+ # Non-blowing-up version of the method above
74
+ def self.load_for_slug(site, slug)
75
+ load_for_slug!(site, slug)
76
+ rescue ActiveRecord::RecordNotFound
77
+ nil
78
+ end
79
+
80
+ # -- Instance Methods -----------------------------------------------------
81
+ # magical merging tag is {cms:page:content} If parent layout has this tag
82
+ # defined its content will be merged. If no such tag found, parent content
83
+ # is ignored.
84
+ def merged_content
85
+ if parent
86
+ regex = /\{\{\s*cms:page:content:?(?:(?::text)|(?::rich_text))?\s*\}\}/
87
+ if parent.merged_content.match(regex)
88
+ parent.merged_content.gsub(regex, content)
89
+ else
90
+ content
91
+ end
92
+ else
93
+ content
94
+ end
95
+ end
96
+
97
+ protected
98
+
99
+ def check_content_tag_presence
100
+ CmsTag.process_content((test_page = CmsPage.new), content)
101
+ if test_page.cms_tags.select{|t| t.class.superclass == CmsBlock}.blank?
102
+ self.errors.add(:content, 'No cms page tags defined')
103
+ end
104
+ end
105
+
106
+ # After saving need to make sure that cached pages for css and js for this
107
+ # layout and its children are gone. Good enough to avoid using cache sweepers.
108
+ def clear_cache
109
+ FileUtils.rm File.expand_path("cms-css/#{self.slug}.css", Rails.public_path), :force => true
110
+ FileUtils.rm File.expand_path("cms-js/#{self.slug}.js", Rails.public_path), :force => true
111
+ end
112
+
113
+ # Forcing page content reload. This will happen in cascade due to #clear_cache mathod above.
114
+ def clear_cached_page_content
115
+ self.cms_pages.each{ |page| page.save! }
116
+ end
117
+
118
+ end
@@ -0,0 +1,163 @@
1
+ class CmsPage < ActiveRecord::Base
2
+
3
+ # -- AR Extensions --------------------------------------------------------
4
+ acts_as_tree :counter_cache => :children_count
5
+
6
+ attr_accessor :cms_tags
7
+
8
+ # -- Relationships --------------------------------------------------------
9
+ belongs_to :cms_site
10
+ belongs_to :cms_layout
11
+ belongs_to :target_page,
12
+ :class_name => 'CmsPage'
13
+ has_many :cms_blocks,
14
+ :dependent => :destroy
15
+ accepts_nested_attributes_for :cms_blocks
16
+ belongs_to :cms_user
17
+
18
+ # -- Callbacks ------------------------------------------------------------
19
+ before_validation :assign_parent,
20
+ :assign_full_path,
21
+ :assign_position
22
+ before_save :set_cached_content
23
+ after_save :sync_child_pages
24
+
25
+ # -- Validations ----------------------------------------------------------
26
+ validates :cms_site_id,
27
+ :presence => true
28
+ validates :label,
29
+ :presence => true
30
+ validates :slug,
31
+ :presence => true,
32
+ :format => /^\w[a-z0-9_-]*$/i,
33
+ :unless => lambda{ |p| p == CmsPage.root || CmsPage.count == 0 }
34
+ validates :cms_layout,
35
+ :presence => true
36
+ validates :full_path,
37
+ :presence => true,
38
+ :uniqueness => { :scope => :cms_site_id }
39
+ validate :validate_target_page
40
+
41
+ # -- Scopes ---------------------------------------------------------------
42
+ scope :published, where(:is_published => true)
43
+
44
+ # -- Class Methods --------------------------------------------------------
45
+ # Tree-like structure for pages
46
+ def self.options_for_select(cms_site, cms_page = nil, current_page = nil, depth = 0, exclude_self = true, spacer = '. . ')
47
+ return [] if (current_page ||= cms_site.cms_pages.root) == cms_page && exclude_self || !current_page
48
+ out = []
49
+ out << [ "#{spacer*depth}#{current_page.label}", current_page.id ] unless current_page == cms_page
50
+ current_page.children.each do |child|
51
+ out += options_for_select(cms_site, cms_page, child, depth + 1, exclude_self, spacer)
52
+ end
53
+ return out.compact
54
+ end
55
+
56
+ # Attempting to initialize page object from yaml file that is found in config.seed_data_path
57
+ # This file defines all attributes of the page plus all the block information
58
+ def self.load_from_file(site, path)
59
+ return nil if LucyCMS.config.seed_data_path.blank?
60
+ path = (path == '/')? '/index' : path.to_s.chomp('/')
61
+ file_path = "#{LucyCMS.config.seed_data_path}/#{site.hostname}/pages#{path}.yml"
62
+ return nil unless File.exists?(file_path)
63
+ attributes = YAML.load_file(file_path).symbolize_keys!
64
+ attributes[:cms_layout] = CmsLayout.load_from_file(site, attributes[:cms_layout])
65
+ attributes[:parent] = CmsPage.load_from_file(site, attributes[:parent])
66
+ attributes[:cms_site] = site
67
+ new(attributes)
68
+ rescue
69
+ raise "Failed to load from #{file_path}"
70
+ end
71
+
72
+ # Wrapper around load_from_file and find_by_full_path
73
+ # returns page object if loaded / found
74
+ def self.load_for_full_path!(site, path)
75
+ if LucyCMS.configuration.seed_data_path
76
+ load_from_file(site, path)
77
+ else
78
+ site.cms_pages.find_by_full_path(path)
79
+ end || raise(ActiveRecord::RecordNotFound, "CmsPage with path: #{path} cannot be found")
80
+ end
81
+
82
+ # Non-blowing-up version of the method above
83
+ def self.load_for_full_path(site, path)
84
+ load_for_full_path!(site, path)
85
+ rescue ActiveRecord::RecordNotFound
86
+ nil
87
+ end
88
+
89
+ # -- Instance Methods -----------------------------------------------------
90
+ # For previewing purposes sometimes we need to have full_path set
91
+ def full_path
92
+ self.read_attribute(:full_path) || self.assign_full_path
93
+ end
94
+
95
+ # Transforms existing cms_block information into a hash that can be used
96
+ # during form processing. That's the only way to modify cms_blocks.
97
+ def cms_blocks_attributes
98
+ self.cms_blocks.inject([]) do |arr, block|
99
+ block_attr = {}
100
+ block_attr[:label] = block.label
101
+ block_attr[:content] = block.content
102
+ block_attr[:id] = block.id
103
+ arr << block_attr
104
+ end
105
+ end
106
+
107
+ # Processing content will return rendered content and will populate
108
+ # self.cms_tags with instances of CmsTag
109
+ def content(force_reload = false)
110
+ @content = read_attribute(:content)
111
+ @content = nil if force_reload
112
+ @content ||= begin
113
+ self.cms_tags = [] # resetting
114
+ cms_layout ? CmsTag.process_content(self, cms_layout.merged_content) : ''
115
+ end
116
+ end
117
+
118
+ # Array of cms_tags for a page. Content generation is called if forced.
119
+ # These also include initialized cms_blocks if present
120
+ def cms_tags(force_reload = false)
121
+ self.content(true) if force_reload
122
+ @cms_tags ||= []
123
+ end
124
+
125
+ # Full url for a page
126
+ def url
127
+ "http://#{self.cms_site.hostname}#{self.full_path}"
128
+ end
129
+
130
+ protected
131
+
132
+ def assign_parent
133
+ self.parent ||= CmsPage.root unless self == CmsPage.root || CmsPage.count == 0
134
+ end
135
+
136
+ def assign_full_path
137
+ self.full_path = self.parent ? "#{self.parent.full_path}/#{self.slug}".squeeze('/') : '/'
138
+ end
139
+
140
+ def assign_position
141
+ return unless self.parent
142
+ max = self.parent.children.maximum(:position)
143
+ self.position = max ? max + 1 : 0
144
+ end
145
+
146
+ def validate_target_page
147
+ return unless self.target_page
148
+ p = self
149
+ while p.target_page do
150
+ return self.errors.add(:target_page_id, 'Invalid Redirect') if (p = p.target_page) == self
151
+ end
152
+ end
153
+
154
+ def set_cached_content
155
+ write_attribute(:content, self.content(true))
156
+ end
157
+
158
+ # Forcing re-saves for child pages so they can update full_paths
159
+ def sync_child_pages
160
+ children.each{ |p| p.save! } if full_path_changed?
161
+ end
162
+
163
+ end
@@ -0,0 +1,38 @@
1
+ class CmsSite < ActiveRecord::Base
2
+
3
+ # -- Relationships --------------------------------------------------------
4
+ has_many :cms_layouts, :dependent => :destroy
5
+ has_many :cms_pages, :dependent => :destroy
6
+ has_many :cms_snippets, :dependent => :destroy
7
+ has_many :cms_uploads, :dependent => :destroy
8
+ has_many :cms_upload_dirs, :dependent => :destroy
9
+
10
+ # -- Validations ----------------------------------------------------------
11
+ validates :label,
12
+ :presence => true,
13
+ :uniqueness => true
14
+ validates :hostname,
15
+ :presence => true,
16
+ :uniqueness => true,
17
+ :format => { :with => /^[\w\.\-]+$/ }
18
+
19
+ validates :authentication,
20
+ :presence => true
21
+
22
+ validates :ldap_hostname,
23
+ :presence => true,
24
+ :unless => :no_ldap
25
+
26
+ validates :ldap_base_DN,
27
+ :presence => true,
28
+ :unless => :no_ldap
29
+
30
+ validates :ldap_uid,
31
+ :presence => true,
32
+ :unless => :no_ldap
33
+
34
+ def no_ldap
35
+ self.authentication != 'LDAP'
36
+ end
37
+
38
+ end