locomotivecms_steam 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +19 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +188 -0
  7. data/LICENSE +20 -0
  8. data/README.md +36 -0
  9. data/Rakefile +17 -0
  10. data/bin/publish +28 -0
  11. data/config/locales/de.yml +157 -0
  12. data/config/locales/en.yml +189 -0
  13. data/config/locales/es.yml +133 -0
  14. data/config/locales/et.yml +154 -0
  15. data/config/locales/fr.yml +148 -0
  16. data/config/locales/it.yml +155 -0
  17. data/config/locales/nb.yml +191 -0
  18. data/config/locales/nl.yml +160 -0
  19. data/config/locales/pl.yml +203 -0
  20. data/config/locales/pt-BR.yml +139 -0
  21. data/config/locales/ru.yml +224 -0
  22. data/lib/locomotive/steam/core_ext.rb +5 -0
  23. data/lib/locomotive/steam/core_ext/array.rb +3 -0
  24. data/lib/locomotive/steam/core_ext/boolean/false.rb +3 -0
  25. data/lib/locomotive/steam/core_ext/boolean/true.rb +3 -0
  26. data/lib/locomotive/steam/core_ext/hash.rb +27 -0
  27. data/lib/locomotive/steam/core_ext/string.rb +8 -0
  28. data/lib/locomotive/steam/exceptions.rb +62 -0
  29. data/lib/locomotive/steam/initializers.rb +5 -0
  30. data/lib/locomotive/steam/initializers/i18n.rb +3 -0
  31. data/lib/locomotive/steam/initializers/markdown.rb +27 -0
  32. data/lib/locomotive/steam/initializers/will_paginate.rb +16 -0
  33. data/lib/locomotive/steam/liquid.rb +22 -0
  34. data/lib/locomotive/steam/liquid/drops/base.rb +46 -0
  35. data/lib/locomotive/steam/liquid/drops/content_entry.rb +48 -0
  36. data/lib/locomotive/steam/liquid/drops/content_types.rb +117 -0
  37. data/lib/locomotive/steam/liquid/drops/page.rb +28 -0
  38. data/lib/locomotive/steam/liquid/drops/session_proxy.rb +18 -0
  39. data/lib/locomotive/steam/liquid/drops/site.rb +26 -0
  40. data/lib/locomotive/steam/liquid/errors.rb +17 -0
  41. data/lib/locomotive/steam/liquid/filters/date.rb +136 -0
  42. data/lib/locomotive/steam/liquid/filters/html.rb +188 -0
  43. data/lib/locomotive/steam/liquid/filters/misc.rb +49 -0
  44. data/lib/locomotive/steam/liquid/filters/resize.rb +18 -0
  45. data/lib/locomotive/steam/liquid/filters/text.rb +55 -0
  46. data/lib/locomotive/steam/liquid/filters/translate.rb +28 -0
  47. data/lib/locomotive/steam/liquid/patches.rb +47 -0
  48. data/lib/locomotive/steam/liquid/scopeable.rb +149 -0
  49. data/lib/locomotive/steam/liquid/tags/consume.rb +97 -0
  50. data/lib/locomotive/steam/liquid/tags/csrf.rb +34 -0
  51. data/lib/locomotive/steam/liquid/tags/editable.rb +6 -0
  52. data/lib/locomotive/steam/liquid/tags/editable/base.rb +50 -0
  53. data/lib/locomotive/steam/liquid/tags/editable/control.rb +19 -0
  54. data/lib/locomotive/steam/liquid/tags/editable/file.rb +15 -0
  55. data/lib/locomotive/steam/liquid/tags/editable/long_text.rb +15 -0
  56. data/lib/locomotive/steam/liquid/tags/editable/short_text.rb +20 -0
  57. data/lib/locomotive/steam/liquid/tags/editable/text.rb +15 -0
  58. data/lib/locomotive/steam/liquid/tags/extends.rb +25 -0
  59. data/lib/locomotive/steam/liquid/tags/google_analytics.rb +28 -0
  60. data/lib/locomotive/steam/liquid/tags/hybrid.rb +27 -0
  61. data/lib/locomotive/steam/liquid/tags/inline_editor.rb +16 -0
  62. data/lib/locomotive/steam/liquid/tags/link_to.rb +56 -0
  63. data/lib/locomotive/steam/liquid/tags/locale_switcher.rb +106 -0
  64. data/lib/locomotive/steam/liquid/tags/nav.rb +287 -0
  65. data/lib/locomotive/steam/liquid/tags/paginate.rb +105 -0
  66. data/lib/locomotive/steam/liquid/tags/path_helper.rb +98 -0
  67. data/lib/locomotive/steam/liquid/tags/path_to.rb +36 -0
  68. data/lib/locomotive/steam/liquid/tags/seo.rb +74 -0
  69. data/lib/locomotive/steam/liquid/tags/session_assign.rb +41 -0
  70. data/lib/locomotive/steam/liquid/tags/snippet.rb +63 -0
  71. data/lib/locomotive/steam/liquid/tags/with_scope.rb +44 -0
  72. data/lib/locomotive/steam/listen.rb +64 -0
  73. data/lib/locomotive/steam/logger.rb +54 -0
  74. data/lib/locomotive/steam/monkey_patches.rb +5 -0
  75. data/lib/locomotive/steam/monkey_patches/better_errors.rb +70 -0
  76. data/lib/locomotive/steam/monkey_patches/dragonfly.rb +79 -0
  77. data/lib/locomotive/steam/monkey_patches/haml.rb +15 -0
  78. data/lib/locomotive/steam/monkey_patches/httparty.rb +46 -0
  79. data/lib/locomotive/steam/monkey_patches/mounter.rb +32 -0
  80. data/lib/locomotive/steam/server.rb +81 -0
  81. data/lib/locomotive/steam/server/dynamic_assets.rb +33 -0
  82. data/lib/locomotive/steam/server/entry_submission.rb +120 -0
  83. data/lib/locomotive/steam/server/favicon.rb +18 -0
  84. data/lib/locomotive/steam/server/locale.rb +42 -0
  85. data/lib/locomotive/steam/server/logging.rb +32 -0
  86. data/lib/locomotive/steam/server/middleware.rb +61 -0
  87. data/lib/locomotive/steam/server/page.rb +69 -0
  88. data/lib/locomotive/steam/server/path.rb +34 -0
  89. data/lib/locomotive/steam/server/renderer.rb +118 -0
  90. data/lib/locomotive/steam/server/templatized_page.rb +32 -0
  91. data/lib/locomotive/steam/server/timezone.rb +18 -0
  92. data/lib/locomotive/steam/standalone_server.rb +33 -0
  93. data/lib/locomotive/steam/version.rb +5 -0
  94. data/lib/steam.rb +4 -0
  95. data/locomotivecms_steam.gemspec +42 -0
  96. data/spec/fixtures/default/README +0 -0
  97. data/spec/fixtures/default/app/content_types/bands.yml +19 -0
  98. data/spec/fixtures/default/app/content_types/events.yml +25 -0
  99. data/spec/fixtures/default/app/content_types/messages.yml +17 -0
  100. data/spec/fixtures/default/app/content_types/songs.yml +25 -0
  101. data/spec/fixtures/default/app/content_types/updates.yml +33 -0
  102. data/spec/fixtures/default/app/views/pages/404.liquid.haml +10 -0
  103. data/spec/fixtures/default/app/views/pages/about_us.fr.liquid.haml +7 -0
  104. data/spec/fixtures/default/app/views/pages/about_us.liquid.haml +21 -0
  105. data/spec/fixtures/default/app/views/pages/about_us.nb.liquid.haml +4 -0
  106. data/spec/fixtures/default/app/views/pages/about_us/jane_doe.liquid.haml +4 -0
  107. data/spec/fixtures/default/app/views/pages/about_us/john_doe.fr.liquid.haml +5 -0
  108. data/spec/fixtures/default/app/views/pages/about_us/john_doe.liquid.haml +6 -0
  109. data/spec/fixtures/default/app/views/pages/all.liquid.haml +13 -0
  110. data/spec/fixtures/default/app/views/pages/archives/news.liquid.haml +10 -0
  111. data/spec/fixtures/default/app/views/pages/contact.liquid.haml +54 -0
  112. data/spec/fixtures/default/app/views/pages/contest.liquid.haml +18 -0
  113. data/spec/fixtures/default/app/views/pages/events.liquid.haml +42 -0
  114. data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +10 -0
  115. data/spec/fixtures/default/app/views/pages/grunge_bands.liquid.haml +8 -0
  116. data/spec/fixtures/default/app/views/pages/index.fr.liquid.haml +3 -0
  117. data/spec/fixtures/default/app/views/pages/index.liquid.haml +100 -0
  118. data/spec/fixtures/default/app/views/pages/music.fr.liquid.haml +4 -0
  119. data/spec/fixtures/default/app/views/pages/music.liquid.haml +42 -0
  120. data/spec/fixtures/default/app/views/pages/songs/template.fr.liquid.haml +16 -0
  121. data/spec/fixtures/default/app/views/pages/songs/template.liquid.haml +18 -0
  122. data/spec/fixtures/default/app/views/pages/songs/template/band.liquid.haml +16 -0
  123. data/spec/fixtures/default/app/views/pages/store.fr.liquid.haml +5 -0
  124. data/spec/fixtures/default/app/views/pages/store.liquid +5 -0
  125. data/spec/fixtures/default/app/views/pages/tags/nav.liquid.haml +6 -0
  126. data/spec/fixtures/default/app/views/pages/tags/nav_in_deep.liquid.haml +6 -0
  127. data/spec/fixtures/default/app/views/pages/unlisted_pages.liquid.haml +9 -0
  128. data/spec/fixtures/default/app/views/snippets/A_Complicated-one.liquid.haml +1 -0
  129. data/spec/fixtures/default/app/views/snippets/footer.liquid.haml +6 -0
  130. data/spec/fixtures/default/app/views/snippets/header.liquid.haml +1 -0
  131. data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +8 -0
  132. data/spec/fixtures/default/app/views/snippets/song.liquid +12 -0
  133. data/spec/fixtures/default/config/deploy.yml +12 -0
  134. data/spec/fixtures/default/config/deploy_example.yml +12 -0
  135. data/spec/fixtures/default/config/site.yml +15 -0
  136. data/spec/fixtures/default/config/translations.yml +3 -0
  137. data/spec/fixtures/default/data/bands.yml +10 -0
  138. data/spec/fixtures/default/data/events.yml +53 -0
  139. data/spec/fixtures/default/data/songs.yml +46 -0
  140. data/spec/fixtures/default/data/updates.yml +48 -0
  141. data/spec/fixtures/default/public/fonts/chunkfive-webfont.eot +0 -0
  142. data/spec/fixtures/default/public/fonts/chunkfive-webfont.svg +213 -0
  143. data/spec/fixtures/default/public/fonts/chunkfive-webfont.ttf +0 -0
  144. data/spec/fixtures/default/public/fonts/chunkfive-webfont.woff +0 -0
  145. data/spec/fixtures/default/public/fonts/chunkfive.css +8 -0
  146. data/spec/fixtures/default/public/fonts/chunkfive.otf +0 -0
  147. data/spec/fixtures/default/public/images/nav_on.png +0 -0
  148. data/spec/fixtures/default/public/images/photo_frame.png +0 -0
  149. data/spec/fixtures/default/public/images/sep.png +0 -0
  150. data/spec/fixtures/default/public/images/top.jpg +0 -0
  151. data/spec/fixtures/default/public/javascripts/application.js.coffee +2 -0
  152. data/spec/fixtures/default/public/javascripts/common.js +1 -0
  153. data/spec/fixtures/default/public/samples/asset_collections/cover.jpg +0 -0
  154. data/spec/fixtures/default/public/samples/photo.jpg +0 -0
  155. data/spec/fixtures/default/public/samples/photo_2.jpg +0 -0
  156. data/spec/fixtures/default/public/stylesheets/application.css +64 -0
  157. data/spec/fixtures/default/public/stylesheets/other/extra.css.less +8 -0
  158. data/spec/fixtures/default/public/stylesheets/other/style.css.scss +13 -0
  159. data/spec/fixtures/default/public/stylesheets/reboot.css +82 -0
  160. data/spec/integration/integration_helper.rb +15 -0
  161. data/spec/integration/server/basic_spec.rb +170 -0
  162. data/spec/integration/server/contact_form_spec.rb +111 -0
  163. data/spec/integration/server/liquid_spec.rb +91 -0
  164. data/spec/integration/server/with_scope_spec.rb +20 -0
  165. data/spec/locales/locales_spec.rb +22 -0
  166. data/spec/spec_helper.rb +21 -0
  167. data/spec/support.rb +4 -0
  168. data/spec/support/examples/locale_file.rb +14 -0
  169. data/spec/support/examples/matching_locale.rb +8 -0
  170. data/spec/support/helpers.rb +22 -0
  171. data/spec/support/matchers/hash.rb +5 -0
  172. metadata +564 -0
@@ -0,0 +1,79 @@
1
+ module Locomotive
2
+ module Steam
3
+ class Dragonfly
4
+
5
+ attr_accessor :path, :enabled
6
+
7
+ def enabled?
8
+ !!self.enabled
9
+ end
10
+
11
+ def resize_url(source, resize_string)
12
+ _source = (case source
13
+ when String then source
14
+ when Hash then source['url'] || source[:url]
15
+ else
16
+ source.try(:url)
17
+ end)
18
+
19
+ if _source.blank?
20
+ Locomotive::Steam::Logger.error "Unable to resize on the fly: #{source.inspect}"
21
+ return
22
+ end
23
+
24
+ return _source unless self.enabled?
25
+
26
+ if _source =~ /^http/
27
+ file = self.class.app.fetch_url(_source)
28
+ else
29
+ file = self.class.app.fetch_file(File.join(self.path, 'public', _source))
30
+ end
31
+
32
+ file.process(:thumb, resize_string).url
33
+ end
34
+
35
+ def self.app
36
+ ::Dragonfly[:images]
37
+ end
38
+
39
+
40
+ def self.instance
41
+ @@instance ||= new
42
+ end
43
+
44
+ def self.setup!(path)
45
+ self.instance.path = path
46
+ self.instance.enabled = false
47
+
48
+ begin
49
+ require 'rack/cache'
50
+ require 'dragonfly'
51
+
52
+ ## initialize Dragonfly ##
53
+ app = ::Dragonfly[:images].configure_with(:imagemagick)
54
+
55
+ ## configure it ##
56
+ ::Dragonfly[:images].configure do |c|
57
+ convert = `which convert`.strip.presence || '/usr/bin/env convert'
58
+ c.convert_command = convert
59
+ c.identify_command = convert
60
+
61
+ c.allow_fetch_url = true
62
+ c.allow_fetch_file = true
63
+
64
+ c.url_format = '/images/dynamic/:job/:basename.:format'
65
+ end
66
+
67
+ self.instance.enabled = true
68
+ rescue Exception => e
69
+
70
+ Locomotive::Steam::Logger.warn %{
71
+ [Dragonfly] !disabled!
72
+ [Dragonfly] If you want to take full benefits of all the features in the LocomotiveSteam, we recommend you to install ImageMagick and RMagick. Check out the documentation here: http://doc.locomotivecms.com/editor/installation.
73
+ }
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,15 @@
1
+ module Haml::Filters
2
+
3
+ remove_filter("Markdown") #remove the existing Markdown filter
4
+
5
+ module Markdown # the contents of this are as before, but without the lazy_require call
6
+
7
+ include Haml::Filters::Base
8
+
9
+ def render text
10
+ Locomotive::Steam::Markdown.steam text
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,46 @@
1
+ require 'uri'
2
+
3
+ module Locomotive
4
+ module Steam
5
+ module Httparty
6
+ class Webservice
7
+
8
+ include ::HTTParty
9
+
10
+ def self.consume(url, options = {})
11
+ url = ::HTTParty.normalize_base_uri(url)
12
+
13
+ uri = URI.parse(url)
14
+ options[:base_uri] = "#{uri.scheme}://#{uri.host}"
15
+ options[:base_uri] += ":#{uri.port}" if uri.port != 80
16
+ path = uri.request_uri
17
+
18
+ options.delete(:format) if options[:format] == 'default'
19
+
20
+ username, password = options.delete(:username), options.delete(:password)
21
+ options[:basic_auth] = { username: username, password: password } if username
22
+
23
+ path ||= '/'
24
+
25
+ # Locomotive::Steam::Logger.debug "[WebService] consuming #{path}, #{options.inspect}"
26
+
27
+ response = self.get(path, options)
28
+
29
+ if response.code == 200
30
+ _response = response.parsed_response
31
+ if _response.respond_to?(:underscore_keys)
32
+ _response.underscore_keys
33
+ else
34
+ _response.collect(&:underscore_keys)
35
+ end
36
+ else
37
+ Locomotive::Steam::Logger.error "[WebService] consumed #{path}, #{options.inspect}, response = #{response.inspect}"
38
+ nil
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Models
4
+ class Page
5
+
6
+ def render(context)
7
+ self.parse(context).render(context)
8
+ end
9
+
10
+ protected
11
+
12
+ def parse(context)
13
+ options = {
14
+ page: self,
15
+ mounting_point: context.registers[:mounting_point],
16
+ error_mode: :strict,
17
+ count_lines: true
18
+ }
19
+
20
+ begin
21
+ template = ::Liquid::Template.parse(self.source, options)
22
+ rescue Liquid::SyntaxError => e
23
+ # do it again on the raw source instead so that the error line matches
24
+ # the source file.
25
+ ::Liquid::Template.parse(self.template.raw_source, options)
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,81 @@
1
+ require 'better_errors'
2
+ require 'coffee_script'
3
+
4
+ require_relative 'listen'
5
+ require_relative 'server/middleware'
6
+ require_relative 'server/favicon'
7
+ require_relative 'server/dynamic_assets'
8
+ require_relative 'server/logging'
9
+ require_relative 'server/entry_submission'
10
+ require_relative 'server/path'
11
+ require_relative 'server/locale'
12
+ require_relative 'server/page'
13
+ require_relative 'server/timezone'
14
+ require_relative 'server/templatized_page'
15
+ require_relative 'server/renderer'
16
+
17
+ require_relative 'liquid'
18
+ require_relative 'initializers'
19
+ require_relative 'monkey_patches'
20
+
21
+ module Locomotive::Steam
22
+ class Server
23
+
24
+ def initialize(reader, options = {})
25
+ Locomotive::Steam::Dragonfly.setup!(reader.mounting_point.path)
26
+
27
+ Sprockets::Sass.add_sass_functions = false
28
+
29
+ @reader = reader
30
+ @app = self.create_rack_app(@reader)
31
+
32
+ BetterErrors.application_root = reader.mounting_point.path
33
+ end
34
+
35
+ def call(env)
36
+ env['steam.mounting_point'] = @reader.mounting_point
37
+ @app.call(env)
38
+ end
39
+
40
+ protected
41
+
42
+ def create_rack_app(reader)
43
+ Rack::Builder.new do
44
+ use Rack::Lint
45
+
46
+ use BetterErrors::MiddlewareWrapper
47
+
48
+ use Rack::Session::Cookie, {
49
+ key: 'steam.session',
50
+ path: '/',
51
+ expire_after: 2592000,
52
+ secret: 'uselessinlocal'
53
+ }
54
+
55
+ use ::Dragonfly::Middleware, :images
56
+
57
+ use Rack::Static, {
58
+ urls: ['/images', '/fonts', '/samples', '/media'],
59
+ root: File.join(reader.mounting_point.path, 'public')
60
+ }
61
+
62
+ use Favicon
63
+ use DynamicAssets, reader.mounting_point.path
64
+
65
+ use Logging
66
+
67
+ use EntrySubmission
68
+
69
+ use Path
70
+ use Locale
71
+ use Timezone
72
+
73
+ use Page
74
+ use TemplatizedPage
75
+
76
+ run Renderer.new
77
+ end
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,33 @@
1
+ module Locomotive::Steam
2
+ class Server
3
+
4
+ class DynamicAssets < Middleware
5
+
6
+ attr_reader :app, :sprockets, :regexp
7
+
8
+ def initialize(app, site_path)
9
+ super(app)
10
+
11
+ @regexp = /^\/(javascripts|stylesheets)\/(.*)$/
12
+
13
+ @sprockets = Locomotive::Mounter::Extensions::Sprockets.environment(site_path)
14
+ end
15
+
16
+ def call(env)
17
+ if env['PATH_INFO'] =~ self.regexp
18
+ env['PATH_INFO'] = $2
19
+
20
+ begin
21
+ self.sprockets.call(env)
22
+ rescue Exception => e
23
+ raise Locomotive::Steam::DefaultException.new "Unable to serve a dynamic asset. Please check the logs.", e
24
+ end
25
+ else
26
+ app.call(env)
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,120 @@
1
+ module Locomotive::Steam
2
+ class Server
3
+
4
+ # Mimic the submission of a content entry
5
+ #
6
+ class EntrySubmission < Middleware
7
+
8
+ def call(env)
9
+ self.set_accessors(env)
10
+
11
+ if self.request.post? && env['PATH_INFO'] =~ /^\/entry_submissions\/(.*)/
12
+ self.process_form($1)
13
+
14
+ # puts "html? #{html?} / json? #{json?} / #{self.callback_url} / #{params.inspect}"
15
+
16
+ if @entry.valid?
17
+ if self.html?
18
+ self.record_submitted_entry
19
+ self.redirect_to self.callback_url
20
+ elsif self.json?
21
+ self.json_response
22
+ end
23
+ else
24
+ if self.html?
25
+ if self.callback_url =~ /^http:\/\//
26
+ self.redirect_to self.callback_url
27
+ else
28
+ env['PATH_INFO'] = self.callback_url
29
+ self.liquid_assigns[@content_type.slug.singularize] = @entry
30
+ app.call(env)
31
+ end
32
+ elsif self.json?
33
+ self.json_response(422)
34
+ end
35
+ end
36
+ else
37
+ self.fetch_submitted_entry
38
+
39
+ app.call(env)
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ def record_submitted_entry
46
+ self.request.session[:now] ||= {}
47
+ self.request.session[:now][:submitted_entry] = [@content_type.slug, @entry._slug]
48
+ end
49
+
50
+ def fetch_submitted_entry
51
+ if data = self.request.session[:now].try(:delete, :submitted_entry)
52
+ content_type = self.mounting_point.content_types[data.first.to_s]
53
+
54
+ entry = (content_type.entries || []).detect { |e| e._slug == data.last }
55
+
56
+ # do not keep track of the entry
57
+ content_type.entries.delete(entry) if entry
58
+
59
+ # add it to the additional liquid assigns for the next liquid rendering
60
+ if entry
61
+ self.liquid_assigns[content_type.slug.singularize] = entry
62
+ end
63
+ end
64
+ end
65
+
66
+ # Mimic the creation of a content entry with a minimal validation.
67
+ #
68
+ # @param [ String ] permalink The permalink (or slug) of the content type
69
+ #
70
+ #
71
+ def process_form(permalink)
72
+ permalink = permalink.split('.').first
73
+
74
+ @content_type = self.mounting_point.content_types[permalink]
75
+
76
+ raise "Unknown content type '#{@content_type.inspect}'" if @content_type.nil?
77
+
78
+ attributes = self.params[:entry] || self.params[:content] || {}
79
+
80
+ @entry = @content_type.build_entry(attributes)
81
+
82
+ # if not valid, we do not need to keep track of the entry
83
+ @content_type.entries.delete(@entry) if !@entry.valid?
84
+ end
85
+
86
+ def callback_url
87
+ (@entry.valid? ? params[:success_callback] : params[:error_callback]) || '/'
88
+ end
89
+
90
+ # Build the JSON response
91
+ #
92
+ # @param [ Integer ] status The HTTP return code
93
+ #
94
+ # @return [ Array ] The rack response depending on the validation status and the requested format
95
+ #
96
+ def json_response(status = 200)
97
+ locale = self.mounting_point.default_locale
98
+
99
+ if self.request.path =~ /^\/(#{self.mounting_point.locales.join('|')})+(\/|$)/
100
+ locale = $1
101
+ end
102
+
103
+ hash = @entry.to_hash(false).tap do |_hash|
104
+ if !@entry.valid?
105
+ _hash['errors'] = @entry.errors.inject({}) do |memo, name|
106
+ memo[name] = ::I18n.t('errors.messages.blank', locale: locale)
107
+ memo
108
+ end
109
+ end
110
+ end
111
+
112
+ [status, { 'Content-Type' => 'application/json' }, [
113
+ { @content_type.slug.singularize => hash }.to_json
114
+ ]]
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,18 @@
1
+ module Locomotive::Steam
2
+ class Server
3
+
4
+ class Favicon < Middleware
5
+
6
+ def call(env)
7
+
8
+ if env['PATH_INFO'] == '/favicon.ico'
9
+ [200, { 'Content-Type' => 'image/vnd.microsoft.icon' }, ['']]
10
+ else
11
+ app.call(env)
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Locomotive::Steam
2
+ class Server
3
+
4
+ # Set the locale from the path if possible or use the default one
5
+ # Examples:
6
+ # /fr/index => locale = :fr
7
+ # /fr/ => locale = :fr
8
+ # /index => locale = :en (default one)
9
+ #
10
+ class Locale < Middleware
11
+
12
+ def call(env)
13
+ self.set_accessors(env)
14
+
15
+ self.set_locale!(env)
16
+
17
+ app.call(env)
18
+ end
19
+
20
+ protected
21
+
22
+ def set_locale!(env)
23
+ locale = self.mounting_point.default_locale
24
+
25
+ if self.path =~ /^(#{self.mounting_point.locales.join('|')})+(\/|$)/
26
+ locale = $1
27
+ self.path = self.path.gsub($1 + $2, '')
28
+ self.path = 'index' if self.path.blank?
29
+ end
30
+
31
+ Locomotive::Mounter.locale = locale
32
+ ::I18n.locale = locale
33
+
34
+ self.log "Detecting locale #{locale.upcase}"
35
+
36
+ env['steam.locale'] = locale
37
+ env['steam.path'] = self.path
38
+ end
39
+
40
+ end
41
+ end
42
+ end