locomotivecms_builder 1.0.0.alpha1

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 (137) hide show
  1. data/.gitignore +31 -0
  2. data/Gemfile +8 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +68 -0
  5. data/Rakefile +47 -0
  6. data/TODO +57 -0
  7. data/bin/builder +9 -0
  8. data/generators/blank/Gemfile.tt +20 -0
  9. data/generators/blank/app/content_types/.empty_directory +1 -0
  10. data/generators/blank/app/views/pages/404.liquid +11 -0
  11. data/generators/blank/app/views/pages/index.liquid +19 -0
  12. data/generators/blank/app/views/snippets/.empty_directory +1 -0
  13. data/generators/blank/config/deploy.yml +12 -0
  14. data/generators/blank/config/site.yml.tt +16 -0
  15. data/generators/blank/config/translations.yml +8 -0
  16. data/generators/blank/config.ru +3 -0
  17. data/generators/blank/data/.empty_directory +1 -0
  18. data/generators/blank/public/fonts/.empty_directory +1 -0
  19. data/generators/blank/public/images/.empty_directory +1 -0
  20. data/generators/blank/public/javascripts/.empty_directory +1 -0
  21. data/generators/blank/public/samples/.empty_directory +1 -0
  22. data/generators/blank/public/stylesheets/.empty_directory +1 -0
  23. data/generators/bootstrap/Gemfile.tt +20 -0
  24. data/generators/bootstrap/app/content_types/.empty_directory +1 -0
  25. data/generators/bootstrap/app/views/pages/404.liquid +13 -0
  26. data/generators/bootstrap/app/views/pages/404.liquid.haml +10 -0
  27. data/generators/bootstrap/app/views/pages/index.liquid +85 -0
  28. data/generators/bootstrap/app/views/pages/index.liquid.haml +72 -0
  29. data/generators/bootstrap/app/views/snippets/footer.liquid +3 -0
  30. data/generators/bootstrap/app/views/snippets/footer.liquid.haml +2 -0
  31. data/generators/bootstrap/config/deploy.yml +12 -0
  32. data/generators/bootstrap/config/site.yml.tt +16 -0
  33. data/generators/bootstrap/config/translations.yml +8 -0
  34. data/generators/bootstrap/config.ru +3 -0
  35. data/generators/bootstrap/data/.empty_directory +1 -0
  36. data/generators/bootstrap/public/fonts/FontAwesome.otf +0 -0
  37. data/generators/bootstrap/public/fonts/font-awesome-ie7.min.css +23 -0
  38. data/generators/bootstrap/public/fonts/font-awesome.css +469 -0
  39. data/generators/bootstrap/public/fonts/font-awesome.min.css +34 -0
  40. data/generators/bootstrap/public/fonts/fontawesome-webfont.eot +0 -0
  41. data/generators/bootstrap/public/fonts/fontawesome-webfont.ttf +0 -0
  42. data/generators/bootstrap/public/fonts/fontawesome-webfont.woff +0 -0
  43. data/generators/bootstrap/public/javascripts/bootstrap.js +2159 -0
  44. data/generators/bootstrap/public/javascripts/bootstrap.min.js +6 -0
  45. data/generators/bootstrap/public/samples/.empty_directory +1 -0
  46. data/generators/bootstrap/public/stylesheets/application.css.scss +39 -0
  47. data/generators/bootstrap/public/stylesheets/bootstrap-responsive.css +1092 -0
  48. data/generators/bootstrap/public/stylesheets/bootstrap-responsive.min.css +9 -0
  49. data/generators/bootstrap/public/stylesheets/bootstrap.css +5652 -0
  50. data/generators/bootstrap/public/stylesheets/bootstrap.min.css +726 -0
  51. data/generators/content_type/app/content_types/%name%.yml.tt +58 -0
  52. data/generators/content_type/data/%name%.yml.tt +24 -0
  53. data/generators/page/template.liquid.haml.tt +35 -0
  54. data/generators/page/template.liquid.tt +1 -0
  55. data/generators/snippet/template.liquid.haml.tt +4 -0
  56. data/generators/snippet/template.liquid.tt +4 -0
  57. data/lib/locomotive/builder/cli.rb +225 -0
  58. data/lib/locomotive/builder/exceptions.rb +17 -0
  59. data/lib/locomotive/builder/generators/content_type.rb +47 -0
  60. data/lib/locomotive/builder/generators/page.rb +57 -0
  61. data/lib/locomotive/builder/generators/site/base.rb +30 -0
  62. data/lib/locomotive/builder/generators/site/blank.rb +23 -0
  63. data/lib/locomotive/builder/generators/site/bootstrap.rb +35 -0
  64. data/lib/locomotive/builder/generators/site.rb +97 -0
  65. data/lib/locomotive/builder/generators/snippet.rb +54 -0
  66. data/lib/locomotive/builder/liquid/drops/base.rb +44 -0
  67. data/lib/locomotive/builder/liquid/drops/content_entry.rb +48 -0
  68. data/lib/locomotive/builder/liquid/drops/content_types.rb +121 -0
  69. data/lib/locomotive/builder/liquid/drops/page.rb +36 -0
  70. data/lib/locomotive/builder/liquid/drops/site.rb +21 -0
  71. data/lib/locomotive/builder/liquid/errors.rb +7 -0
  72. data/lib/locomotive/builder/liquid/filters/date.rb +98 -0
  73. data/lib/locomotive/builder/liquid/filters/html.rb +154 -0
  74. data/lib/locomotive/builder/liquid/filters/misc.rb +28 -0
  75. data/lib/locomotive/builder/liquid/filters/resize.rb +18 -0
  76. data/lib/locomotive/builder/liquid/filters/text.rb +50 -0
  77. data/lib/locomotive/builder/liquid/filters/translate.rb +24 -0
  78. data/lib/locomotive/builder/liquid/patches.rb +47 -0
  79. data/lib/locomotive/builder/liquid/tags/consume.rb +58 -0
  80. data/lib/locomotive/builder/liquid/tags/csrf.rb +34 -0
  81. data/lib/locomotive/builder/liquid/tags/editable/base.rb +46 -0
  82. data/lib/locomotive/builder/liquid/tags/editable/control.rb +19 -0
  83. data/lib/locomotive/builder/liquid/tags/editable/file.rb +15 -0
  84. data/lib/locomotive/builder/liquid/tags/editable/long_text.rb +15 -0
  85. data/lib/locomotive/builder/liquid/tags/editable/short_text.rb +15 -0
  86. data/lib/locomotive/builder/liquid/tags/editable.rb +5 -0
  87. data/lib/locomotive/builder/liquid/tags/extends.rb +25 -0
  88. data/lib/locomotive/builder/liquid/tags/google_analytics.rb +28 -0
  89. data/lib/locomotive/builder/liquid/tags/inline_editor.rb +16 -0
  90. data/lib/locomotive/builder/liquid/tags/locale_switcher.rb +180 -0
  91. data/lib/locomotive/builder/liquid/tags/nav.rb +167 -0
  92. data/lib/locomotive/builder/liquid/tags/paginate.rb +105 -0
  93. data/lib/locomotive/builder/liquid/tags/seo.rb +74 -0
  94. data/lib/locomotive/builder/liquid/tags/snippet.rb +42 -0
  95. data/lib/locomotive/builder/liquid/tags/with_scope.rb +43 -0
  96. data/lib/locomotive/builder/liquid.rb +19 -0
  97. data/lib/locomotive/builder/listen.rb +48 -0
  98. data/lib/locomotive/builder/misc/core_ext.rb +29 -0
  99. data/lib/locomotive/builder/misc/dragonfly.rb +82 -0
  100. data/lib/locomotive/builder/misc/httparty.rb +47 -0
  101. data/lib/locomotive/builder/misc/i18n.rb +2 -0
  102. data/lib/locomotive/builder/misc/will_paginate.rb +16 -0
  103. data/lib/locomotive/builder/misc.rb +5 -0
  104. data/lib/locomotive/builder/server/dynamic_assets.rb +31 -0
  105. data/lib/locomotive/builder/server/entry_submission.rb +116 -0
  106. data/lib/locomotive/builder/server/favicon.rb +17 -0
  107. data/lib/locomotive/builder/server/locale.rb +42 -0
  108. data/lib/locomotive/builder/server/middleware.rb +54 -0
  109. data/lib/locomotive/builder/server/not_found.rb +18 -0
  110. data/lib/locomotive/builder/server/page.rb +59 -0
  111. data/lib/locomotive/builder/server/path.rb +34 -0
  112. data/lib/locomotive/builder/server/renderer.rb +105 -0
  113. data/lib/locomotive/builder/server/templatized_page.rb +32 -0
  114. data/lib/locomotive/builder/server.rb +78 -0
  115. data/lib/locomotive/builder/standalone_server.rb +33 -0
  116. data/lib/locomotive/builder/version.rb +5 -0
  117. data/lib/locomotive/builder.rb +167 -0
  118. data/locales/de.yml +143 -0
  119. data/locales/en.yml +164 -0
  120. data/locales/es.yml +119 -0
  121. data/locales/et.yml +140 -0
  122. data/locales/fr.yml +133 -0
  123. data/locales/it.yml +141 -0
  124. data/locales/nb.yml +177 -0
  125. data/locales/nl.yml +148 -0
  126. data/locales/pl.yml +189 -0
  127. data/locales/pt-BR.yml +125 -0
  128. data/locales/ru.yml +210 -0
  129. data/locomotivecms_builder.gemspec +42 -0
  130. data/spec/integration/cassettes/pull.yml +590 -0
  131. data/spec/integration/cassettes/push.yml +775 -0
  132. data/spec/integration/integration_helper.rb +15 -0
  133. data/spec/integration/server_spec.rb +37 -0
  134. data/spec/integration/sites_spec.rb +27 -0
  135. data/spec/spec_helper.rb +12 -0
  136. data/spec/support/helpers.rb +13 -0
  137. metadata +468 -0
@@ -0,0 +1,54 @@
1
+ require 'thor/group'
2
+ require 'active_support'
3
+ require 'active_support/core_ext'
4
+
5
+ module Locomotive
6
+ module Builder
7
+ module Generators
8
+ class Snippet < Thor::Group
9
+
10
+ include Thor::Actions
11
+
12
+ argument :slug
13
+ argument :target_path # path to the site
14
+
15
+ attr_accessor :haml, :locales
16
+
17
+ def ask_for_haml_and_locales
18
+ self.locales = []
19
+ self.haml = yes?('Do you prefer a HAML template ?')
20
+
21
+ if yes?('Is your snippet localized ?')
22
+ self.locales = ask('What are the locales other than the default one (comma separated) ?').split(',').map(&:strip)
23
+ end
24
+ end
25
+
26
+ def create_snippet
27
+ extension = self.haml ? 'liquid.haml' : 'liquid'
28
+
29
+ options = { slug: slug, translated: false }
30
+ file_path = File.join(pages_path, slug)
31
+
32
+ template "template.#{extension}.tt", "#{file_path}.#{extension}", options
33
+
34
+ self.locales.each do |locale|
35
+ options[:translated] = true
36
+ template "template.#{extension}.tt", "#{file_path}.#{locale}.#{extension}", options
37
+ end
38
+ end
39
+
40
+ def self.source_root
41
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'generators', 'snippet')
42
+ end
43
+
44
+ protected
45
+
46
+ def pages_path
47
+ File.join(target_path, 'app', 'views', 'snippets')
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # Code taken from Mephisto sources (http://mephistoblog.com/)
2
+ module Locomotive
3
+ module Builder
4
+ module Liquid
5
+ module Drops
6
+ class Base < ::Liquid::Drop
7
+
8
+ @@forbidden_attributes = %w{_id _version _index}
9
+
10
+ attr_reader :_source
11
+
12
+ def initialize(source)
13
+ @_source = source
14
+ end
15
+
16
+ def id
17
+ (@_source.respond_to?(:id) ? @_source.id : nil) || 'new'
18
+ end
19
+
20
+ # converts an array of records to an array of liquid drops
21
+ def self.liquify(*records, &block)
22
+ i = -1
23
+ records =
24
+ records.inject [] do |all, r|
25
+ i+=1
26
+ attrs = (block && block.arity == 1) ? [r] : [r, i]
27
+ all << (block ? block.call(*attrs) : r.to_liquid)
28
+ all
29
+ end
30
+ records.compact!
31
+ records
32
+ end
33
+
34
+ protected
35
+
36
+ def liquify(*records, &block)
37
+ self.class.liquify(*records, &block)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Drops
5
+ class ContentEntry < Base
6
+
7
+ delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
8
+
9
+ def _label
10
+ @_label ||= self._source._label
11
+ end
12
+
13
+ def _permalink
14
+ @_source._permalink.try(:parameterize)
15
+ end
16
+
17
+ alias :_slug :_permalink
18
+
19
+ def next
20
+ self
21
+ end
22
+
23
+ def previous
24
+ self
25
+ end
26
+
27
+ def errors
28
+ (@_source.errors || []).inject({}) do |memo, name|
29
+ memo[name] = ::I18n.t('errors.messages.blank')
30
+ memo
31
+ end
32
+ end
33
+
34
+ def before_method(meth)
35
+ return '' if self._source.nil?
36
+
37
+ if not @@forbidden_attributes.include?(meth.to_s)
38
+ self._source.send(meth)
39
+ else
40
+ nil
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,121 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Drops
5
+ class ContentTypes < ::Liquid::Drop
6
+
7
+ def before_method(meth)
8
+ type = self.mounting_point.content_types[meth.to_s]
9
+ ProxyCollection.new(type)
10
+ end
11
+
12
+ end
13
+
14
+ class ProxyCollection < ::Liquid::Drop
15
+
16
+ def initialize(content_type)
17
+ @content_type = content_type
18
+ @collection = nil
19
+ end
20
+
21
+ def first
22
+ self.collection.first
23
+ end
24
+
25
+ def last
26
+ self.collection.last
27
+ end
28
+
29
+ def size
30
+ self.collection.size
31
+ end
32
+
33
+ alias :length :size
34
+
35
+ def each(&block)
36
+ self.collection.each(&block)
37
+ end
38
+
39
+ def public_submission_url
40
+ "/entry_submissions/#{@content_type.slug}"
41
+ end
42
+
43
+ def api
44
+ { 'create' => "/entry_submissions/#{@content_type.slug}" }
45
+ end
46
+
47
+ def before_method(meth)
48
+ if (meth.to_s =~ /^group_by_(.+)$/) == 0
49
+ self.group_entries_by(@content_type, $1)
50
+ elsif (meth.to_s =~ /^(.+)_options$/) == 0
51
+ self.select_options_for(@content_type, $1)
52
+ else
53
+ @content_type.send(meth)
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ def group_entries_by(content_type, name)
60
+ field = @content_type.find_field(name)
61
+
62
+ return {} if field.nil? || !%w(belongs_to select).include?(field.type.to_s)
63
+
64
+ (@content_type.entries || []).group_by do |entry|
65
+ entry.send(name.to_sym)
66
+ end.to_a.collect do |group|
67
+ { name: group.first, entries: group.last }.with_indifferent_access
68
+ end
69
+ end
70
+
71
+ def select_options_for(content_type, name)
72
+ field = @content_type.find_field(name)
73
+
74
+ return {} if field.nil? || field.type.to_s != 'select'
75
+
76
+ field.select_options.map(&:name)
77
+ end
78
+
79
+ def paginate(options = {})
80
+ @collection ||= self.collection.paginate(options)
81
+ {
82
+ collection: @collection,
83
+ current_page: @collection.current_page,
84
+ previous_page: @collection.previous_page,
85
+ next_page: @collection.next_page,
86
+ total_entries: @collection.total_entries,
87
+ total_pages: @collection.total_pages,
88
+ per_page: @collection.per_page
89
+ }
90
+ end
91
+
92
+ def collection
93
+ return unless @collection.blank?
94
+
95
+ if @context['with_scope'].blank?
96
+ @collection = @content_type.entries
97
+ else
98
+ @collection = []
99
+
100
+ conditions = @context['with_scope'].clone.delete_if { |k, _| %w(order_by per_page page).include?(k) }
101
+
102
+ @content_type.entries.each do |content|
103
+ accepted = (conditions.map do |key, value|
104
+ case value
105
+ when TrueClass, FalseClass, String then content.send(key) == value
106
+ else
107
+ true
108
+ end
109
+ end).all? # all conditions works ?
110
+
111
+ @collection << content if accepted
112
+ end
113
+ end
114
+
115
+ @collection
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,36 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Drops
5
+ class Page < Base
6
+
7
+ delegate :title, :slug, :fullpath, :parent, :depth, :seo_title, :redirect_url, :meta_description, :meta_keywords, :to => '_source'
8
+
9
+ def children
10
+ _children = @_source.children || []
11
+ _children = _children.sort { |a, b| a.position.to_i <=> b.position.to_i }
12
+ @children ||= liquify(*_children)
13
+ end
14
+
15
+ def published?
16
+ @_source.published?
17
+ end
18
+
19
+ def redirect?
20
+ self._source.redirect?
21
+ end
22
+
23
+ def breadcrumbs
24
+ # TODO
25
+ ''
26
+ end
27
+
28
+ def listed?
29
+ @_source.listed?
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Drops
5
+ class Site < Base
6
+
7
+ delegate :name, :seo_title, :meta_description, :meta_keywords, :to => '_source'
8
+
9
+ def index
10
+ @index ||= self.mounting_point.pages['index']
11
+ end
12
+
13
+ def pages
14
+ @pages ||= liquify(*self._source.pages)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ class PageNotFound < ::Liquid::Error; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Filters
5
+ module Date
6
+
7
+ def localized_date(input, *args)
8
+ return '' if input.blank?
9
+
10
+ format, locale = args
11
+
12
+ locale ||= I18n.locale
13
+ format ||= I18n.t('date.formats.default', :locale => locale)
14
+
15
+ if input.is_a?(String)
16
+ begin
17
+ fragments = ::Date._strptime(input, format)
18
+ input = ::Date.new(fragments[:year], fragments[:mon], fragments[:mday])
19
+ rescue
20
+ input = Time.parse(input)
21
+ end
22
+ end
23
+
24
+ return input.to_s unless input.respond_to?(:strftime)
25
+
26
+ I18n.l input, :format => format, :locale => locale
27
+ end
28
+
29
+ alias :format_date :localized_date
30
+
31
+ def distance_of_time_in_words(input, *args)
32
+ return '' if input.blank?
33
+
34
+ from_time = input
35
+ to_time = args[0] || Time.now
36
+
37
+ from_time = from_time.to_time if from_time.respond_to?(:to_time)
38
+ to_time = to_time.to_time if to_time.respond_to?(:to_time)
39
+ distance_in_minutes = (((to_time - from_time).abs)/60).round
40
+ distance_in_seconds = ((to_time - from_time).abs).round
41
+
42
+ ::I18n.with_options({ :scope => :'datetime.distance_in_words' }) do |locale|
43
+
44
+ case distance_in_minutes
45
+ when 0..1
46
+ 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
49
+
50
+ 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
54
+ 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
57
+ end
58
+
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
66
+ else
67
+ fyear = from_time.year
68
+ fyear += 1 if from_time.month >= 3
69
+ tyear = to_time.year
70
+ tyear -= 1 if to_time.month < 3
71
+ leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| ::Date.leap?(x)}
72
+ minute_offset_for_leap_year = leap_years * 1440
73
+ # Discount the leap year days when calculating year distance.
74
+ # e.g. if there are 20 leap year days between 2 dates having the same day
75
+ # and month then the based on 365 days calculation
76
+ # the distance in years will come out to over 80 years when in written
77
+ # english it would read better as about 80 years.
78
+ minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
79
+ remainder = (minutes_with_offset % 525600)
80
+ distance_in_years = (minutes_with_offset / 525600)
81
+ if remainder < 131400
82
+ locale.t(:about_x_years, :count => distance_in_years)
83
+ elsif remainder < 394200
84
+ locale.t(:over_x_years, :count => distance_in_years)
85
+ else
86
+ locale.t(:almost_x_years, :count => distance_in_years + 1)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ ::Liquid::Template.register_filter(Date)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,154 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Filters
5
+ module Html
6
+
7
+ # Write the link to a stylesheet resource
8
+ # input: url of the css file
9
+ def stylesheet_tag(input, media = 'screen')
10
+ return '' if input.nil?
11
+
12
+ input = "/stylesheets/#{input}" unless input =~ /^(\/|http:)/
13
+
14
+ input = "#{input}.css" unless input.ends_with?('.css')
15
+
16
+ %{<link href="#{input}" media="#{media}" rel="stylesheet" type="text/css" />}
17
+ end
18
+
19
+ # Write the link to javascript resource
20
+ # input: url of the javascript file
21
+ def javascript_tag(input)
22
+ return '' if input.nil?
23
+
24
+ input = "/javascripts/#{input}" unless input =~ /^(\/|http:)/
25
+
26
+ input = "#{input}.js" unless input.ends_with?('.js')
27
+
28
+ %{<script src="#{input}" type="text/javascript"></script>}
29
+ end
30
+
31
+ # Write an image tag
32
+ # input: url of the image OR asset drop
33
+ def image_tag(input, *args)
34
+ image_options = inline_options(args_to_options(args))
35
+
36
+ input = "/images/#{input}" unless input =~ /^(\/|http:)/
37
+
38
+ "<img src=\"#{File.join('/', get_url_from_asset(input))}\" #{image_options}/>"
39
+ end
40
+
41
+ # Write a theme image tag
42
+ # input: name of file including folder
43
+ # example: 'about/myphoto.jpg' | theme_image # <img src="images/about/myphoto.jpg" />
44
+ def theme_image_tag(input, *args)
45
+ image_options = inline_options(args_to_options(args))
46
+ "<img src=\"#{theme_image_url(input)}\" #{image_options}/>"
47
+ end
48
+
49
+ def theme_image_url(input)
50
+ return '' if input.nil?
51
+
52
+ input = "images/#{input}" unless input.starts_with?('/')
53
+
54
+ File.join('/', input)
55
+ end
56
+
57
+ def image_format(input, *args)
58
+ format = args_to_options(args).first
59
+ "#{input}.#{format}"
60
+ end
61
+
62
+ # Embed a flash movie into a page
63
+ # input: url of the flash movie OR asset drop
64
+ # width: width (in pixel or in %) of the embedded movie
65
+ # height: height (in pixel or in %) of the embedded movie
66
+ def flash_tag(input, *args)
67
+ path = get_url_from_asset(input)
68
+ embed_options = inline_options(args_to_options(args))
69
+ %{
70
+ <object #{embed_options}>
71
+ <param name="movie" value="#{path}" />
72
+ <embed src="#{path}" #{embed_options}/>
73
+ </embed>
74
+ </object>
75
+ }.gsub(/ >/, '>').strip
76
+ end
77
+
78
+ # Render the navigation for a paginated collection
79
+ def default_pagination(paginate, *args)
80
+ return '' if paginate['parts'].empty?
81
+
82
+ options = args_to_options(args)
83
+
84
+ previous_label = options[:previous_label] || I18n.t('pagination.previous')
85
+ next_label = options[:next_label] || I18n.t('pagination.next')
86
+
87
+ previous_link = (if paginate['previous'].blank?
88
+ "<span class=\"disabled prev_page\">#{previous_label}</span>"
89
+ else
90
+ "<a href=\"#{absolute_url(paginate['previous']['url'])}\" class=\"prev_page\">#{previous_label}</a>"
91
+ end)
92
+
93
+ links = ""
94
+ paginate['parts'].each do |part|
95
+ links << (if part['is_link']
96
+ "<a href=\"#{absolute_url(part['url'])}\">#{part['title']}</a>"
97
+ elsif part['hellip_break']
98
+ "<span class=\"gap\">#{part['title']}</span>"
99
+ else
100
+ "<span class=\"current\">#{part['title']}</span>"
101
+ end)
102
+ end
103
+
104
+ next_link = (if paginate['next'].blank?
105
+ "<span class=\"disabled next_page\">#{next_label}</span>"
106
+ else
107
+ "<a href=\"#{absolute_url(paginate['next']['url'])}\" class=\"next_page\">#{next_label}</a>"
108
+ end)
109
+
110
+ %{<div class="pagination #{options[:css]}">
111
+ #{previous_link}
112
+ #{links}
113
+ #{next_link}
114
+ </div>}
115
+ end
116
+
117
+ protected
118
+
119
+ # Convert an array of properties ('key:value') into a hash
120
+ # Ex: ['width:50', 'height:100'] => { :width => '50', :height => '100' }
121
+ def args_to_options(*args)
122
+ options = {}
123
+ args.flatten.each do |a|
124
+ if (a =~ /^(.*):(.*)$/)
125
+ options[$1.to_sym] = $2
126
+ end
127
+ end
128
+ options
129
+ end
130
+
131
+ # Write options (Hash) into a string according to the following pattern:
132
+ # <key1>="<value1>", <key2>="<value2", ...etc
133
+ def inline_options(options = {})
134
+ return '' if options.empty?
135
+ (options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ') << ' '
136
+ end
137
+
138
+ # Get the path to be used in html tags such as image_tag, flash_tag, ...etc
139
+ # input: url (String) OR asset drop
140
+ def get_url_from_asset(input)
141
+ input.respond_to?(:url) ? input.url : input
142
+ end
143
+
144
+ def absolute_url(url)
145
+ url =~ /^\// ? url : "/#{url}"
146
+ end
147
+ end
148
+
149
+ ::Liquid::Template.register_filter(Html)
150
+
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,28 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Filters
5
+ module Misc
6
+
7
+ # was called modulo at first
8
+ def str_modulo(word, index, modulo)
9
+ (index.to_i + 1) % modulo == 0 ? word : ''
10
+ end
11
+
12
+ # Get the nth element of the passed in array
13
+ def index(array, position)
14
+ array.at(position) if array.respond_to?(:at)
15
+ end
16
+
17
+ def default(input, value)
18
+ input.blank? ? value : input
19
+ end
20
+
21
+ end
22
+
23
+ ::Liquid::Template.register_filter(Misc)
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Liquid
4
+ module Filters
5
+ module Resize
6
+
7
+ def resize(input, resize_string)
8
+ Locomotive::Builder::Dragonfly.instance.resize_url(input, resize_string)
9
+ end
10
+
11
+ end
12
+
13
+ ::Liquid::Template.register_filter(Resize)
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,50 @@
1
+ require 'RedCloth'
2
+
3
+ module Locomotive
4
+ module Builder
5
+ module Liquid
6
+ module Filters
7
+ module Text
8
+
9
+ # right justify and padd a string
10
+ def rjust(input, integer, padstr = '')
11
+ input.to_s.rjust(integer, padstr)
12
+ end
13
+
14
+ # left justify and padd a string
15
+ def ljust(input, integer, padstr = '')
16
+ input.to_s.ljust(integer, padstr)
17
+ end
18
+
19
+ def underscore(input)
20
+ input.to_s.gsub(' ', '_').gsub('/', '_').underscore
21
+ end
22
+
23
+ def dasherize(input)
24
+ input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
25
+ end
26
+
27
+ # alias newline_to_br
28
+ def multi_line(input)
29
+ input.to_s.gsub("\n", '<br/>')
30
+ end
31
+
32
+ def concat(input, *args)
33
+ result = input.to_s
34
+ args.flatten.each { |a| result << a.to_s }
35
+ result
36
+ end
37
+
38
+
39
+ def textile(input)
40
+ ::RedCloth.new(input).to_html
41
+ end
42
+
43
+ end
44
+
45
+ ::Liquid::Template.register_filter(Text)
46
+
47
+ end
48
+ end
49
+ end
50
+ end