add section middleware
Julien Girard
committed May 23, 2018
commit 57f8069df8e164124755ced104e02b1bc92a3cee
Showing 21
changed files with
267 additions
and 167 deletions
locomotive/steam/middlewares.rb b/lib/locomotive/steam/middlewares.rb
+1
-1
| @@ | @@ -1,5 +1,5 @@ |
| require_relative 'middlewares/thread_safe' | |
| - | require_relative 'middlewares/helpers' |
| + | require_relative 'middlewares/concerns/helpers' |
| require_relative_all 'middlewares' | |
locomotive/steam/middlewares/concerns/helpers.rb b/lib/locomotive/steam/middlewares/concerns/helpers.rb
+59
-0
| @@ | @@ -0,0 +1,59 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | |
| + | module Helpers |
| + | |
| + | def html? |
| + | ['text/html', 'application/x-www-form-urlencoded', 'multipart/form-data'].include?(self.request.media_type) && |
| + | !self.request.xhr? && |
| + | !self.json? |
| + | end |
| + | |
| + | def json? |
| + | self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json' |
| + | end |
| + | |
| + | def render_response(content, code = 200, type = nil) |
| + | @next_response = [code, { 'Content-Type' => type || 'text/html' }, [content]] |
| + | end |
| + | |
| + | def redirect_to(location, type = 301) |
| + | _location = mounted_on && !location.starts_with?(mounted_on) && (location =~ Locomotive::Steam::IsHTTP).nil? ? "#{mounted_on}#{location}" : location |
| + | |
| + | self.log "Redirected to #{_location}".blue |
| + | |
| + | @next_response = [type, { 'Content-Type' => 'text/html', 'Location' => _location }, []] |
| + | end |
| + | |
| + | def modify_path(path = nil, &block) |
| + | path ||= env['steam.path'] |
| + | |
| + | segments = path.split('/') |
| + | yield(segments) |
| + | path = segments.join('/') |
| + | |
| + | path = '/' if path.blank? |
| + | path += "?#{request.query_string}" unless request.query_string.empty? |
| + | path |
| + | end |
| + | |
| + | # make sure the location passed in parameter doesn't |
| + | # include the "mounted_on" parameter. |
| + | # If so, returns the location without the "mounted_on" string. |
| + | def make_local_path(location) |
| + | return location if mounted_on.blank? |
| + | location.gsub(Regexp.new('^' + mounted_on), '') |
| + | end |
| + | |
| + | def mounted_on |
| + | request.env['steam.mounted_on'] |
| + | end |
| + | |
| + | def log(msg, offset = 2) |
| + | Locomotive::Common::Logger.info (' ' * offset) + msg |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/steam/middlewares/concerns/liquid_context.rb b/lib/locomotive/steam/middlewares/concerns/liquid_context.rb
+89
-0
| @@ | @@ -0,0 +1,89 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | module LiquidContext |
| + | |
| + | def liquid_context |
| + | ::Liquid::Context.new(liquid_assigns, {}, liquid_registers, true) |
| + | end |
| + | |
| + | def liquid_registers |
| + | { |
| + | request: request, |
| + | locale: locale, |
| + | site: site, |
| + | page: page, |
| + | services: services, |
| + | repositories: services.repositories, |
| + | logger: Locomotive::Common::Logger, |
| + | live_editing: !!env['steam.live_editing'], |
| + | session: request.session |
| + | } |
| + | end |
| + | |
| + | def liquid_assigns |
| + | _default_liquid_assigns.merge( |
| + | _locale_liquid_assigns.merge( |
| + | _request_liquid_assigns.merge( |
| + | _http_actions_liquid_assigns.merge( |
| + | _steam_liquid_assigns)))) |
| + | end |
| + | |
| + | def _default_liquid_assigns |
| + | { |
| + | 'current_page' => params[:page], |
| + | 'params' => params.stringify_keys, |
| + | 'now' => Time.zone.now, |
| + | 'today' => Date.today, |
| + | 'mode' => Locomotive::Steam.configuration.mode, |
| + | 'wagon' => Locomotive::Steam.configuration.mode == :test, |
| + | 'live_editing' => live_editing? |
| + | } |
| + | end |
| + | |
| + | def _steam_liquid_assigns |
| + | { |
| + | 'site' => nil, |
| + | 'page' => nil, |
| + | 'models' => Locomotive::Steam::Liquid::Drops::ContentTypes.new, |
| + | 'contents' => Locomotive::Steam::Liquid::Drops::ContentTypes.new, |
| + | 'current_user' => {}, |
| + | 'session' => Locomotive::Steam::Liquid::Drops::SessionProxy.new, |
| + | } |
| + | end |
| + | |
| + | def _locale_liquid_assigns |
| + | { |
| + | 'locale' => locale.to_s, |
| + | 'default_locale' => site.default_locale.to_s, |
| + | 'locales' => site.locales.map(&:to_s) |
| + | } |
| + | end |
| + | |
| + | def _request_liquid_assigns |
| + | { |
| + | 'base_url' => request.base_url, |
| + | 'fullpath' => request.fullpath, |
| + | 'http_method' => request.request_method, |
| + | 'ip_address' => request.ip, |
| + | 'mounted_on' => mounted_on, |
| + | 'path' => request.path, |
| + | 'referer' => request.referer, |
| + | 'url' => request.url, |
| + | 'user_agent' => request.user_agent, |
| + | 'host' => request.host_with_port |
| + | } |
| + | end |
| + | |
| + | def _http_actions_liquid_assigns |
| + | { |
| + | 'head?' => request.head?, |
| + | 'get?' => request.get?, |
| + | 'post?' => request.post?, |
| + | 'put?' => request.put?, |
| + | 'delete?' => request.delete? |
| + | } |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| \ No newline at end of file | |
locomotive/steam/middlewares/helpers.rb b/lib/locomotive/steam/middlewares/helpers.rb
+0
-59
| @@ | @@ -1,59 +0,0 @@ |
| - | module Locomotive::Steam |
| - | module Middlewares |
| - | |
| - | module Helpers |
| - | |
| - | def html? |
| - | ['text/html', 'application/x-www-form-urlencoded', 'multipart/form-data'].include?(self.request.media_type) && |
| - | !self.request.xhr? && |
| - | !self.json? |
| - | end |
| - | |
| - | def json? |
| - | self.request.content_type == 'application/json' || File.extname(self.request.path) == '.json' |
| - | end |
| - | |
| - | def render_response(content, code = 200, type = nil) |
| - | @next_response = [code, { 'Content-Type' => type || 'text/html' }, [content]] |
| - | end |
| - | |
| - | def redirect_to(location, type = 301) |
| - | _location = mounted_on && !location.starts_with?(mounted_on) && (location =~ Locomotive::Steam::IsHTTP).nil? ? "#{mounted_on}#{location}" : location |
| - | |
| - | self.log "Redirected to #{_location}".blue |
| - | |
| - | @next_response = [type, { 'Content-Type' => 'text/html', 'Location' => _location }, []] |
| - | end |
| - | |
| - | def modify_path(path = nil, &block) |
| - | path ||= env['steam.path'] |
| - | |
| - | segments = path.split('/') |
| - | yield(segments) |
| - | path = segments.join('/') |
| - | |
| - | path = '/' if path.blank? |
| - | path += "?#{request.query_string}" unless request.query_string.empty? |
| - | path |
| - | end |
| - | |
| - | # make sure the location passed in parameter doesn't |
| - | # include the "mounted_on" parameter. |
| - | # If so, returns the location without the "mounted_on" string. |
| - | def make_local_path(location) |
| - | return location if mounted_on.blank? |
| - | location.gsub(Regexp.new('^' + mounted_on), '') |
| - | end |
| - | |
| - | def mounted_on |
| - | request.env['steam.mounted_on'] |
| - | end |
| - | |
| - | def log(msg, offset = 2) |
| - | Locomotive::Common::Logger.info (' ' * offset) + msg |
| - | end |
| - | |
| - | end |
| - | |
| - | end |
| - | end |
locomotive/steam/middlewares/renderer.rb b/lib/locomotive/steam/middlewares/renderer.rb
+1
-83
| @@ | @@ -4,6 +4,7 @@ module Locomotive::Steam |
| class Renderer < ThreadSafe | |
| include Helpers | |
| + | include LiquidContext |
| def _call | |
| if page | |
| @@ | @@ -44,89 +45,6 @@ module Locomotive::Steam |
| raise e | |
| end | |
| end | |
| - | |
| - | def liquid_context |
| - | ::Liquid::Context.new(liquid_assigns, {}, liquid_registers, true) |
| - | end |
| - | |
| - | def liquid_registers |
| - | { |
| - | request: request, |
| - | locale: locale, |
| - | site: site, |
| - | page: page, |
| - | services: services, |
| - | repositories: services.repositories, |
| - | logger: Locomotive::Common::Logger, |
| - | live_editing: !!env['steam.live_editing'], |
| - | session: request.session |
| - | } |
| - | end |
| - | |
| - | def liquid_assigns |
| - | _default_liquid_assigns.merge( |
| - | _locale_liquid_assigns.merge( |
| - | _request_liquid_assigns.merge( |
| - | _http_actions_liquid_assigns.merge( |
| - | _steam_liquid_assigns)))) |
| - | end |
| - | |
| - | def _default_liquid_assigns |
| - | { |
| - | 'current_page' => params[:page], |
| - | 'params' => params.stringify_keys, |
| - | 'now' => Time.zone.now, |
| - | 'today' => Date.today, |
| - | 'mode' => Locomotive::Steam.configuration.mode, |
| - | 'wagon' => Locomotive::Steam.configuration.mode == :test, |
| - | 'live_editing' => live_editing? |
| - | } |
| - | end |
| - | |
| - | def _steam_liquid_assigns |
| - | { |
| - | 'site' => site.to_liquid, |
| - | 'page' => page.to_liquid, |
| - | 'models' => Locomotive::Steam::Liquid::Drops::ContentTypes.new, |
| - | 'contents' => Locomotive::Steam::Liquid::Drops::ContentTypes.new, |
| - | 'current_user' => {}, |
| - | 'session' => Locomotive::Steam::Liquid::Drops::SessionProxy.new, |
| - | }.merge(env['steam.liquid_assigns']) |
| - | end |
| - | |
| - | def _locale_liquid_assigns |
| - | { |
| - | 'locale' => locale.to_s, |
| - | 'default_locale' => site.default_locale.to_s, |
| - | 'locales' => site.locales.map(&:to_s) |
| - | } |
| - | end |
| - | |
| - | def _request_liquid_assigns |
| - | { |
| - | 'base_url' => request.base_url, |
| - | 'fullpath' => request.fullpath, |
| - | 'http_method' => request.request_method, |
| - | 'ip_address' => request.ip, |
| - | 'mounted_on' => mounted_on, |
| - | 'path' => request.path, |
| - | 'referer' => request.referer, |
| - | 'url' => request.url, |
| - | 'user_agent' => request.user_agent, |
| - | 'host' => request.host_with_port |
| - | } |
| - | end |
| - | |
| - | def _http_actions_liquid_assigns |
| - | { |
| - | 'head?' => request.head?, |
| - | 'get?' => request.get?, |
| - | 'post?' => request.post?, |
| - | 'put?' => request.put?, |
| - | 'delete?' => request.delete? |
| - | } |
| - | end |
| - | |
| end | |
| end | |
locomotive/steam/middlewares/section.rb b/lib/locomotive/steam/middlewares/section.rb
+32
-0
| @@ | @@ -0,0 +1,32 @@ |
| + | module Locomotive::Steam |
| + | module Middlewares |
| + | class Section < ThreadSafe |
| + | |
| + | include Helpers |
| + | include LiquidContext |
| + | |
| + | def _call |
| + | if section_id = get_section_id(env['PATH_INFO']) |
| + | html = render(section_id) |
| + | render_response(html, 200) |
| + | end |
| + | end |
| + | |
| + | private |
| + | |
| + | def get_section_id(path_info) |
| + | path_info.match(/^\/_sections\/(?<section_id>[a-z0-9]+$)/)['section_id'] |
| + | end |
| + | |
| + | def section_finder |
| + | services.section_finder |
| + | end |
| + | |
| + | def render(section_id) |
| + | liquid_source = "{% section '#{section_id}' %}" |
| + | document = Liquid::Template.parse liquid_source |
| + | document.render(liquid_context) |
| + | end |
| + | end |
| + | end |
| + | end |
locomotive/steam/server.rb b/lib/locomotive/steam/server.rb
+2
-1
| @@ | @@ -67,7 +67,8 @@ module Locomotive::Steam |
| Middlewares::Path, | |
| Middlewares::Page, | |
| Middlewares::Sitemap, | |
| - | Middlewares::TemplatizedPage |
| + | Middlewares::TemplatizedPage, |
| + | Middlewares::Section |
| ] | |
| end | |
spec/unit/liquid/tags/section_spec.rb
+27
-11
| @@ | @@ -9,24 +9,39 @@ describe Locomotive::Steam::Liquid::Tags::Section do |
| before do | |
| allow(finder).to receive(:find).and_return(section) | |
| - | |
| end | |
| describe 'rendering' do | |
| - | let(:section) { instance_double( |
| - | 'Section', |
| - | liquid_source: 'built by NoCoffee', |
| - | definition: { |
| - | default: 'some default JSON' |
| - | } |
| - | )} |
| - | |
| subject { render_template(source, context) } | |
| - | it { is_expected.to eq 'Locomotive built by NoCoffee' } |
| - | context 'rendering error (action) found in the section' do |
| + | shared_examples "works normally" do |
| + | specify { is_expected.to eq 'Locomotive built by NoCoffee' } |
| + | end |
| + | context 'with simple example' do |
| + | let(:section) { instance_double( |
| + | 'Section', |
| + | liquid_source: 'built by NoCoffee', |
| + | definition: { |
| + | default: 'some default JSON' |
| + | } |
| + | )} |
| + | |
| + | it_behaves_like 'works normally' |
| + | end |
| + | |
| + | context 'with empty definition' do |
| + | let(:section) { instance_double( |
| + | 'Section', |
| + | liquid_source: 'built by NoCoffee', |
| + | definition: {} |
| + | )} |
| + | it_behaves_like 'works normally' |
| + | end |
| + | |
| + | |
| + | context 'rendering error (action) found in the section' do |
| let(:section) { instance_double( | |
| 'section', | |
| liquid_source: '{% action "Hello world" %}a.b(+}{% endaction %}', | |
| @@ | @@ -41,3 +56,4 @@ describe Locomotive::Steam::Liquid::Tags::Section do |
| end | |
| end | |
| end | |
| + | |
spec/unit/middlewares/auth_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/auth' | |
| describe Locomotive::Steam::Middlewares::Auth::AuthOptions do | |
spec/unit/middlewares/entry_submission_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/entry_submission' | |
| describe Locomotive::Steam::Middlewares::EntrySubmission do | |
spec/unit/middlewares/helpers_spec.rb
+1
-1
| @@ | @@ -1,6 +1,6 @@ |
| require 'spec_helper' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| describe Locomotive::Steam::Middlewares::Helpers do | |
spec/unit/middlewares/locale_redirection_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/locale_redirection' | |
| describe Locomotive::Steam::Middlewares::LocaleRedirection do | |
spec/unit/middlewares/locale_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/locale' | |
| describe Locomotive::Steam::Middlewares::Locale do | |
spec/unit/middlewares/page_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/page' | |
| describe Locomotive::Steam::Middlewares::Page do | |
spec/unit/middlewares/private_access_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/private_access' | |
| describe Locomotive::Steam::Middlewares::PrivateAccess do | |
spec/unit/middlewares/redirection_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/redirection' | |
| describe Locomotive::Steam::Middlewares::Redirection do | |
spec/unit/middlewares/renderer_spec.rb
+2
-1
| @@ | @@ -1,7 +1,8 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/liquid_context' |
| require_relative '../../../lib/locomotive/steam/middlewares/renderer' | |
| describe Locomotive::Steam::Middlewares::Renderer do | |
spec/unit/middlewares/section_spec.rb
+43
-0
| @@ | @@ -0,0 +1,43 @@ |
| + | require 'spec_helper' |
| + | |
| + | require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/liquid_context' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/section' |
| + | |
| + | describe Locomotive::Steam::Middlewares::Section do |
| + | |
| + | let(:app) { ->(env) { [200, env, 'app'] }} |
| + | let(:url) { 'http://example.com/_sections/header' } |
| + | let(:env) { env_for(url, 'steam.site' => site) } |
| + | |
| + | let(:site) { instance_double('Site', default_locale: 'en', locales: ['en'], to_liquid: '') } |
| + | let(:section) { instance_double('Section', definition: {}, liquid_source: 'Here some HTML') } |
| + | let(:section_finder) { instance_double('SectionFinderService') } |
| + | let(:repositories) { instance_double('Repositories')} |
| + | |
| + | let(:services) { instance_double( |
| + | 'Services', |
| + | section_finder: section_finder, |
| + | repositories: repositories, |
| + | locale: 'en') |
| + | } |
| + | |
| + | before do |
| + | env['steam.page'] = nil |
| + | env['steam.services'] = services |
| + | env['steam.locale'] = :en |
| + | env['steam.request'] = Rack::Request.new(env) |
| + | allow(section_finder).to receive(:find).with('header').and_return(section) |
| + | end |
| + | |
| + | subject do |
| + | middleware = described_class.new(app) |
| + | middleware.call(env) |
| + | end |
| + | |
| + | it 'works' do |
| + | is_expected.to eq [200, {"Content-Type"=>"text/html"}, ['Here some HTML']] |
| + | end |
| + | |
| + | end |
spec/unit/middlewares/site_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/site' | |
| describe Locomotive::Steam::Middlewares::Site do | |
spec/unit/middlewares/sitemap_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/sitemap' | |
| describe Locomotive::Steam::Middlewares::Sitemap do | |
spec/unit/middlewares/url_redirection_spec.rb
+1
-1
| @@ | @@ -1,7 +1,7 @@ |
| require 'spec_helper' | |
| require_relative '../../../lib/locomotive/steam/middlewares/thread_safe' | |
| - | require_relative '../../../lib/locomotive/steam/middlewares/helpers' |
| + | require_relative '../../../lib/locomotive/steam/middlewares/concerns/helpers' |
| require_relative '../../../lib/locomotive/steam/middlewares/url_redirection' | |
| describe Locomotive::Steam::Middlewares::UrlRedirection do | |