alchemy_cms 2.4.1 → 2.5.0.b2

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 (163) hide show
  1. data/.travis.yml +1 -1
  2. data/README.md +18 -17
  3. data/alchemy_cms.gemspec +5 -10
  4. data/app/assets/images/alchemy/icons.png +0 -0
  5. data/app/assets/stylesheets/alchemy/archive.scss +27 -0
  6. data/app/assets/stylesheets/alchemy/base.scss +0 -51
  7. data/app/assets/stylesheets/alchemy/elements.scss +37 -2
  8. data/app/assets/stylesheets/alchemy/icons.scss +4 -0
  9. data/app/assets/stylesheets/alchemy/modules.scss +4 -0
  10. data/app/assets/stylesheets/alchemy/sitemap.scss +1 -1
  11. data/app/assets/stylesheets/alchemy/tables.scss +1 -1
  12. data/app/assets/stylesheets/alchemy/variables.scss +1 -0
  13. data/app/controllers/alchemy/admin/pages_controller.rb +1 -0
  14. data/app/controllers/alchemy/admin/pictures_controller.rb +22 -8
  15. data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
  16. data/app/controllers/alchemy/admin/sites_controller.rb +6 -0
  17. data/app/controllers/alchemy/base_controller.rb +8 -0
  18. data/app/controllers/alchemy/elements_controller.rb +33 -3
  19. data/app/controllers/alchemy/messages_controller.rb +47 -40
  20. data/app/controllers/alchemy/pages_controller.rb +8 -31
  21. data/app/controllers/alchemy/pictures_controller.rb +64 -30
  22. data/app/helpers/alchemy/admin/base_helper.rb +7 -0
  23. data/app/helpers/alchemy/admin/pages_helper.rb +12 -0
  24. data/app/helpers/alchemy/elements_helper.rb +2 -0
  25. data/app/helpers/alchemy/pages_helper.rb +30 -10
  26. data/app/helpers/alchemy/url_helper.rb +1 -0
  27. data/app/models/alchemy/content.rb +1 -2
  28. data/app/models/alchemy/element.rb +47 -2
  29. data/app/models/alchemy/language.rb +27 -14
  30. data/app/models/alchemy/page.rb +1 -1
  31. data/app/models/alchemy/picture.rb +46 -41
  32. data/app/models/alchemy/site.rb +44 -0
  33. data/app/views/alchemy/admin/elements/_element_head.html.erb +1 -0
  34. data/app/views/alchemy/admin/languages/index.html.erb +23 -0
  35. data/app/views/alchemy/admin/pages/edit.html.erb +27 -1
  36. data/app/views/alchemy/admin/pages/fold.js.erb +1 -0
  37. data/app/views/alchemy/admin/partials/_upload_form.html.erb +2 -0
  38. data/app/views/alchemy/admin/pictures/_picture.html.erb +24 -2
  39. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +5 -4
  40. data/app/views/alchemy/admin/pictures/create.js.erb +1 -9
  41. data/app/views/alchemy/admin/pictures/info.html.erb +42 -0
  42. data/app/views/alchemy/admin/resources/_form.html.erb +0 -2
  43. data/app/views/alchemy/admin/resources/_resource.html.erb +2 -1
  44. data/app/views/alchemy/admin/resources/index.html.erb +2 -1
  45. data/app/views/alchemy/elements/show.html.erb +1 -6
  46. data/app/views/alchemy/elements/show.js.erb +4 -10
  47. data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -0
  48. data/app/views/alchemy/search/_form.html.erb +9 -6
  49. data/app/views/alchemy/search/_result.html.erb +1 -1
  50. data/bin/alchemy +13 -120
  51. data/config/alchemy/config.yml +7 -11
  52. data/config/alchemy/modules.yml +24 -12
  53. data/config/authorization_rules.rb +6 -2
  54. data/config/initializers/dragonfly.rb +20 -0
  55. data/config/locales/alchemy.de.yml +57 -28
  56. data/config/locales/alchemy.en.yml +18 -4
  57. data/config/routes.rb +4 -2
  58. data/db/migrate/20121121162313_switch_from_fleximage_to_dragonfly.rb +21 -0
  59. data/db/migrate/20121205155004_create_alchemy_sites.rb +14 -0
  60. data/db/migrate/20121211163003_add_public_to_alchemy_sites.rb +6 -0
  61. data/lib/alchemy/capistrano.rb +7 -2
  62. data/lib/alchemy/ferret_search.rb +84 -0
  63. data/lib/alchemy/picture_attributes.rb +29 -0
  64. data/lib/alchemy/seeder.rb +10 -16
  65. data/lib/alchemy/upgrader.rb +59 -8
  66. data/lib/alchemy/version.rb +1 -1
  67. data/lib/alchemy_cms.rb +7 -4
  68. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +3 -0
  69. data/lib/rails/generators/alchemy/elements/elements_generator.rb +5 -1
  70. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +1 -0
  71. data/lib/rails/generators/alchemy/scaffold/files/{pages.html.erb → application.html.erb} +0 -0
  72. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +11 -20
  73. data/lib/rails/templates/alchemy.rb +1 -7
  74. data/lib/tasks/{database.rake → alchemy/db.rake} +1 -1
  75. data/lib/tasks/{install.rake → alchemy/install.rake} +9 -14
  76. data/lib/tasks/{upgrade.rake → alchemy/upgrade.rake} +1 -1
  77. data/spec/controllers/elements_controller_spec.rb +24 -9
  78. data/spec/controllers/pictures_controller_spec.rb +11 -8
  79. data/{app → spec/dummy/app}/views/alchemy/elements/_article_editor.html.erb +0 -0
  80. data/{app → spec/dummy/app}/views/alchemy/elements/_article_view.html.erb +0 -0
  81. data/{app → spec/dummy/app}/views/alchemy/elements/_headline_view.html.erb +0 -0
  82. data/{app → spec/dummy/app}/views/alchemy/elements/_news_view.html.erb +0 -0
  83. data/{app → spec/dummy/app}/views/alchemy/elements/_searchresult_view.html.erb +0 -0
  84. data/{app → spec/dummy/app}/views/alchemy/page_layouts/_standard.html.erb +0 -0
  85. data/spec/dummy/config/alchemy/elements.yml +86 -0
  86. data/spec/dummy/config/alchemy/page_layouts.yml +26 -0
  87. data/spec/dummy/config/application.rb +1 -1
  88. data/spec/dummy/db/migrate/20121121162313_switch_from_fleximage_to_dragonfly.rb +21 -0
  89. data/spec/dummy/db/migrate/20121205155004_create_alchemy_sites.rb +14 -0
  90. data/spec/dummy/db/migrate/20121211163003_add_public_to_alchemy_sites.rb +6 -0
  91. data/spec/dummy/db/schema.rb +21 -6
  92. data/spec/factories.rb +6 -2
  93. data/spec/integration/translation_integration_spec.rb +4 -18
  94. data/spec/models/element_spec.rb +4 -4
  95. data/spec/models/picture_spec.rb +37 -20
  96. data/spec/models/site_spec.rb +69 -0
  97. data/spec/routing_spec.rb +115 -115
  98. data/spec/spec_helper.rb +1 -3
  99. data/spec/support/alchemy/specs_helpers.rb +4 -4
  100. data/vendor/assets/javascripts/jquery_plugins/jquery.html5uploader.js +1 -1
  101. metadata +72 -96
  102. data/app/assets/stylesheets/alchemy/standard_set.css +0 -440
  103. data/app/views/alchemy/elements/_bild_editor.html.erb +0 -1
  104. data/app/views/alchemy/elements/_bild_text_editor.html.erb +0 -7
  105. data/app/views/alchemy/elements/_bild_text_view.html.erb +0 -9
  106. data/app/views/alchemy/elements/_bild_view.html.erb +0 -9
  107. data/app/views/alchemy/elements/_claim_editor.html.erb +0 -1
  108. data/app/views/alchemy/elements/_claim_view.html.erb +0 -1
  109. data/app/views/alchemy/elements/_contactform_editor.html.erb +0 -4
  110. data/app/views/alchemy/elements/_contactform_view.html.erb +0 -78
  111. data/app/views/alchemy/elements/_download_editor.html.erb +0 -4
  112. data/app/views/alchemy/elements/_download_view.html.erb +0 -7
  113. data/app/views/alchemy/elements/_footnote_editor.html.erb +0 -1
  114. data/app/views/alchemy/elements/_footnote_view.html.erb +0 -5
  115. data/app/views/alchemy/elements/_header_editor.html.erb +0 -1
  116. data/app/views/alchemy/elements/_header_view.html.erb +0 -1
  117. data/app/views/alchemy/elements/_headline_editor.html.erb +0 -1
  118. data/app/views/alchemy/elements/_image_mosaic_editor.html.erb +0 -3
  119. data/app/views/alchemy/elements/_image_mosaic_view.html.erb +0 -14
  120. data/app/views/alchemy/elements/_intro_editor.html.erb +0 -1
  121. data/app/views/alchemy/elements/_intro_image_text_editor.html.erb +0 -3
  122. data/app/views/alchemy/elements/_intro_image_text_view.html.erb +0 -16
  123. data/app/views/alchemy/elements/_intro_view.html.erb +0 -3
  124. data/app/views/alchemy/elements/_news_editor.html.erb +0 -3
  125. data/app/views/alchemy/elements/_searchresult_editor.html.erb +0 -4
  126. data/app/views/alchemy/elements/_sitemap_editor.html.erb +0 -3
  127. data/app/views/alchemy/elements/_sitemap_view.html.erb +0 -38
  128. data/app/views/alchemy/elements/_sitename_editor.html.erb +0 -1
  129. data/app/views/alchemy/elements/_sitename_view.html.erb +0 -1
  130. data/app/views/alchemy/elements/_subheadline_editor.html.erb +0 -1
  131. data/app/views/alchemy/elements/_subheadline_view.html.erb +0 -5
  132. data/app/views/alchemy/elements/_text_editor.html.erb +0 -1
  133. data/app/views/alchemy/elements/_text_view.html.erb +0 -3
  134. data/app/views/alchemy/page_layouts/_contact.html.erb +0 -14
  135. data/app/views/alchemy/page_layouts/_external.html.erb +0 -0
  136. data/app/views/alchemy/page_layouts/_intro.html.erb +0 -14
  137. data/app/views/alchemy/page_layouts/_layout_footer.html.erb +0 -14
  138. data/app/views/alchemy/page_layouts/_layout_header.html.erb +0 -14
  139. data/app/views/alchemy/page_layouts/_news.html.erb +0 -14
  140. data/app/views/alchemy/page_layouts/_newsletter_layout.html.erb +0 -1
  141. data/app/views/alchemy/page_layouts/_search.html.erb +0 -14
  142. data/app/views/alchemy/pictures/show.gif.flexi +0 -19
  143. data/app/views/alchemy/pictures/show.jpg.flexi +0 -19
  144. data/app/views/alchemy/pictures/show.png.flexi +0 -19
  145. data/app/views/alchemy/pictures/thumbnail.png.flexi +0 -13
  146. data/app/views/alchemy/pictures/zoom.jpg.flexi +0 -3
  147. data/app/views/alchemy/pictures/zoom.png.flexi +0 -3
  148. data/app/views/layouts/alchemy/pages.html.erb +0 -51
  149. data/config/alchemy/elements.yml +0 -274
  150. data/config/alchemy/page_layouts.yml +0 -75
  151. data/config/asset_packages.yml +0 -30
  152. data/config/initializers/localeapp.rb +0 -9
  153. data/lib/rails/generators/alchemy/plugin/files/translation.pot +0 -3
  154. data/lib/rails/generators/alchemy/plugin/files/translation_de.po +0 -3
  155. data/lib/rails/generators/alchemy/plugin/files/translation_en.po +0 -3
  156. data/lib/rails/generators/alchemy/plugin/plugin_generator.rb +0 -37
  157. data/lib/rails/generators/alchemy/plugin/templates/authorization_rules.rb +0 -34
  158. data/lib/rails/generators/alchemy/plugin/templates/config.yml +0 -30
  159. data/lib/rails/generators/alchemy/plugin/templates/init.rb +0 -1
  160. data/lib/rails/generators/alchemy/plugin/templates/plugin.rb +0 -0
  161. data/lib/rails/generators/alchemy/plugin/templates/routes.rb +0 -10
  162. data/lib/tasks/fleximage.rake +0 -154
  163. data/spec/dummy/app/views/layouts/.gitkeep +0 -0
@@ -14,7 +14,7 @@ module Alchemy
14
14
  else
15
15
  search_terms = ActiveRecord::Base.sanitize("%#{params[:query]}%")
16
16
  items = resource_handler.model.where(resource_handler.searchable_attributes.map { |attribute|
17
- "#{resource_handler.namespaced_model_name.pluralize}.#{attribute[:name]} LIKE #{search_terms}"
17
+ "`#{resource_handler.model.table_name}`.`#{attribute[:name]}` LIKE #{search_terms}"
18
18
  }.join(" OR "))
19
19
  end
20
20
  instance_variable_set("@#{resource_handler.resources_name}", items.page(params[:page] || 1).per(per_page_value_for_screen_size))
@@ -0,0 +1,6 @@
1
+ module Alchemy
2
+ module Admin
3
+ class SitesController < ResourcesController
4
+ end
5
+ end
6
+ end
@@ -6,6 +6,7 @@ module Alchemy
6
6
 
7
7
  protect_from_forgery
8
8
 
9
+ before_filter :set_current_site
9
10
  before_filter :set_language
10
11
  before_filter :mailer_set_url_options
11
12
 
@@ -45,6 +46,11 @@ module Alchemy
45
46
 
46
47
  private
47
48
 
49
+ # Sets the current site.
50
+ def set_current_site
51
+ Site.current = Site.where(host: request.host).first || Site.default
52
+ end
53
+
48
54
  # Sets Alchemy's GUI translation to users preffered language and stores it in the session.
49
55
  #
50
56
  # Guesses the language from browser locale. If not successful it takes the default.
@@ -60,6 +66,8 @@ module Alchemy
60
66
  session[:current_locale] = ::I18n.locale = params[:locale]
61
67
  elsif current_user && current_user.language.present?
62
68
  ::I18n.locale = current_user.language
69
+ elsif Rails.env == 'test' # OMG I hate to do this. But it helps...
70
+ ::I18n.locale = 'en'
63
71
  else
64
72
  ::I18n.locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first)
65
73
  end
@@ -4,19 +4,49 @@ module Alchemy
4
4
  filter_access_to :show, :attribute_check => true, :model => Alchemy::Element, :load_method => :load_element
5
5
  layout false
6
6
 
7
- # Returns the element partial as HTML or as JavaScript that tries to replace a given +container_id+ with the partial content via jQuery.
7
+ # == Renders the element view partial
8
+ #
9
+ # === Accepted Formats
10
+ #
11
+ # * html
12
+ # * js (Tries to replace a given +container_id+ with the elements view partial content via jQuery.)
13
+ # * json (A JSON object that includes all contents and their ingredients)
14
+ #
8
15
  def show
9
16
  @page = @element.page
17
+ @options = params[:options]
18
+
10
19
  respond_to do |format|
11
20
  format.html
12
- format.js
21
+ format.js { @container_id = params[:container_id] }
22
+ format.json do
23
+ render json: @element.to_json(
24
+ only: [:id, :name, :updated_at],
25
+ methods: [:tag_list],
26
+ include: {
27
+ contents: {
28
+ only: [:id, :name, :updated_at, :essence_type],
29
+ methods: [:ingredient],
30
+ include: {
31
+ essence: {
32
+ except: [:created_at, :creator_id, :do_not_index, :public, :updater_id]
33
+ }
34
+ }
35
+ }
36
+ }
37
+ )
38
+ end
13
39
  end
14
40
  end
15
41
 
16
42
  private
17
43
 
18
44
  def load_element
19
- @element = Element.find(params[:id])
45
+ element = Element.available
46
+ if !current_user
47
+ element = element.not_restricted
48
+ end
49
+ @element = element.find(params[:id])
20
50
  end
21
51
 
22
52
  end
@@ -1,44 +1,48 @@
1
- # == Sending Messages:
2
- # To send Messages via contact forms you can create your form fields in the config.yml
3
- #
4
- # === Example:
5
- # Make an Element with this options inside your @elements.yml file:
6
- #
7
- # - name: contactform
8
- # contents:
9
- # - name: mail_to
10
- # type: EssenceText
11
- # - name: subject
12
- # type: EssenceText
13
- # - name: mail_from
14
- # type: EssenceText
15
- # - name: success_page
16
- # type: EssenceText
17
- #
18
- # The fields +mail_to+, +mail_from+, +subject+ and +success_page+ are recommended.
19
- # The +Alchemy::MessagesController+ uses them to send your mails. So your customer has full controll of these values inside his contactform element.
20
- #
21
- # Then make a page layout for your contact page in the +page_layouts.yml+ file:
22
- #
23
- # - name: contact
24
- # unique: true
25
- # cache: false
26
- # elements: [pageheading, heading, contactform]
27
- # autogenerate: [contactform]
28
- #
29
- # Disabling the page caching is stronlgy recommended!
30
- #
31
- # The editor view for your element should have this layout:
32
- #
33
- # <%= render_essence_editor_by_name(element, 'mail_from') %>
34
- # <%= render_essence_editor_by_name(element, 'mail_to') %>
35
- # <%= render_essence_editor_by_name(element, 'subject') %>
36
- # <%= page_selector(element, 'success_page', :page_attribute => :urlname) %>
37
- #
38
- # Please have a look at the +alchemy/config/config.yml+ file for further Message settings.
39
-
40
1
  module Alchemy
2
+ #
3
+ # == Sending Messages:
4
+ #
5
+ # To send Messages via contact forms you can create your form fields in the config.yml
6
+ #
7
+ # === Example:
8
+ #
9
+ # Make an Element with this options inside your @elements.yml file:
10
+ #
11
+ # - name: contactform
12
+ # contents:
13
+ # - name: mail_to
14
+ # type: EssenceText
15
+ # - name: subject
16
+ # type: EssenceText
17
+ # - name: mail_from
18
+ # type: EssenceText
19
+ # - name: success_page
20
+ # type: EssenceText
21
+ #
22
+ # The fields +mail_to+, +mail_from+, +subject+ and +success_page+ are recommended.
23
+ # The +Alchemy::MessagesController+ uses them to send your mails. So your customer has full controll of these values inside his contactform element.
24
+ #
25
+ # Then make a page layout for your contact page in the +page_layouts.yml+ file:
26
+ #
27
+ # - name: contact
28
+ # unique: true
29
+ # cache: false
30
+ # elements: [pageheading, heading, contactform]
31
+ # autogenerate: [contactform]
32
+ #
33
+ # Disabling the page caching is stronlgy recommended!
34
+ #
35
+ # The editor view for your element should have this layout:
36
+ #
37
+ # <%= render_essence_editor_by_name(element, 'mail_from') %>
38
+ # <%= render_essence_editor_by_name(element, 'mail_to') %>
39
+ # <%= render_essence_editor_by_name(element, 'subject') %>
40
+ # <%= page_selector(element, 'success_page', :page_attribute => :urlname) %>
41
+ #
42
+ # Please have a look at the +alchemy/config/config.yml+ file for further Message settings.
43
+ #
41
44
  class MessagesController < Alchemy::BaseController
45
+ include Alchemy::FerretSearch
42
46
 
43
47
  before_filter :get_page, :except => :create
44
48
 
@@ -57,6 +61,9 @@ module Alchemy
57
61
  @message = Message.new(params[:message])
58
62
  @message.ip = request.remote_ip
59
63
  @element = Element.find_by_id(@message.contact_form_id)
64
+ if @element.nil?
65
+ raise ActiveRecord::RecordNotFound, "Contact form id not found. Please pass the :contact_form_id in a hidden field. Example: <%= f.hidden_field :contact_form_id, :value => element.id %>"
66
+ end
60
67
  @page = @element.page
61
68
  @root_page = @page.get_language_root
62
69
  if @message.valid?
@@ -67,7 +74,7 @@ module Alchemy
67
74
  end
68
75
  end
69
76
 
70
- private
77
+ private
71
78
 
72
79
  def mailer_config
73
80
  Alchemy::Config.get(:mailer)
@@ -1,7 +1,6 @@
1
1
  module Alchemy
2
2
  class PagesController < Alchemy::BaseController
3
-
4
- rescue_from ActionController::RoutingError, :with => :render_404
3
+ include Alchemy::FerretSearch
5
4
 
6
5
  # We need to include this helper because we need the breadcrumb method.
7
6
  # And we cannot define the breadcrump method as helper_method, because rspec does not see helper_methods.
@@ -9,6 +8,8 @@ module Alchemy
9
8
  # Anyone with a better idea please provide a patch.
10
9
  include Alchemy::BaseHelper
11
10
 
11
+ rescue_from ActionController::RoutingError, :with => :render_404
12
+
12
13
  before_filter :render_page_or_redirect, :only => [:show, :sitemap]
13
14
  before_filter :perform_search, :only => :show, :if => proc { configuration(:ferret) }
14
15
 
@@ -18,8 +19,10 @@ module Alchemy
18
19
  :cache_path => proc { @page.cache_key(request) },
19
20
  :if => proc {
20
21
  if @page && Alchemy::Config.get(:cache_pages)
21
- pagelayout = PageLayout.get(@page.page_layout)
22
- pagelayout['cache'].nil? || pagelayout['cache']
22
+ pagelayout = PageLayout.get(@page.page_layout)
23
+ if (pagelayout['cache'].nil? || pagelayout['cache']) && pagelayout['searchresults'] != true
24
+ true
25
+ end
23
26
  else
24
27
  false
25
28
  end
@@ -62,7 +65,7 @@ module Alchemy
62
65
  @page = Page.language_root_for(Language.get_default.id)
63
66
  else
64
67
  if params[:lang].blank?
65
- @page = Page.contentpages.find_by_urlname(params[:urlname])
68
+ @page = Page.contentpages.where(urlname: params[:urlname], language_id: Language.get_default).first
66
69
  store_language_in_session(@page.language) if @page.present?
67
70
  return @page
68
71
  else
@@ -110,32 +113,6 @@ module Alchemy
110
113
  end
111
114
  end
112
115
 
113
- # Performs a search on EssenceRichtext and EssenceText for params['query'].
114
- # Only performing the search when ferret is enabled in the alchemy/config.yml and
115
- # a Page gets found where the searchresults can be rendered. This Page gets found
116
- # when a page_layout is marked for rendering searchresults:
117
- # 'searchresults: true' in alchemy/page_layouts.yml
118
- def perform_search
119
- searchresult_page_layouts = PageLayout.get_all_by_attributes({:searchresults => true})
120
- if searchresult_page_layouts.any?
121
- @search_result_page = Page.find_by_page_layout_and_public_and_language_id(searchresult_page_layouts.first["name"], true, session[:language_id])
122
- if !params[:query].blank? && @search_result_page
123
- @search_results = []
124
- %w(Alchemy::EssenceText Alchemy::EssenceRichtext).each do |e|
125
- @search_results += e.constantize.includes(:contents => {:element => :page}).find_with_ferret(
126
- "*#{params[:query]}*",
127
- {:limit => :all},
128
- {:conditions => [
129
- 'alchemy_pages.public = ? AND alchemy_pages.layoutpage = ? AND alchemy_pages.restricted = ? AND alchemy_pages.language_id = ?',
130
- true, false, false, session[:language_id]
131
- ]}
132
- )
133
- end
134
- return @search_results.sort { |y, x| x.ferret_score <=> y.ferret_score } if @search_results.any?
135
- end
136
- end
137
- end
138
-
139
116
  def redirect_to_public_child
140
117
  @page = @page.self_and_descendants.published.not_restricted.first
141
118
  if @page
@@ -1,6 +1,8 @@
1
1
  module Alchemy
2
2
  class PicturesController < Alchemy::BaseController
3
3
 
4
+ ALLOWED_IMAGE_TYPES = %w(png jpeg gif)
5
+
4
6
  caches_page :show, :thumbnail, :zoom
5
7
 
6
8
  before_filter :load_picture, :ensure_secure_params
@@ -9,42 +11,60 @@ module Alchemy
9
11
  filter_access_to :thumbnail
10
12
 
11
13
  def show
12
- @size = params[:size]
13
- @crop = !params[:crop].nil?
14
- @crop_from = normalized_size(params[:crop_from])
15
- @crop_size = params[:crop_size]
16
- @padding = params[:padding]
17
- @upsample = !params[:upsample].nil? ? true : false
18
- @effects = params[:effects]
19
- respond_to do |format|
20
- format.jpg
21
- format.png
22
- format.gif
14
+ image_file = @picture.image_file
15
+
16
+ if image_file.nil?
17
+ raise MissingImageFileError, "Missing image file for #{@picture.inspect}"
18
+ end
19
+
20
+ upsample = params[:upsample] == 'true'
21
+ crop_from = normalized_size(params[:crop_from])
22
+ crop_size = params[:crop_size]
23
+ size = params[:size]
24
+
25
+ if params[:crop_size].present? && params[:crop_from].present?
26
+ crop_from = params[:crop_from].split('x')
27
+ image_file = image_file.process(:thumb, "#{params[:crop_size]}+#{crop_from[0]}+#{crop_from[1]}")
28
+ elsif params[:crop] == 'crop' && size.present?
29
+ image_file = image_file.process(:thumb, "#{size}#")
23
30
  end
31
+
32
+ if size.present?
33
+ image_file = image_file.process(:resize, size + '>')
34
+ end
35
+
36
+ respond_to { |format| send_image(image_file, format) }
24
37
  end
25
38
 
26
39
  def thumbnail
40
+ image_file = @picture.image_file
41
+
27
42
  case params[:size]
28
- when "small"
29
- @size = "80x60"
30
- when "medium"
31
- @size = "160x120"
32
- when "large"
33
- @size = "240x180"
34
- when nil
35
- @size = "111x93"
43
+ when "small" then size = "80x60"
44
+ when "medium" then size = "160x120"
45
+ when "large" then size = "240x180"
46
+ when nil then size = "111x93"
36
47
  else
37
- @size = params[:size]
48
+ size = params[:size]
38
49
  end
39
- if !params[:crop_size].blank? && !params[:crop_from].blank?
40
- @crop = true
41
- elsif params[:crop] == 'crop'
42
- @default_crop = true
50
+
51
+ if params[:crop_size].present? && params[:crop_from].present?
52
+ crop_from = params[:crop_from].split('x')
53
+ image_file = image_file.process(:thumb, "#{params[:crop_size]}+#{crop_from[0]}+#{crop_from[1]}")
54
+ elsif params[:crop] == 'crop' && size.present?
55
+ image_file = image_file.process(:thumb, "#{size}#")
43
56
  end
57
+
58
+ if size.present?
59
+ image_file = image_file.process(:resize, size + '>')
60
+ end
61
+
62
+ respond_to { |format| send_image(image_file, format) }
44
63
  end
45
64
 
46
65
  def zoom
47
- #
66
+ image_file = @picture.image_file
67
+ respond_to { |format| send_image(image_file, format) }
48
68
  end
49
69
 
50
70
  private
@@ -62,18 +82,32 @@ module Alchemy
62
82
 
63
83
  def ensure_secure_params
64
84
  token = params[:sh]
65
- digest = Digest::SHA1.hexdigest(secured_params)[0..15]
85
+ digest = PictureAttributes.secure(params)
66
86
  bad_request unless token && (token == digest)
67
87
  end
68
88
 
69
- def secured_params
70
- [params[:id], params[:size], params[:crop], params[:crop_from], params[:crop_size], Rails.configuration.secret_token].join('-')
71
- end
72
-
73
89
  def bad_request
74
90
  render :text => "Bad picture parameters in #{request.path}", :status => 400
75
91
  return false
76
92
  end
77
93
 
94
+ def send_image(image_file, format)
95
+ ALLOWED_IMAGE_TYPES.each do |type|
96
+ format.send(type) do
97
+ if type == "jpeg"
98
+ quality = params[:quality] || Config.get(:output_image_jpg_quality)
99
+ image_file = image_file.encode(type, "-quality #{quality}")
100
+ else
101
+ image_file = image_file.encode(type)
102
+ end
103
+ render :text => image_file.data
104
+ end
105
+ end
106
+ end
107
+
78
108
  end
109
+
110
+ class MissingImageFileError < StandardError
111
+ end
112
+
79
113
  end
@@ -539,6 +539,13 @@ module Alchemy
539
539
  taglist.uniq.join(',')
540
540
  end
541
541
 
542
+ def render_hint_for(element)
543
+ return unless element.has_hint?
544
+ link_to '#', :class => 'element_hint' do
545
+ render_icon(:hint) + content_tag(:span, element.hint, :class => 'bubble')
546
+ end
547
+ end
548
+
542
549
  end
543
550
  end
544
551
  end
@@ -81,6 +81,18 @@ module Alchemy
81
81
  custom_config_string.html_safe
82
82
  end
83
83
 
84
+ def preview_sizes_for_select
85
+ options_for_select([
86
+ 'auto',
87
+ [t('240', :scope => 'preview_sizes'), 240],
88
+ [t('320', :scope => 'preview_sizes'), 320],
89
+ [t('480', :scope => 'preview_sizes'), 480],
90
+ [t('768', :scope => 'preview_sizes'), 768],
91
+ [t('1024', :scope => 'preview_sizes'), 1024],
92
+ [t('1280', :scope => 'preview_sizes'), 1280]
93
+ ])
94
+ end
95
+
84
96
  end
85
97
  end
86
98
  end
@@ -2,6 +2,8 @@ module Alchemy
2
2
  module ElementsHelper
3
3
 
4
4
  include Alchemy::EssencesHelper
5
+ include Alchemy::UrlHelper
6
+ include Alchemy::ElementsBlockHelper
5
7
 
6
8
  # Renders all elements from current page.
7
9
  #