dust-cms 0.0.05

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 (294) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +3 -0
  3. data/Rakefile +5 -0
  4. data/app/assets/images/admin/blank.png +0 -0
  5. data/app/assets/images/admin/dust-letterpress.png +0 -0
  6. data/app/assets/images/admin/main-back.png +0 -0
  7. data/app/assets/images/admin/ui/delete-icon.png +0 -0
  8. data/app/assets/images/admin/ui/edit-icon.png +0 -0
  9. data/app/assets/images/admin/ui/handle.png +0 -0
  10. data/app/assets/images/admin/ui/icons.png +0 -0
  11. data/app/assets/images/admin/ui/index-icon.png +0 -0
  12. data/app/assets/images/admin/ui/new-icon.png +0 -0
  13. data/app/assets/images/entypo/entypo.eot +0 -0
  14. data/app/assets/images/entypo/entypo.svg +13 -0
  15. data/app/assets/images/entypo/entypo.ttf +0 -0
  16. data/app/assets/images/entypo/entypo.woff +0 -0
  17. data/app/assets/images/entypo-social/entypo-social.eot +0 -0
  18. data/app/assets/images/entypo-social/entypo-social.svg +13 -0
  19. data/app/assets/images/entypo-social/entypo-social.ttf +0 -0
  20. data/app/assets/images/entypo-social/entypo-social.woff +0 -0
  21. data/app/assets/images/fancybox/blank.gif +0 -0
  22. data/app/assets/images/fancybox/fancy_close.png +0 -0
  23. data/app/assets/images/fancybox/fancy_loading.png +0 -0
  24. data/app/assets/images/fancybox/fancy_nav_left.png +0 -0
  25. data/app/assets/images/fancybox/fancy_nav_right.png +0 -0
  26. data/app/assets/images/fancybox/fancy_shadow_e.png +0 -0
  27. data/app/assets/images/fancybox/fancy_shadow_n.png +0 -0
  28. data/app/assets/images/fancybox/fancy_shadow_ne.png +0 -0
  29. data/app/assets/images/fancybox/fancy_shadow_nw.png +0 -0
  30. data/app/assets/images/fancybox/fancy_shadow_s.png +0 -0
  31. data/app/assets/images/fancybox/fancy_shadow_se.png +0 -0
  32. data/app/assets/images/fancybox/fancy_shadow_sw.png +0 -0
  33. data/app/assets/images/fancybox/fancy_shadow_w.png +0 -0
  34. data/app/assets/images/fancybox/fancy_title_left.png +0 -0
  35. data/app/assets/images/fancybox/fancy_title_main.png +0 -0
  36. data/app/assets/images/fancybox/fancy_title_over.png +0 -0
  37. data/app/assets/images/fancybox/fancy_title_right.png +0 -0
  38. data/app/assets/images/fancybox/fancybox-x.png +0 -0
  39. data/app/assets/images/fancybox/fancybox-y.png +0 -0
  40. data/app/assets/images/fancybox/fancybox.png +0 -0
  41. data/app/assets/javascripts/cms/dust/defaults.js.coffee +31 -0
  42. data/app/assets/javascripts/cms/dust/gallery/photo.js.coffee +1 -0
  43. data/app/assets/javascripts/cms/dust/gallery/photo_view.js.coffee +21 -0
  44. data/app/assets/javascripts/cms/dust/gallery/photos.js.coffee +6 -0
  45. data/app/assets/javascripts/cms/dust/gallery/photos_view.js.coffee +12 -0
  46. data/app/assets/javascripts/cms/dust/gallery/router.js.coffee +14 -0
  47. data/app/assets/javascripts/cms/dust/gallery.js.coffee +31 -0
  48. data/app/assets/javascripts/cms/dust/nav.js.coffee +21 -0
  49. data/app/assets/javascripts/cms/dust/sections.js.coffee +21 -0
  50. data/app/assets/javascripts/cms/dust/sortables.js.coffee +64 -0
  51. data/app/assets/javascripts/cms/dust/window.js.coffee +11 -0
  52. data/app/assets/javascripts/cms/dust.js.coffee +19 -0
  53. data/app/assets/javascripts/cms/lib/backbone.js +42 -0
  54. data/app/assets/javascripts/cms/lib/fineuploader-3.0.js +71 -0
  55. data/app/assets/javascripts/cms/lib/handlebars.js +1920 -0
  56. data/app/assets/javascripts/cms/lib/spin.js +2 -0
  57. data/app/assets/javascripts/cms/lib/underscore.js +1 -0
  58. data/app/assets/javascripts/cms.js +14 -0
  59. data/app/assets/javascripts/core/jquery.form.js +785 -0
  60. data/app/assets/javascripts/core/jquery.html5.js +29 -0
  61. data/app/assets/javascripts/core/jquery.mousewheel-3.0.2.pack.js +13 -0
  62. data/app/assets/javascripts/core/jquery.placeholder.min.js +11 -0
  63. data/app/assets/javascripts/core/nestedsortables.js +429 -0
  64. data/app/assets/javascripts/core/serializelist.js +66 -0
  65. data/app/assets/javascripts/core/tipTip.js +21 -0
  66. data/app/assets/javascripts/core.js +4 -0
  67. data/app/assets/javascripts/front_end/application-main.js.coffee +27 -0
  68. data/app/assets/javascripts/front_end/map.js +34 -0
  69. data/app/assets/javascripts/front_end/video.js +4569 -0
  70. data/app/assets/javascripts/front_end.js +18 -0
  71. data/app/assets/stylesheets/cms/flash_messages.css.scss +17 -0
  72. data/app/assets/stylesheets/cms/footer.css.scss +12 -0
  73. data/app/assets/stylesheets/cms/forms.css.scss +67 -0
  74. data/app/assets/stylesheets/cms/gallery.css.scss +21 -0
  75. data/app/assets/stylesheets/cms/icons.css.scss +123 -0
  76. data/app/assets/stylesheets/cms/jquery-ui.custom.scss +6 -0
  77. data/app/assets/stylesheets/cms/layout.css.scss +162 -0
  78. data/app/assets/stylesheets/cms/lib/grid.css.scss +116 -0
  79. data/app/assets/stylesheets/cms/lib/mixins.css.scss +20 -0
  80. data/app/assets/stylesheets/cms/login.scss +12 -0
  81. data/app/assets/stylesheets/cms/main.old +155 -0
  82. data/app/assets/stylesheets/cms/nav.css.scss +73 -0
  83. data/app/assets/stylesheets/cms/sections.scss +17 -0
  84. data/app/assets/stylesheets/cms/sortables.scss +20 -0
  85. data/app/assets/stylesheets/cms.css.scss +30 -0
  86. data/app/assets/stylesheets/core/app/defaults.css.scss +556 -0
  87. data/app/assets/stylesheets/core/plugins/PIE.htc +96 -0
  88. data/app/assets/stylesheets/core/plugins/jquery-ui-1.8.5.custom.old +572 -0
  89. data/app/assets/stylesheets/core/plugins/jquery.fancybox-1.3.1.css +364 -0
  90. data/app/assets/stylesheets/core/plugins/skeleton.css +155 -0
  91. data/app/assets/stylesheets/core/plugins/tipTip.css +115 -0
  92. data/app/assets/stylesheets/core/plugins/uploadify.css +25 -0
  93. data/app/assets/stylesheets/core/reset/reset.css +211 -0
  94. data/app/assets/stylesheets/core/reset/text.css +86 -0
  95. data/app/assets/stylesheets/core.css.scss +14 -0
  96. data/app/assets/stylesheets/front_end/app/just-delete-me-and-start-over.css.scss +70 -0
  97. data/app/assets/stylesheets/front_end.css +14 -0
  98. data/app/controllers/authentication_controller.rb +30 -0
  99. data/app/controllers/dust/blocks_controller.rb +49 -0
  100. data/app/controllers/dust/contacts_controller.rb +89 -0
  101. data/app/controllers/dust/dashboard_controller.rb +26 -0
  102. data/app/controllers/dust/gallery/albums_controller.rb +49 -0
  103. data/app/controllers/dust/gallery/api/photos_controller.rb +28 -0
  104. data/app/controllers/dust/gallery/photos_controller.rb +47 -0
  105. data/app/controllers/dust/menu_items_controller.rb +51 -0
  106. data/app/controllers/dust/menus_controller.rb +47 -0
  107. data/app/controllers/dust/pages_controller.rb +52 -0
  108. data/app/controllers/dust/password_resets_controller.rb +48 -0
  109. data/app/controllers/dust/posts_controller.rb +47 -0
  110. data/app/controllers/dust/roles_controller.rb +47 -0
  111. data/app/controllers/dust/sessions_controller.rb +29 -0
  112. data/app/controllers/dust/site_wides_controller.rb +28 -0
  113. data/app/controllers/dust/sortable_controller.rb +17 -0
  114. data/app/controllers/dust/users_controller.rb +52 -0
  115. data/app/controllers/front_end/page_controller.rb +27 -0
  116. data/app/controllers/front_end/post_controller.rb +14 -0
  117. data/app/controllers/front_end/sitemap_controller.rb +11 -0
  118. data/app/controllers/front_end_controller.rb +18 -0
  119. data/app/helpers/error_messages_helper.rb +23 -0
  120. data/app/helpers/exceptions.rb +4 -0
  121. data/app/helpers/layout_helper.rb +28 -0
  122. data/app/helpers/misc_helper.rb +29 -0
  123. data/app/helpers/region_helper.rb +32 -0
  124. data/app/mailers/post_office.rb +39 -0
  125. data/app/models/ckeditor/asset.rb +7 -0
  126. data/app/models/ckeditor/attachment_file.rb +7 -0
  127. data/app/models/ckeditor/picture.rb +7 -0
  128. data/app/models/dust/block.rb +114 -0
  129. data/app/models/dust/builder/page.rb +84 -0
  130. data/app/models/dust/builder/site_wide.rb +50 -0
  131. data/app/models/dust/contact.rb +34 -0
  132. data/app/models/dust/gallery/album.rb +14 -0
  133. data/app/models/dust/gallery/photo.rb +23 -0
  134. data/app/models/dust/handlebar.rb +59 -0
  135. data/app/models/dust/map.rb +21 -0
  136. data/app/models/dust/menu/item_dependency.rb +66 -0
  137. data/app/models/dust/menu.rb +11 -0
  138. data/app/models/dust/menu_item.rb +64 -0
  139. data/app/models/dust/page.rb +52 -0
  140. data/app/models/dust/post.rb +39 -0
  141. data/app/models/dust/role.rb +9 -0
  142. data/app/models/dust/section.rb +11 -0
  143. data/app/models/dust/session.rb +28 -0
  144. data/app/models/dust/site_wide.rb +41 -0
  145. data/app/models/dust/sort.rb +52 -0
  146. data/app/models/dust/sortable_item.rb +21 -0
  147. data/app/models/dust/user.rb +49 -0
  148. data/app/uploaders/ckeditor_attachment_file_uploader.rb +42 -0
  149. data/app/uploaders/ckeditor_picture_uploader.rb +53 -0
  150. data/app/uploaders/gallery_photo_uploader.rb +52 -0
  151. data/app/uploaders/image_uploader.rb +51 -0
  152. data/app/uploaders/slide_image_uploader.rb +51 -0
  153. data/app/views/dust/blocks/_block.html.haml +20 -0
  154. data/app/views/dust/blocks/_form.html.haml +50 -0
  155. data/app/views/dust/blocks/_normal_block_content.html.haml +1 -0
  156. data/app/views/dust/blocks/_search.html.haml +4 -0
  157. data/app/views/dust/blocks/edit.html.haml +4 -0
  158. data/app/views/dust/blocks/index.html.haml +16 -0
  159. data/app/views/dust/blocks/new.html.haml +3 -0
  160. data/app/views/dust/contacts/_form.html.haml +37 -0
  161. data/app/views/dust/contacts/_import_csv.html.haml +8 -0
  162. data/app/views/dust/contacts/_instance.html.haml +13 -0
  163. data/app/views/dust/contacts/_search.html.haml +4 -0
  164. data/app/views/dust/contacts/edit.html.haml +2 -0
  165. data/app/views/dust/contacts/index.html.haml +17 -0
  166. data/app/views/dust/contacts/index.json.haml +6 -0
  167. data/app/views/dust/contacts/new.html.haml +3 -0
  168. data/app/views/dust/dashboard/_options.html.haml +6 -0
  169. data/app/views/dust/dashboard/show.html.haml +33 -0
  170. data/app/views/dust/dashboard/update.html.haml +6 -0
  171. data/app/views/dust/gallery/albums/_form.html.haml +52 -0
  172. data/app/views/dust/gallery/albums/_photo.html.haml +12 -0
  173. data/app/views/dust/gallery/albums/edit.html.haml +3 -0
  174. data/app/views/dust/gallery/albums/index.html.haml +18 -0
  175. data/app/views/dust/gallery/albums/new.html.haml +4 -0
  176. data/app/views/dust/gallery/albums/show.html.haml +2 -0
  177. data/app/views/dust/gallery/photos/_form.html.haml +26 -0
  178. data/app/views/dust/gallery/photos/edit.html.haml +3 -0
  179. data/app/views/dust/gallery/photos/index.html.haml +18 -0
  180. data/app/views/dust/gallery/photos/new.html.haml +4 -0
  181. data/app/views/dust/gallery/photos/show.json.jbuilder +5 -0
  182. data/app/views/dust/menu_items/_form.html.haml +24 -0
  183. data/app/views/dust/menu_items/_roots.html.haml +3 -0
  184. data/app/views/dust/menu_items/_search.html.haml +4 -0
  185. data/app/views/dust/menu_items/_tree.html.haml +11 -0
  186. data/app/views/dust/menu_items/edit.html.haml +2 -0
  187. data/app/views/dust/menu_items/index.html.haml +19 -0
  188. data/app/views/dust/menu_items/new.html.haml +2 -0
  189. data/app/views/dust/menus/_form.html.haml +39 -0
  190. data/app/views/dust/menus/edit.html.haml +3 -0
  191. data/app/views/dust/menus/index.html.haml +18 -0
  192. data/app/views/dust/menus/new.html.haml +4 -0
  193. data/app/views/dust/menus/show.html.haml +2 -0
  194. data/app/views/dust/pages/_form.html.haml +68 -0
  195. data/app/views/dust/pages/_search.html.haml +4 -0
  196. data/app/views/dust/pages/edit.html.haml +3 -0
  197. data/app/views/dust/pages/index.html.haml +16 -0
  198. data/app/views/dust/pages/new.html.haml +3 -0
  199. data/app/views/dust/password_resets/edit.html.haml +6 -0
  200. data/app/views/dust/password_resets/new.html.haml +10 -0
  201. data/app/views/dust/posts/_form.html.haml +39 -0
  202. data/app/views/dust/posts/edit.html.haml +3 -0
  203. data/app/views/dust/posts/index.html.haml +18 -0
  204. data/app/views/dust/posts/new.html.haml +4 -0
  205. data/app/views/dust/posts/show.html.haml +2 -0
  206. data/app/views/dust/roles/_form.html.haml +11 -0
  207. data/app/views/dust/roles/edit.html.haml +2 -0
  208. data/app/views/dust/roles/index.html.haml +14 -0
  209. data/app/views/dust/roles/new.html.haml +2 -0
  210. data/app/views/dust/sessions/_form.html.haml +18 -0
  211. data/app/views/dust/sessions/new.html.haml +2 -0
  212. data/app/views/dust/site_wides/new.html.haml +19 -0
  213. data/app/views/dust/slides/_form.html.haml +26 -0
  214. data/app/views/dust/slides/_search.html.haml +4 -0
  215. data/app/views/dust/slides/_slideshow.html.haml +12 -0
  216. data/app/views/dust/slides/edit.html.haml +5 -0
  217. data/app/views/dust/slides/index.html.haml +25 -0
  218. data/app/views/dust/slides/index.js.haml +2 -0
  219. data/app/views/dust/slides/new.html.haml +6 -0
  220. data/app/views/dust/slides/show.html.haml +15 -0
  221. data/app/views/dust/sortable/sort.js.coffee +10 -0
  222. data/app/views/dust/users/_form.html.haml +27 -0
  223. data/app/views/dust/users/_search.html.haml +4 -0
  224. data/app/views/dust/users/_user_bar.html.haml +10 -0
  225. data/app/views/dust/users/dashboard.html.haml +40 -0
  226. data/app/views/dust/users/edit.html.haml +2 -0
  227. data/app/views/dust/users/index.html.haml +16 -0
  228. data/app/views/dust/users/new.html.haml +2 -0
  229. data/app/views/front_end/page/_admin.html.haml +6 -0
  230. data/app/views/front_end/page/search.html.haml +9 -0
  231. data/app/views/front_end/page/show.html.haml +8 -0
  232. data/app/views/front_end/post/_admin.html.haml +7 -0
  233. data/app/views/front_end/post/show.html.haml +12 -0
  234. data/app/views/front_end/sitemap/index.html.haml +4 -0
  235. data/app/views/front_end/sitemap/index.xml.haml +9 -0
  236. data/app/views/layouts/app_partials/_analytics.html.haml +11 -0
  237. data/app/views/layouts/app_partials/_application_tree.html.haml +6 -0
  238. data/app/views/layouts/cms.html.haml +52 -0
  239. data/app/views/layouts/cms_partials/_nav.html.haml +5 -0
  240. data/app/views/layouts/front_end.html.haml +22 -0
  241. data/app/views/layouts/sessions.html.haml +19 -0
  242. data/app/views/post_office/contact_confirmation.html.haml +7 -0
  243. data/app/views/post_office/contact_request.html.haml +24 -0
  244. data/app/views/post_office/password_reset_instructions.html.haml +6 -0
  245. data/app/views/widgets/_contact_form.html.haml +20 -0
  246. data/app/views/widgets/_map.html.haml +16 -0
  247. data/app/views/widgets/_quick_contact_form.html.haml +10 -0
  248. data/app/views/widgets/_site_map.html.haml +7 -0
  249. data/app/views/widgets/_site_menu.html.haml +10 -0
  250. data/app/views/widgets/_slider.html.haml +0 -0
  251. data/app/views/widgets/_user_login.html.haml +13 -0
  252. data/app/views/widgets/galleries/_archive.html.haml +1 -0
  253. data/app/views/widgets/galleries/_show.html.haml +0 -0
  254. data/app/views/widgets/posts/_index.html.haml +1 -0
  255. data/app/views/widgets/posts/_show.html.haml +0 -0
  256. data/config/authorization_rules.rb +23 -0
  257. data/config/generators/templates/haml/scaffold/_form.html.haml +19 -0
  258. data/config/generators/templates/haml/scaffold/edit.html.haml +3 -0
  259. data/config/generators/templates/haml/scaffold/index.html.haml +18 -0
  260. data/config/generators/templates/haml/scaffold/new.html.haml +4 -0
  261. data/config/generators/templates/haml/scaffold/show.html.haml +2 -0
  262. data/config/generators/templates/rails/scaffold_controller/controller.rb +51 -0
  263. data/config/initializers/app_string_io.rb +12 -0
  264. data/config/initializers/ckeditor.rb +18 -0
  265. data/config/initializers/client_side_validations.rb +13 -0
  266. data/config/initializers/dust_config.rb +22 -0
  267. data/config/initializers/dust_core_reloader.rb +11 -0
  268. data/config/initializers/sorcery.rb +398 -0
  269. data/config/initializers/wrap_parameters.rb +14 -0
  270. data/config/routes.rb +55 -0
  271. data/db/migrate/20101206025845_create_roles.rb +11 -0
  272. data/db/migrate/20110217212357_create_ckeditor_assets.rb +31 -0
  273. data/db/migrate/20110218000640_create_pages.rb +15 -0
  274. data/db/migrate/20110218000641_create_sections.rb +15 -0
  275. data/db/migrate/20110218002220_create_contacts.rb +22 -0
  276. data/db/migrate/20110218020608_create_menu_items.rb +21 -0
  277. data/db/migrate/20110507014158_create_blocks.rb +23 -0
  278. data/db/migrate/20121106195938_sorcery_core.rb +17 -0
  279. data/db/migrate/20121106195939_sorcery_remember_me.rb +15 -0
  280. data/db/migrate/20121106195940_sorcery_reset_password.rb +17 -0
  281. data/db/migrate/20121106195941_sorcery_activity_logging.rb +17 -0
  282. data/db/migrate/20121106200754_sorcery_user_activation.rb +17 -0
  283. data/db/migrate/20130220044031_create_site_wides.rb +11 -0
  284. data/db/migrate/20130220051658_create_menus.rb +11 -0
  285. data/db/migrate/20130223030136_create_albums.rb +13 -0
  286. data/db/migrate/20130223040911_create_photos.rb +15 -0
  287. data/db/migrate/20130223044553_create_posts.rb +15 -0
  288. data/lib/dust/engine.rb +18 -0
  289. data/lib/dust/utils.rb +14 -0
  290. data/lib/dust/version.rb +3 -0
  291. data/lib/dust-cms.rb +53 -0
  292. data/lib/tasks/dust_tasks.rake +51 -0
  293. data/lib/tasks/seed.rb +46 -0
  294. metadata +613 -0
@@ -0,0 +1,114 @@
1
+ module Dust
2
+ class Block < ActiveRecord::Base
3
+ attr_accessible :title, :body, :partial_name, :where_to_show, :show, :show_title, :classes, :weight, :column_span, :column_offset
4
+
5
+ default_scope :order => 'weight ASC'
6
+
7
+ include ActionView::Helpers::TextHelper
8
+ include ActionView::Helpers::SanitizeHelper
9
+
10
+ validates_presence_of :title
11
+ validates_uniqueness_of :title
12
+
13
+ def self.regions
14
+ pretty_regions = []
15
+ Dust.config.regions.each do |region|
16
+ pretty_regions << [region.humanize.titleize, region]
17
+ end
18
+ Dust::Page.all.each do |page|
19
+ pretty_regions.concat page.sections.map{ |s| ["#{page.nav_link} | #{s.title}", s.title.parameterize] } unless page.sections.blank?
20
+ end
21
+ pretty_regions
22
+ end
23
+
24
+ def self.grid
25
+ grid = OpenStruct.new
26
+ grid.columns = (1..12).map{ |i| [i.to_words.titleize, "#{i.to_words} columns"] }
27
+ grid.offsets = (1..12).map{|i| ["Offset by #{i.to_words.titleize}", "offset-by-#{i.to_words}"]}
28
+ grid
29
+ end
30
+
31
+ def self.page(search, page)
32
+ search(search).paginate(:per_page => 12, :page => page)
33
+ end
34
+
35
+ def self.search(search)
36
+ if search
37
+ where("title LIKE ? OR body LIKE ?", "%#{search}%", "%#{search}%").where("show_title = ? OR 'show' != ?", false, '')
38
+ else
39
+ scoped
40
+ end
41
+ end
42
+
43
+ def final_classes
44
+ [column_span, column_offset, classes].join(" ")
45
+ end
46
+
47
+ def url_list
48
+ show.split("\r\n")
49
+ end
50
+
51
+ def show_me?(uri)
52
+ show = false
53
+ show = true if (url_list.include?(uri) || url_list.blank?)
54
+ show = true if (uri == "/" && url_list.include?("/#{Dust.config.root}"))
55
+ show
56
+ end
57
+
58
+ def self.find_active(uri)
59
+ blocks = Block.all
60
+ blocks.delete_if {|b| !b.show_me?(uri) }
61
+ blocks
62
+ end
63
+
64
+ def front_end_content
65
+ options = {
66
+ :block => self
67
+ }
68
+
69
+ Handlebar.render(body, options)
70
+ end
71
+
72
+ def pages
73
+ pages = []
74
+ Page.all.each do |page|
75
+ pages << page if url_list.include?(page.menu_item.url)
76
+ pages << page if url_list.blank?
77
+ end
78
+ puts url_list.inspect
79
+ puts pages.inspect
80
+ pages
81
+ end
82
+
83
+ def self.widget_list
84
+ files = []
85
+ paths = widget_filenames
86
+ puts paths
87
+ paths.each do |filename|
88
+ if filename[0] != "." # if file is not hidden
89
+ files.push filename.sub('_', '').gsub('.html.haml', '')
90
+ end
91
+ end
92
+ files
93
+ end
94
+
95
+ private
96
+
97
+ def self.widget_files
98
+ paths = []
99
+ Dir["#{Dust.root}/app/views/widgets/**/*"].each {|path| paths << path }
100
+ Dir["#{Rails.root}/app/views/widgets/**/**"].each {|path| paths << path }
101
+ paths
102
+ end
103
+
104
+ def self.widget_filenames
105
+ widget_files.select{ |p| File.file?(p) }.map { |f| widget_option(f) }
106
+ end
107
+
108
+ def self.widget_option(path)
109
+ partial_path = path.gsub("#{Dust.root}/app/views/widgets/", "").gsub("#{Rails.root}/app/views/widgets/", "")
110
+ partial_path
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,84 @@
1
+ module Dust
2
+ module Builder
3
+ class Page
4
+
5
+ def initialize(options={})
6
+ @page = options[:page]
7
+ @sections = options[:sections] || []
8
+ @page_attrs = options[:attrs] if options[:attrs]
9
+ end
10
+
11
+ def save
12
+ build_sections
13
+ update_blocks
14
+ if @page.errors.blank?
15
+ @page.save
16
+ else
17
+ false
18
+ end
19
+ end
20
+
21
+ def update
22
+ build_sections
23
+ update_blocks
24
+ if @page.errors.blank?
25
+ @page.update_attributes(@page_attrs)
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+
34
+ def build_sections
35
+ @sections.each do |section_attr|
36
+ section = ::Dust::Section.find_or_create_by_id_and_page_id(section_attr[0], @page.id)
37
+
38
+ if section_attr[1]["_destroy"] == "1"
39
+ section.destroy
40
+ else
41
+ section_attr[1].delete("_destroy")
42
+ section.id = nil if section.new_record?
43
+ section.assign_attributes section_attr[1]
44
+
45
+ determine_validity_of(section)
46
+ @page.sections << section
47
+ end
48
+ end
49
+ end
50
+
51
+ def update_blocks
52
+ if @page.menu_item.url_changed?
53
+ previous = @page.menu_item.url_was
54
+ current = @page.menu_item.url
55
+
56
+ @page.old_blocks.each do |block|
57
+ show = block.show.gsub(previous, current)
58
+ unless block.update_attributes(:show => show)
59
+ validate_block(block)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def validate_block(block)
66
+ @page.errors[:base] << "Block #{block.title} is not valid"
67
+ block.errors.full_messages.each do |error|
68
+ @page.errors[:base] << "Block | #{error}"
69
+ end
70
+ end
71
+
72
+ def determine_validity_of(section)
73
+ unless section.valid?
74
+ @page.errors[:base] << "Section #{section.title} is not valid"
75
+ section.errors.full_messages.each do |error|
76
+ @page.errors[:base] << "Section | #{error}"
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,50 @@
1
+ module Dust
2
+ module Builder
3
+ class SiteWide
4
+
5
+ include ActiveModel::Validations
6
+
7
+ attr_accessor :variables
8
+
9
+ def initialize(options={})
10
+ @options = options[:options]
11
+ @variables = []
12
+ end
13
+
14
+ def update
15
+ build_variables
16
+ if self.errors.blank?
17
+ update_variables
18
+ else
19
+ false
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def update_variables
26
+ @variables.each do |var|
27
+ var.save
28
+ end
29
+ end
30
+
31
+ def build_variables
32
+ @options.each do |option|
33
+ variable = Dust::SiteWide.find option[0]
34
+ variable.assign_attributes option[1]
35
+ determine_validity_of variable
36
+ end
37
+ end
38
+
39
+ def determine_validity_of(variable)
40
+ unless variable.valid?
41
+ variable.errors.full_messages.each do |error|
42
+ self.errors[:base] << "#{variable.category}:#{variable.name} | #{error}"
43
+ end
44
+ end
45
+ @variables << variable
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,34 @@
1
+ module Dust
2
+ class Contact < ActiveRecord::Base
3
+ attr_accessible :name, :email, :company_name, :phone, :address, :city, :state, :zip, :message, :hear
4
+
5
+ validates_presence_of :name
6
+ validates_presence_of :email
7
+ validates_format_of :email, :with => /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i, :message => "Should look like an email address."
8
+ validates_presence_of :message
9
+
10
+ def self.total_on(date)
11
+ where("date(created_at) = ?", date)
12
+ end
13
+
14
+ def self.page(search, page, date)
15
+ search(search, date).order("created_at DESC").paginate(:per_page => 12, :page => page)
16
+ end
17
+
18
+ def deliver_messages
19
+ Dust.config.mailer.contact_confirmation(self).deliver
20
+ Dust.config.mailer.contact_request(self).deliver
21
+ end
22
+
23
+ def self.search(search, date)
24
+ if search
25
+ where("name LIKE ? OR email LIKE ? OR message LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
26
+ elsif date
27
+ where("date(created_at) IS ?", (Time.at(date.to_i / 1000)).to_date)
28
+ else
29
+ scoped
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module Dust
2
+ module Gallery
3
+ class Album < ActiveRecord::Base
4
+ include Dust::Menu::ItemDependency
5
+
6
+ attr_accessible :description, :position, :title
7
+ acts_as_nested_set
8
+
9
+ validates_presence_of :title, :description
10
+
11
+ has_many :photos, :dependent => :destroy
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module Dust
2
+ module Gallery
3
+ class Photo < ActiveRecord::Base
4
+ attr_accessible :description, :lft, :parent_id, :rgt, :title, :album_id, :filename
5
+ acts_as_nested_set
6
+
7
+ mount_uploader :filename, Dust.config.uploader
8
+
9
+ belongs_to :album
10
+
11
+ validates_presence_of :album_id
12
+
13
+ def url
14
+ filename.url
15
+ end
16
+
17
+ def success
18
+ true
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ module Dust
2
+ class Handlebar < Mustache
3
+
4
+ def app_config
5
+ raw_config = File.read("#{Rails.root}/config/app_config.yml")
6
+ yaml_data = YAML.load(raw_config)
7
+ Hashie::Mash.new(yaml_data)
8
+ end
9
+
10
+ def block(id)
11
+ @block = Block.find_by_id(id)
12
+ @block.front_end_content
13
+ end
14
+
15
+ def method_missing(name, *args, &block)
16
+ if name.to_s =~ /^block_(\d+)/
17
+ block($1)
18
+ else
19
+ return super
20
+ end
21
+ end
22
+
23
+ def respond_to?(method)
24
+ if method.to_s =~ /^block_(\d+)/
25
+ method.to_s =~ /^block_(\d+)/
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def blocks
32
+ Block.all
33
+ end
34
+
35
+ def menu
36
+ MenuItem.all
37
+ end
38
+
39
+ def slides
40
+ Nivo::Slide.rotate.map{ |slide|
41
+ {
42
+ :image => slide.image.url
43
+ }
44
+ }
45
+ end
46
+
47
+ def recent
48
+ Post.recent.map{ |post|
49
+ {
50
+ :title => post.title,
51
+ :content => post.preview,
52
+ :published_at => post.published_date,
53
+ :slug => post.kind == "workshop" ? "workshops" : "resources"
54
+ }
55
+ }
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ module Dust
2
+ class Map
3
+
4
+ attr_accessor :address, :width, :height, :content
5
+
6
+ def initialize(options={})
7
+ @address = options[:address] ||= "Lalana Ramboatiana, Antananarivo, Madagascar"
8
+ @width = options[:width] ||= 400
9
+ @height = options[:height] ||= 400
10
+ @content = options[:content]||= "Madagascar Royal Palace"
11
+ end
12
+
13
+ def self.find(map_name)
14
+ maps = Hashie::Mash.new(YAML.load(File.read("#{Rails.root}/config/maps.yml")))
15
+ map_options = maps[map_name] ||= {}
16
+ return Map.new map_options
17
+ end
18
+
19
+ end
20
+ end
21
+
@@ -0,0 +1,66 @@
1
+
2
+ module Dust
3
+ class Menu
4
+ module ItemDependency
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attr_accessible :filename, :nav_link, :active, :menu
9
+ has_one :menu_item, :as => :linkable, :dependent => :destroy, :autosave => true, :class_name => Dust::MenuItem
10
+
11
+ auto_build :menu_item
12
+ end
13
+
14
+ def match_path
15
+ menu_item.url
16
+ end
17
+
18
+ def filename
19
+ self.menu_item.url.gsub("/", "")
20
+ end
21
+
22
+ def filename=(filename)
23
+ self.menu_item.url = "/#{filename}"
24
+ end
25
+
26
+ def active
27
+ self.menu_item.active
28
+ end
29
+
30
+ def active=(active)
31
+ self.menu_item.active = active
32
+ end
33
+
34
+ def nav_link
35
+ self.menu_item.title
36
+ end
37
+
38
+ def nav_link=(filename)
39
+ self.menu_item.title = filename
40
+ end
41
+
42
+ def menu
43
+ self.menu_item.menu_id
44
+ end
45
+
46
+ def menu=(menu_id)
47
+ self.menu_item.menu_id = menu_id
48
+ end
49
+
50
+ module ClassMethods
51
+ def find_by_filename(filename)
52
+ filename = "/#{filename}"
53
+ where(:menu_items => {:url => filename}).joins(:menu_item).first
54
+ end
55
+
56
+ def new_with_menu_item(options={})
57
+ item = self.new
58
+ item.build_menu_item
59
+ item.assign_attributes options
60
+ item
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ module Dust
2
+ class Menu < ActiveRecord::Base
3
+ attr_accessible :desc, :title, :nestable
4
+
5
+ has_many :menu_items, :dependent => :destroy
6
+
7
+ def active_items
8
+ menu_items.roots.where(:active => true)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,64 @@
1
+ module Dust
2
+ class MenuItem < ActiveRecord::Base
3
+ attr_accessible :title, :url, :active, :lft, :rgt, :parent_id, :menu_id
4
+
5
+ acts_as_nested_set
6
+
7
+ belongs_to :menu
8
+ belongs_to :linkable, :polymorphic => true
9
+ validates_uniqueness_of :url
10
+
11
+ scope :sitemap, :select => 'url, created_at, updated_at', :limit => 50000
12
+
13
+ def self.page(search, page)
14
+ search(search).order("title").paginate(:per_page => 12, :page => page)
15
+ end
16
+
17
+ def self.manage(search)
18
+ roots.search(search).order("title")
19
+ end
20
+
21
+ def self.search(search)
22
+ if search
23
+ where("title LIKE ?", "%#{search}%")
24
+ else
25
+ scoped
26
+ end
27
+ end
28
+
29
+ def self.menu
30
+ list = self.roots
31
+ list.where("active = ?", true)
32
+ end
33
+
34
+ def edit_linkable
35
+ "/#{root.linkable_type.downcase.pluralize}/#{root.linkable_id}/edit"
36
+ end
37
+
38
+ def destroy_linkable
39
+ "/#{root.linkable_type.downcase.pluralize}/#{root.linkable_id}"
40
+ end
41
+
42
+ def children_urls
43
+ self.descendants.map{ |item| item.url }
44
+ end
45
+
46
+ REGEX = '^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$'
47
+
48
+ def html_options?(uri)
49
+ mash = Hashie::Mash.new
50
+
51
+ mash.class = "last" if self == self.self_and_siblings.all(:conditions => ['active = ?', true]).last
52
+ mash.target = "_blank" if url.match(REGEX)
53
+ mash.class = "active" if self.is_active? uri
54
+ mash.class = "active last" if (self.is_active? uri) and self == self.self_and_siblings.last
55
+ mash
56
+ end
57
+
58
+ def is_active?(uri)
59
+ true if uri == url or children_urls.include?(uri) or (uri == "/" and self.url == "/welcome")
60
+ end
61
+
62
+ end
63
+ end
64
+
@@ -0,0 +1,52 @@
1
+ module Dust
2
+ class Page < ActiveRecord::Base
3
+ attr_accessible :meta_title, :meta_description, :description, :classes
4
+ has_many :sections
5
+
6
+ include ActionView::Helpers::TextHelper
7
+ include ActionView::Helpers::SanitizeHelper
8
+ include Dust::Menu::ItemDependency
9
+
10
+ validates_presence_of :meta_title
11
+ after_create :create_starter_block
12
+ has_many :blocks,
13
+ :finder_sql => proc{"SELECT `blocks`.* FROM `blocks` WHERE `blocks`.`show` LIKE \"%/#{filename}%\" ORDER BY weight ASC"}
14
+ has_many :old_blocks, :class_name => Block,
15
+ :finder_sql => proc{"SELECT `blocks`.* FROM `blocks` WHERE `blocks`.`show` LIKE \"%#{menu_item.url_was}%\" ORDER BY weight ASC"}
16
+
17
+ #-- ActiveRecord Queries --#
18
+ def self.page(search, page)
19
+ search(search).order("meta_title").paginate(:per_page => 12, :page => page)
20
+ end
21
+
22
+ def self.search(search)
23
+ if search
24
+ where("meta_title LIKE ? OR meta_description LIKE ?", "%#{search}%", "%#{search}%")
25
+ else
26
+ scoped
27
+ end
28
+ end
29
+
30
+ def front_end_content
31
+ options = { :page => self }
32
+ Handlebar.render(content, options)
33
+ end
34
+
35
+ def create_description
36
+ meta_description
37
+ end
38
+
39
+ def create_starter_block
40
+ Block.new(
41
+ :show_title => true,
42
+ :title => "#{self.meta_title} Page Content",
43
+ :body => "<h1> #{self.meta_title} </h1> <p>New content.</p>",
44
+ :classes => "twelve columns",
45
+ :where_to_show => Dust.config.default_region,
46
+ :show => "/#{self.filename}",
47
+ :weight => 0
48
+ ).save
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ module Dust
2
+ class Post < ActiveRecord::Base
3
+ include Dust::Menu::ItemDependency
4
+ mount_uploader :file, ImageUploader
5
+
6
+ attr_accessible :body, :file, :published, :published_date, :share, :share_type, :title
7
+
8
+ validates_presence_of :title, :body, :published_date
9
+
10
+ def share_types
11
+ ['Facebook', 'Twitter']
12
+ end
13
+
14
+ def published_date
15
+ self.published_at ? self.published_at.strftime("%Y/%m/%d") : Time.now.strftime("%Y/%m/%d")
16
+ end
17
+
18
+ def published_date=(date_str)
19
+ self.published_at = Time.parse date_str
20
+ end
21
+
22
+ def slug
23
+ "#{published_date}/#{url_title.parameterize}"
24
+ end
25
+
26
+ def url_title
27
+ title.blank? ? "empty-title" : title
28
+ end
29
+
30
+ def filename
31
+ url_title
32
+ end
33
+
34
+ def filename=(filename="")
35
+ self.menu_item.url = "/post/#{slug}"
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,9 @@
1
+ module Dust
2
+ class Role < ActiveRecord::Base
3
+
4
+ has_many :users
5
+
6
+ attr_accessible :name
7
+
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Dust
2
+ class Section < ActiveRecord::Base
3
+ belongs_to :page
4
+ attr_accessible :classes, :position, :title
5
+ acts_as_nested_set
6
+ default_scope roots
7
+
8
+ validates_presence_of :title
9
+ validates_uniqueness_of :title
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Dust
2
+ class Session
3
+ include ActiveModel::Validations
4
+ include ActiveModel::Conversion
5
+ extend ActiveModel::Naming
6
+
7
+ attr_accessor :username, :password, :user, :remember_me
8
+
9
+ validates_presence_of :username, :password
10
+ validate :found_user?
11
+
12
+ def initialize(attributes=nil, user=nil)
13
+ attributes ||= {}
14
+ @user = user
15
+ attributes.each do |name, value|
16
+ send("#{name}=", value)
17
+ end
18
+ end
19
+
20
+ def found_user?
21
+ errors[:base] << "User not found" unless @user
22
+ end
23
+
24
+ def persisted?
25
+ false
26
+ end
27
+ end
28
+ end