alchemy_cms 2.4.1 → 2.5.0.b2

Sign up to get free protection for your applications and to get access to all the features.
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
  #