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'