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,58 @@
1
+ # Public name of this content type
2
+ name: <%= config[:name].humanize %>
3
+
4
+ # TODO: explain
5
+ slug: <%= config[:name] %>
6
+
7
+ # Explanation for the backoffice
8
+ description: A description of the content type for the editors
9
+
10
+ # Default field (e.g title)
11
+ label_field_name: <%= config[:fields].first.name %>
12
+
13
+ # Order of entries
14
+ order_by: manually # default: manually, also available: created_at or any field slug
15
+
16
+ # Order direction
17
+ # order_direction: asc # default: asc, also available: desc
18
+
19
+ # Display entries grouped by <field> in the backoffice
20
+ # group_by: <your field>
21
+
22
+ # Activate public 'create' API (e.g for a contact form)
23
+ # public_submission_enabled: false
24
+
25
+ # Emails to be notified on new entries using the public API
26
+ # public_submission_accounts: ['john@acme.net']
27
+
28
+ # Describe each field. The name shoud always be an underscored string
29
+ fields: <% config[:fields].each_with_index do |field, index| %>
30
+ - <%= field.name -%>: # Name of the field
31
+ label: <%= field.name.humanize %>
32
+ type: <%= field.type %>
33
+ required: <%= index == 0 ? true : field.required %>
34
+ hint: A description of the field for the editors
35
+ localized: false<% if field.type == 'text' %>
36
+ # Enable or not the RTE [html|text]
37
+ # text_formatting: html<% end -%><% if field.type == 'select' -%>
38
+ # if localized, use
39
+ # en: ['option1_en', 'option2_en']
40
+ # fr: ['option1_fr', 'option2_fr']
41
+ select_options: ['option 1', 'option 2', 'option 3']<% end -%><% if field.type == 'belongs_to'%>
42
+ # Slug of the target content type (eg post if this content type is a comment)
43
+ class_name: <your class slug><% end -%><% if field.type == 'has_many' -%>
44
+ # Define the slug of the target content type (eg. comments)
45
+ class_name: <your class slug>
46
+ # Define the name of the field referring to <%= config[:name].humanize -%> in the target content type (eg. post)
47
+ inverse_of: <field in your target content type>
48
+ # If you want to manage the entries of the relationship directly from the source entry
49
+ ui_enabled: true
50
+ <% end -%><% if field.type == 'many_to_many' -%>
51
+ # Define the slug of the target content type
52
+ class_name: <your class slug>
53
+ inverse_of: <field in your target content type>
54
+ # If you want to manage the entries of the relationship directly from the source entry
55
+ ui_enabled: true
56
+ <% end -%>
57
+
58
+ <% end -%>
@@ -0,0 +1,24 @@
1
+ <% 4.times do |i| -%>
2
+ - "Sample <%= i + 1 %>":
3
+ <% config[:fields][1..-1].each do |field| -%>
4
+ <% case field.type -%>
5
+ <% when 'string' -%>
6
+ <%= field.name -%>: "<%= Faker::Lorem.sentence -%>"
7
+ <% when 'text' -%>
8
+ <%= field.name -%>: "<%= Faker::Lorem.paragraph -%>"
9
+ <% when 'select' -%>
10
+ <%= field.name -%>: null # Use the value of a select option defined in the app/content_types/<%= config[:name] -%>.rb file.
11
+ <% when 'boolean' -%>
12
+ <%= field.name -%>: true # Or false
13
+ <% when 'date' -%>
14
+ <%= field.name -%>: <%= Time.now.strftime('%Y/%M/%d') -%> # YYYY/MM/DD
15
+ <% when 'file' -%>
16
+ <%= field.name -%>: null # Path to a file in the public/samples folder or to a remote and external file.
17
+ <% when 'belongs_to' -%>
18
+ <%= field.name -%>: null # Permalink of the target entry
19
+ <% when 'many_to_many' -%>
20
+ <%= field.name -%>: [] # Permalink of the target entries
21
+ <% end -%>
22
+ <% end -%>
23
+
24
+ <% end -%>
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: <%= config[:slug].humanize -%>
3
+ <% if config[:translated] %>
4
+
5
+ # TODO: explain it (used only if the page is not for the defaut locale)
6
+ slug: <%= config[:slug] -%>
7
+ <% end %>
8
+
9
+ # TODO: explain it
10
+ listed: true
11
+
12
+ # TODO: explain it
13
+ published: true
14
+
15
+ # TODO: explain it
16
+ # position: 1
17
+
18
+ # TODO: explain it
19
+ # redirect_url: "<url to a page or to a remote url>"
20
+
21
+ # TODO: explain it
22
+ # content_type: "<slug of one of the content types>"
23
+
24
+ # TODO: explain it
25
+ # editable_elements:
26
+ # 'some_block/some_slug': "<text>"
27
+ # 'some_block/some_slug': "<relative path to the file under the public/samples folder>"
28
+ ---
29
+ {% extends parent %}
30
+
31
+ {% block main %}
32
+
33
+ %p Hello world
34
+
35
+ {% endblock %}
@@ -0,0 +1 @@
1
+ TEST LIQUID
@@ -0,0 +1,4 @@
1
+ {% raw %}
2
+ / To use your snippet, just add the following code in your page template
3
+ / {% include <%= config[:slug] -%> %}
4
+ {% endraw %}
@@ -0,0 +1,4 @@
1
+ {% raw %}
2
+ <!-- To use your snippet, just add the following code in your page template-->
3
+ <!-- {% include <%= config[:slug] -%> %} -->
4
+ {% endraw %}
@@ -0,0 +1,225 @@
1
+ require 'thor'
2
+ require 'thor/runner'
3
+
4
+ module Locomotive
5
+ module Builder
6
+ module CLI
7
+
8
+ module CheckPath
9
+
10
+ protected
11
+
12
+ # Check if the path given in option ('.' by default) points to a LocomotiveCMS
13
+ # site. It is also possible to pass a path other than the one from the options.
14
+ #
15
+ # @param [ String ] path The optional path instead of options['path']
16
+ #
17
+ # @return [ String ] The fullpath to the LocomotiveCMS site or nil if it is not a valid site.
18
+ #
19
+ def check_path!(path = nil)
20
+ path ||= options['path']
21
+
22
+ path = path == '.' ? Dir.pwd : File.expand_path(path)
23
+
24
+ (File.exists?(File.join(path, 'config', 'site.yml')) ? path : nil).tap do |_path|
25
+ if _path.nil?
26
+ say 'The path does not point to a LocomotiveCMS site', :red
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ class Generate < Thor
34
+
35
+ include Locomotive::Builder::CLI::CheckPath
36
+
37
+ class_option :path, aliases: '-p', type: :string, default: '.', optional: true, desc: 'if your LocomotiveCMS site is not in the current path'
38
+
39
+ desc 'content_type NAME FIELDS', 'Create a content type with NAME as the slug and FIELDS as the list of fields.'
40
+ long_desc <<-LONGDESC
41
+ Create a content type with NAME as the slug and FIELDS as the list of fields.
42
+ The fields follows that schema:
43
+
44
+ field_1[:type][:required] field_2[:type][:required]
45
+
46
+ Examples:
47
+
48
+ * builder generate content_type songs name:string duration:string
49
+
50
+ * builder generate content_type posts title body:text:true published_at:date
51
+ LONGDESC
52
+ def content_type(name, *fields)
53
+ say('The fields are missing', :red) and return false if fields.empty?
54
+
55
+ if check_path!
56
+ Locomotive::Builder.generate :content_type, name, self.options['path'], fields
57
+ end
58
+ end
59
+
60
+ desc 'page FULLPATH', 'Create a page. No need to pass an extension to the FULLPATH arg'
61
+ long_desc <<-LONGDESC
62
+ Create a page. The generator will ask for the extension (liquid or haml) and also
63
+ if the page is localized or not.
64
+
65
+ Examples:
66
+
67
+ * builder generate page contact
68
+
69
+ * builder generate page about_us/me
70
+ LONGDESC
71
+ def page(fullpath)
72
+ if check_path!
73
+ Locomotive::Builder.generate :page, fullpath, self.options['path']
74
+ end
75
+ end
76
+
77
+ desc 'snippet SLUG', 'Create a snippet'
78
+ long_desc <<-LONGDESC
79
+ Create a snippet. The generator will ask for the extension (liquid or haml) and also
80
+ if the snippet is localized or not.
81
+
82
+ Example:
83
+
84
+ * builder generate snippet footer
85
+ LONGDESC
86
+ def snippet(slug)
87
+ if check_path!
88
+ Locomotive::Builder.generate :snippet, slug, self.options['path']
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ class Main < Thor
95
+
96
+ include Locomotive::Builder::CLI::CheckPath
97
+
98
+ desc 'version', 'Version of the LocomotiveCMS builder'
99
+ def version
100
+ require 'locomotive/builder/version'
101
+ say Locomotive::Builder::VERSION
102
+ end
103
+
104
+ desc 'init NAME [PATH]', 'Create a brand new LocomotiveCMS site'
105
+ method_option :template, aliases: '-t', type: 'string', default: 'blank', desc: 'instead of building from a blank site, you can have a pre-fetched site with form a template (see the templates command)'
106
+ def init(name, path = '.')
107
+ require 'locomotive/builder/generators/site'
108
+ generator = Locomotive::Builder::Generators::Site.get(options[:template])
109
+ if generator.nil?
110
+ say "Unknown site template '#{options[:template]}'", :red
111
+ else
112
+ Locomotive::Builder.init(name, path, generator)
113
+ end
114
+ end
115
+
116
+ desc 'generate TYPE ...ARGS', 'Generate resources (content_types, page, snippets) for a LocomotiveCMS site'
117
+ subcommand 'generate', Generate
118
+
119
+ desc 'list_templates', 'List all the templates to create either a site or a content type'
120
+ def list_templates
121
+ require 'locomotive/builder/generators/site'
122
+ if Locomotive::Builder::Generators::Site.empty?
123
+ say 'No templates', :red
124
+ else
125
+ Locomotive::Builder::Generators::Site.list.each do |info|
126
+ say info.name, :bold, false
127
+ say " - #{info.description}" unless info.description.blank?
128
+ end
129
+ end
130
+ end
131
+
132
+ desc 'serve [PATH]', 'Serve a LocomotiveCMS site from the file system'
133
+ method_option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: 'The host (address) of the Thin server'
134
+ method_option :port, aliases: '-p', type: 'string', default: '3333', desc: 'The port of the Thin server'
135
+ def serve(path = '.')
136
+ if check_path!(path)
137
+ begin
138
+ Locomotive::Builder.serve(path, options)
139
+ rescue Exception => e
140
+ say e.message, :red
141
+ end
142
+ end
143
+ end
144
+
145
+ desc 'push ENV [PATH]', 'Push a site to a remote LocomotiveCMS engine'
146
+ method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
147
+ method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Force the push of a resource'
148
+ method_option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
149
+ def push(env, path = '.')
150
+ if check_path!(path)
151
+ if connection_info = self.retrieve_connection_info(env, path)
152
+ begin
153
+ Locomotive::Builder.push(path, connection_info, options)
154
+ rescue Exception => e
155
+ say e.message, :red
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ desc 'pull ENV [PATH]', 'Pull a site from a remote LocomotiveCMS engine'
162
+ method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
163
+ # method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Force the push of a resource'
164
+ # method_option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
165
+ def pull(env, path = '.')
166
+ if check_path!(path)
167
+ if connection_info = self.retrieve_connection_info(env, path)
168
+ begin
169
+ Locomotive::Builder.pull(path, connection_info, options)
170
+ rescue Exception => e
171
+ say e.message, :red
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ desc 'destroy ENV [PATH]', 'Destroy a remote LocomotiveCMS engine'
178
+ def destroy(env, path = '.')
179
+ if check_path!(path)
180
+ if connection_info = self.retrieve_connection_info(env, path)
181
+ if ask('Are you sure ?', limited_to: %w(yes no)) == 'yes'
182
+ Locomotive::Builder.destroy(path, connection_info)
183
+ else
184
+ say 'The destroy operation has been cancelled', :red
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ # desc "pull NAME SITE_URL EMAIL PASSWORD", "Pull an existing LocomotiveCMS site powered by the engine"
191
+ # def pull(name, site_url, email, password)
192
+ # say("ERROR: \"#{name}\" directory already exists", :red) and return if File.exists?(name)
193
+ # Locomotive::Builder.pull(name, site_url, email, password)
194
+ # end
195
+
196
+ protected
197
+
198
+ # From a site specified by a path, retrieve the information of the connection
199
+ # for a environment located in the config/deploy.yml file of the site.
200
+ #
201
+ # @param [ String ] env The environment (development, staging, production, ...etc)
202
+ # @param [ String ] path The path of the local site
203
+ #
204
+ # @return [ Hash ] The information of the connection or nil if errors
205
+ #
206
+ def retrieve_connection_info(env, path)
207
+ connection_info = nil
208
+ begin
209
+ path_to_deploy_file = File.join(path, 'config', 'deploy.yml')
210
+ connection_info = YAML::load(File.open(path_to_deploy_file).read)[env.to_s]
211
+
212
+ if connection_info.nil?
213
+ raise "No #{env.to_s} environment found in the config/deploy.yml file"
214
+ end
215
+ rescue Exception => e
216
+ say "Unable to read the information about the remote LocomotiveCMS site (#{e.message})", :red
217
+ end
218
+ connection_info
219
+ end
220
+
221
+ end
222
+
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,17 @@
1
+ module Locomotive
2
+ module Builder
3
+
4
+ class DefaultException < ::Exception
5
+
6
+ def initialize(message = nil)
7
+ # no specific treatment for now
8
+ super
9
+ end
10
+
11
+ end
12
+
13
+ class MounterException < DefaultException
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'thor/group'
2
+ require 'ostruct'
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+ require 'faker'
6
+
7
+ module Locomotive
8
+ module Builder
9
+ module Generators
10
+ class ContentType < Thor::Group
11
+
12
+ include Thor::Actions
13
+
14
+ argument :name
15
+ argument :target_path
16
+ argument :fields
17
+
18
+ def copy_sources
19
+ directory('.', target_path, { recursive: true }, {
20
+ name: self.name,
21
+ fields: extract_fields(fields)
22
+ })
23
+ end
24
+
25
+ def self.source_root
26
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'generators', 'content_type')
27
+ end
28
+
29
+ protected
30
+
31
+ def extract_fields(fields)
32
+ fields.map do |raw_attributes|
33
+ name, type, required = raw_attributes.split(':')
34
+
35
+ OpenStruct.new({
36
+ name: name,
37
+ type: type || 'string',
38
+ required: %w(true required).include?(required)
39
+ })
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,57 @@
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 Page < 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 page 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_page
27
+ extension = self.haml ? 'liquid.haml' : 'liquid'
28
+
29
+ segments = self.slug.split('/')
30
+ while segment = segments.pop do
31
+ options = { slug: segment, translated: false }
32
+ file_path = File.join(pages_path, segments, segment)
33
+
34
+ template "template.#{extension}.tt", "#{file_path}.#{extension}", options
35
+
36
+ self.locales.each do |locale|
37
+ options[:translated] = true
38
+ template "template.#{extension}.tt", "#{file_path}.#{locale}.#{extension}", options
39
+ end
40
+ end
41
+ end
42
+
43
+ def self.source_root
44
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'generators', 'page')
45
+ end
46
+
47
+ protected
48
+
49
+ def pages_path
50
+ File.join(target_path, 'app', 'views', 'pages')
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
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
+ module Site
9
+
10
+ class Base < Thor::Group
11
+
12
+ include Thor::Actions
13
+
14
+ argument :name
15
+ argument :target_path
16
+
17
+ def self.source_root
18
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', '..', 'generators', self.name.demodulize.underscore)
19
+ end
20
+
21
+ def destination
22
+ File.join(target_path, name)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Generators
4
+ module Site
5
+
6
+ class Blank < Base
7
+
8
+ def copy_sources
9
+ directory('.', self.destination, { recursive: true }, {
10
+ name: self.name,
11
+ version: Locomotive::Builder::VERSION
12
+ })
13
+ end
14
+
15
+ end
16
+
17
+ Locomotive::Builder::Generators::Site.register(:blank, Blank, %{
18
+ A blank LocomotiveCMS site with the minimal files.
19
+ })
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Locomotive
2
+ module Builder
3
+ module Generators
4
+ module Site
5
+
6
+ class Bootstrap < Base
7
+
8
+ def copy_sources
9
+ directory('.', self.destination, { recursive: true }, {
10
+ name: self.name,
11
+ version: Locomotive::Builder::VERSION
12
+ })
13
+ end
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
+ remove_file File.join(self.destination, 'app/views/snippets/footer.liquid')
20
+ else
21
+ remove_file File.join(self.destination, 'app/views/pages/index.liquid.haml')
22
+ remove_file File.join(self.destination, 'app/views/pages/404.liquid.haml')
23
+ remove_file File.join(self.destination, 'app/views/snippets/footer.liquid.haml')
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ Locomotive::Builder::Generators::Site.register(:bootstrap, Bootstrap, %{
30
+ A LocomotiveCMS site powered by Twitter bootstrap (v2.2.2).
31
+ })
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ require 'ostruct'
2
+ require 'singleton'
3
+
4
+ module Locomotive
5
+ module Builder
6
+ module Generators
7
+
8
+ module Site
9
+
10
+ # Register a generator by adding it to the list of existing generators.
11
+ #
12
+ # @param [ String ] name The name of the generator
13
+ # @param [ Class ] klass The class of the generator
14
+ # @param [ String ] description The description of the generator (can be nil)
15
+ #
16
+ # @return [ Boolean ] True if the registration has been successful, false otherwise.
17
+ #
18
+ def self.register(name, klass, description = nil)
19
+ Locomotive::Builder::Generators::Site::List.instance.register(name, klass, description)
20
+ end
21
+
22
+ # Return the information about a generator from its name.
23
+ #
24
+ # @param [ String ] name The name of the generator
25
+ #
26
+ # @return [ Object ] The information of the found generator or nil
27
+ #
28
+ def self.get(name)
29
+ Locomotive::Builder::Generators::Site::List.instance.get(name)
30
+ end
31
+
32
+ # List all the generators
33
+ #
34
+ # @return [ Array ] The filtered (or not) list of generators
35
+ #
36
+ def self.list
37
+ Locomotive::Builder::Generators::Site::List.instance._list
38
+ end
39
+
40
+ # Tell if the list of generators is empty or not .
41
+ #
42
+ # @return [ Boolean ] True if empty
43
+ #
44
+ def self.empty?
45
+ Locomotive::Builder::Generators::Site::List.instance._list.empty?
46
+ end
47
+
48
+ class List
49
+
50
+ include ::Singleton
51
+
52
+ attr_accessor :_list
53
+
54
+ def initialize
55
+ self._list = []
56
+ end
57
+
58
+ # Return the information about a generator from its name.
59
+ #
60
+ # @param [ String ] name The name of the generator
61
+ #
62
+ # @return [ Object ] The information of the found generator or nil
63
+ #
64
+ def get(name)
65
+ self._list.detect { |entry| entry.name == name.to_sym }
66
+ end
67
+
68
+ # Register a generator by adding it to the list of existing generators.
69
+ #
70
+ # @param [ String ] name The name of the generator
71
+ # @param [ Class ] klass The class of the generator
72
+ # @param [ String ] description The description of the generator (can be nil)
73
+ #
74
+ # @return [ Boolean ] True if the registration has been successful, false otherwise.
75
+ #
76
+ def register(name, klass, description = nil)
77
+ return false unless self.get(name).nil?
78
+
79
+ self._list << OpenStruct.new({
80
+ name: name.to_sym,
81
+ klass: klass,
82
+ description: description ? description.strip.gsub("\n", '') : nil
83
+ })
84
+
85
+ self._list.last
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+
95
+ require 'locomotive/builder/generators/site/base'
96
+ require 'locomotive/builder/generators/site/blank'
97
+ require 'locomotive/builder/generators/site/bootstrap'