locomotivecms_wagon 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +1 -1
  4. data/Rakefile +1 -1
  5. data/generators/blank/app/views/pages/404.liquid.haml +11 -0
  6. data/generators/blank/app/views/pages/index.liquid.haml +12 -0
  7. data/generators/blank/config/site.yml.tt +3 -0
  8. data/generators/bootstrap/config/site.yml.tt +3 -0
  9. data/generators/content_type/data/%name%.yml.tt +2 -2
  10. data/generators/foundation/config/site.yml.tt +3 -0
  11. data/lib/locomotive/wagon.rb +10 -2
  12. data/lib/locomotive/wagon/cli.rb +1 -1
  13. data/lib/locomotive/wagon/exceptions.rb +27 -0
  14. data/lib/locomotive/wagon/generators/site/blank.rb +10 -1
  15. data/lib/locomotive/wagon/liquid.rb +1 -1
  16. data/lib/locomotive/wagon/liquid/drops/content_types.rb +5 -0
  17. data/lib/locomotive/wagon/liquid/drops/session_proxy.rb +18 -0
  18. data/lib/locomotive/wagon/liquid/drops/site.rb +4 -0
  19. data/lib/locomotive/wagon/liquid/errors.rb +10 -0
  20. data/lib/locomotive/wagon/liquid/filters/date.rb +62 -24
  21. data/lib/locomotive/wagon/liquid/filters/html.rb +7 -5
  22. data/lib/locomotive/wagon/liquid/filters/misc.rb +17 -0
  23. data/lib/locomotive/wagon/liquid/filters/text.rb +8 -2
  24. data/lib/locomotive/wagon/liquid/patches.rb +1 -1
  25. data/lib/locomotive/wagon/liquid/scopeable.rb +128 -11
  26. data/lib/locomotive/wagon/liquid/tags/consume.rb +60 -18
  27. data/lib/locomotive/wagon/liquid/tags/editable/base.rb +4 -4
  28. data/lib/locomotive/wagon/liquid/tags/extends.rb +2 -2
  29. data/lib/locomotive/wagon/liquid/tags/google_analytics.rb +2 -2
  30. data/lib/locomotive/wagon/liquid/tags/link_to.rb +20 -9
  31. data/lib/locomotive/wagon/liquid/tags/locale_switcher.rb +7 -7
  32. data/lib/locomotive/wagon/liquid/tags/nav.rb +22 -22
  33. data/lib/locomotive/wagon/liquid/tags/paginate.rb +2 -2
  34. data/lib/locomotive/wagon/liquid/tags/session_assign.rb +41 -0
  35. data/lib/locomotive/wagon/liquid/tags/snippet.rb +25 -6
  36. data/lib/locomotive/wagon/liquid/tags/with_scope.rb +9 -8
  37. data/lib/locomotive/wagon/misc.rb +5 -1
  38. data/lib/locomotive/wagon/misc/better_errors.rb +70 -0
  39. data/lib/locomotive/wagon/misc/core_ext.rb +8 -1
  40. data/lib/locomotive/wagon/misc/haml.rb +15 -0
  41. data/lib/locomotive/wagon/misc/markdown.rb +27 -0
  42. data/lib/locomotive/wagon/misc/mounter.rb +32 -0
  43. data/lib/locomotive/wagon/server.rb +6 -4
  44. data/lib/locomotive/wagon/server/dynamic_assets.rb +3 -8
  45. data/lib/locomotive/wagon/server/logging.rb +2 -2
  46. data/lib/locomotive/wagon/server/renderer.rb +17 -12
  47. data/lib/locomotive/wagon/server/timezone.rb +18 -0
  48. data/lib/locomotive/wagon/version.rb +1 -1
  49. data/locales/en.yml +11 -0
  50. data/locomotivecms_wagon.gemspec +6 -5
  51. data/spec/fixtures/default/app/content_types/events.yml +7 -1
  52. data/spec/fixtures/default/app/views/pages/contest.liquid.haml +18 -0
  53. data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +10 -0
  54. data/spec/fixtures/default/app/views/pages/index.liquid.haml +2 -6
  55. data/spec/fixtures/default/app/views/pages/music.fr.liquid.haml +4 -0
  56. data/spec/fixtures/default/app/views/pages/songs/template.fr.liquid.haml +16 -0
  57. data/spec/fixtures/default/app/views/pages/songs/template/band.liquid.haml +16 -0
  58. data/spec/fixtures/default/app/views/snippets/footer.liquid.haml +6 -0
  59. data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +1 -1
  60. data/spec/fixtures/default/data/events.yml +4 -0
  61. data/spec/integration/cassettes/pull.yml +308 -450
  62. data/spec/integration/cassettes/push.yml +446 -492
  63. data/spec/integration/cassettes/staging.yml +360 -500
  64. data/spec/integration/cli_spec.rb +2 -2
  65. data/spec/integration/server/basic_spec.rb +30 -0
  66. data/spec/integration/server/liquid_spec.rb +7 -0
  67. data/spec/integration/server/with_scope_spec.rb +20 -0
  68. data/spec/integration/sites_spec.rb +8 -7
  69. data/spec/support/helpers.rb +1 -1
  70. metadata +65 -78
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb39ff86bec9126c980c162d426f7ead8e32e492
4
+ data.tar.gz: a65b32d9e41c8080aa8d607e5cb5179fff549741
5
+ SHA512:
6
+ metadata.gz: 41a4b7df5f1d43a0711b49e4da1c289baff7867e3ffd054ae7df5db31fc7d4d6e9b398d998482f3075a926e82f851cea5f29b2fdf12c45d610a13835768b7cf3
7
+ data.tar.gz: 4499bdf2efbdcfbd628a09a4d4383e97d68f39f5d0828369f97143278ea772503de60d932fd48514293af0aa578735bb612db904faf62d47bbb140c7d354b134
data/Gemfile CHANGED
@@ -4,6 +4,10 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  # Development
7
+ # gem 'locomotivecms_solid', path: '../gems/solid', require: false
7
8
  # gem 'locomotivecms_mounter', path: '../gems/mounter', require: false
8
9
 
10
+ # gem 'locomotivecms-liquid', path: '../gems/liquid', require: false
11
+ # gem 'locomotivecms-solid', path: '../gems/solid', require: false
12
+
9
13
  gem 'rb-fsevent', '~> 0.9.1'
data/README.md CHANGED
@@ -51,6 +51,6 @@ Please, visit the documentation website of LocomotiveCMS.
51
51
 
52
52
  ## Contact
53
53
 
54
- Feel free to contact me at did at locomotivecms dot com.
54
+ Feel free to contact me (did at locomotivecms dot com).
55
55
 
56
56
  Copyright (c) 2013 NoCoffee, released under the MIT license
data/Rakefile CHANGED
@@ -39,7 +39,7 @@ namespace :development do
39
39
  exit unless Locomotive::Wagon.clone('site', '.', { host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive' })
40
40
  end
41
41
 
42
- Locomotive::Wagon.push('site', {host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive'}, force: true, force_translations: true, data: true)
42
+ Locomotive::Wagon.push('site', {host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive'}, force: true, translations: false, data: true)
43
43
  end
44
44
  end
45
45
 
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: Page not found
3
+ published: false
4
+ ---
5
+ {% extends index %}
6
+
7
+ {% block 'main' %}
8
+
9
+ %p Page not found
10
+
11
+ {% endblock %}
@@ -0,0 +1,12 @@
1
+ !!!
2
+ %html{lang: "en"}
3
+ %head
4
+ %meta{charset: "utf-8"}
5
+ %title {{ site.name }}
6
+ %meta{name: "keywords", value: "{{ site.meta_keywords }}"}
7
+ %meta{name: "description", value: "{{ site.meta_description }}"}
8
+ %body
9
+ %h1 {{ page.title }}
10
+ {% block 'main' %}
11
+ %p Lorem ipsum....
12
+ {% endblock %}
@@ -10,6 +10,9 @@ name: <%= config[:name] %>
10
10
  # TODO: explain it
11
11
  locales: [en]
12
12
 
13
+ # TODO: explain it
14
+ # timezone: Paris
15
+
13
16
  # TODO: explain it
14
17
  seo_title: <%= @name %>
15
18
  meta_keywords: "some meta keywords"
@@ -10,6 +10,9 @@ name: <%= config[:name] %>
10
10
  # TODO: explain it
11
11
  locales: [en]
12
12
 
13
+ # TODO: explain it
14
+ # timezone: Paris
15
+
13
16
  # TODO: explain it
14
17
  seo_title: <%= @name %>
15
18
  meta_keywords: "some meta keywords"
@@ -11,7 +11,7 @@
11
11
  <% when 'boolean' -%>
12
12
  <%= field.name -%>: true # Or false
13
13
  <% when 'date' -%>
14
- <%= field.name -%>: <%= Time.now.strftime('%Y/%M/%d') -%> # YYYY/MM/DD
14
+ <%= field.name -%>: <%= Time.now.strftime('%Y/%m/%d') -%> # YYYY/MM/DD
15
15
  <% when 'file' -%>
16
16
  <%= field.name -%>: null # Path to a file in the public/samples folder or to a remote and external file.
17
17
  <% when 'belongs_to' -%>
@@ -21,4 +21,4 @@
21
21
  <% end -%>
22
22
  <% end -%>
23
23
 
24
- <% end -%>
24
+ <% end -%>
@@ -10,6 +10,9 @@ name: <%= config[:name] %>
10
10
  # TODO: explain it
11
11
  locales: [en]
12
12
 
13
+ # TODO: explain it
14
+ # timezone: Paris
15
+
13
16
  # TODO: explain it
14
17
  seo_title: <%= @name %>
15
18
  meta_keywords: "some meta keywords"
@@ -24,12 +24,20 @@ module Locomotive
24
24
  if reader = self.require_mounter(path, true)
25
25
  Bundler.require 'misc'
26
26
 
27
- require 'thin'
28
27
  require 'locomotive/wagon/server'
28
+ app = Locomotive::Wagon::Server.new(reader)
29
29
 
30
- server = Thin::Server.new(options[:host], options[:port], Locomotive::Wagon::Server.new(reader))
30
+ require 'thin'
31
+ server = Thin::Server.new(options[:host], options[:port], app)
31
32
  server.threaded = true # TODO: make it an option ?
32
33
  server.start
34
+
35
+ # require 'unicorn' # TODO: gem 'unicorn'
36
+ # server = Unicorn::HttpServer.new(app)
37
+ # server.start
38
+
39
+ # require 'rack'
40
+ # Rack::Handler::WEBrick.run(app, { :'Port' => options[:port], :'Host' => options[:host] })
33
41
  end
34
42
  end
35
43
 
@@ -182,7 +182,7 @@ module Locomotive
182
182
  desc 'push ENV [PATH]', 'Push a site to a remote LocomotiveCMS engine'
183
183
  method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
184
184
  method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Force the push of a resource'
185
- method_option :force_translations, type: 'boolean', default: false, desc: 'Force the push of local translations. You must specify it even if already using -f'
185
+ method_option :translations, aliases: '-t', type: 'boolean', default: false, desc: 'Push the local translations (by default, they are not)'
186
186
  method_option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
187
187
  method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
188
188
  def push(env, path = '.')
@@ -20,6 +20,33 @@ module Locomotive
20
20
 
21
21
  end
22
22
 
23
+ class RendererException < DefaultException
24
+
25
+ attr_accessor :name, :template, :liquid_context
26
+
27
+ def initialize(exception, name, template, liquid_context)
28
+ self.name, self.template, self.liquid_context = name, template, liquid_context
29
+
30
+ self.log_page_into_backtrace(exception)
31
+
32
+ super(exception.message)
33
+
34
+ self.set_backtrace(exception.backtrace)
35
+ end
36
+
37
+ def log_page_into_backtrace(exception)
38
+ line = self.template.line_offset
39
+ line += (exception.respond_to?(:line) ? exception.line : 0) + 1
40
+
41
+ message = "#{self.template.filepath}:#{line}:in `#{self.name}'"
42
+
43
+ Locomotive::Wagon::Logger.fatal "[ERROR] #{exception.message} - #{message}\n".red
44
+
45
+ exception.backtrace.unshift message
46
+ end
47
+
48
+ end
49
+
23
50
  class MounterException < DefaultException
24
51
  end
25
52
 
@@ -11,7 +11,16 @@ module Locomotive
11
11
  version: Locomotive::Wagon::VERSION
12
12
  })
13
13
  end
14
-
14
+
15
+ def choose_haml_over_html
16
+ if yes?('Do you prefer HAML templates ?')
17
+ remove_file File.join(self.destination, 'app/views/pages/index.liquid')
18
+ remove_file File.join(self.destination, 'app/views/pages/404.liquid')
19
+ else
20
+ remove_file File.join(self.destination, 'app/views/pages/index.liquid.haml')
21
+ remove_file File.join(self.destination, 'app/views/pages/404.liquid.haml')
22
+ end
23
+ end
15
24
  end
16
25
 
17
26
  Locomotive::Wagon::Generators::Site.register(:blank, Blank, %{
@@ -1,4 +1,4 @@
1
- require 'liquid'
1
+ require 'solid'
2
2
  require 'locomotive/mounter'
3
3
  require 'locomotive/wagon/liquid/scopeable'
4
4
  require 'locomotive/wagon/liquid/drops/base'
@@ -99,6 +99,11 @@ module Locomotive
99
99
  def collection
100
100
  return unless @collection.blank?
101
101
 
102
+ # define the default order_by if not set
103
+ if @context['with_scope'] && !@context['with_scope']['order_by'].blank? && !%w(manually position).include?(@content_type.order_by)
104
+ @context['with_scope']['order_by'] = @content_type.order_by + '.' + @content_type.order_direction
105
+ end
106
+
102
107
  @collection = apply_scope(@content_type.entries)
103
108
  end
104
109
  end
@@ -0,0 +1,18 @@
1
+ module Locomotive
2
+ module Wagon
3
+ module Liquid
4
+ module Drops
5
+
6
+ class SessionProxy < ::Liquid::Drop
7
+
8
+ def before_method(meth)
9
+ request = @context.registers[:request]
10
+ request.session[meth.to_sym]
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -15,6 +15,10 @@ module Locomotive
15
15
  @pages ||= liquify(*apply_scope(self.mounting_point.pages.values))
16
16
  end
17
17
 
18
+ def domains
19
+ self._source.domains
20
+ end
21
+
18
22
  end
19
23
  end
20
24
  end
@@ -2,6 +2,16 @@ module Locomotive
2
2
  module Wagon
3
3
  module Liquid
4
4
  class PageNotFound < ::Liquid::Error; end
5
+
6
+ class PageNotTranslated < ::Liquid::Error; end
7
+
8
+ class ContentEntryNotTranslated < ::Liquid::Error; end
9
+
10
+ class UnknownConditionInScope < ::Liquid::Error; end
11
+
12
+ class UnknownConditionInScope < ::Liquid::Error; end
13
+
14
+ class ConnectionRefused < ::Liquid::Error; end
5
15
  end
6
16
  end
7
17
  end
@@ -4,65 +4,92 @@ module Locomotive
4
4
  module Filters
5
5
  module Date
6
6
 
7
+ def parse_date_time(input, format = nil)
8
+ return '' if input.blank?
9
+
10
+ format ||= I18n.t('time.formats.default')
11
+ date_time = ::DateTime._strptime(input, format)
12
+
13
+ if date_time
14
+ ::Time.zone.local(date_time[:year], date_time[:mon], date_time[:mday], date_time[:hour], date_time[:min], date_time[:sec] || 0)
15
+ else
16
+ ::Time.zone.parse(input) rescue ''
17
+ end
18
+ end
19
+
20
+ def parse_date(input, format)
21
+ return '' if input.blank?
22
+
23
+ format ||= I18n.t('date.formats.default')
24
+ date = ::Date._strptime(input, format)
25
+
26
+ if date
27
+ ::Date.new(date[:year], date[:mon], date[:mday])
28
+ else
29
+ ::Date.parse(value) rescue ''
30
+ end
31
+ end
32
+
7
33
  def localized_date(input, *args)
8
34
  return '' if input.blank?
9
35
 
10
36
  format, locale = args
11
37
 
12
38
  locale ||= I18n.locale
13
- format ||= I18n.t('date.formats.default', :locale => locale)
39
+ format ||= I18n.t('date.formats.default', locale: locale)
14
40
 
15
41
  if input.is_a?(String)
16
42
  begin
17
43
  fragments = ::Date._strptime(input, format)
18
44
  input = ::Date.new(fragments[:year], fragments[:mon], fragments[:mday])
19
45
  rescue
20
- input = Time.parse(input)
46
+ input = Time.zone.parse(input)
21
47
  end
22
48
  end
23
49
 
24
50
  return input.to_s unless input.respond_to?(:strftime)
25
51
 
26
- I18n.l input, :format => format, :locale => locale
52
+ I18n.l input, format: format, locale: locale
27
53
  end
28
54
 
29
55
  alias :format_date :localized_date
30
56
 
31
- def distance_of_time_in_words(input, *args)
57
+ def distance_of_time_in_words(input, from_time = Time.zone.now, include_seconds = false)
32
58
  return '' if input.blank?
33
59
 
34
- from_time = input
35
- to_time = args[0] || Time.now
60
+ # make sure we deals with instances of Time
61
+ to_time = to_time(input)
62
+ from_time = to_time(from_time)
36
63
 
37
64
  from_time = from_time.to_time if from_time.respond_to?(:to_time)
38
65
  to_time = to_time.to_time if to_time.respond_to?(:to_time)
39
66
  distance_in_minutes = (((to_time - from_time).abs)/60).round
40
67
  distance_in_seconds = ((to_time - from_time).abs).round
41
68
 
42
- ::I18n.with_options({ :scope => :'datetime.distance_in_words' }) do |locale|
69
+ ::I18n.with_options({ scope: :'datetime.distance_in_words' }) do |locale|
43
70
 
44
71
  case distance_in_minutes
45
72
  when 0..1
46
73
  return distance_in_minutes == 0 ?
47
- locale.t(:less_than_x_minutes, :count => 1) :
48
- locale.t(:x_minutes, :count => distance_in_minutes) unless include_seconds
74
+ locale.t(:less_than_x_minutes, count: 1) :
75
+ locale.t(:x_minutes, count: distance_in_minutes) unless include_seconds
49
76
 
50
77
  case distance_in_seconds
51
- when 0..4 then locale.t :less_than_x_seconds, :count => 5
52
- when 5..9 then locale.t :less_than_x_seconds, :count => 10
53
- when 10..19 then locale.t :less_than_x_seconds, :count => 20
78
+ when 0..4 then locale.t :less_than_x_seconds, count: 5
79
+ when 5..9 then locale.t :less_than_x_seconds, count: 10
80
+ when 10..19 then locale.t :less_than_x_seconds, count: 20
54
81
  when 20..39 then locale.t :half_a_minute
55
- when 40..59 then locale.t :less_than_x_minutes, :count => 1
56
- else locale.t :x_minutes, :count => 1
82
+ when 40..59 then locale.t :less_than_x_minutes, count: 1
83
+ else locale.t :x_minutes, count: 1
57
84
  end
58
85
 
59
- when 2..44 then locale.t :x_minutes, :count => distance_in_minutes
60
- when 45..89 then locale.t :about_x_hours, :count => 1
61
- when 90..1439 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round
62
- when 1440..2519 then locale.t :x_days, :count => 1
63
- when 2520..43199 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round
64
- when 43200..86399 then locale.t :about_x_months, :count => 1
65
- when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
86
+ when 2..44 then locale.t :x_minutes, count: distance_in_minutes
87
+ when 45..89 then locale.t :about_x_hours, count: 1
88
+ when 90..1439 then locale.t :about_x_hours, count: (distance_in_minutes.to_f / 60.0).round
89
+ when 1440..2519 then locale.t :x_days, count: 1
90
+ when 2520..43199 then locale.t :x_days, count: (distance_in_minutes.to_f / 1440.0).round
91
+ when 43200..86399 then locale.t :about_x_months, count: 1
92
+ when 86400..525599 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round
66
93
  else
67
94
  fyear = from_time.year
68
95
  fyear += 1 if from_time.month >= 3
@@ -79,16 +106,27 @@ module Locomotive
79
106
  remainder = (minutes_with_offset % 525600)
80
107
  distance_in_years = (minutes_with_offset / 525600)
81
108
  if remainder < 131400
82
- locale.t(:about_x_years, :count => distance_in_years)
109
+ locale.t(:about_x_years, count: distance_in_years)
83
110
  elsif remainder < 394200
84
- locale.t(:over_x_years, :count => distance_in_years)
111
+ locale.t(:over_x_years, count: distance_in_years)
85
112
  else
86
- locale.t(:almost_x_years, :count => distance_in_years + 1)
113
+ locale.t(:almost_x_years, count: distance_in_years + 1)
87
114
  end
88
115
  end
89
116
  end
90
117
  end
91
118
 
119
+ private
120
+
121
+ def to_time(input)
122
+ case input
123
+ when Date then input.to_time
124
+ when String then Time.zone.parse(input)
125
+ else
126
+ input
127
+ end
128
+ end
129
+
92
130
  end
93
131
 
94
132
  ::Liquid::Template.register_filter(Date)
@@ -23,11 +23,13 @@ module Locomotive
23
23
  def stylesheet_url(input)
24
24
  return '' if input.nil?
25
25
 
26
- input = "/stylesheets/#{input}" unless input =~ /^(\/|https?:)/
27
-
28
- input = "#{input}.css" unless input.ends_with?('.css')
29
-
30
- input
26
+ if input =~ /^https?:/
27
+ input
28
+ else
29
+ input = "/stylesheets/#{input}" unless input =~ /^\//
30
+ input = "#{input}.css" unless input.ends_with?('.css')
31
+ input
32
+ end
31
33
  end
32
34
 
33
35
  # Write the link to a stylesheet resource
@@ -22,6 +22,23 @@ module Locomotive
22
22
  rand(input.to_i)
23
23
  end
24
24
 
25
+ # map/collect on a given property (support to_f, to_i)
26
+ def map(input, property)
27
+ flatten_if_necessary(input).map do |e|
28
+ e = e.call if e.is_a?(Proc)
29
+
30
+ if property == "to_liquid"
31
+ e
32
+ elsif property == "to_f"
33
+ e.to_f
34
+ elsif property == "to_i"
35
+ e.to_i
36
+ elsif e.respond_to?(:[])
37
+ e[property]
38
+ end
39
+ end
40
+ end
41
+
25
42
  end
26
43
 
27
44
  ::Liquid::Template.register_filter(Misc)