first draft for the content type generator (needs a little bit of refactoring)

did committed Jan 14, 2013
commit 69cb39e283896929e7b7fad9c7ddcbf2b56c2dee
Showing 9 changed files with 207 additions and 42 deletions
TODO +2 -1
@@ @@ -22,11 +22,12 @@ x content types / liquid
- params to launch the thin server (port, address ?)
- commands:
- create
- x sites
+ - sites
x blank
x twitter bootstrap + HAML
? localized
? boilerplate
+ - copy Bundler / Gemfile
- content types
- push:
- option to select to push only some parts (pages, ...etc)
bin/builder +3 -3
@@ @@ -3,7 +3,7 @@
# FIXME: needed if you don't launch it with bundler
# $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
- require "locomotive/builder"
- require "locomotive/builder/cli"
+ require 'locomotive/builder'
+ require 'locomotive/builder/cli'
- Locomotive::Builder::CLI.start
\ No newline at end of file
+ Locomotive::Builder::CLI::Main.start
\ No newline at end of file
generators/content_type/app/content_types/%name%.yml.tt +48 -0
@@ @@ -0,0 +1,48 @@
+ # TODO: explain
+ name: <%= config[:name].humanize %>
+
+ # TODO: explain
+ slug: <%= config[:name] %>
+
+ # TODO: explain
+ description: A description of the content type for the editors
+
+ # TODO: explain
+ label_field_name: <%= config[:fields].first.name %>
+
+ # TODO: explain
+ order_by: manually # TODO: list all different values
+
+ # TODO: explain
+ # group_by: <your field>
+
+ # TODO: explain
+ # public_submission_enabled: false
+ # public_submission_accounts: ['john@acme.net']
+
+ # TODO: explain
+ fields: <% config[:fields].each do |field| %>
+ - <%= field.name -%>: # Name of the field
+ label: <%= field.name.humanize %>
+ type: <%= field.type %>
+ required: <%= field.required %>
+ hint: A description of the field for the editors
+ localized: false<% if field.type == 'select' -%>
+ # TODO: explain (localization)
+ select_options: ['option 1', 'option 2', 'option 3']
+ <% end -%><% if field.type == 'belongs_to' -%>
+ # TODO: explain
+ class_name: SLUG OF THE TARGET CONTENT TYPE
+ <% end -%><% if field.type == 'has_many' -%>
+ # TODO: explain
+ class_name: SLUG OF THE TARGET CONTENT TYPE
+ inverse_of: NAME OF THE FIELD IN THE TARGET CONTENT TYPE
+ ui_enabled: true
+ <% end -%><% if field.type == 'many_to_many' -%>
+ # TODO: explain
+ class_name: SLUG OF THE TARGET CONTENT TYPE
+ inverse_of: NAME OF THE FIELD IN THE TARGET CONTENT TYPE
+ ui_enabled: true
+ <% end -%>
+
+ <% end -%>
generators/content_type/data/%name%.yml.tt +1 -0
@@ @@ -0,0 +1 @@
+ %name%.yml.tt
\ No newline at end of file
locomotive/builder/cli.rb b/lib/locomotive/builder/cli.rb +97 -35
@@ @@ -1,50 +1,112 @@
require 'thor'
+ require 'thor/runner'
module Locomotive
module Builder
- class CLI < Thor
-
- desc 'init NAME [PATH]', 'Create a brand new LocomotiveCMS site'
- 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)'
- def init(name, path = '.')
- require 'locomotive/builder/generators'
- generator = Locomotive::Builder::Generators.get(options[:template])
- if generator.nil?
- say "Unknown site template '#{options[:template]}'", :red
- else
- Locomotive::Builder.init(name, path, generator)
+ module CLI
+
+ class Generate < Thor
+
+ class_option :path, aliases: '-p', type: :string, default: '.', optional: true, desc: 'if your LocomotiveCMS site is not in the current path'
+
+ desc 'content_type NAME FIELDS', 'Create a content type with NAME as the slug and FIELDS as the list of fields.'
+ long_desc <<-LONGDESC
+ Create a content type with NAME as the slug and FIELDS as the list of fields.
+ The fields follows that schema:
+
+ field_1[:type][:required] field_2[:type][:required]
+
+ Examples:
+
+ * builder generate content_type songs name:string duration:string
+
+ * builder generate content_type posts title body:text:true published_at:date
+ LONGDESC
+ def content_type(name, *fields)
+ say('The fields are missing', :red) and return false if fields.empty?
+
+ if path = check_path!
+ require 'locomotive/builder/generators/content_type'
+
+ script = Locomotive::Builder::Generators::ContentType.new([name, self.options['path'], fields], {}, {})
+ script.invoke_all
+ else
+ say 'The path does not point to a LocomotiveCMS site', :red
+ end
end
- end
- desc 'serve [PATH]', 'Serve a LocomotiveCMS site from the file system'
- method_option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: "The host (address) of the Thin server"
- method_option :port, aliases: '-p', type: 'string', default: '3333', desc: "The port of the Thin server"
- def serve(path = '.')
- Locomotive::Builder.serve(path, options)
- end
+ desc 'page PATH', 'Create a page whose NAME is its fullpath'
+ def page(path)
+ puts "TODO [page] #{path}"
+ end
- desc "pull NAME SITE_URL EMAIL PASSWORD", "Pull an existing LocomotiveCMS site powered by the engine"
- def pull(name, site_url, email, password)
- say("ERROR: \"#{name}\" directory already exists", :red) and return if File.exists?(name)
- Locomotive::Builder.pull(name, site_url, email, password)
- end
+ desc 'snippet NAME', 'Create a snippet'
+ def snippet(name)
+ puts "TODO [snippet] #{name}"
+ end
+
+ protected
+
+ # Check if the path given in option ('.' by default) points to a LocomotiveCMS
+ # site.
+ #
+ # @return [ String ] The fullpath to the LocomotiveCMS site or nil if it is not a valid site.
+ #
+ def check_path!
+ path = options['path'] == '.' ? Dir.pwd : File.expand_path(options['path'])
+
+ File.exists?(File.join(path, 'config', 'site.yml')) ? path : nil
+ end
- desc "push PATH SITE_URL EMAIL PASSWORD", "Push a site created by the builder to a remote LocomotiveCMS engine"
- def push(path, site_url, email, password)
- Locomotive::Builder.push(path, site_url, email, password)
end
- desc "list_templates", "List all the templates to create either a site or a content type"
- def list_templates
- require 'locomotive/builder/generators'
- if Locomotive::Builder::Generators.empty?(:site)
- say "No templates", :red
- else
- Locomotive::Builder::Generators.list(:site).each do |info|
- say info.name, :bold, false
- say " - #{info.description}" unless info.description.blank?
+ class Main < Thor
+
+ desc 'init NAME [PATH]', 'Create a brand new LocomotiveCMS site'
+ 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)'
+ def init(name, path = '.')
+ require 'locomotive/builder/generators'
+ generator = Locomotive::Builder::Generators.get(options[:template])
+ if generator.nil?
+ say "Unknown site template '#{options[:template]}'", :red
+ else
+ Locomotive::Builder.init(name, path, generator)
+ end
+ end
+
+ desc 'generate TYPE ...ARGS', 'Generate resources (content_types, page, snippets) for a LocomotiveCMS site'
+ subcommand 'generate', Generate
+
+ desc 'list_templates', 'List all the templates to create either a site or a content type'
+ def list_templates
+ require 'locomotive/builder/generators'
+ if Locomotive::Builder::Generators.empty?(:site)
+ say 'No templates', :red
+ else
+ Locomotive::Builder::Generators.list(:site).each do |info|
+ say info.name, :bold, false
+ say " - #{info.description}" unless info.description.blank?
+ end
end
end
+
+ desc 'serve [PATH]', 'Serve a LocomotiveCMS site from the file system'
+ method_option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: 'The host (address) of the Thin server'
+ method_option :port, aliases: '-p', type: 'string', default: '3333', desc: 'The port of the Thin server'
+ def serve(path = '.')
+ Locomotive::Builder.serve(path, options)
+ end
+
+ # desc "pull NAME SITE_URL EMAIL PASSWORD", "Pull an existing LocomotiveCMS site powered by the engine"
+ # def pull(name, site_url, email, password)
+ # say("ERROR: \"#{name}\" directory already exists", :red) and return if File.exists?(name)
+ # Locomotive::Builder.pull(name, site_url, email, password)
+ # end
+
+ # desc "push PATH SITE_URL EMAIL PASSWORD", "Push a site created by the builder to a remote LocomotiveCMS engine"
+ # def push(path, site_url, email, password)
+ # Locomotive::Builder.push(path, site_url, email, password)
+ # end
end
end
locomotive/builder/generators/content_type.rb b/lib/locomotive/builder/generators/content_type.rb +51 -0
@@ @@ -0,0 +1,51 @@
+ require 'thor/group'
+ require 'ostruct'
+ require 'active_support'
+ require 'active_support/core_ext'
+
+ module Locomotive
+ module Builder
+ module Generators
+ class ContentType < Thor::Group
+
+ include Thor::Actions
+
+ argument :name
+ argument :target_path
+ argument :fields
+
+ def copy_sources
+ directory('.', target_path, { recursive: true }, {
+ name: self.name,
+ fields: extract_fields(fields)
+ })
+ end
+
+ def self.source_root
+ File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'generators', 'content_type')
+ end
+
+ protected
+
+ def extract_fields(fields)
+ fields.map do |raw_attributes|
+ name, type, required = raw_attributes.split(':')
+
+ OpenStruct.new({
+ name: name,
+ type: type || 'string',
+ required: required || false
+ })
+ end
+ end
+
+ # def destination
+ # File.join(target_path, name)
+ # end
+
+ end
+
+ # Locomotive::Builder::Generators.register(:others, :content_type, SimpleContentType)
+ end
+ end
+ end
\ No newline at end of file
locomotive/builder/generators/defaults.rb b/lib/locomotive/builder/generators/defaults.rb +3 -1
@@ @@ -1,3 +1,5 @@
# sites
require 'locomotive/builder/generators/sites/blank'
- require 'locomotive/builder/generators/sites/bootstrap'
\ No newline at end of file
+ require 'locomotive/builder/generators/sites/bootstrap'
+
+ require 'locomotive/builder/generators/content_type'
\ No newline at end of file
locomotive/builder/generators/list.rb b/lib/locomotive/builder/generators/list.rb +1 -1
@@ @@ -67,7 +67,7 @@ module Locomotive
type: type.to_sym,
name: name.to_sym,
klass: klass,
- description: description.strip.gsub("\n", '')
+ description: description ? description.strip.gsub("\n", '') : nil
})
self._list.last
locomotive/builder/generators/sites/bootstrap.rb b/lib/locomotive/builder/generators/sites/bootstrap.rb +1 -1
@@ @@ -12,7 +12,7 @@ module Locomotive
end
def choose_haml_over_html
- if yes?('Do you want HAML templates ?')
+ if yes?('Do you prefer HAML templates ?')
remove_file File.join(self.destination, 'app/views/pages/index.liquid')
remove_file File.join(self.destination, 'app/views/pages/404.liquid')
remove_file File.join(self.destination, 'app/views/snippets/footer.liquid')