better generator for the content types + make sure the subdomain is valid when generating a new site + force color option when generating a site, snippet or a content type
did
committed May 14, 2014
commit cbd079ca426c858ecb407d9f21a278b38b565122
Showing 18
changed files with
150 additions
and 121 deletions
generators/blank/config/site.yml.tt
+2
-2
| @@ | @@ -1,12 +1,12 @@ |
| # The name of this site | |
| - | # This text displays in the back-office and |
| + | # This text displays in the back-office and |
| # can be used in templates through the site.name global variable | |
| name: <%= config[:name] %> | |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/bootstrap/config/site.yml.tt
+2
-2
| @@ | @@ -1,12 +1,12 @@ |
| # The name of this site | |
| - | # This text displays in the back-office and |
| + | # This text displays in the back-office and |
| # can be used in templates through the site.name global variable | |
| name: <%= config[:name] %> | |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/bootstrap2/config/site.yml.tt
+1
-1
| @@ | @@ -6,7 +6,7 @@ name: <%= config[:name] %> |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/bootstrap3/config/site.yml.tt
+1
-1
| @@ | @@ -6,7 +6,7 @@ name: <%= config[:name] %> |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/content_type/app/content_types/%name%.yml.tt
+0
-57
| @@ | @@ -1,57 +0,0 @@ |
| - | # Human readable name of this type |
| - | name: <%= config[:name].humanize %> |
| - | |
| - | # Lowercase, underscored handle used to access this type |
| - | slug: <%= config[:name] %> |
| - | |
| - | # Explanatory text displayed in the back-office |
| - | description: A description of the content type for the editors |
| - | |
| - | # Slug of field used to identify entries by default, such as the title |
| - | label_field_name: <%= config[:fields].first.name %> |
| - | |
| - | # Valid values: manually, created_at, updated_at, or the slug of any field |
| - | order_by: manually |
| - | |
| - | # Valid values: asc (ascending) and desc (descending). Set to asc by default. |
| - | # order_direction: asc |
| - | |
| - | # Specify a field slug to group entries by that field in the back-office. |
| - | # group_by: <your field> |
| - | |
| - | # Activate public 'create' API (e.g for a contact form) |
| - | # public_submission_enabled: false |
| - | |
| - | # Array of emails to be notified of new entries made with the public API |
| - | # public_submission_accounts: ['john@example.com'] |
| - | |
| - | # A list describing each field |
| - | fields: <% config[:fields].each_with_index do |field, index| %> |
| - | - <%= field.name -%>: # The lowercase, underscored name of the field |
| - | label: <%= field.name.humanize %> # Human readable name of the field |
| - | type: <%= field.type %> |
| - | required: <%= index == 0 ? true : field.required %> |
| - | hint: Explanatory text displayed in the back office |
| - | localized: false<% if field.type == 'text' %> |
| - | # text_formatting: html # html (uses rich text editor) or text (uses plain text editor)<% end -%><% if field.type == 'select' -%> |
| - | # if localized, use |
| - | # en: ['option1_en', 'option2_en'] |
| - | # fr: ['option1_fr', 'option2_fr'] |
| - | select_options: ['option 1', 'option 2', 'option 3']<% end -%><% if field.type == 'belongs_to'%> |
| - | # Slug of the target content type (eg post if this content type is a comment) |
| - | class_name: <your class slug><% end -%><% if field.type == 'has_many' -%> |
| - | # Define the slug of the target content type (eg. comments) |
| - | class_name: <your class slug> |
| - | # Define the name of the field referring to <%= config[:name].humanize -%> in the target content type (eg. post) |
| - | inverse_of: <field in your target content type> |
| - | # If you want to manage the entries of the relationship directly from the source entry |
| - | ui_enabled: true |
| - | <% end -%><% if field.type == 'many_to_many' -%> |
| - | # Define the slug of the target content type |
| - | class_name: <your class slug> |
| - | inverse_of: <field in your target content type> |
| - | # If you want to manage the entries of the relationship directly from the source entry |
| - | ui_enabled: true |
| - | <% end -%> |
| - | |
| - | <% end -%> |
generators/content_type/app/content_types/%slug%.yml.tt
+57
-0
| @@ | @@ -0,0 +1,57 @@ |
| + | # Human readable name of this type |
| + | name: <%= config[:name] %> |
| + | |
| + | # Lowercase, underscored handle used to access this type |
| + | slug: <%= config[:slug] %> |
| + | |
| + | # Explanatory text displayed in the back-office |
| + | description: A description of the content type for the editors |
| + | |
| + | # Slug of field used to identify entries by default, such as the title |
| + | label_field_name: <%= config[:fields].first.name %> |
| + | |
| + | # Valid values: manually, created_at, updated_at, or the slug of any field |
| + | order_by: manually |
| + | |
| + | # Valid values: asc (ascending) and desc (descending). Set to asc by default. |
| + | # order_direction: asc |
| + | |
| + | # Specify a field slug to group entries by that field in the back-office. |
| + | # group_by: <your field> |
| + | |
| + | # Activate public 'create' API (e.g for a contact form) |
| + | # public_submission_enabled: false |
| + | |
| + | # Array of emails to be notified of new entries made with the public API |
| + | # public_submission_accounts: ['john@example.com'] |
| + | |
| + | # A list describing each field |
| + | fields: <% config[:fields].each_with_index do |field, index| %> |
| + | - <%= field.name -%>: # The lowercase, underscored name of the field |
| + | label: <%= field.label %> # Human readable name of the field |
| + | type: <%= field.type %> |
| + | required: <%= index == 0 ? true : field.required %> |
| + | hint: Explanatory text displayed in the back office |
| + | localized: false<% if field.type == 'text' %> |
| + | # text_formatting: html # html (uses rich text editor) or text (uses plain text editor)<% end -%><% if field.type == 'select' -%> |
| + | # if localized, use |
| + | # en: ['option1_en', 'option2_en'] |
| + | # fr: ['option1_fr', 'option2_fr'] |
| + | select_options: ['option 1', 'option 2', 'option 3']<% end -%><% if field.type == 'belongs_to'%> |
| + | # Slug of the target content type (eg post if this content type is a comment) |
| + | class_name: <%= field.class_name %><% end -%><% if field.type == 'has_many' -%> |
| + | # Define the slug of the target content type (eg. comments) |
| + | class_name: <%= field.class_name %> |
| + | # Define the name of the field referring to <%= config[:name].humanize -%> in the target content type (eg. post) |
| + | inverse_of: <%= field.inverse_of %> |
| + | # If you want to manage the entries of the relationship directly from the source entry |
| + | ui_enabled: true |
| + | <% end -%><% if field.type == 'many_to_many' -%> |
| + | # Define the slug of the target content type |
| + | class_name: <%= field.class_name %> |
| + | inverse_of: <%= field.inverse_of %> |
| + | # If you want to manage the entries of the relationship directly from the source entry |
| + | ui_enabled: true |
| + | <% end -%> |
| + | |
| + | <% end -%> |
generators/content_type/data/%name%.yml.tt
+0
-24
| @@ | @@ -1,24 +0,0 @@ |
| - | <% 4.times do |i| -%> |
| - | - "Sample <%= i + 1 %>"<%= ':' if config[:fields].size > 1 %> |
| - | <% config[:fields][1..-1].each do |field| -%> |
| - | <% case field.type -%> |
| - | <% when 'string' -%> |
| - | <%= field.name -%>: "<%= Faker::Lorem.sentence -%>" |
| - | <% when 'text' -%> |
| - | <%= field.name -%>: "<%= Faker::Lorem.paragraph -%>" |
| - | <% when 'select' -%> |
| - | <%= field.name -%>: null # Use the value of a select option defined in the app/content_types/<%= config[:name] -%>.rb file. |
| - | <% when 'boolean' -%> |
| - | <%= field.name -%>: true # Or false |
| - | <% when 'date' -%> |
| - | <%= field.name -%>: <%= Time.now.strftime('%Y/%m/%d') -%> # YYYY/MM/DD |
| - | <% when 'file' -%> |
| - | <%= field.name -%>: null # Path to a file in the public/samples folder or to a remote and external file. |
| - | <% when 'belongs_to' -%> |
| - | <%= field.name -%>: null # Slug of the target entry |
| - | <% when 'many_to_many' -%> |
| - | <%= field.name -%>: [] # Array of target entry slugs |
| - | <% end -%> |
| - | <% end -%> |
| - | |
| - | <% end -%> |
| \ No newline at end of file | |
generators/content_type/data/%slug%.yml.tt
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | <% 4.times do |i| -%> |
| + | - "Sample <%= i + 1 %>"<%= ':' if config[:fields].size > 1 %> |
| + | <% config[:fields][1..-1].each do |field| -%> |
| + | <% case field.type -%> |
| + | <% when 'string' -%> |
| + | <%= field.name -%>: "<%= Faker::Lorem.sentence -%>" |
| + | <% when 'text' -%> |
| + | <%= field.name -%>: "<%= Faker::Lorem.paragraph -%>" |
| + | <% when 'select' -%> |
| + | <%= field.name -%>: null # Use the value of a select option defined in the app/content_types/<%= config[:name] -%>.rb file. |
| + | <% when 'boolean' -%> |
| + | <%= field.name -%>: true # Or false |
| + | <% when 'date' -%> |
| + | <%= field.name -%>: <%= Time.now.strftime('%Y/%m/%d') -%> # YYYY/MM/DD |
| + | <% when 'file' -%> |
| + | <%= field.name -%>: null # Path to a file in the public/samples folder or to a remote and external file. |
| + | <% when 'belongs_to' -%> |
| + | <%= field.name -%>: null # Slug of the target entry |
| + | <% when 'many_to_many' -%> |
| + | <%= field.name -%>: [] # Array of target entry slugs |
| + | <% end -%> |
| + | <% end -%> |
| + | |
| + | <% end -%> |
| \ No newline at end of file | |
generators/foundation4/config/site.yml.tt
+2
-2
| @@ | @@ -1,12 +1,12 @@ |
| # The name of this site | |
| - | # This text displays in the back-office and |
| + | # This text displays in the back-office and |
| # can be used in templates through the site.name global variable | |
| name: <%= config[:name] %> | |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/foundation5/config/site.yml.tt
+2
-2
| @@ | @@ -1,12 +1,12 @@ |
| # The name of this site | |
| - | # This text displays in the back-office and |
| + | # This text displays in the back-office and |
| # can be used in templates through the site.name global variable | |
| name: <%= config[:name] %> | |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | # subdomain: sample |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
generators/line_case/config/site.yml.tt
+1
-1
| @@ | @@ -6,7 +6,7 @@ name: <%= config[:name] %> |
| # The site's subdomain | |
| # This option is for sites on multi-site engines | |
| # The value determines where the site can be accessed under the engine's primary domain | |
| - | subdomain: <%= config[:name].dasherize.downcase %> |
| + | subdomain: <%= config[:name].gsub(' ', '-').dasherize.downcase %> |
| # An array of domain aliases for the site | |
| # This option is for sites on multi-site engines | |
locomotive/wagon.rb b/lib/locomotive/wagon.rb
+10
-11
| @@ | @@ -54,14 +54,16 @@ module Locomotive |
| # Create a site from a site generator. | |
| # | |
| - | # @param [ String ] name The name of the site (underscored) |
| - | # @param [ String ] path The destination path of the site |
| - | # @param [ Boolean ] skip_bundle Do not run bundle install |
| # @param [ Object ] generator The wrapping class of the generator itself | |
| - | # @param [ String ] options Options for the generator (ex: --force_haml) |
| + | # @param [ Array ] args [name of the site, destination path of the site, skip bundle flag, force_haml] |
| + | # @param [ Hash ] options General options (ex: --force-color) |
| # | |
| - | def self.init(name, path, skip_bundle, generator, options) |
| - | generator.klass.start [name, path, skip_bundle, options] |
| + | def self.init(generator_klass, args, options = {}) |
| + | args, opts = Thor::Options.split(args) |
| + | |
| + | generator = generator_klass.new(args, opts, {}) |
| + | generator.force_color_if_asked(options) |
| + | generator.invoke_all |
| end | |
| # Start the thin server which serves the LocomotiveCMS site from the system. | |
| @@ | @@ -126,11 +128,8 @@ module Locomotive |
| lib = "locomotive/wagon/generators/#{name}" | |
| require lib | |
| - | puts args.inspect |
| - | puts options.inspect |
| - | puts "-------" |
| - | |
| - | generator = lib.camelize.constantize.new(args, options, {}) |
| + | generator = lib.camelize.constantize.new(args, options, { behavior: :skip }) |
| + | generator.force_color_if_asked(options) |
| generator.invoke_all | |
| end | |
locomotive/wagon/cli.rb b/lib/locomotive/wagon/cli.rb
+16
-7
| @@ | @@ -47,33 +47,39 @@ module Locomotive |
| class Generate < Thor | |
| + | include Locomotive::Wagon::CLI::ForceColor |
| include Locomotive::Wagon::CLI::CheckPath | |
| class_option :path, aliases: '-p', type: :string, default: '.', optional: true, desc: 'if your LocomotiveCMS site is not in the current path' | |
| desc 'content_type SLUG FIELDS', 'Creates a content type with the specified slug and fields.' | |
| + | method_option :name, aliases: '-n', type: :string, default: nil, optional: true, desc: 'Name of the content type as it will be displayed in the back-office' |
| long_desc <<-LONGDESC | |
| Creates a content type with the specified slug and fields. | |
| SLUG should be plural, lowercase, and underscored. | |
| - | FIELDS format: field_1[:TYPE][:REQUIRED] field_2[:TYPE][:REQUIRED] ... |
| + | FIELDS format: field_1[:TYPE][:LABEL][:REQUIRED][:LOCALIZED][:TARGET_CONTENT_TYPE_SLUG] field_2[:TYPE][:LABEL][:REQUIRED][:LOCALIZED][:TARGET_CONTENT_TYPE_SLUG] ... |
| TYPE values: string, text, integer, float, boolean, email, date, date_time, file, tags, select, belongs_to, has_many, or many_to_many. Default is string. | |
| To require a field, set REQUIRED to true. The first field is required by default. | |
| + | TARGET_CONTENT_TYPE_SLUG is the slug of the content type used in the relationship. |
| + | |
| Examples: | |
| * wagon generate content_type posts title published_at:date_time:true body:text | |
| - | * wagon generate content_type products title price:float photo:file category:belongs_to:true |
| + | * wagon generate content_type products title price:float photo:file category:belongs_to:Category:true:false:main_categories |
| LONGDESC | |
| def content_type(name, *fields) | |
| + | force_color_if_asked(options) |
| + | |
| say('The fields are missing', :red) and return false if fields.empty? | |
| if check_path! | |
| - | Locomotive::Wagon.generate :content_type, name, self.options['path'], fields |
| + | Locomotive::Wagon.generate :content_type, [name, fields, self.options.delete('path')], self.options |
| end | |
| end | |
| @@ | @@ -94,6 +100,8 @@ module Locomotive |
| * wagon generate page about_us/me | |
| LONGDESC | |
| def page(fullpath) | |
| + | force_color_if_asked(options) |
| + | |
| if path = check_path! | |
| self.options[:default_locales] = self.site_config(path)['locales'] | |
| Locomotive::Wagon.generate :page, [fullpath, self.options.delete('path')], self.options | |
| @@ | @@ -110,10 +118,11 @@ module Locomotive |
| * wagon generate snippet footer | |
| LONGDESC | |
| def snippet(slug) | |
| + | force_color_if_asked(options) |
| + | |
| if path = check_path! | |
| - | raise 'TODO' |
| locales = self.site_config(path)['locales'] | |
| - | Locomotive::Wagon.generate :snippet, slug, self.options['path'], locales |
| + | Locomotive::Wagon.generate :snippet, [slug, locales, self.options.delete('path')], self.options |
| end | |
| end | |
| @@ | @@ -137,7 +146,7 @@ module Locomotive |
| include Locomotive::Wagon::CLI::CheckPath | |
| include Locomotive::Wagon::CLI::ForceColor | |
| - | class_option :force_color, aliases: '-c', type: :boolean, default: false, desc: 'Whether or not to use ANSI color in the output.' |
| + | class_option :force_color, type: :boolean, default: false, desc: 'Whether or not to use ANSI color in the output.' |
| desc 'version', 'Version of the LocomotiveCMS Wagon' | |
| def version | |
| @@ | @@ -170,7 +179,7 @@ module Locomotive |
| exit(1) | |
| else | |
| begin | |
| - | if Locomotive::Wagon.init(name, path, options[:skip_bundle].to_s, generator, generator_options) |
| + | if Locomotive::Wagon.init(generator.klass, [name, path, options[:skip_bundle].to_s, generator_options], { force_color: options[:force_color] }) |
| self.print_next_instructions_when_site_created(name, path, options[:skip_bundle]) | |
| end | |
| rescue GeneratorException => e | |
locomotive/wagon/generators/content_type.rb b/lib/locomotive/wagon/generators/content_type.rb
+26
-10
| @@ | @@ -10,14 +10,16 @@ module Locomotive |
| class ContentType < Thor::Group | |
| include Thor::Actions | |
| + | include Locomotive::Wagon::CLI::ForceColor |
| - | argument :name |
| - | argument :target_path |
| + | argument :slug |
| argument :fields | |
| + | argument :target_path |
| def copy_sources | |
| directory('.', target_path, { recursive: true }, { | |
| - | name: self.name, |
| + | name: name, |
| + | slug: slug, |
| fields: extract_fields(fields) | |
| }) | |
| end | |
| @@ | @@ -28,15 +30,29 @@ module Locomotive |
| protected | |
| + | def name |
| + | options['name'] || slug.humanize |
| + | end |
| + | |
| def extract_fields(fields) | |
| fields.map do |raw_attributes| | |
| - | name, type, required = raw_attributes.split(':') |
| - | |
| - | OpenStruct.new({ |
| - | name: name, |
| - | type: type || 'string', |
| - | required: %w(true required).include?(required) |
| - | }) |
| + | name, type, label, required, localized, target_content_type_slug = raw_attributes.split(':') |
| + | |
| + | OpenStruct.new( |
| + | name: name, |
| + | label: label || name.humanize, |
| + | type: type || 'string', |
| + | required: %w(true required).include?(required), |
| + | localized: %w(true required).include?(localized) |
| + | ).tap do |field| |
| + | if %w(belongs_to has_many many_to_many).include?(type) |
| + | field.class_name = target_content_type_slug |
| + | |
| + | inverse_of = type == 'belongs_to' ? target_content_type_slug.singularize : target_content_type_slug |
| + | |
| + | field.inverse_of = inverse_of |
| + | end |
| + | end |
| end | |
| end | |
locomotive/wagon/generators/page.rb b/lib/locomotive/wagon/generators/page.rb
+1
-0
| @@ | @@ -8,6 +8,7 @@ module Locomotive |
| class Page < Thor::Group | |
| include Thor::Actions | |
| + | include Locomotive::Wagon::CLI::ForceColor |
| argument :slug | |
| argument :target_path # path to the site | |
locomotive/wagon/generators/site/base.rb b/lib/locomotive/wagon/generators/site/base.rb
+2
-0
| @@ | @@ -10,6 +10,7 @@ module Locomotive |
| class Base < Thor::Group | |
| include Thor::Actions | |
| + | include Locomotive::Wagon::CLI::ForceColor |
| argument :name | |
| argument :target_path | |
| @@ | @@ -37,6 +38,7 @@ module Locomotive |
| end | |
| def haml? | |
| + | puts options.inspect |
| if options[:haml].nil? | |
| yes?('Do you prefer HAML templates ?') | |
| else | |
locomotive/wagon/generators/snippet.rb b/lib/locomotive/wagon/generators/snippet.rb
+2
-1
| @@ | @@ -8,10 +8,11 @@ module Locomotive |
| class Snippet < Thor::Group | |
| include Thor::Actions | |
| + | include Locomotive::Wagon::CLI::ForceColor |
| argument :slug | |
| - | argument :target_path # path to the site |
| argument :locales | |
| + | argument :target_path # path to the site |
| attr_accessor :haml | |
locomotive/wagon/misc/hosting_api.rb b/lib/locomotive/wagon/misc/hosting_api.rb
+1
-0
| @@ | @@ -5,6 +5,7 @@ module Locomotive |
| include HTTParty | |
| + | # base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.com' |
| # base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.fr' | |
| base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.dev:3000' | |