knitkit 2.0.0

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 (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