integrating Steam [WIP]

did committed Mar 29, 2015
commit c0b0e9b3f090a88547221a3ffe6e57d3bdd825d7
Showing 58 changed files with 111 additions and 3220 deletions
Gemfile +4 -0
@@ @@ -13,6 +13,10 @@ gem 'rb-fsevent', '~> 0.9.1'
gem 'therubyracer'
+ gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: '53a910eb6e', require: false
+ gem 'locomotivecms_coal', github: 'locomotivecms/coal', ref: '6ae10e3684', require: false
+
+
group :test do
gem 'pry'
gem 'coveralls', require: false
README.md +1 -1
@@ @@ -37,7 +37,7 @@ Please, visit the documentation website of LocomotiveCMS.
#### Run the server with a default site
- $ bundle exec bin/wagon serve <path to the mounter gem>/spec/fixtures/default
+ $ bundle exec bin/wagon serve spec/fixtures/default
#### Push a site
locomotive/wagon.rb b/lib/locomotive/wagon.rb +105 -72
@@ @@ -72,62 +72,28 @@ module Locomotive
# @param [ Hash ] options The options for the thin server (host, port)
#
def self.serve(path, options)
- if reader = self.require_mounter(path, true)
- use_listen = !options[:disable_listen]
-
- if options[:force]
- begin
- self.stop(path)
- sleep(2) # make sure we wait enough for the server process to stop
- rescue
- end
- end
-
- # TODO: new feature -> pick the right Rack handler (Thin, Puma, ...etc)
- server = self.thin_server(reader, options.slice(:host, :port, :disable_listen, :live_reload_port))
+ self.require_steam(path)
- if options[:daemonize]
- # very important to get the parent pid in order to differenciate the sub process from the parent one
- parent_pid = Process.pid
+ server = self.build_server(options)
+ use_listen = !options[:disable_listen]
- # The Daemons gem closes all file descriptors when it daemonizes the process. So any logfiles that were opened before the Daemons block will be closed inside the forked process.
- # So, close the current logger and set it up again when daemonized.
- Locomotive::Wagon::Logger.close
-
- server.log_file = File.join(File.expand_path(path), 'log', 'server.log')
- server.pid_file = File.join(File.expand_path(path), 'log', 'server.pid')
- server.daemonize
-
- use_listen = Process.pid != parent_pid && !options[:disable_listen]
-
- if Process.pid != parent_pid
- # A "new logger" inside the daemon.
- Locomotive::Wagon::Logger.setup(path, false)
- Locomotive::Mounter.logger = Locomotive::Wagon::Logger.instance.logger
- end
- end
+ self.stop(path, true) if options[:force]
- # listen_thread = Thread.new do
- Locomotive::Wagon::Listen.instance.start(reader) if use_listen
+ use_listen = self.daemonize(path, server, use_listen) if options[:daemonize]
- server.start
- # end
+ # TODO
+ # Locomotive::Wagon::Listen.instance.start(reader) if use_listen
- # server_thread = Thread.new { server.start }
-
- # hit Control + C to stop
- # Signal.trap('INT') { EventMachine.stop }
- # Signal.trap('TERM') { EventMachine.stop }
-
- # listen_thread.join
- # server_thread.join
- end
+ server.start
end
- def self.stop(path)
+ def self.stop(path, force = false)
pid_file = File.join(File.expand_path(path), 'log', 'server.pid')
pid = File.read(pid_file).to_i
Process.kill('TERM', pid)
+
+ # make sure we wait enough for the server process to stop
+ sleep(2) if force
end
# Generate components for the LocomotiveCMS site such as content types, snippets, pages.
@@ @@ -234,52 +200,119 @@ module Locomotive
Locomotive::Mounter::EngineApi.delete('/current_site.json')
end
- # Load the Locomotive::Mounter lib and set it up (logger, ...etc).
- # If the second parameter is set to true, then the method builds
- # an instance of the reader from the path passed in first parameter.
- #
- # @param [ String ] path The path to the local site
- # @param [ Boolean ] get_reader Tell if it builds an instance of the reader.
- # @param [ Boolean ] require_misc Tell if it requires the gems inside the misc bundler group
- #
- # @param [ Object ] An instance of the reader is the get_reader parameter has been set.
- #
- def self.require_mounter(path, get_reader = false, require_misc = true)
- Locomotive::Wagon::Logger.setup(path, false)
+ def self.require_steam(path, require_misc = true)
+ require 'locomotive/steam'
- require 'locomotive/mounter'
+ Locomotive::Steam.configure do |config|
+ config.mode = :test
+ config.adapter = { name: :filesystem, path: path }
+ config.serve_assets = true
+ config.asset_path = File.expand_path(File.join(path, 'public'))
+ config.minify_assets = false
+ end
- Locomotive::Mounter.logger = Locomotive::Wagon::Logger.instance.logger
+ Locomotive::Wagon::Logger.setup(path, false)
if require_misc
require 'bundler'
Bundler.require 'misc'
end
- if get_reader
- begin
- reader = Locomotive::Mounter::Reader::FileSystem.instance
- reader.run!(path: path)
- reader
- rescue Exception => e
- raise Locomotive::Wagon::MounterException.new "Unable to read the local LocomotiveCMS site. Please check the logs.", e
- end
+ # logger = Locomotive::Wagon::Logger.instance.logger
+ # logger.info "YEAAH"
+
+ Locomotive::Common.reset
+ Locomotive::Common.configure do |config|
+ config_file = File.expand_path(File.join(path, 'log', 'wagon.log'))
+ config.notifier = Locomotive::Common::Logger.setup(config_file)
end
end
- protected
+ # # Load the Locomotive::Mounter lib and set it up (logger, ...etc).
+ # # If the second parameter is set to true, then the method builds
+ # # an instance of the reader from the path passed in first parameter.
+ # #
+ # # @param [ String ] path The path to the local site
+ # # @param [ Boolean ] get_reader Tell if it builds an instance of the reader.
+ # # @param [ Boolean ] require_misc Tell if it requires the gems inside the misc bundler group
+ # #
+ # # @param [ Object ] An instance of the reader is the get_reader parameter has been set.
+ # #
+ # def self.require_mounter(path, get_reader = false, require_misc = true)
+ # Locomotive::Wagon::Logger.setup(path, false)
+
+ # require 'locomotive/mounter'
+
+ # Locomotive::Mounter.logger = Locomotive::Wagon::Logger.instance.logger
+
+ # if require_misc
+ # require 'bundler'
+ # Bundler.require 'misc'
+ # end
+
+ # if get_reader
+ # begin
+ # reader = Locomotive::Mounter::Reader::FileSystem.instance
+ # reader.run!(path: path)
+ # reader
+ # rescue Exception => e
+ # raise Locomotive::Wagon::MounterException.new "Unable to read the local LocomotiveCMS site. Please check the logs.", e
+ # end
+ # end
+ # end
- def self.thin_server(reader, options)
- require 'locomotive/wagon/server'
- app = Locomotive::Wagon::Server.new(reader, options)
+ protected
+ def self.build_server(options)
# TODO: new feature -> pick the right Rack handler (Thin, Puma, ...etc)
+
+ require 'locomotive/steam/server'
require 'thin'
+
+ app = Locomotive::Steam::Server.to_app
+
Thin::Server.new(options[:host], options[:port], { signals: true }, app).tap do |server|
server.threaded = true
end
end
+ def self.daemonize_server(server, path, use_listen)
+ if options[:daemonize]
+ # very important to get the parent pid in order to differenciate the sub process from the parent one
+ parent_pid = Process.pid
+
+ # The Daemons gem closes all file descriptors when it daemonizes the process. So any logfiles that were opened before the Daemons block will be closed inside the forked process.
+ # So, close the current logger and set it up again when daemonized.
+ Locomotive::Wagon::Logger.close
+
+ server.log_file = File.join(File.expand_path(path), 'log', 'server.log')
+ server.pid_file = File.join(File.expand_path(path), 'log', 'server.pid')
+ server.daemonize
+
+ use_listen = Process.pid != parent_pid && !options[:disable_listen]
+
+ if Process.pid != parent_pid
+ # A "new logger" inside the daemon.
+ Locomotive::Wagon::Logger.setup(path, false)
+ # Locomotive::Mounter.logger = Locomotive::Wagon::Logger.instance.logger
+ Locomotive::Common.configure do |config|
+ config.notifier = Locomotive::Wagon::Logger.instance.logger
+ end
+ end
+ end
+ end
+
+ # def self.thin_server(reader, options)
+ # require 'locomotive/wagon/server'
+ # app = Locomotive::Wagon::Server.new(reader, options)
+
+ # # TODO: new feature -> pick the right Rack handler (Thin, Puma, ...etc)
+ # require 'thin'
+ # Thin::Server.new(options[:host], options[:port], { signals: true }, app).tap do |server|
+ # server.threaded = true
+ # end
+ # end
+
def self.validate_resources(resources, writers_or_readers)
return if resources.nil?
locomotive/wagon/liquid.rb b/lib/locomotive/wagon/liquid.rb +0 -21
@@ @@ -1,21 +0,0 @@
- require 'solid'
- require 'locomotive/mounter'
- require 'locomotive/wagon/liquid/scopeable'
- require 'locomotive/wagon/liquid/drops/base'
- require 'locomotive/wagon/liquid/tags/hybrid'
- require 'locomotive/wagon/liquid/tags/path_helper'
-
- %w{. drops tags filters}.each do |dir|
- Dir[File.join(File.dirname(__FILE__), 'liquid', dir, '*.rb')].each { |lib| require lib }
- end
-
- # add to_liquid methods to main models from the mounter
- %w{site page content_entry}.each do |name|
- klass = "Locomotive::Mounter::Models::#{name.classify}".constantize
-
- klass.class_eval <<-EOV
- def to_liquid
- ::Locomotive::Wagon::Liquid::Drops::#{name.classify}.new(self)
- end
- EOV
- end
locomotive/wagon/liquid/drops/base.rb b/lib/locomotive/wagon/liquid/drops/base.rb +0 -46
@@ @@ -1,46 +0,0 @@
- # Code taken from Mephisto sources (http://mephistoblog.com/)
- module Locomotive
- module Wagon
- module Liquid
- module Drops
- class Base < ::Liquid::Drop
-
- @@forbidden_attributes = %w{_id _version _index}
-
- def initialize(source)
- @_source = source
- end
-
- def id
- (@_source.respond_to?(:id) ? @_source.id : nil) || 'new'
- end
-
- # converts an array of records to an array of liquid drops
- def self.liquify(*records, &block)
- i = -1
- records =
- records.inject [] do |all, r|
- i+=1
- attrs = (block && block.arity == 1) ? [r] : [r, i]
- all << (block ? block.call(*attrs) : r.to_liquid)
- all
- end
- records.compact!
- records
- end
-
- protected
-
- def liquify(*records, &block)
- self.class.liquify(*records, &block)
- end
-
- def _source
- @_source
- end
-
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/drops/content_entry.rb b/lib/locomotive/wagon/liquid/drops/content_entry.rb +0 -49
@@ @@ -1,49 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Drops
- class ContentEntry < Base
-
- delegate :seo_title, :meta_keywords, :meta_description, to: :@_source
-
- def _label
- @_label ||= @_source._label
- end
-
- def _permalink
- @_source._permalink.try(:parameterize)
- end
-
- alias :_slug :_permalink
- alias :_id :_permalink
-
- def next
- self
- end
-
- def previous
- self
- end
-
- def errors
- (@_source.errors || []).inject({}) do |memo, name|
- memo[name] = ::I18n.t('errors.messages.blank')
- memo
- end
- end
-
- def before_method(meth)
- return '' if @_source.nil?
-
- if not @@forbidden_attributes.include?(meth.to_s)
- @_source.send(meth)
- else
- nil
- end
- end
-
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/drops/content_types.rb b/lib/locomotive/wagon/liquid/drops/content_types.rb +0 -119
@@ @@ -1,119 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Drops
- class ContentTypes < ::Liquid::Drop
-
- def before_method(meth)
- type = self.mounting_point.content_types[meth.to_s]
- ProxyCollection.new(type)
- end
-
- end
-
- class ProxyCollection < ::Liquid::Drop
-
- include Scopeable
-
- def initialize(content_type)
- @content_type = content_type
- @collection = nil
- end
-
- def all
- self.collection
- end
-
- def any
- self.collection.any?
- end
-
- def first
- self.collection.first
- end
-
- def last
- self.collection.last
- end
-
- def size
- self.collection.size
- end
-
- alias :length :size
- alias :count :size
-
- def each(&block)
- self.collection.each(&block)
- end
-
- def public_submission_url
- "/entry_submissions/#{@content_type.slug}"
- end
-
- def api
- { 'create' => "/entry_submissions/#{@content_type.slug}" }
- end
-
- def before_method(meth)
- if (meth.to_s =~ /^group_by_(.+)$/) == 0
- self.group_entries_by(@content_type, $1)
- elsif (meth.to_s =~ /^(.+)_options$/) == 0
- self.select_options_for(@content_type, $1)
- else
- @content_type.send(meth)
- end
- end
-
- protected
-
- def group_entries_by(content_type, name)
- field = @content_type.find_field(name)
-
- return {} if field.nil? || !%w(belongs_to select).include?(field.type.to_s)
-
- (@content_type.entries || []).group_by do |entry|
- entry.send(name.to_sym)
- end.to_a.collect do |group|
- { name: group.first, entries: group.last }.with_indifferent_access
- end
- end
-
- def select_options_for(content_type, name)
- field = @content_type.find_field(name)
-
- return {} if field.nil? || field.type.to_s != 'select'
-
- field.select_options.map(&:name)
- end
-
- def paginate(options = {})
- @collection = self.collection.paginate(options)
- {
- collection: @collection,
- current_page: @collection.current_page,
- previous_page: @collection.previous_page,
- next_page: @collection.next_page,
- total_entries: @collection.total_entries,
- total_pages: @collection.total_pages,
- per_page: @collection.per_page
- }
- end
-
- def collection
- return @collection unless @collection.blank?
-
- # define the default order_by if not set
- if @context['with_scope'] && @context['with_scope']['order_by'].blank? && !%w(manually position).include?(@content_type.order_by)
- field = @content_type.order_by || 'created_at'
- direction = @content_type.order_direction || 'asc'
- @context['with_scope']['order_by'] = "#{field}.#{direction}"
- end
-
- @collection = apply_scope(@content_type.entries)
- end
- end
- end
- end
- end
- end
locomotive/wagon/liquid/drops/page.rb b/lib/locomotive/wagon/liquid/drops/page.rb +0 -84
@@ @@ -1,84 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Drops
- class Page < Base
-
- delegate :fullpath, :parent, :depth, :seo_title, :redirect_url, :meta_description, :meta_keywords,
- :templatized?, :published?, :redirect?, :listed?, :handle, to: :@_source
-
- def title
- title = @_source.templatized? ? @context['entry'].try(:_label) : nil
- title || @_source.title
- end
-
- def slug
- slug = @_source.templatized? ? @context['entry'].try(:_slug).try(:singularize) : nil
- slug || @_source.slug
- end
-
- def is_layout?
- @_source.is_layout
- end
-
- def original_title
- @_source.title
- end
-
- def original_slug
- @_source.slug
- end
-
- def children
- _children = @_source.children || []
- _children = _children.sort { |a, b| a.position.to_i <=> b.position.to_i }
- @children ||= liquify(*_children)
- end
-
- def content_type
- ProxyCollection.new(@_source.content_type) if @_source.content_type
- end
-
- def editable_elements
- @editable_elements_hash ||= build_editable_elements_hash
- end
-
- def breadcrumbs
- # TODO
- ''
- end
-
- private
-
- def build_editable_elements_hash
- {}.tap do |hash|
- @_source.editable_elements.each do |el|
- safe_slug = el.slug.parameterize.underscore
- keys = el.block.try(:split, '/').try(:compact) || []
-
- _hash = _build_editable_elements_hashes(hash, keys)
-
- _hash[safe_slug] = el.content
- end
- end
- end
-
- def _build_editable_elements_hashes(hash, keys)
- _hash = hash
-
- keys.each do |key|
- safe_key = key.parameterize.underscore
-
- _hash[safe_key] = {} if _hash[safe_key].nil?
-
- _hash = _hash[safe_key]
- end
-
- _hash
- end
-
- end
- end
- end
- end
- end
locomotive/wagon/liquid/drops/session_proxy.rb b/lib/locomotive/wagon/liquid/drops/session_proxy.rb +0 -18
@@ @@ -1,18 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Drops
-
- class SessionProxy < ::Liquid::Drop
-
- def before_method(meth)
- request = @context.registers[:request]
- request.session[meth.to_sym]
- end
-
- end
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/drops/site.rb b/lib/locomotive/wagon/liquid/drops/site.rb +0 -26
@@ @@ -1,26 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Drops
- class Site < Base
- include Scopeable
-
- delegate :name, :seo_title, :meta_description, :meta_keywords, to: :@_source
-
- def index
- @index ||= self.mounting_point.pages['index']
- end
-
- def pages
- liquify(*apply_scope(self.mounting_point.pages.values))
- end
-
- def domains
- @_source.domains
- end
-
- end
- end
- end
- end
- end
locomotive/wagon/liquid/errors.rb b/lib/locomotive/wagon/liquid/errors.rb +0 -17
@@ @@ -1,17 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- class PageNotFound < ::Liquid::Error; end
-
- class PageNotTranslated < ::Liquid::Error; end
-
- class ContentEntryNotTranslated < ::Liquid::Error; end
-
- class UnknownConditionInScope < ::Liquid::Error; end
-
- class UnknownConditionInScope < ::Liquid::Error; end
-
- class ConnectionRefused < ::Liquid::Error; end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/date.rb b/lib/locomotive/wagon/liquid/filters/date.rb +0 -136
@@ @@ -1,136 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Date
-
- def parse_date_time(input, format = nil)
- return '' if input.blank?
-
- format ||= I18n.t('time.formats.default')
- date_time = ::DateTime._strptime(input, format)
-
- if date_time
- ::Time.zone.local(date_time[:year], date_time[:mon], date_time[:mday], date_time[:hour], date_time[:min], date_time[:sec] || 0)
- else
- ::Time.zone.parse(input) rescue ''
- end
- end
-
- def parse_date(input, format)
- return '' if input.blank?
-
- format ||= I18n.t('date.formats.default')
- date = ::Date._strptime(input, format)
-
- if date
- ::Date.new(date[:year], date[:mon], date[:mday])
- else
- ::Date.parse(value) rescue ''
- end
- end
-
- def localized_date(input, *args)
- return '' if input.blank?
-
- format, locale = args
-
- locale ||= I18n.locale
- format ||= I18n.t('date.formats.default', locale: locale)
-
- if input.is_a?(String)
- begin
- fragments = ::Date._strptime(input, format)
- input = ::Date.new(fragments[:year], fragments[:mon], fragments[:mday])
- rescue
- input = Time.zone.parse(input)
- end
- end
-
- return input.to_s unless input.respond_to?(:strftime)
-
- I18n.l input, format: format, locale: locale
- end
-
- alias :format_date :localized_date
-
- def distance_of_time_in_words(input, from_time = Time.zone.now, include_seconds = false)
- return '' if input.blank?
-
- # make sure we deals with instances of Time
- to_time = to_time(input)
- from_time = to_time(from_time)
-
- from_time = from_time.to_time if from_time.respond_to?(:to_time)
- to_time = to_time.to_time if to_time.respond_to?(:to_time)
- distance_in_minutes = (((to_time - from_time).abs)/60).round
- distance_in_seconds = ((to_time - from_time).abs).round
-
- ::I18n.with_options({ scope: :'datetime.distance_in_words' }) do |locale|
-
- case distance_in_minutes
- when 0..1
- return distance_in_minutes == 0 ?
- locale.t(:less_than_x_minutes, count: 1) :
- locale.t(:x_minutes, count: distance_in_minutes) unless include_seconds
-
- case distance_in_seconds
- when 0..4 then locale.t :less_than_x_seconds, count: 5
- when 5..9 then locale.t :less_than_x_seconds, count: 10
- when 10..19 then locale.t :less_than_x_seconds, count: 20
- when 20..39 then locale.t :half_a_minute
- when 40..59 then locale.t :less_than_x_minutes, count: 1
- else locale.t :x_minutes, count: 1
- end
-
- when 2..44 then locale.t :x_minutes, count: distance_in_minutes
- when 45..89 then locale.t :about_x_hours, count: 1
- when 90..1439 then locale.t :about_x_hours, count: (distance_in_minutes.to_f / 60.0).round
- when 1440..2519 then locale.t :x_days, count: 1
- when 2520..43199 then locale.t :x_days, count: (distance_in_minutes.to_f / 1440.0).round
- when 43200..86399 then locale.t :about_x_months, count: 1
- when 86400..525599 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round
- else
- fyear = from_time.year
- fyear += 1 if from_time.month >= 3
- tyear = to_time.year
- tyear -= 1 if to_time.month < 3
- leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| ::Date.leap?(x)}
- minute_offset_for_leap_year = leap_years * 1440
- # Discount the leap year days when calculating year distance.
- # e.g. if there are 20 leap year days between 2 dates having the same day
- # and month then the based on 365 days calculation
- # the distance in years will come out to over 80 years when in written
- # english it would read better as about 80 years.
- minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
- remainder = (minutes_with_offset % 525600)
- distance_in_years = (minutes_with_offset / 525600)
- if remainder < 131400
- locale.t(:about_x_years, count: distance_in_years)
- elsif remainder < 394200
- locale.t(:over_x_years, count: distance_in_years)
- else
- locale.t(:almost_x_years, count: distance_in_years + 1)
- end
- end
- end
- end
-
- private
-
- def to_time(input)
- case input
- when Date then input.to_time
- when String then Time.zone.parse(input)
- else
- input
- end
- end
-
- end
-
- ::Liquid::Template.register_filter(Date)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/html.rb b/lib/locomotive/wagon/liquid/filters/html.rb +0 -188
@@ @@ -1,188 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Html
-
- # Returns a link tag that browsers and news readers can use to auto-detect an RSS or ATOM feed.
- # input: url of the feed
- # example:
- # {{ '/foo/bar' | auto_discovery_link_tag: 'rel:alternate', 'type:application/atom+xml', 'title:A title' }}
- def auto_discovery_link_tag(input, *args)
- options = args_to_options(args)
-
- rel = options[:rel] || 'alternate'
- type = options[:type] || MIME::Types.type_for('rss').first
- title = options[:title] || 'RSS'
-
- %{<link rel="#{rel}" type="#{type}" title="#{title}" href="#{input}" />}
- end
-
- # Write the url of a theme stylesheet
- # input: name of the css file
- def stylesheet_url(input)
- return '' if input.nil?
-
- if input =~ /^https?:/
- input
- else
- input = "/stylesheets/#{input}" unless input =~ /^\//
- input = "#{input}.css" unless input.ends_with?('.css')
- input
- end
- end
-
- # Write the link to a stylesheet resource
- # input: url of the css file
- def stylesheet_tag(input, media = 'screen')
- return '' if input.nil?
-
- input = stylesheet_url(input)
-
- %{<link href="#{input}" media="#{media}" rel="stylesheet" type="text/css" />}
- end
-
- # Write the url to javascript resource
- # input: name of the javascript file
- def javascript_url(input)
- return '' if input.nil?
-
- input = "/javascripts/#{input}" unless input =~ /^(\/|https?:)/
-
- input = "#{input}.js" unless input.ends_with?('.js')
-
- input
- end
-
- # Write the link to javascript resource
- # input: url of the javascript file
- def javascript_tag(input)
- return '' if input.nil?
-
- input = javascript_url(input)
-
- %{<script src="#{input}" type="text/javascript"></script>}
- end
-
- # Write an image tag
- # input: url of the image OR asset drop
- def image_tag(input, *args)
- image_options = inline_options(args_to_options(args))
-
- "<img src=\"#{get_url_from_asset(input)}\" #{image_options}>"
- end
-
- # Write a theme image tag
- # input: name of file including folder
- # example: 'about/myphoto.jpg' | theme_image # <img src="images/about/myphoto.jpg" />
- def theme_image_tag(input, *args)
- image_options = inline_options(args_to_options(args))
- "<img src=\"#{theme_image_url(input)}\" #{image_options}/>"
- end
-
- def theme_image_url(input)
- return '' if input.nil?
-
- input = "images/#{input}" unless input.starts_with?('/')
-
- File.join('/', input)
- end
-
- def image_format(input, *args)
- format = args_to_options(args).first
- "#{input}.#{format}"
- end
-
- # Embed a flash movie into a page
- # input: url of the flash movie OR asset drop
- # width: width (in pixel or in %) of the embedded movie
- # height: height (in pixel or in %) of the embedded movie
- def flash_tag(input, *args)
- path = get_url_from_asset(input)
- embed_options = inline_options(args_to_options(args))
- %{
- <object #{embed_options}>
- <param name="movie" value="#{path}" />
- <embed src="#{path}" #{embed_options}/>
- </embed>
- </object>
- }.gsub(/ >/, '>').strip
- end
-
- # Render the navigation for a paginated collection
- def default_pagination(paginate, *args)
- return '' if paginate['parts'].empty?
-
- options = args_to_options(args)
-
- previous_label = options[:previous_label] || I18n.t('pagination.previous')
- next_label = options[:next_label] || I18n.t('pagination.next')
-
- previous_link = (if paginate['previous'].blank?
- "<span class=\"disabled prev_page\">#{previous_label}</span>"
- else
- "<a href=\"#{absolute_url(paginate['previous']['url'])}\" class=\"prev_page\">#{previous_label}</a>"
- end)
-
- links = ""
- paginate['parts'].each do |part|
- links << (if part['is_link']
- "<a href=\"#{absolute_url(part['url'])}\">#{part['title']}</a>"
- elsif part['hellip_break']
- "<span class=\"gap\">#{part['title']}</span>"
- else
- "<span class=\"current\">#{part['title']}</span>"
- end)
- end
-
- next_link = (if paginate['next'].blank?
- "<span class=\"disabled next_page\">#{next_label}</span>"
- else
- "<a href=\"#{absolute_url(paginate['next']['url'])}\" class=\"next_page\">#{next_label}</a>"
- end)
-
- %{<div class="pagination #{options[:css]}">
- #{previous_link}
- #{links}
- #{next_link}
- </div>}
- end
-
- protected
-
- # Convert an array of properties ('key:value') into a hash
- # Ex: ['width:50', 'height:100'] => { :width => '50', :height => '100' }
- def args_to_options(*args)
- options = {}
- args.flatten.each do |a|
- if (a =~ /^(.*):(.*)$/)
- options[$1.to_sym] = $2
- end
- end
- options
- end
-
- # Write options (Hash) into a string according to the following pattern:
- # <key1>="<value1>", <key2>="<value2", ...etc
- def inline_options(options = {})
- return '' if options.empty?
- (options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ') << ' '
- end
-
- # Get the path to be used in html tags such as image_tag, flash_tag, ...etc
- # input: url (String) OR asset drop
- def get_url_from_asset(input)
- input.respond_to?(:url) ? input.url : input
- end
-
- def absolute_url(url)
- url =~ /^\// ? url : "/#{url}"
- end
- end
-
- ::Liquid::Template.register_filter(Html)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/misc.rb b/lib/locomotive/wagon/liquid/filters/misc.rb +0 -49
@@ @@ -1,49 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Misc
-
- # was called modulo at first
- def str_modulo(word, index, modulo)
- (index.to_i + 1) % modulo == 0 ? word : ''
- end
-
- # Get the nth element of the passed in array
- def index(array, position)
- array.at(position) if array.respond_to?(:at)
- end
-
- def default(input, value)
- input.blank? ? value : input
- end
-
- def random(input)
- rand(input.to_i)
- end
-
- # map/collect on a given property (support to_f, to_i)
- def map(input, property)
- flatten_if_necessary(input).map do |e|
- e = e.call if e.is_a?(Proc)
-
- if property == "to_liquid"
- e
- elsif property == "to_f"
- e.to_f
- elsif property == "to_i"
- e.to_i
- elsif e.respond_to?(:[])
- e[property]
- end
- end
- end
-
- end
-
- ::Liquid::Template.register_filter(Misc)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/resize.rb b/lib/locomotive/wagon/liquid/filters/resize.rb +0 -18
@@ @@ -1,18 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Resize
-
- def resize(input, resize_string)
- Locomotive::Wagon::Dragonfly.instance.resize_url(input, resize_string)
- end
-
- end
-
- ::Liquid::Template.register_filter(Resize)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/text.rb b/lib/locomotive/wagon/liquid/filters/text.rb +0 -55
@@ @@ -1,55 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Text
-
- # right justify and padd a string
- def rjust(input, integer, padstr = '')
- input.to_s.rjust(integer, padstr)
- end
-
- # left justify and padd a string
- def ljust(input, integer, padstr = '')
- input.to_s.ljust(integer, padstr)
- end
-
- def underscore(input)
- input.to_s.gsub(' ', '_').gsub('/', '_').underscore
- end
-
- def dasherize(input)
- input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
- end
-
- # alias newline_to_br
- def multi_line(input)
- input.to_s.gsub("\n", '<br/>')
- end
-
- def concat(input, *args)
- result = input.to_s
- args.flatten.each { |a| result << a.to_s }
- result
- end
-
- def encode(input)
- Rack::Utils.escape(input)
- end
-
- def textile(input)
- ::RedCloth.new(input).to_html
- end
-
- def markdown(input)
- Locomotive::Wagon::Markdown.render(input)
- end
-
- end
-
- ::Liquid::Template.register_filter(Text)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/filters/translate.rb b/lib/locomotive/wagon/liquid/filters/translate.rb +0 -28
@@ @@ -1,28 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Filters
- module Translate
-
- def translate(key, locale = nil, scope = nil)
- locale ||= I18n.locale.to_s
- if scope.blank?
- translation = @context.registers[:mounting_point].translations[key.to_s]
-
- if translation
- translation.get(locale) || translation.get(Locomotive::Mounter.locale.to_s)
- else
- "[unknown translation key: #{key}]"
- end
- else
- I18n.t(key, scope: scope.split('.'), locale: locale)
- end
- end
- end
-
- ::Liquid::Template.register_filter(Translate)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/patches.rb b/lib/locomotive/wagon/liquid/patches.rb +0 -47
@@ @@ -1,47 +0,0 @@
- module Liquid
-
- class Drop
-
- def mounting_point
- @context.registers[:mounting_point]
- end
-
- def site
- @context.registers[:site]
- end
-
- end
-
- class Template
-
- # creates a new <tt>Template</tt> object from liquid source code
- def parse_with_utf8(source, context = {})
- if RUBY_VERSION =~ /1\.9/
- source = source.force_encoding('UTF-8') if source.present?
- end
- self.parse_without_utf8(source, context)
- end
-
- alias_method_chain :parse, :utf8
-
- end
-
- module StandardFilters
-
- private
-
- def to_number(obj)
- case obj
- when Numeric
- obj
- when String
- (obj.strip =~ /^\d+\.\d+$/) ? obj.to_f : obj.to_i
- when DateTime, Date, Time
- obj.to_time.to_i
- else
- 0
- end
- end
- end
-
- end
locomotive/wagon/liquid/scopeable.rb b/lib/locomotive/wagon/liquid/scopeable.rb +0 -151
@@ @@ -1,151 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Scopeable
-
- def apply_scope(entries)
- if @context['with_scope'].blank?
- entries
- else
- # extract the conditions
- _conditions = @context['with_scope'].clone.delete_if { |k, _| %w(order_by per_page page).include?(k) }
-
- # build the chains of conditions
- conditions = _conditions.map { |name, value| Condition.new(name, value) }
-
- Locomotive::Wagon::Logger.info "[with_scope] conditions: #{conditions.map(&:to_s).join(', ')}"
-
- # get only the entries matching ALL the conditions
- _entries = entries.find_all do |content|
- accepted = true
-
- conditions.each do |_condition|
- unless _condition.matches?(content)
- accepted = false
- break # no to go further
- end
- end
-
- accepted
- end
-
- self._apply_scope_order(_entries, @context['with_scope']['order_by'])
- end
- end
-
- def _apply_scope_order(entries, order_by)
- return entries if order_by.blank?
-
- name, direction = order_by.split(/[\s\.]/).map(&:to_sym)
-
- Locomotive::Wagon::Logger.info "[with_scope] order_by #{name} #{direction || 'asc'}"
-
- if direction == :asc || direction.nil?
- entries.sort { |a, b| a.send(name) <=> b.send(name) }
- else
- entries.sort { |a, b| b.send(name) <=> a.send(name) }
- end
- end
-
- class Condition
-
- OPERATORS = %w(all gt gte in lt lte ne nin size)
-
- attr_accessor :name, :operator, :right_operand
-
- def initialize(name, value)
- self.name, self.right_operand = name, value
-
- self.name = :_slug if %w(id _id).include?(name.to_s)
-
- self.process_right_operand
-
- # default value
- self.operator = :==
-
- self.decode_operator_based_on_name
- end
-
- def matches?(entry)
- value = self.get_value(entry)
-
- self.decode_operator_based_on_value(value)
-
- case self.operator
- when :== then value == self.right_operand
- when :ne then value != self.right_operand
- when :matches then self.right_operand =~ value
- when :gt then value > self.right_operand
- when :gte then value >= self.right_operand
- when :lt then value < self.right_operand
- when :lte then value <= self.right_operand
- when :size then value.size == self.right_operand
- when :all then [*self.right_operand].contains?(value)
- when :in, :nin
- _matches = if value.is_a?(Array)
- [*value].contains?([*self.right_operand])
- else
- [*self.right_operand].include?(value)
- end
- self.operator == :in ? _matches : !_matches
- else
- raise UnknownConditionInScope.new("#{self.operator} is unknown or not implemented.")
- end
- end
-
- def to_s
- "#{name} #{operator} #{self.right_operand.to_s}"
- end
-
- protected
-
- def get_value(entry)
- value = entry.send(self.name)
-
- if value.respond_to?(:_slug)
- # belongs_to
- value._slug
- elsif value.respond_to?(:map)
- # many_to_many or tags ?
- value.map { |v| v.respond_to?(:_slug) ? v._slug : v }
- else
- value
- end
- end
-
- def process_right_operand
- if self.right_operand.respond_to?(:_slug)
- # belongs_to
- self.right_operand = self.right_operand._slug
- elsif self.right_operand.respond_to?(:map) && self.right_operand.first.respond_to?(:_slug)
- # many_to_many
- self.right_operand = self.right_operand.map do |entry|
- entry.try(&:_slug)
- end
- end
- end
-
- def decode_operator_based_on_name
- if name =~ /^([a-z0-9_-]+)\.(#{OPERATORS.join('|')})$/
- self.name = $1.to_sym
- self.operator = $2.to_sym
- end
-
- if self.right_operand.is_a?(Regexp)
- self.operator = :matches
- end
- end
-
- def decode_operator_based_on_value(value)
- case value
- when Array
- self.operator = :in if self.operator == :==
- end
- end
-
- end
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/consume.rb b/lib/locomotive/wagon/liquid/tags/consume.rb +0 -100
@@ @@ -1,100 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- # Consume web services as easy as pie directly in liquid !
- #
- # Usage:
- #
- # {% consume blog from 'http://nocoffee.tumblr.com/api/read.json?num=3', username: 'john', password: 'easy', format: 'json', expires_in: 3000 %}
- # {% for post in blog.posts %}
- # {{ post.title }}
- # {% endfor %}
- # {% endconsume %}
- #
- class Consume < ::Liquid::Block
-
- Syntax = /(#{::Liquid::VariableSignature}+)\s*from\s*(#{::Liquid::QuotedString}|#{::Liquid::VariableSignature}+)(.*)?/
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @target = $1
-
- self.prepare_url($2)
- self.prepare_api_arguments($3)
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.consume"), options[:line])
- end
-
- @local_cache_key = self.hash
-
- super
- end
-
- def render(context)
- self.set_api_options(context)
-
- if instance_variable_defined? :@variable_name
- @url = context[@variable_name]
- end
- render_all_without_cache(context)
- end
-
- protected
-
- def prepare_url(token)
- if token.match(::Liquid::QuotedString)
- @url = token.gsub(/['"]/, '')
- elsif token.match(::Liquid::VariableSignature)
- @variable_name = token
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
- end
- end
-
- def prepare_api_arguments(string)
- string = string.gsub(/^(\s*,)/, '').strip
- @api_arguments = Solid::Arguments.parse(string)
- end
-
- def set_api_options(context)
- @api_options = @api_arguments.interpolate(context).first || {}
- @expires_in = @api_options.delete(:expires_in) || 0
- end
-
- def cached_response
- @@local_cache ||= {}
- @@local_cache[@local_cache_key]
- end
-
- def cached_response=(response)
- @@local_cache ||= {}
- @@local_cache[@local_cache_key] = response
- end
-
- def render_all_without_cache(context)
- context.stack do
- begin
- context.scopes.last[@target.to_s] = Locomotive::Wagon::Httparty::Webservice.consume(@url, @api_options)
- self.cached_response = context.scopes.last[@target.to_s]
- rescue Timeout::Error
- context.scopes.last[@target.to_s] = self.cached_response
- rescue ::Liquid::Error => e
- raise e
- rescue => e
- liquid_e = ::Liquid::Error.new(e.message, line)
- liquid_e.set_backtrace(e.backtrace)
- raise liquid_e
- end
-
- render_all(@nodelist, context)
- end
- end
-
- end
-
- ::Liquid::Template.register_tag('consume', Consume)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/csrf.rb b/lib/locomotive/wagon/liquid/tags/csrf.rb +0 -34
@@ @@ -1,34 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Csrf
-
- class Param < ::Liquid::Tag
-
- def render(context)
- %{<input type="hidden" name="authenticity_token" value="helloworld" />}
- end
-
- end
-
- class Meta < ::Liquid::Tag
-
- def render(context)
- %{
- <meta name="csrf-param" content="authenticity_token" />
- <meta name="csrf-token" content="helloworld" />
- }
- end
-
- end
-
- end
-
- ::Liquid::Template.register_tag('csrf_param', Csrf::Param)
- ::Liquid::Template.register_tag('csrf_meta', Csrf::Meta)
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable.rb b/lib/locomotive/wagon/liquid/tags/editable.rb +0 -6
@@ @@ -1,6 +0,0 @@
- require 'locomotive/wagon/liquid/tags/editable/base'
- require 'locomotive/wagon/liquid/tags/editable/text'
- require 'locomotive/wagon/liquid/tags/editable/short_text'
- require 'locomotive/wagon/liquid/tags/editable/long_text'
- require 'locomotive/wagon/liquid/tags/editable/file'
- require 'locomotive/wagon/liquid/tags/editable/control'
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/base.rb b/lib/locomotive/wagon/liquid/tags/editable/base.rb +0 -50
@@ @@ -1,50 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class Base < ::Liquid::Block
-
- Syntax = /(#{::Liquid::QuotedFragment})(\s*,\s*#{::Liquid::Expression}+)?/
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @slug = $1.gsub(/[\"\']/, '')
- @_options = {}
- markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/^'/, '').gsub(/'$/, '') }
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.#{tag_name}"), options[:line])
- end
-
- super
- end
-
- def render(context)
- current_page = context.registers[:page]
-
- element = current_page.find_editable_element(self.current_block_name(context), @slug)
-
- if element.present?
- render_element(context, element)
- else
- super
- end
- end
-
- protected
-
- def render_element(context, element)
- element.content
- end
-
- def current_block_name(context)
- context['block'].try(:name)
- end
-
- end
-
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/control.rb b/lib/locomotive/wagon/liquid/tags/editable/control.rb +0 -19
@@ @@ -1,19 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class Control < Base
-
- def render(context)
- super
- end
-
- end
-
- ::Liquid::Template.register_tag('editable_control', Control)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/file.rb b/lib/locomotive/wagon/liquid/tags/editable/file.rb +0 -15
@@ @@ -1,15 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class File < Base
-
- end
-
- ::Liquid::Template.register_tag('editable_file', File)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/long_text.rb b/lib/locomotive/wagon/liquid/tags/editable/long_text.rb +0 -15
@@ @@ -1,15 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class LongText < ShortText
-
- end
-
- ::Liquid::Template.register_tag('editable_long_text', LongText)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/short_text.rb b/lib/locomotive/wagon/liquid/tags/editable/short_text.rb +0 -20
@@ @@ -1,20 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class ShortText < Base
-
- def render(context)
- Locomotive::Wagon::Logger.warn " [#{self.current_block_name(context)}/#{@slug}] The editable_{short|long}_text tags are deprecated. Use editable_text instead.".colorize(:orange)
- super(context)
- end
-
- end
-
- ::Liquid::Template.register_tag('editable_short_text', ShortText)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/editable/text.rb b/lib/locomotive/wagon/liquid/tags/editable/text.rb +0 -15
@@ @@ -1,15 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module Editable
- class Text < Base
-
- end
-
- ::Liquid::Template.register_tag('editable_text', Text)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/extends.rb b/lib/locomotive/wagon/liquid/tags/extends.rb +0 -25
@@ @@ -1,25 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- class Extends < ::Liquid::Extends
-
- def parse_parent_template
- mounting_point = @options[:mounting_point]
-
- page = if @template_name == 'parent'
- @options[:page].parent
- else
- mounting_point.pages[@template_name]
- end
-
- ::Liquid::Template.parse(page.source, { mounting_point: mounting_point, page: page })
- end
-
- end
-
- ::Liquid::Template.register_tag('extends', Extends)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/fetch_page.rb b/lib/locomotive/wagon/liquid/tags/fetch_page.rb +0 -41
@@ @@ -1,41 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- # Fetch a page from its handle and assign it to a liquid variable.
- #
- # Usage:
- #
- # {% fetch_page 'about_us' as a_page %}
- # <p>{{ a_page.title }}</p>
- #
- class FetchPage < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::VariableSignature}+)\s+as\s+(#{::Liquid::VariableSignature}+)/
-
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @handle = $1
- @var = $2
- else
- raise SyntaxError.new("Syntax Error in 'fetch_page' - Valid syntax: fetch_page page_handle as variable")
- end
-
- super
- end
-
- def render(context)
- mounting_point = context.registers[:mounting_point]
- context.scopes.last[@var] = mounting_point.pages.values.find { |_page| _page.handle == @handle }
- ''
- end
-
- end
-
- ::Liquid::Template.register_tag('fetch_page', FetchPage)
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/google_analytics.rb b/lib/locomotive/wagon/liquid/tags/google_analytics.rb +0 -28
@@ @@ -1,28 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- class GoogleAnalytics < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::Expression}+)?/
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @account_id = $1.gsub('\'', '')
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.google_analytics"), options[:line])
- end
-
- super
- end
-
- def render(context)
- "<!-- google analytics for #{@account_id} -->"
- end
- end
-
- ::Liquid::Template.register_tag('google_analytics', GoogleAnalytics)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/hybrid.rb b/lib/locomotive/wagon/liquid/tags/hybrid.rb +0 -27
@@ @@ -1,27 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- class Hybrid < ::Liquid::Block
- def parse(tokens)
- nesting = 0
- tokens.each do |token|
- next unless token =~ IsTag
- if token =~ FullToken
- if nesting == 0 && $1 == block_delimiter
- @render_as_block = true
- super
- return
- elsif $1 == block_name
- nesting += 1
- elsif $1 == block_delimiter
- nesting -= 1
- end
- end
- end
- end
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/inline_editor.rb b/lib/locomotive/wagon/liquid/tags/inline_editor.rb +0 -16
@@ @@ -1,16 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- class InlineEditor < ::Liquid::Tag
-
- def render(context)
- ''
- end
- end
-
- ::Liquid::Template.register_tag('inline_editor', InlineEditor)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/link_to.rb b/lib/locomotive/wagon/liquid/tags/link_to.rb +0 -56
@@ @@ -1,56 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- class LinkTo < Hybrid
-
- Syntax = /(#{::Liquid::Expression}+)(#{::Liquid::TagAttributes}?)/
-
- include PathHelper
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @handle = $1
- @_options = {}
- markup.scan(::Liquid::TagAttributes) do |key, value|
- @_options[key] = value
- end
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.link_to"), options[:line])
- end
-
- super
- end
-
- def render(context)
- render_path(context) do |page, path|
- label = label_from_page(page)
-
- if @render_as_block
- context.scopes.last['target'] = page
- label = super.html_safe
- end
-
- %{<a href="#{path}">#{label}</a>}
- end
- end
-
- protected
-
- def label_from_page(page)
- ::Locomotive::Mounter.with_locale(@_options['locale']) do
- if page.templatized?
- page.content_entry._label
- else
- page.title
- end
- end
- end
-
- end
-
- ::Liquid::Template.register_tag('link_to', LinkTo)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/locale_switcher.rb b/lib/locomotive/wagon/liquid/tags/locale_switcher.rb +0 -106
@@ @@ -1,106 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- # Display the links to change the locale of the current page
- #
- # Usage:
- #
- # {% locale_switcher %} => <div id="locale-switcher"><a href="/features" class="current en">Features</a><a href="/fr/fonctionnalites" class="fr">Fonctionnalités</a></div>
- #
- # {% locale_switcher label: locale, sep: ' - ' }
- #
- # options:
- # - label: iso (de, fr, en, ...etc), locale (Deutsch, Français, English, ...etc), title (page title)
- # - sep: piece of html code separating 2 locales
- #
- # notes:
- # - "iso" is the default choice for label
- # - " | " is the default separating code
- #
- class LocaleSwitcher < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::Expression}+)?/
-
- def initialize(tag_name, markup, tokens, options)
- @_options = { label: 'iso', sep: ' | ' }
-
- if markup =~ Syntax
- markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }
-
- @_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.locale_switcher"), options[:line])
- end
-
- super
- end
-
- def render(context)
- @site, @page = context.registers[:site], context.registers[:page]
- @default_locale = context.registers[:mounting_point].default_locale
-
- output = %(<div id="locale-switcher">)
-
- output += @site.locales.collect do |locale|
- Locomotive::Mounter.with_locale(locale) do
- fullpath = localized_fullpath(locale)
-
- if @page.templatized?
- permalink = context['entry']._permalink
-
- if permalink
- fullpath.gsub!('*', permalink)
- else
- fullpath = '404'
- end
- end
-
- css = link_class(locale, context['locale'])
-
- %(<a href="/#{fullpath}" class="#{css}">#{link_label(locale)}</a>)
- end
- end.join(@_options[:sep])
-
- output += %(</div>)
- end
-
- private
-
- def link_class(locale, current_locale)
- css = [locale]
- css << 'current' if locale.to_s == current_locale.to_s
- css.join(' ')
- end
-
- def link_label(locale)
- case @_options[:label]
- when 'iso' then locale
- when 'locale' then I18n.t("locomotive.locales.#{locale}")
- when 'title' then @page.title # FIXME: this returns nil if the page has not been translated in the locale
- else
- locale
- end
- end
-
- def localized_fullpath(locale)
- return nil if @page.fullpath_translations.blank?
-
- fullpath = @page.safe_fullpath || @page.fullpath_or_default
-
- if locale.to_s == @default_locale.to_s # no need to specify the locale
- @page.index? ? '' : fullpath
- elsif @page.index? # avoid /en/index or /fr/index, prefer /en or /fr instead
- locale
- else
- File.join(locale, fullpath)
- end
- end
-
- end
-
- ::Liquid::Template.register_tag('locale_switcher', LocaleSwitcher)
- end
- end
- end
- end
locomotive/wagon/liquid/tags/model_form.rb b/lib/locomotive/wagon/liquid/tags/model_form.rb +0 -67
@@ @@ -1,67 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- # Display the form html tag with the appropriate hidden fields in order to create
- # a content entry from a public site.
- # It handles callbacks, csrf and target url out of the box.
- #
- # Usage:
- #
- # {% model_form 'newsletter_addresses' %}
- # <input type='text' name='content[email]' />
- # <input type='submit' value='Add' />
- # {% endform_form %}
- #
- # {% model_form 'newsletter_addresses', class: 'a-css-class', success: 'http://www.google.fr', error: '/error' %}...{% endform_form %}
- #
- class ModelForm < Solid::Block
-
- tag_name :model_form
-
- def display(*options, &block)
- name = options.shift
- options = options.shift || {}
-
- form_attributes = { method: 'POST', enctype: 'multipart/form-data' }.merge(options.slice(:id, :class))
-
- html_content_tag :form,
- content_type_html(name) + callbacks_html(options) + yield,
- form_attributes
- end
-
- def content_type_html(name)
- html_tag :input, type: 'hidden', name: 'content_type_slug', value: name
- end
-
- def callbacks_html(options)
- options.slice(:success, :error).map do |(name, value)|
- html_tag :input, type: 'hidden', name: "#{name}_callback", value: value
- end.join('')
- end
-
- private
-
- def html_content_tag(name, content, options = {})
- "<#{name} #{inline_options(options)}>#{content}</#{name}>"
- end
-
- def html_tag(name, options = {})
- "<#{name} #{inline_options(options)} />"
- end
-
- # Write options (Hash) into a string according to the following pattern:
- # <key1>="<value1>", <key2>="<value2", ...etc
- def inline_options(options = {})
- return '' if options.empty?
- (options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ')
- end
-
- end
-
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/nav.rb b/lib/locomotive/wagon/liquid/tags/nav.rb +0 -287
@@ @@ -1,287 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- # Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
- # The html output is based on the ul/li tags.
- #
- # Usage:
- #
- # {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
- #
- # {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }
- #
- class Nav < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::Expression}+)?/
-
- attr_accessor :current_page, :mounting_point
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @source = ($1 || 'page').gsub(/"|'/, '')
-
- self.set_options(markup, options)
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.nav"), options[:line])
- end
-
- super
- end
-
- def render(context)
- self.set_accessors_from_context(context)
-
- entries = self.fetch_entries
- output = self.build_entries_output(entries)
-
- if self.no_wrapper?
- output
- else
- self.render_tag(:nav, id: @_options[:id], css: @_options[:class]) do
- self.render_tag(:ul) { output }
- end
- end
- end
-
- protected
-
- # Build recursively the links of all the pages.
- #
- # @param [ Array ] entries List of pages
- #
- # @return [ String ] The final HTML output
- #
- def build_entries_output(entries, depth = 1)
- output = []
-
- entries.each_with_index do |page, index|
- css = []
- css << 'first' if index == 0
- css << 'last' if index == entries.size - 1
-
- output << self.render_entry_link(page, css.join(' '), depth)
- end
-
- output.join("\n")
- end
-
- # Get all the children of a source: site (index page), parent or page.
- #
- # @return [ Array ] List of pages
- #
- def fetch_entries
- children = (case @source
- when 'site' then self.mounting_point.pages['index']
- when 'parent' then self.current_page.parent || self.current_page
- when 'page' then self.current_page
- else
- self.mounting_point.pages[@source]
- end).children.try(:clone) || []
-
- children.delete_if { |p| !include_page?(p) }
- end
-
- # Determine whether or not a page should be a part of the menu.
- #
- # @param [ Object ] page The page
- #
- # @return [ Boolean ] True if the page can be included or not
- #
- def include_page?(page)
- if !page.listed? || page.templatized? || !page.published?
- false
- elsif @_options[:exclude]
- (page.fullpath =~ @_options[:exclude]).nil?
- else
- true
- end
- end
-
- # Determine wether or not a page is currently the displayed one.
- #
- # @param [ Object ] page The page
- #
- # @return [ Boolean ]
- #
- def page_selected?(page)
- self.current_page.fullpath =~ /^#{page.fullpath}(\/.*)?$/
- end
-
- # Determine if the children of a page have to be rendered or not.
- # It depends on the depth passed in the option.
- #
- # @param [ Object ] page The page
- # @param [ Integer ] depth The current depth
- #
- # @return [ Boolean ] True if the children have to be rendered.
- #
- def render_children_for_page?(page, depth)
- depth.succ <= @_options[:depth].to_i &&
- (page.children || []).select { |child| self.include_page?(child) }.any?
- end
-
- # Return the label of an entry. It may use or not the template
- # given by the snippet option.
- #
- # @param [ Object ] page The page
- #
- # @return [ String ] The label in HTML
- #
- def entry_label(page)
- icon = @_options[:icon] ? '<span></span>' : ''
- title = @_options[:liquid_render] ? @_options[:liquid_render].render('page' => page) : page.title
-
- if icon.blank?
- title
- elsif @_options[:icon] == 'after'
- "#{title} #{icon}"
- else
- "#{icon} #{title}"
- end
- end
-
- # Return the localized url of an entry (page).
- #
- # @param [ Object ] page The page
- #
- # @return [ String ] The localized url
- #
- def entry_url(page)
- if ::I18n.locale.to_s == self.mounting_point.default_locale.to_s
- "/#{page.fullpath}"
- else
- "/#{::I18n.locale}/#{page.fullpath}"
- end
- end
-
- # Return the css of an entry (page).
- #
- # @param [ Object ] page The page
- # @param [ String ] css The extra css
- #
- # @return [ String ] The css
- #
- def entry_css(page, css = '')
- _css = 'link'
- _css += " #{page} #{@_options[:active_class]}" if self.page_selected?(page)
-
- (_css + " #{css}").strip
- end
-
- # Return the HTML output of a page and its children if requested.
- #
- # @param [ Object ] page The page
- # @param [ String ] css The current css to apply to the entry
- # @param [ Integer] depth Used to know if the children has to be added or not.
- #
- # @return [ String ] The HTML output
- #
- def render_entry_link(page, css, depth)
- url = self.entry_url(page)
- label = self.entry_label(page)
- css = self.entry_css(page, css)
- options = ''
-
- if self.render_children_for_page?(page, depth) && self.bootstrap?
- url = '#'
- label += %{ <b class="caret"></b>}
- css += ' dropdown'
- options = %{ class="dropdown-toggle" data-toggle="dropdown"}
- end
-
- self.render_tag(:li, id: "#{page.slug.to_s.dasherize}-link", css: css) do
- children_output = depth.succ <= @_options[:depth].to_i ? self.render_entry_children(page, depth.succ) : ''
- %{<a href="#{url}"#{options}>#{label}</a>} + children_output
- end
- end
-
- # Recursively create a nested unordered list for the depth specified.
- #
- # @param [ Array ] entries The children of the page
- # @param [ Integer ] depth The current depth
- #
- # @return [ String ] The HTML code
- #
- def render_entry_children(page, depth)
- entries = (page.children || []).select { |child| self.include_page?(child) }
- css = self.bootstrap? ? 'dropdown-menu' : ''
-
- unless entries.empty?
- self.render_tag(:ul, id: "#{@_options[:id]}-#{page.slug.to_s.dasherize}", css: css) do
- self.build_entries_output(entries, depth)
- end
- else
- ''
- end
- end
-
- # Set the value (default or assigned by the tag) of the options.
- #
- def set_options(markup, options)
- @_options = { id: 'nav', class: '', active_class: 'on', bootstrap: false, no_wrapper: false }
-
- markup.scan(::Liquid::TagAttributes) { |key, value| @_options[key.to_sym] = value.gsub(/"|'/, '') }
-
- @_options[:exclude] = Regexp.new(@_options[:exclude]) if @_options[:exclude]
-
- if @_options[:snippet]
- if template = self.parse_snippet_template(options, @_options[:snippet])
- @_options[:liquid_render] = template
- end
- end
- end
-
- # Avoid to call context.registers to get the current page
- # and the mounting point.
- #
- def set_accessors_from_context(context)
- self.current_page = context.registers[:page]
- self.mounting_point = context.registers[:mounting_point]
- end
-
- # Parse the template of the snippet give in option of the tag.
- # If the template_name contains a liquid tag or drop, it will
- # be used an inline template.
- #
- def parse_snippet_template(context, template_name)
- source = if template_name.include?('{')
- template_name
- else
- context[:mounting_point].snippets[template_name].try(:source)
- end
-
- source ? ::Liquid::Template.parse(source) : nil
- end
-
- # Render any kind HTML tags. The content of the tag comes from
- # the block.
- #
- # @param [ String ] tag_name Name of the HTML tag (li, ul, div, ...etc).
- # @param [ String ] html_options Id, class, ..etc
- #
- # @return [ String ] The HTML
- #
- def render_tag(tag_name, html_options = {}, &block)
- options = ['']
- options << %{id="#{html_options[:id]}"} if html_options[:id].present?
- options << %{class="#{html_options[:css]}"} if html_options[:css].present?
-
- %{<#{tag_name}#{options.join(' ')}>#{yield}</#{tag_name}>}
- end
-
- def bootstrap?
- @_options[:bootstrap].to_bool
- end
-
- def no_wrapper?
- @_options[:no_wrapper].to_bool
- end
-
- ::Liquid::Template.register_tag('nav', Nav)
- end
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/paginate.rb b/lib/locomotive/wagon/liquid/tags/paginate.rb +0 -105
@@ @@ -1,105 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- # Paginate a collection
- #
- # Usage:
- #
- # {% paginate contents.projects by 5 %}
- # {% for project in paginate.collection %}
- # {{ project.name }}
- # {% endfor %}
- # {% endpaginate %}
- #
-
- class Paginate < ::Liquid::Block
-
- Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @collection_name = $1
- @per_page = $2.to_i
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.paginate"), options[:line])
- end
-
- super
- end
-
- def render(context)
- context.stack do
- collection = context[@collection_name]
-
- raise ::Liquid::ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection.nil?
-
- pagination = collection.send(:paginate, {
- :page => context['current_page'],
- :per_page => @per_page }).stringify_keys!
-
- page_count, current_page = pagination['total_pages'], pagination['current_page']
-
- path = sanitize_path(context['fullpath'])
-
- pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
- pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']
- pagination['parts'] = []
-
- hellip_break = false
-
- if page_count > 1
- 1.upto(page_count) do |page|
- if current_page == page
- pagination['parts'] << no_link(page)
- elsif page == 1
- pagination['parts'] << link(page, page, path)
- elsif page == page_count - 1
- pagination['parts'] << link(page, page, path)
- elsif page <= current_page - window_size or page >= current_page + window_size
- next if hellip_break
- pagination['parts'] << no_link('&hellip;')
- hellip_break = true
- next
- else
- pagination['parts'] << link(page, page, path)
- end
-
- hellip_break = false
- end
- end
-
- context['paginate'] = pagination
-
- render_all(@nodelist, context)
- end
- end
-
- private
-
- def sanitize_path(path)
- _path = path.gsub(/page=[0-9]+&?/, '').gsub(/_pjax=true&?/, '')
- _path = _path.slice(0..-2) if _path.last == '?' || _path.last == '&'
- _path
- end
-
- def window_size
- 3
- end
-
- def no_link(title)
- { 'title' => title, 'is_link' => false, 'hellip_break' => title == '&hellip;' }
- end
-
- def link(title, page, path)
- _path = %(#{path}#{path.include?('?') ? '&' : '?'}page=#{page})
- { 'title' => title, 'url' => _path, 'is_link' => true }
- end
- end
-
- ::Liquid::Template.register_tag('paginate', Paginate)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/path_helper.rb b/lib/locomotive/wagon/liquid/tags/path_helper.rb +0 -97
@@ @@ -1,97 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- module PathHelper
-
- def render_path(context, &block)
- site = context.registers[:site]
-
- if page = self.retrieve_page_from_handle(context)
- path = self.public_page_fullpath(context, page)
-
- if block_given?
- block.call page, path
- else
- path
- end
- else
- raise Liquid::PageNotTranslated.new(%{[link_to] Unable to find a page for the #{@handle}. Wrong handle or missing template for your content.})
- end
- end
-
- protected
-
- def retrieve_page_from_handle(context)
- mounting_point = context.registers[:mounting_point]
-
- context.scopes.reverse_each do |scope|
- handle = scope[@handle] || @handle
-
- page = case handle
- when Locomotive::Mounter::Models::Page then handle
- when Liquid::Drops::Page then handle.instance_variable_get(:@_source)
- when String then fetch_page(mounting_point, handle)
- when Liquid::Drops::ContentEntry then fetch_page(mounting_point, handle.instance_variable_get(:@_source), true)
- when Locomotive::Mounter::Models::ContentEntry then fetch_page(mounting_point, handle, true)
- else
- nil
- end
-
- return page unless page.nil?
- end
-
- nil
- end
-
- def fetch_page(mounting_point, handle, templatized = false)
- ::Locomotive::Mounter.with_locale(@_options['locale']) do
- if templatized
- page = mounting_point.pages.values.find do |_page|
- _page.templatized? &&
- _page.content_type.slug == handle.content_type.slug &&
- (@_options['with'].nil? || _page.handle == @_options['with'])
- end
-
- page.content_entry = handle if page
-
- page
- else
- mounting_point.pages.values.find { |_page| _page.handle == handle }
- end
- end
- end
-
- def public_page_fullpath(context, page)
- mounting_point = context.registers[:mounting_point]
- locale = @_options['locale'] || ::I18n.locale
-
- if !page.translated_in?(locale)
- title = page.title_translations.values.compact.first
- raise Liquid::PageNotTranslated.new(%{the "#{title}" page is not translated in #{locale.upcase}})
- end
-
- fullpath = ::Locomotive::Mounter.with_locale(locale) do
- page.fullpath.clone
- end
-
- fullpath = "#{locale}/#{fullpath}" if locale.to_s != mounting_point.default_locale.to_s
-
- if page.templatized?
- if page.content_entry._slug.nil?
- title = %{#{page.content_entry.content_type.name.singularize} "#{page.content_entry.send(page.content_entry.content_type.label_field_name)}"}
- raise Liquid::ContentEntryNotTranslated.new(%{the #{title} slug is not translated in #{locale.upcase}})
- end
- fullpath.gsub!(/(content[_-]type[_-]template|template)/, page.content_entry._slug)
- end
-
- File.join('/', fullpath)
- end
-
- end
- end
-
- end
- end
- end
locomotive/wagon/liquid/tags/path_to.rb b/lib/locomotive/wagon/liquid/tags/path_to.rb +0 -36
@@ @@ -1,36 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- class PathTo < ::Liquid::Tag
-
- include PathHelper
-
- Syntax = /(#{::Liquid::Expression}+)(#{::Liquid::TagAttributes}?)/
-
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @handle = $1
- @_options = {}
- markup.scan(::Liquid::TagAttributes) do |key, value|
- @_options[key] = value
- end
- else
- raise SyntaxError.new("Syntax Error in 'path_to' - Valid syntax: path_to <page|page_handle|content_entry>(, locale: [fr|de|...], with: <page_handle>")
- end
-
- super
- end
-
- def render(context)
- render_path(context)
- end
-
- end
-
- ::Liquid::Template.register_tag('path_to', PathTo)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/seo.rb b/lib/locomotive/wagon/liquid/tags/seo.rb +0 -74
@@ @@ -1,74 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
- module SEO
-
- class Base < ::Liquid::Tag
-
- def render(context)
- %{
- #{self.render_title(context)}
- #{self.render_metadata(context)}
- }
- end
-
- protected
-
- def render_title(context)
- title = self.value_for(:seo_title, context)
- title = context.registers[:site].name if title.blank?
-
- %{
- <title>#{title}</title>
- }
- end
-
- def render_metadata(context)
- %{
- <meta name="description" content="#{self.value_for(:meta_description, context)}" />
- <meta name="keywords" content="#{self.value_for(:meta_keywords, context)}" />
- }
- end
-
- # Removes whitespace and quote characters from the input
- def sanitized_string(string)
- string ? string.strip.gsub(/"/, '') : ''
- end
-
- def value_for(attribute, context)
- object = self.metadata_object(context)
- value = object.try(attribute.to_sym).blank? ? context.registers[:site].send(attribute.to_sym) : object.send(attribute.to_sym)
- self.sanitized_string(value)
- end
-
- def metadata_object(context)
- context['content_instance'] || context['page']
- end
- end
-
- class Title < Base
-
- def render(context)
- self.render_title(context)
- end
-
- end
-
- class Metadata < Base
-
- def render(context)
- self.render_metadata(context)
- end
-
- end
-
- end
-
- ::Liquid::Template.register_tag('seo', SEO::Base)
- ::Liquid::Template.register_tag('seo_title', SEO::Title)
- ::Liquid::Template.register_tag('seo_metadata', SEO::Metadata)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/session_assign.rb b/lib/locomotive/wagon/liquid/tags/session_assign.rb +0 -41
@@ @@ -1,41 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- # Assign sets a variable in your session.
- #
- # {% session_assign foo = 'monkey' %}
- #
- # You can then use the variable later in the page.
- #
- # {{ session.foo }}
- #
- class SessionAssign < ::Liquid::Tag
- Syntax = /(#{::Liquid::VariableSignature}+)\s*=\s*(#{::Liquid::QuotedFragment}+)/
-
- def initialize(tag_name, markup, tokens, options)
- if markup =~ Syntax
- @to = $1
- @from = $2
- else
- raise ::Liquid::SyntaxError.new(options[:locale].t("errors.syntax.session_assign"), options[:line])
- end
-
- super
- end
-
- def render(context)
- request = context.registers[:request]
-
- request.session[@to.to_sym] = context[@from]
- ''
- end
-
- end
-
- ::Liquid::Template.register_tag('session_assign', SessionAssign)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/snippet.rb b/lib/locomotive/wagon/liquid/tags/snippet.rb +0 -63
@@ @@ -1,63 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- class Snippet < ::Liquid::Include
-
- def render(context)
- name = @template_name.gsub(/[\"\']/, '')
- snippet = context.registers[:mounting_point].snippets[name]
-
- raise ::Liquid::StandardError.new("Unknown snippet \"#{name}\"") if snippet.nil?
-
- partial = self.parse_template(snippet)
-
- variable = context[@variable_name || @template_name[1..-2]]
-
- context.stack do
- @attributes.each do |key, value|
- context[key] = context[value]
- end
-
- output = (if variable.is_a?(Array)
- variable.collect do |variable|
- context[@template_name[1..-2]] = variable
- partial.render(context)
- end
- else
- context[@template_name[1..-2]] = variable
- partial.render(context)
- end)
-
- Locomotive::Wagon::Logger.info " Rendered snippet #{name}"
-
- output
- end
- end
-
- protected
-
- def parse_template(snippet)
- begin
- ::Liquid::Template.parse(snippet.source)
- rescue ::Liquid::Error => e
- # do it again on the raw source instead so that the error line matches
- # the source file.
- begin
- ::Liquid::Template.parse(snippet.template.raw_source)
- rescue ::Liquid::Error => e
- e.backtrace.unshift "#{snippet.template.filepath}:#{e.line + 1}:in `#{snippet.name}'"
- e.line = self.line - 1
- raise e
- end
- end
- end
-
- end
-
- ::Liquid::Template.register_tag('include', Snippet)
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/liquid/tags/with_scope.rb b/lib/locomotive/wagon/liquid/tags/with_scope.rb +0 -48
@@ @@ -1,48 +0,0 @@
- module Locomotive
- module Wagon
- module Liquid
- module Tags
-
- class WithScope < Solid::Block
-
- OPERATORS = %w(all exists gt gte in lt lte ne nin size near within)
-
- SYMBOL_OPERATORS_REGEXP = /(\w+\.(#{OPERATORS.join('|')})){1}\s*\:/
-
- # register the tag
- tag_name :with_scope
-
- def initialize(tag_name, arguments_string, tokens, context = {})
- # convert symbol operators into valid ruby code
- arguments_string.gsub!(SYMBOL_OPERATORS_REGEXP, ':"\1" =>')
-
- super(tag_name, arguments_string, tokens, context)
- end
-
- def display(options = {}, &block)
- current_context.stack do
- current_context['with_scope'] = self.decode(options)
- yield
- end
- end
-
- protected
-
- def decode(options)
- HashWithIndifferentAccess.new.tap do |hash|
- options.each do |key, value|
- hash[key] = (case value
- # regexp inside a string
- when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
- else
- value
- end)
- end
- end
- end
- end
-
- end
- end
- end
- end
\ No newline at end of file
locomotive/wagon/server.rb b/lib/locomotive/wagon/server.rb +0 -86
@@ @@ -1,86 +0,0 @@
- require 'rack-livereload'
- require 'better_errors'
- require 'coffee_script'
-
- require 'locomotive/wagon/listen'
- require 'locomotive/wagon/server/middleware'
- require 'locomotive/wagon/server/favicon'
- require 'locomotive/wagon/server/dynamic_assets'
- require 'locomotive/wagon/server/logging'
- require 'locomotive/wagon/server/entry_submission'
- require 'locomotive/wagon/server/path'
- require 'locomotive/wagon/server/locale'
- require 'locomotive/wagon/server/page'
- require 'locomotive/wagon/server/timezone'
- require 'locomotive/wagon/server/templatized_page'
- require 'locomotive/wagon/server/renderer'
-
- require 'locomotive/wagon/liquid'
- require 'locomotive/wagon/misc'
-
- module Locomotive::Wagon
- class Server
-
- attr_reader :options
-
- def initialize(reader, options = {})
- Locomotive::Wagon::Dragonfly.setup!(reader.mounting_point.path)
-
- Sprockets::Sass.add_sass_functions = false
-
- @reader = reader
- @options = options
- @app = self.create_rack_app(@reader, @options)
-
- BetterErrors.application_root = reader.mounting_point.path
- end
-
- def call(env)
- env['wagon.mounting_point'] = @reader.mounting_point
- @app.call(env)
- end
-
- protected
-
- def create_rack_app(reader, options)
- Rack::Builder.new do
- use Rack::LiveReload, live_reload_port: options[:live_reload_port] if options[:live_reload_port]
-
- use Rack::Lint
-
- use BetterErrors::MiddlewareWrapper
-
- use Rack::Session::Cookie, {
- key: 'wagon.session',
- path: '/',
- expire_after: 2592000,
- secret: 'uselessinlocal'
- }
-
- use ::Dragonfly::Middleware, :images
-
- use Rack::Static, {
- urls: ['/images', '/fonts', '/samples', '/media'],
- root: File.join(reader.mounting_point.path, 'public')
- }
-
- use Favicon
- use DynamicAssets, reader.mounting_point.path
-
- use Logging
-
- use EntrySubmission
-
- use Path
- use Locale
- use Timezone
-
- use Page
- use TemplatizedPage
-
- run Renderer.new
- end
- end
-
- end
- end
locomotive/wagon/server/dynamic_assets.rb b/lib/locomotive/wagon/server/dynamic_assets.rb +0 -33
@@ @@ -1,33 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- class DynamicAssets < Middleware
-
- attr_reader :app, :sprockets, :regexp
-
- def initialize(app, site_path)
- super(app)
-
- @regexp = /^\/(javascripts|stylesheets)\/(.*)$/
-
- @sprockets = Locomotive::Mounter::Extensions::Sprockets.environment(site_path)
- end
-
- def call(env)
- if env['PATH_INFO'] =~ self.regexp
- env['PATH_INFO'] = $2
-
- begin
- self.sprockets.call(env)
- rescue Exception => e
- raise Locomotive::Wagon::DefaultException.new "Unable to serve a dynamic asset. Please check the logs.", e
- end
- else
- app.call(env)
- end
- end
-
- end
-
- end
- end
locomotive/wagon/server/entry_submission.rb b/lib/locomotive/wagon/server/entry_submission.rb +0 -151
@@ @@ -1,151 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Mimic the submission of a content entry
- #
- class EntrySubmission < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- if slug = get_content_type_slug(env)
- self.process_form(slug)
-
- self.navigation_behavior(env)
- else
- self.fetch_submitted_entry
-
- app.call(env)
- end
- end
-
- # Render or redirect depending on:
- # - the status of the content entry (valid or not)
- # - the presence of a callback or not
- # - the type of response asked by the browser (html or json)
- #
- def navigation_behavior(env)
- if @entry.valid?
- navigation_success(env)
- else
- navigation_error(env)
- end
- end
-
- def navigation_success(env)
- if self.html?
- self.record_submitted_entry
- self.redirect_to success_location
- elsif self.json?
- self.json_response
- end
- end
-
- def navigation_error(env)
- if self.html?
- if error_location =~ %r(^http://)
- self.redirect_to error_location
- else
- env['PATH_INFO'] = error_location
- self.liquid_assigns[@content_type.slug.singularize] = @entry
- app.call(env)
- end
- elsif self.json?
- self.json_response(422)
- end
- end
-
- protected
-
- def success_location; location(:success); end
- def error_location; location(:error); end
-
- def location(state)
- params[:"#{state}_callback"] || (entry_submissions_path? ? '/' : path_info)
- end
-
- def entry_submissions_path?
- !(path_info =~ %r(^/entry_submissions/)).nil?
- end
-
- # Get the slug (or permalink) of the content type either from the PATH_INFO variable (old way)
- # or from the presence of the content_type_slug param (model_form tag).
- #
- def get_content_type_slug(env)
- if request.post? && (path_info =~ %r(^/entry_submissions/(.*)) || params[:content_type_slug])
- $1 || params[:content_type_slug]
- end
- end
-
- # Record in session the newly "persisted" content entry.
- #
- def record_submitted_entry
- session[:now] ||= {}
- session[:now][:submitted_entry] = [@content_type.slug, @entry._slug]
- end
-
- def fetch_submitted_entry
- if data = session[:now].try(:delete, :submitted_entry)
- content_type = self.mounting_point.content_types[data.first.to_s]
-
- entry = (content_type.entries || []).detect { |e| e._slug == data.last }
-
- # do not keep track of the entry
- content_type.entries.delete(entry) if entry
-
- # add it to the additional liquid assigns for the next liquid rendering
- if entry
- self.liquid_assigns[content_type.slug.singularize] = entry
- end
- end
- end
-
- # Mimic the creation of a content entry with a minimal validation.
- #
- # @param [ String ] slug The slug (or permalink) of the content type
- #
- #
- def process_form(slug)
- slug = slug.split('.').first
-
- @content_type = self.mounting_point.content_types[slug]
-
- raise "Unknown content type '#{@content_type.inspect}'" if @content_type.nil?
-
- attributes = self.params[:entry] || self.params[:content] || {}
-
- @entry = @content_type.build_entry(attributes)
-
- # if not valid, we do not need to keep track of the entry
- @content_type.entries.delete(@entry) if !@entry.valid?
- end
-
- # Build the JSON response
- #
- # @param [ Integer ] status The HTTP return code
- #
- # @return [ Array ] The rack response depending on the validation status and the requested format
- #
- def json_response(status = 200)
- locale = self.mounting_point.default_locale
-
- if self.request.path =~ /^\/(#{self.mounting_point.locales.join('|')})+(\/|$)/
- locale = $1
- end
-
- hash = @entry.to_hash(false).tap do |_hash|
- if !@entry.valid?
- _hash['errors'] = @entry.errors.inject({}) do |memo, name|
- memo[name] = ::I18n.t('errors.messages.blank', locale: locale)
- memo
- end
- end
- end
-
- [status, { 'Content-Type' => 'application/json' }, [hash.to_json]]
- end
-
- end
-
- end
- end
\ No newline at end of file
locomotive/wagon/server/favicon.rb b/lib/locomotive/wagon/server/favicon.rb +0 -17
@@ @@ -1,17 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- class Favicon < Middleware
-
- def call(env)
- if env['PATH_INFO'] == '/favicon.ico'
- [200, { 'Content-Type' => 'image/vnd.microsoft.icon' }, ['']]
- else
- app.call(env)
- end
- end
-
- end
-
- end
- end
\ No newline at end of file
locomotive/wagon/server/locale.rb b/lib/locomotive/wagon/server/locale.rb +0 -42
@@ @@ -1,42 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Set the locale from the path if possible or use the default one
- # Examples:
- # /fr/index => locale = :fr
- # /fr/ => locale = :fr
- # /index => locale = :en (default one)
- #
- class Locale < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- self.set_locale!(env)
-
- app.call(env)
- end
-
- protected
-
- def set_locale!(env)
- locale = self.mounting_point.default_locale
-
- if self.path =~ /^(#{self.mounting_point.locales.join('|')})+(\/|$)/
- locale = $1
- self.path = self.path.gsub($1 + $2, '')
- self.path = 'index' if self.path.blank?
- end
-
- Locomotive::Mounter.locale = locale
- ::I18n.locale = locale
-
- self.log "Detecting locale #{locale.upcase}"
-
- env['wagon.locale'] = locale
- env['wagon.path'] = self.path
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/server/logging.rb b/lib/locomotive/wagon/server/logging.rb +0 -32
@@ @@ -1,32 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Track the request into the current logger
- #
- class Logging < Middleware
-
- def call(env)
- now = Time.now
-
- log "Started #{env['REQUEST_METHOD'].upcase} \"#{env['PATH_INFO']}\" at #{now}".light_white
-
- app.call(env).tap do |response|
- done_in_ms = ((Time.now - now) * 10000).truncate / 10.0
- log "Completed #{code_to_human(response.first)} in #{done_in_ms}ms\n\n".green
- end
- end
-
- protected
-
- def code_to_human(code)
- case code.to_i
- when 200 then '200 OK'
- when 301 then '301 Found'
- when 302 then '302 Found'
- when 404 then '404 Not Found'
- end
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/server/middleware.rb b/lib/locomotive/wagon/server/middleware.rb +0 -63
@@ @@ -1,63 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- class Middleware
-
- extend Forwardable
- def_delegators :request, :path_info, :session
-
- attr_accessor :app, :request, :path, :liquid_assigns
- attr_accessor :mounting_point, :page, :content_entry
-
- def initialize(app = nil)
- @app = app
- end
-
- def call(env)
- app.call(env)
- end
-
- protected
-
- def set_accessors(env)
- self.request = Rack::Request.new(env)
- self.path = env['wagon.path']
- self.mounting_point = env['wagon.mounting_point']
- self.page = env['wagon.page']
- self.content_entry = env['wagon.content_entry']
-
- env['wagon.liquid_assigns'] ||= {}
- self.liquid_assigns = env['wagon.liquid_assigns']
- end
-
- def site
- self.mounting_point.site
- end
-
- def params
- self.request.params.deep_symbolize_keys
- end
-
- def html?
- ['text/html', 'application/x-www-form-urlencoded'].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 redirect_to(location, type = 301)
- self.log "Redirected to #{location}"
- [type, { 'Content-Type' => 'text/html', 'Location' => location }, []]
- end
-
- def log(msg)
- Locomotive::Wagon::Logger.info msg
- end
-
- end
-
- end
- end
\ No newline at end of file
locomotive/wagon/server/page.rb b/lib/locomotive/wagon/server/page.rb +0 -67
@@ @@ -1,67 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Sanitize the path from the previous middleware in order
- # to make it work for the renderer.
- #
- class Page < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- self.set_page!(env)
-
- app.call(env)
- end
-
- protected
-
- def set_page!(env)
- page = self.fetch_page
-
- if page
- self.log "Found page \"#{page.title}\" [#{page.safe_fullpath}]"
- end
-
- env['wagon.page'] = page
- end
-
- def fetch_page
- matchers = self.path_combinations(self.path)
-
- pages = self.mounting_point.pages.values.find_all do |_page|
- matchers.include?(_page.safe_fullpath) ||
- matchers.include?(_page.safe_fullpath.try(:underscore))
- end.sort_by { |p| p.position || Float::INFINITY }
-
- if pages.size > 1
- self.log "Found multiple pages: #{pages.collect(&:title).join(', ')}"
- end
-
- pages.first
- end
-
- def path_combinations(path)
- self._path_combinations(path.split('/'))
- end
-
- def _path_combinations(segments, can_include_template = true)
- return nil if segments.empty?
-
- segment = segments.shift
-
- (can_include_template ? [segment, '*'] : [segment]).map do |_segment|
- if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != '*'))
- [*_combinations].map do |_combination|
- File.join(_segment, _combination)
- end
- else
- [_segment]
- end
- end.flatten
- end
-
- end
-
- end
- end
locomotive/wagon/server/path.rb b/lib/locomotive/wagon/server/path.rb +0 -34
@@ @@ -1,34 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Sanitize the path from the previous middleware in order
- # to make it work for the renderer.
- #
- class Path < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- self.set_path!(env)
-
- app.call(env)
- end
-
- protected
-
- def set_path!(env)
- path = env['PATH_INFO'].clone
-
- path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '')
- path.gsub!(/^\//, '')
- path.gsub!(/^[A-Z]:\//, '')
-
- path = 'index' if path.blank?
-
- env['wagon.path'] = path
- end
-
- end
-
- end
- end
\ No newline at end of file
locomotive/wagon/server/renderer.rb b/lib/locomotive/wagon/server/renderer.rb +0 -118
@@ @@ -1,118 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- class Renderer < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- if self.page
- if self.page.redirect?
- self.redirect_to(self.page.redirect_url, self.page.redirect_type)
- else
- type = self.page.response_type || 'text/html'
- html = self.render_page
-
- self.log " Rendered liquid page template"
-
- [200, { 'Content-Type' => type }, [html]]
- end
- else
- [404, { 'Content-Type' => 'text/html' }, [self.render_404]]
- end
- end
-
- protected
-
- def render_page
- context = self.locomotive_context
- begin
- self.page.render(context)
- rescue Exception => e
- raise RendererException.new(e, self.page.title, self.page.template, context)
- end
- end
-
- def render_404
- if self.page = self.mounting_point.pages['404']
- self.render_page
- else
- 'Page not found'
- end
- end
-
- # Build the Liquid context used to render the Locomotive page. It
- # stores both assigns and registers.
- #
- # @param [ Hash ] other_assigns Assigns coming for instance from the controler (optional)
- #
- # @return [ Object ] A new instance of the Liquid::Context class.
- #
- def locomotive_context(other_assigns = {})
- assigns = self.locomotive_default_assigns
-
- # assigns from other middlewares
- assigns.merge!(self.liquid_assigns)
-
- assigns.merge!(other_assigns)
-
- # templatized page
- if self.page && self.content_entry
- ['content_entry', 'entry', self.page.content_type.slug.singularize].each do |key|
- assigns[key] = self.content_entry
- end
- end
-
- # Tip: switch from false to true to enable the re-thrown exception flag
- ::Liquid::Context.new({}, assigns, self.locomotive_default_registers, true)
- end
-
- # Return the default Liquid assigns used inside the Locomotive Liquid context
- #
- # @return [ Hash ] The default liquid assigns object
- #
- def locomotive_default_assigns
- {
- 'site' => self.site.to_liquid,
- 'page' => self.page,
- 'models' => Locomotive::Wagon::Liquid::Drops::ContentTypes.new,
- 'contents' => Locomotive::Wagon::Liquid::Drops::ContentTypes.new,
- 'current_page' => self.params[:page],
- 'params' => self.params.stringify_keys,
- 'path' => self.request.path,
- 'fullpath' => self.request.fullpath,
- 'url' => self.request.url,
- 'ip_address' => self.request.ip,
- 'post?' => self.request.post?,
- 'host' => self.request.host_with_port,
- 'now' => Time.zone.now,
- 'today' => Date.today,
- 'locale' => I18n.locale.to_s,
- 'default_locale' => self.mounting_point.default_locale.to_s,
- 'locales' => self.mounting_point.locales.map(&:to_s),
- 'current_user' => {},
- 'session' => Locomotive::Wagon::Liquid::Drops::SessionProxy.new,
- 'wagon' => true,
- 'editing' => false
- }
- end
-
- # Return the default Liquid registers used inside the Locomotive Liquid context
- #
- # @return [ Hash ] The default liquid registers object
- #
- def locomotive_default_registers
- {
- request: self.request,
- site: self.site,
- page: self.page,
- mounting_point: self.mounting_point,
- inline_editor: false,
- logger: Locomotive::Wagon::Logger
- }
- end
-
- end
-
- end
- end
locomotive/wagon/server/templatized_page.rb b/lib/locomotive/wagon/server/templatized_page.rb +0 -32
@@ @@ -1,32 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- class TemplatizedPage < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- if self.page && self.page.templatized?
- self.set_content_entry!(env)
- end
-
- app.call(env)
- end
-
- protected
-
- def set_content_entry!(env)
- %r(^#{self.page.safe_fullpath.gsub('*', '([^\/]+)')}$) =~ self.path
-
- permalink = $1
-
- if content_entry = self.page.content_type.find_entry(permalink)
- env['wagon.content_entry'] = content_entry
- else
- env['wagon.page'] = nil
- end
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/server/timezone.rb b/lib/locomotive/wagon/server/timezone.rb +0 -18
@@ @@ -1,18 +0,0 @@
- module Locomotive::Wagon
- class Server
-
- # Set the timezone according to the settings of the site
- #
- class Timezone < Middleware
-
- def call(env)
- self.set_accessors(env)
-
- Time.use_zone(site.try(:timezone) || 'UTC') do
- app.call(env)
- end
- end
-
- end
- end
- end
\ No newline at end of file
locomotive/wagon/version.rb b/lib/locomotive/wagon/version.rb +1 -1
@@ @@ -1,5 +1,5 @@
module Locomotive
module Wagon
- VERSION = '1.5.3'
+ VERSION = '2.0.0-alpha'
end
end
locomotivecms_wagon.gemspec +0 -10
@@ @@ -20,12 +20,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'thor'
gem.add_dependency 'thin', '~> 1.6.1'
- gem.add_dependency 'activesupport', '~> 3.2.18'
- gem.add_dependency 'locomotivecms-solid', '~> 0.2.2.1'
- gem.add_dependency 'RedCloth', '~> 4.2.8'
- gem.add_dependency 'redcarpet', '~> 3.0.0'
- gem.add_dependency 'dragonfly', '~> 0.9.12'
- gem.add_dependency 'rack-cache', '~> 1.1'
gem.add_dependency 'better_errors', '~> 1.0.1'
gem.add_dependency 'rubyzip', '~> 1.1.0'
gem.add_dependency 'netrc', '~> 0.7.7'
@@ @@ -33,10 +27,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'listen', '~> 2.7.5'
gem.add_dependency 'rack-livereload', '~> 0.3.15'
- gem.add_dependency 'httmultiparty', '0.3.10'
- gem.add_dependency 'will_paginate', '~> 3.0.3'
- gem.add_dependency 'locomotivecms_mounter', '~> 1.5.2'
-
gem.add_dependency 'faker', '~> 0.9.5'
gem.add_development_dependency 'rake', '~> 10.0.4'