knitkit 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. data/GPL-3-LICENSE +674 -0
  2. data/README.md +6 -0
  3. data/Rakefile +30 -0
  4. data/app/assets/javascripts/knitkit/application.js +9 -0
  5. data/app/assets/stylesheets/knitkit/application.css +7 -0
  6. data/app/controllers/knitkit/articles_controller.rb +7 -0
  7. data/app/controllers/knitkit/base_controller.rb +45 -0
  8. data/app/controllers/knitkit/blogs_controller.rb +27 -0
  9. data/app/controllers/knitkit/comments_controller.rb +18 -0
  10. data/app/controllers/knitkit/erp_app/desktop/app_controller.rb +135 -0
  11. data/app/controllers/knitkit/erp_app/desktop/articles_controller.rb +144 -0
  12. data/app/controllers/knitkit/erp_app/desktop/comments_controller.rb +43 -0
  13. data/app/controllers/knitkit/erp_app/desktop/content_controller.rb +27 -0
  14. data/app/controllers/knitkit/erp_app/desktop/file_assets_controller.rb +145 -0
  15. data/app/controllers/knitkit/erp_app/desktop/image_assets_controller.rb +28 -0
  16. data/app/controllers/knitkit/erp_app/desktop/inquiries_controller.rb +68 -0
  17. data/app/controllers/knitkit/erp_app/desktop/position_controller.rb +20 -0
  18. data/app/controllers/knitkit/erp_app/desktop/theme_controller.rb +272 -0
  19. data/app/controllers/knitkit/erp_app/desktop/versions_controller.rb +135 -0
  20. data/app/controllers/knitkit/erp_app/desktop/website_controller.rb +177 -0
  21. data/app/controllers/knitkit/erp_app/desktop/website_nav_controller.rb +143 -0
  22. data/app/controllers/knitkit/erp_app/desktop/website_section_controller.rb +116 -0
  23. data/app/controllers/knitkit/unauthorized_controller.rb +8 -0
  24. data/app/controllers/knitkit/website_sections_controller.rb +17 -0
  25. data/app/helpers/application_helper.rb +132 -0
  26. data/app/models/article.rb +14 -0
  27. data/app/models/blog.rb +21 -0
  28. data/app/models/comment.rb +24 -0
  29. data/app/models/content.rb +158 -0
  30. data/app/models/extensions/user.rb +5 -0
  31. data/app/models/published_element.rb +9 -0
  32. data/app/models/published_website.rb +118 -0
  33. data/app/models/theme.rb +239 -0
  34. data/app/models/website.rb +457 -0
  35. data/app/models/website_host.rb +3 -0
  36. data/app/models/website_inquiry.rb +11 -0
  37. data/app/models/website_inquiry_mailer.rb +12 -0
  38. data/app/models/website_nav.rb +17 -0
  39. data/app/models/website_nav_item.rb +21 -0
  40. data/app/models/website_section.rb +152 -0
  41. data/app/models/website_section_content.rb +4 -0
  42. data/app/views/knitkit/articles/index.html.erb +3 -0
  43. data/app/views/knitkit/articles/show.html.erb +4 -0
  44. data/app/views/knitkit/blogs/_add_comment.html.erb +28 -0
  45. data/app/views/knitkit/blogs/_comment.html.erb +8 -0
  46. data/app/views/knitkit/blogs/index.html.erb +51 -0
  47. data/app/views/knitkit/blogs/index.rss.builder +23 -0
  48. data/app/views/knitkit/blogs/show.html.erb +22 -0
  49. data/app/views/knitkit/unauthorized/index.html.erb +4 -0
  50. data/app/views/knitkit/website_sections/index.html.erb +6 -0
  51. data/app/views/layouts/knitkit/base.html.erb +59 -0
  52. data/app/views/menus/knitkit/_default_menu.html.erb +23 -0
  53. data/app/views/menus/knitkit/_default_section_menu.html.erb +27 -0
  54. data/app/views/menus/knitkit/_default_sub_menu.html.erb +45 -0
  55. data/app/views/menus/knitkit/_default_sub_section_menu.html.erb +49 -0
  56. data/app/views/shared/knitkit/_bread_crumb.html.erb +7 -0
  57. data/app/views/shared/knitkit/_footer.html.erb +3 -0
  58. data/app/views/website_inquiry_mailer/inquiry.erb +3 -0
  59. data/app/widgets/contact_us/base.rb +86 -0
  60. data/app/widgets/contact_us/javascript/contact_us.js +13 -0
  61. data/app/widgets/contact_us/views/_contact_form.html.erb +36 -0
  62. data/app/widgets/contact_us/views/error.html.erb +10 -0
  63. data/app/widgets/contact_us/views/index.html.erb +1 -0
  64. data/app/widgets/contact_us/views/layouts/base.html.erb +7 -0
  65. data/app/widgets/contact_us/views/success.html.erb +4 -0
  66. data/app/widgets/google_map/base.rb +48 -0
  67. data/app/widgets/google_map/javascript/google_map.js +174 -0
  68. data/app/widgets/google_map/views/index.html.erb +41 -0
  69. data/app/widgets/login/base.rb +61 -0
  70. data/app/widgets/login/javascript/login.js +162 -0
  71. data/app/widgets/login/views/index.html.erb +37 -0
  72. data/app/widgets/login/views/layouts/base.html.erb +14 -0
  73. data/app/widgets/login/views/login_header.html.erb +9 -0
  74. data/app/widgets/login/views/reset_password.html.erb +26 -0
  75. data/app/widgets/manage_profile/base.rb +327 -0
  76. data/app/widgets/manage_profile/javascript/manage_profile.js +11 -0
  77. data/app/widgets/manage_profile/views/_contact_information_form.html.erb +180 -0
  78. data/app/widgets/manage_profile/views/_password_form.html.erb +20 -0
  79. data/app/widgets/manage_profile/views/_user_information_form.html.erb +30 -0
  80. data/app/widgets/manage_profile/views/contact_type_in_use.html.erb +4 -0
  81. data/app/widgets/manage_profile/views/default_type_error.html.erb +5 -0
  82. data/app/widgets/manage_profile/views/error.html.erb +3 -0
  83. data/app/widgets/manage_profile/views/index.html.erb +46 -0
  84. data/app/widgets/manage_profile/views/layouts/base.html.erb +1 -0
  85. data/app/widgets/manage_profile/views/password_blank.html.erb +4 -0
  86. data/app/widgets/manage_profile/views/password_invalid.html.erb +4 -0
  87. data/app/widgets/manage_profile/views/password_success.html.erb +3 -0
  88. data/app/widgets/manage_profile/views/success.html.erb +3 -0
  89. data/app/widgets/reset_password/base.rb +42 -0
  90. data/app/widgets/reset_password/javascript/reset_password.js +13 -0
  91. data/app/widgets/reset_password/views/index.html.erb +31 -0
  92. data/app/widgets/reset_password/views/layouts/base.html.erb +1 -0
  93. data/app/widgets/search/base.rb +80 -0
  94. data/app/widgets/search/javascript/search.js +31 -0
  95. data/app/widgets/search/views/_search.html.erb +39 -0
  96. data/app/widgets/search/views/index.html.erb +3 -0
  97. data/app/widgets/search/views/layouts/base.html.erb +24 -0
  98. data/app/widgets/search/views/show.html.erb +48 -0
  99. data/app/widgets/signup/base.rb +72 -0
  100. data/app/widgets/signup/javascript/signup.js +13 -0
  101. data/app/widgets/signup/views/_signup_form.html.erb +36 -0
  102. data/app/widgets/signup/views/error.html.erb +11 -0
  103. data/app/widgets/signup/views/index.html.erb +1 -0
  104. data/app/widgets/signup/views/layouts/base.html.erb +7 -0
  105. data/app/widgets/signup/views/success.html.erb +4 -0
  106. data/config/environment.rb +0 -0
  107. data/config/routes.rb +41 -0
  108. data/db/data_migrations/20110509223702_add_publisher_role.rb +11 -0
  109. data/db/data_migrations/20110816153456_add_knitkit_application.rb +31 -0
  110. data/db/data_migrations/upgrade/20111011203718_create_paths_for_sections.rb +13 -0
  111. data/db/data_migrations/upgrade/20111216192114_add_secured_models_to_menu_items.rb +18 -0
  112. data/db/data_migrations/upgrade/20111216202819_set_contents_iid_to_permalink_where_null.rb +12 -0
  113. data/db/migrate/20110211002317_setup_knitkit.rb +259 -0
  114. data/db/migrate/upgrade/20111014190442_update_contents.rb +25 -0
  115. data/db/migrate/upgrade/20111014201502_add_published_by_to_published_elements.rb +22 -0
  116. data/db/migrate/upgrade/20111017133851_add_iid_to_section.rb +21 -0
  117. data/db/migrate/upgrade/20111027145006_add_in_menu_to_section.rb +19 -0
  118. data/lib/knitkit.rb +12 -0
  119. data/lib/knitkit/engine.rb +26 -0
  120. data/lib/knitkit/extensions.rb +18 -0
  121. data/lib/knitkit/extensions/action_controller/theme_support/acts_as_themed_controller.rb +88 -0
  122. data/lib/knitkit/extensions/active_record/acts_as_commentable.rb +28 -0
  123. data/lib/knitkit/extensions/active_record/acts_as_publishable.rb +38 -0
  124. data/lib/knitkit/extensions/active_record/theme_support/has_many_themes.rb +34 -0
  125. data/lib/knitkit/extensions/compass/widgets/base.rb +53 -0
  126. data/lib/knitkit/extensions/core/array.rb +5 -0
  127. data/lib/knitkit/extensions/railties/action_view.rb +187 -0
  128. data/lib/knitkit/extensions/railties/theme_support/asset_tag_helper.rb +198 -0
  129. data/lib/knitkit/extensions/railties/theme_support/theme_file_resolver.rb +44 -0
  130. data/lib/knitkit/routing_filter/section_router.rb +55 -0
  131. data/lib/knitkit/syntax_validator.rb +32 -0
  132. data/lib/knitkit/version.rb +3 -0
  133. data/lib/tasks/knitkit_tasks.rake +4 -0
  134. data/public/images/knitkit/bullet.png +0 -0
  135. data/public/images/knitkit/content.png +0 -0
  136. data/public/images/knitkit/footer.png +0 -0
  137. data/public/images/knitkit/graphic.png +0 -0
  138. data/public/images/knitkit/greyFadeDown.png +0 -0
  139. data/public/images/knitkit/link.png +0 -0
  140. data/public/images/knitkit/logo.png +0 -0
  141. data/public/images/knitkit/menu.png +0 -0
  142. data/public/images/knitkit/menu_select.png +0 -0
  143. data/public/images/knitkit/search.png +0 -0
  144. data/public/javascripts/datepicker.js +440 -0
  145. data/public/javascripts/erp_app/desktop/applications/knitkit/articles_grid_panel.js +473 -0
  146. data/public/javascripts/erp_app/desktop/applications/knitkit/center_region.js +576 -0
  147. data/public/javascripts/erp_app/desktop/applications/knitkit/comments_grid_panel.js +217 -0
  148. data/public/javascripts/erp_app/desktop/applications/knitkit/east_region.js +26 -0
  149. data/public/javascripts/erp_app/desktop/applications/knitkit/file_assets_panel.js +109 -0
  150. data/public/javascripts/erp_app/desktop/applications/knitkit/image_assets_data_view.js +30 -0
  151. data/public/javascripts/erp_app/desktop/applications/knitkit/image_assets_panel.js +160 -0
  152. data/public/javascripts/erp_app/desktop/applications/knitkit/inquiries_grid_panel.js +46 -0
  153. data/public/javascripts/erp_app/desktop/applications/knitkit/module.js +46 -0
  154. data/public/javascripts/erp_app/desktop/applications/knitkit/publish_window.js +92 -0
  155. data/public/javascripts/erp_app/desktop/applications/knitkit/published_grid_panel.js +220 -0
  156. data/public/javascripts/erp_app/desktop/applications/knitkit/section_articles_grid_panel.js +613 -0
  157. data/public/javascripts/erp_app/desktop/applications/knitkit/themes_tree_panel.js +573 -0
  158. data/public/javascripts/erp_app/desktop/applications/knitkit/versions_grid_panel.js +664 -0
  159. data/public/javascripts/erp_app/desktop/applications/knitkit/west_region.js +2161 -0
  160. data/public/javascripts/erp_app/desktop/applications/knitkit/widgets_panel.js +52 -0
  161. data/public/stylesheets/datepicker.css +121 -0
  162. data/public/stylesheets/erp_app/desktop/applications/knitkit/knitkit.css +114 -0
  163. data/public/stylesheets/extjs/resources/css/knitkit_extjs_4.css +219 -0
  164. data/public/stylesheets/knitkit/style.css +394 -0
  165. metadata +289 -0
@@ -0,0 +1,28 @@
1
+ module Knitkit
2
+ module Extensions
3
+ module ActiveRecord
4
+ module ActsAsCommentable
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def acts_as_commentable
12
+ has_many :comments, :as => :commented_record, :dependent => :destroy
13
+
14
+ extend ActsAsCommentable::SingletonMethods
15
+ include ActsAsCommentable::InstanceMethods
16
+ end
17
+
18
+ end
19
+
20
+ module SingletonMethods
21
+ end
22
+
23
+ module InstanceMethods
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ module Knitkit
2
+ module Extensions
3
+ module ActiveRecord
4
+ module ActsAsPublishable
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def can_be_published
12
+ after_destroy :destroy_published_elements
13
+
14
+ extend ActsAsPublishable::SingletonMethods
15
+ include ActsAsPublishable::InstanceMethods
16
+ end
17
+
18
+ end
19
+
20
+ module SingletonMethods
21
+ end
22
+
23
+ module InstanceMethods
24
+ def publish(site, comment, version, current_user)
25
+ site.publish_element(comment, self, version, current_user)
26
+ end
27
+
28
+ def destroy_published_elements
29
+ published_elements = PublishedElement.where('published_element_record_id = ? and (published_element_record_type = ? or published_element_record_type = ?)', self.id, self.class.to_s, self.class.superclass.to_s)
30
+ published_elements.each do |published_element|
31
+ published_element.destroy
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ module Knitkit
2
+ module Extensions
3
+ module ActiveRecord
4
+ module ThemeSupport
5
+ module HasManyThemes
6
+ def self.included(base)
7
+ base.extend ActMacro
8
+ end
9
+
10
+ module ActMacro
11
+ def has_many_themes(options = {})
12
+ return if has_many_themes?
13
+
14
+ has_many :themes, :dependent => :delete_all do
15
+ def active
16
+ find(:all, :conditions => 'active = 1')
17
+ end
18
+ end
19
+
20
+ include InstanceMethods # FIXME instead, check for the association being present
21
+ end
22
+
23
+ def has_many_themes?
24
+ included_modules.include?(Knitkit::Extensions::ActiveRecord::ThemeSupport::HasManyThemes::InstanceMethods)
25
+ end
26
+ end
27
+
28
+ module InstanceMethods
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ ::ErpApp::Widgets::Base.class_eval do
2
+ private
3
+
4
+ def add_view_paths
5
+ #set default view paths
6
+ cached_resolver = ErpApp::Widgets::Base.view_resolver_cache.find{|resolver| resolver.to_path == File.join(locate,"/views")}
7
+ if cached_resolver.nil?
8
+ resolver = ActionView::OptimizedFileSystemResolver.new(File.join(locate,"/views"))
9
+ prepend_view_path(resolver)
10
+ ErpApp::Widgets::Base.view_resolver_cache << resolver
11
+ else
12
+ prepend_view_path(cached_resolver)
13
+ end
14
+
15
+ #set overrides by themes
16
+ current_theme_paths.each do |theme|
17
+ resolver = case ErpTechSvcs::FileSupport.options[:storage]
18
+ when :s3
19
+ ErpTechSvcs::FileSupport::S3Manager.reload
20
+ path = "/#{theme[:url]}/widgets/#{self.name}"
21
+ cached_resolver = ErpApp::Widgets::Base.view_resolver_cache.find{|cached_resolver| cached_resolver.to_path == path}
22
+ if cached_resolver.nil?
23
+ resolver = ActionView::S3Resolver.new(path)
24
+ ErpApp::Widgets::Base.view_resolver_cache << resolver
25
+ resolver
26
+ else
27
+ cached_resolver
28
+ end
29
+ when :filesystem
30
+ path = "#{theme[:path]}/widgets/#{self.name}"
31
+ cached_resolver = ErpApp::Widgets::Base.view_resolver_cache.find{|cached_resolver| cached_resolver.to_path == path}
32
+ if cached_resolver.nil?
33
+ resolver = ActionView::ThemeFileResolver.new(path)
34
+ ErpApp::Widgets::Base.view_resolver_cache << resolver
35
+ resolver
36
+ else
37
+ cached_resolver
38
+ end
39
+ end
40
+ prepend_view_path(resolver)
41
+ end
42
+ end
43
+
44
+ def current_themes
45
+ @website = Website.find_by_host(request.host_with_port) if @website.nil?
46
+ @website.themes.active if @website
47
+ end
48
+
49
+ def current_theme_paths
50
+ current_themes ? current_themes.map { |theme| {:path => theme.path.to_s, :url => theme.url.to_s}} : []
51
+ end
52
+
53
+ end
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def to_path(sep = '/')
3
+ reject { |s| s.blank? }.join(sep)
4
+ end
5
+ end
@@ -0,0 +1,187 @@
1
+ ActionView::Base.class_eval do
2
+
3
+ def published_content_created_by
4
+ "by #{@published_content.content.created_by.username}" rescue ''
5
+ end
6
+
7
+ def blog_add_comment_form
8
+ render :partial => 'add_comment' unless current_user.nil?
9
+ end
10
+
11
+ def blog_topics(css_class='tag_link')
12
+ html = ''
13
+
14
+ @website_section.get_topics.each do |tag|
15
+ html += '<div class="'+css_class+'">'
16
+ html += link_to(tag.name, main_app.blog_tag_path(@website_section.id, tag.id))
17
+ html += '</div>'
18
+ end
19
+
20
+ raw html
21
+ end
22
+
23
+ def blog_rss_links(link_title='RSS Feed')
24
+ if params[:action] == 'tag'
25
+ return link_to link_title, main_app.blog_tag_url(params[:section_id], params[:tag_id], :rss)
26
+ else
27
+ return link_to link_title, main_app.blogs_url(params[:section_id], :rss)
28
+ end
29
+ end
30
+
31
+ def blog_recent_approved_comments
32
+ if @published_content.content.comments.recent.approved.empty?
33
+ return 'No Comments'
34
+ else
35
+ html = ''
36
+
37
+ @published_content.content.comments.recent.approved.each do |comment|
38
+ html += render :partial => 'comment', :locals => {:comment => comment}
39
+ end
40
+
41
+ return raw html
42
+ end
43
+ end
44
+
45
+ def blog_pagination(css_class, params)
46
+ return will_paginate @contents, :class => css_class, :params => {
47
+ :section_id => params[:section_id],
48
+ :per_page => params[:per_page],
49
+ :format => params[:format],
50
+ :only_path => true,
51
+ :use_route => params[:use_route],
52
+ :scope => main_app
53
+ }
54
+ end
55
+
56
+ # render a piece of content by internal identifier regardless if it belongs to a section or not
57
+ def render_content(iid)
58
+ content = Content.find_by_internal_identifier(iid)
59
+ content_version = Content.get_published_version(@active_publication, content)
60
+ raw content_version.body_html.nil? ? '' : content_version.body_html
61
+ end
62
+
63
+ def render_content_area(name)
64
+ html = ''
65
+
66
+ section_contents = WebsiteSectionContent.find(:all,
67
+ :joins => :content,
68
+ :conditions => {
69
+ :website_section_id => @website_section.id,
70
+ :content_area => name.to_s },
71
+ :order => :position )
72
+
73
+ published_contents = []
74
+ section_contents.each do |sc|
75
+ content_version = Content.get_published_version(@active_publication, sc.content)
76
+ published_contents << content_version unless content_version.nil?
77
+ end
78
+
79
+ published_contents.each do |content|
80
+ body_html = content.body_html.nil? ? '' : content.body_html
81
+ html << body_html
82
+ end
83
+
84
+ raw html
85
+ end
86
+
87
+ def render_version_viewing
88
+ html = ''
89
+
90
+ if !session[:website_version].blank? && !session[:website_version].empty?
91
+ site_version_hash = session[:website_version].find{|item| item[:website_id] == @website.id}
92
+ unless site_version_hash.nil?
93
+ if site_version_hash[:version].to_f != @website.active_publication.version
94
+ html = "<div style='float:left;'>Viewing version #{site_version_hash[:version].to_f} <a href='/view_current_publication'>View current publication</a></div>"
95
+ end
96
+ end
97
+ end
98
+
99
+ raw html
100
+ end
101
+
102
+ def menu_item_selected(menu_item)
103
+ result = false
104
+ result = request.path == menu_item.path
105
+ unless result
106
+ menu_item.descendants.each do |child|
107
+ result = request.path == child.path
108
+ break if result
109
+ end
110
+ end
111
+ result
112
+ end
113
+
114
+ #options
115
+ #nothing
116
+ # - uses current page to lookup section and go up tree
117
+ #menu
118
+ # - menu to look for menu title in
119
+ #menu_item
120
+ # - title of menu_item to start breadcrumbs at
121
+ #section_unique_name
122
+ # - sections permalink to start breadcrumbs at
123
+ def build_crumbs(options={})
124
+ links = []
125
+ if options[:menu]
126
+ menu = WebsiteNav.find_by_name(options[:menu])
127
+ raise "Menu with name #{options[:menu]} does not exist" if menu.nil?
128
+ menu_item = menu.website_nav_items.find(:first, :conditions => ["title = ?", options[:menu_item]])
129
+ raise "Menu Item with Title #{options[:menu]} does not exist" if menu_item.nil?
130
+ links = menu_item.self_and_ancestors.map{|child| {:url => child.path, :title => child.title}}
131
+ elsif options[:section_unique_name]
132
+ section = WebsiteSection.find_by_internal_identifier(options[:section_unique_name])
133
+ raise "Website Section with that unique name does not exist" if section.nil?
134
+ links = section.self_and_ancestors.map{|child| {:url => child.path, :title => child.title}}
135
+ else
136
+ links = @website_section.self_and_ancestors.collect{|child| {:url => child.path, :title => child.title}}
137
+ end
138
+ links
139
+
140
+ render :partial => 'shared/knitkit/bread_crumb', :locals => {:links => links}
141
+ end
142
+ #options
143
+ #menu
144
+ # - use a designed layout not sections
145
+ #layout
146
+ # - use defined layout
147
+ def render_menu(contents, options={})
148
+ locals = {:contents => contents}
149
+ if options[:menu]
150
+ menu = WebsiteNav.find_by_name_and_website_id(options[:menu], @website.id)
151
+ raise "Menu with name #{options[:menu]} does not exist" if menu.nil?
152
+ layout = options[:layout] ? "menus/#{options[:layout]}" : "menus/knitkit/default_menu"
153
+ locals[:menu_items] = menu.website_nav_items.positioned
154
+ else
155
+ layout = options[:layout] ? "menus/#{options[:layout]}" : "menus/knitkit/default_section_menu"
156
+ end
157
+
158
+ render :partial => layout, :locals => locals
159
+ end
160
+
161
+ #options
162
+ #menu
163
+ # - use a designed layout not sections
164
+ #menu_item
165
+ # - menu item title to start at
166
+ #section_unique_name
167
+ # - section to begin at
168
+ #layout
169
+ # - use defined layout
170
+ def render_sub_menu(contents, options={})
171
+ locals = {:contents => contents}
172
+ if options[:menu]
173
+ menu = WebsiteNav.find_by_name_and_website_id(options[:menu], @website.id)
174
+ raise "Menu with name #{options[:menu]} does not exist" if menu.nil?
175
+ locals[:menu_items] = (options[:menu_item].nil? ? menu.all_menu_items.find{|item| menu_item_selected(item)}.positioned_children : menu.all_menu_items.find{|item| item.title = options[:menu_item]}.positioned_children)
176
+ raise "No menu items exist" if locals[:menu_items].nil?
177
+ layout = options[:layout] ? "menus/#{options[:layout]}" : "menus/knitkit/default_sub_menu"
178
+ else
179
+ section = options[:section_unique_name].nil? ? @website_section : WebsiteSection.find_by_internal_identifier(options[:section_unique_name])
180
+ raise "No website sections exist" if section.nil?
181
+ locals[:section] = section
182
+ layout = options[:layout] ? "menus/#{options[:layout]}" : "menus/knitkit/default_sub_section_menu"
183
+ end
184
+
185
+ render :partial => layout, :locals => locals
186
+ end
187
+ end
@@ -0,0 +1,198 @@
1
+ # With http://github.com/rails/rails/commit/104898fcb7958bcb69ba0239d6de8aa37f2da9ba
2
+ # Rails edge (2.3) reverted all the nice oop changes that were introduced to
3
+ # asset_tag_helper in 2.2 ... so no point to code against the 2.2'ish API
4
+ # any more. Ok, let's instead overwrite everything. OMG ... suck, why does
5
+ # this so remind me of PHP.
6
+
7
+ require 'action_view/helpers/asset_tag_helper'
8
+
9
+ module ActionView
10
+ module Helpers
11
+ module AssetTagHelper
12
+ def theme_javascript_path(theme, source)
13
+ theme = controller.website.themes.find_by_theme_id(theme) unless theme.is_a?(Theme)
14
+ file = theme.files.where('name = ? and directory = ?', source, "/#{theme.url}/javascripts").first
15
+ file.nil? ? '' : file.data.url
16
+ end
17
+ alias_method :theme_path_to_javascript, :theme_javascript_path
18
+
19
+ def theme_javascript_include_tag(theme_id, *sources)
20
+ theme = controller.website.themes.find_by_theme_id(theme_id)
21
+ return("could not find theme with the id #{theme_id}") unless theme
22
+
23
+ options = sources.extract_options!.stringify_keys
24
+ cache = options.delete("cache")
25
+ recursive = options.delete("recursive")
26
+
27
+ if ActionController::Base.perform_caching && cache
28
+ joined_javascript_name = (cache == true ? "all" : cache) + ".js"
29
+ joined_javascript_path = File.join(theme.path + '/javascripts', joined_javascript_name)
30
+
31
+ paths = theme_compute_javascript_paths(theme, sources, recursive)
32
+ theme_write_asset_file_contents(theme, joined_javascript_path, paths) unless File.exists?(joined_javascript_path)
33
+ raw theme_javascript_src_tag(theme, joined_javascript_name, options)
34
+ else
35
+ sources = theme_expand_javascript_sources(theme, sources, recursive).collect do |source|
36
+ theme_javascript_src_tag(theme, source, options)
37
+ end.join("\n")
38
+ raw sources
39
+ end
40
+ end
41
+
42
+ def theme_stylesheet_path(theme, source)
43
+ theme = controller.website.themes.find_by_theme_id(theme) unless theme.is_a?(Theme)
44
+ file = theme.files.where('name = ? and directory = ?', source, "/#{theme.url}/stylesheets").first
45
+ file.nil? ? '' : file.data.url
46
+ end
47
+ alias_method :theme_path_to_stylesheet, :theme_stylesheet_path
48
+
49
+ def theme_stylesheet_link_tag(theme_id, *sources)
50
+ theme = controller.website.themes.find_by_theme_id(theme_id)
51
+ return("could not find theme with the id #{theme_id}") unless theme
52
+
53
+ options = sources.extract_options!.stringify_keys
54
+ cache = options.delete("cache")
55
+ recursive = options.delete("recursive")
56
+
57
+ if ActionController::Base.perform_caching && cache
58
+ joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
59
+ joined_stylesheet_path = File.join(theme.path + '/stylesheets', joined_stylesheet_name)
60
+
61
+ paths = theme_compute_stylesheet_paths(theme, sources, recursive)
62
+ theme_write_asset_file_contents(theme, joined_stylesheet_path, paths) unless File.exists?(joined_stylesheet_path)
63
+ raw theme_stylesheet_tag(theme, joined_stylesheet_name, options)
64
+ else
65
+ sources = theme_expand_stylesheet_sources(theme, sources, recursive).collect do |source|
66
+ theme_stylesheet_tag(theme, source, options)
67
+ end.join("\n")
68
+ raw sources
69
+ end
70
+ end
71
+
72
+ def theme_image_path(theme, source)
73
+ theme = controller.website.themes.find_by_theme_id(theme) unless theme.is_a?(Theme)
74
+ file = theme.files.where('name = ? and directory = ?', source, "/#{theme.url}/images").first
75
+ file.nil? ? '' : file.data.url
76
+ end
77
+ alias_method :theme_path_to_image, :theme_image_path # aliased to avoid conflicts with an image_path named route
78
+
79
+ def theme_image_tag(theme_id, source, options = {})
80
+ theme = controller.website.themes.find_by_theme_id(theme_id)
81
+ return("could not find theme with the id #{theme_id}") unless theme
82
+
83
+ options.symbolize_keys!
84
+ options[:src] = theme_path_to_image(theme, source)
85
+ options[:alt] ||= File.basename(options[:src], '.*').split('.').first.to_s.capitalize
86
+
87
+ if size = options.delete(:size)
88
+ options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
89
+ end
90
+
91
+ if mouseover = options.delete(:mouseover)
92
+ options[:onmouseover] = "this.src='#{theme_image_path(theme, mouseover)}'"
93
+ options[:onmouseout] = "this.src='#{theme_image_path(theme, options[:src])}'"
94
+ end
95
+
96
+ tag("img", options)
97
+ end
98
+
99
+ private
100
+ def theme_compute_public_path(theme, source, dir, ext = nil, include_host = true)
101
+ has_request = controller.respond_to?(:request)
102
+
103
+ if ext && (File.extname(source).blank? || File.exist?(File.join(theme.path, dir, "#{source}.#{ext}")))
104
+ source += ".#{ext}"
105
+ end
106
+
107
+ unless source =~ %r{^[-a-z]+://}
108
+ source = "/#{dir}/#{source}" unless source[0] == ?/
109
+
110
+ source = theme_rewrite_asset_path(theme, source)
111
+
112
+ if has_request && include_host
113
+ unless source =~ %r{^#{ActionController::Base.config.relative_url_root}/}
114
+ source = "#{ActionController::Base.config.relative_url_root}#{source}"
115
+ end
116
+ end
117
+ end
118
+
119
+ source
120
+ end
121
+
122
+ def theme_rails_asset_id(theme, source)
123
+ if asset_id = ENV["RAILS_ASSET_ID"]
124
+ asset_id
125
+ else
126
+ path = File.join(theme.path, source)
127
+ asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : ''
128
+ asset_id
129
+ end
130
+ end
131
+
132
+ def theme_rewrite_asset_path(theme, source)
133
+ asset_id = theme_rails_asset_id(theme, source)
134
+ if asset_id.blank?
135
+ source
136
+ else
137
+ source + "?#{asset_id}"
138
+ end
139
+ end
140
+
141
+ def theme_javascript_src_tag(theme, source, options)
142
+ options = { "type" => Mime::JS, "src" => theme_path_to_javascript(theme, source) }.merge(options)
143
+ content_tag("script", "", options)
144
+ end
145
+
146
+ def theme_stylesheet_tag(theme, source, options)
147
+ options = { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen",
148
+ "href" => html_escape(theme_path_to_stylesheet(theme, source)) }.merge(options)
149
+ tag("link", options, false, false)
150
+ end
151
+
152
+ def theme_compute_javascript_paths(theme, *args)
153
+ theme_expand_javascript_sources(theme, *args).collect do |source|
154
+ theme_compute_public_path(theme, source, theme.url + '/javascripts', 'js', false)
155
+ end
156
+ end
157
+
158
+ def theme_compute_stylesheet_paths(theme, *args)
159
+ theme_expand_stylesheet_sources(theme, *args).collect do |source|
160
+ theme_compute_public_path(theme, source, theme.url + '/stylesheets', 'css', false)
161
+ end
162
+ end
163
+
164
+ def theme_expand_javascript_sources(theme, sources, recursive = false)
165
+ if sources.include?(:all)
166
+ all_javascript_files = collect_asset_files(theme.path + '/javascripts', ('**' if recursive), '*.js').uniq
167
+ else
168
+ sources.flatten
169
+ end
170
+ end
171
+
172
+ def theme_expand_stylesheet_sources(theme, sources, recursive)
173
+ if sources.first == :all
174
+ collect_asset_files(theme.path + '/stylesheets', ('**' if recursive), '*.css')
175
+ else
176
+ sources.flatten
177
+ end
178
+ end
179
+
180
+ def theme_write_asset_file_contents(theme, joined_asset_path, asset_paths)
181
+ FileUtils.mkdir_p(File.dirname(joined_asset_path))
182
+ File.open(joined_asset_path, "w+") do |cache|
183
+ cache.write(theme_join_asset_file_contents(theme, asset_paths))
184
+ end
185
+ mt = asset_paths.map { |p| File.mtime(theme_asset_file_path(theme, p)) }.max
186
+ File.utime(mt, mt, joined_asset_path)
187
+ end
188
+
189
+ def theme_join_asset_file_contents(theme, paths)
190
+ paths.collect { |path| File.read(theme_asset_file_path(theme, path)) }.join("\n\n")
191
+ end
192
+
193
+ def theme_asset_file_path(theme, path)
194
+ File.join(Theme.root_dir, path.split('?').first)
195
+ end
196
+ end
197
+ end
198
+ end