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.
- data/.gitignore +31 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +47 -0
- data/TODO +57 -0
- data/bin/builder +9 -0
- data/generators/blank/Gemfile.tt +20 -0
- data/generators/blank/app/content_types/.empty_directory +1 -0
- data/generators/blank/app/views/pages/404.liquid +11 -0
- data/generators/blank/app/views/pages/index.liquid +19 -0
- data/generators/blank/app/views/snippets/.empty_directory +1 -0
- data/generators/blank/config/deploy.yml +12 -0
- data/generators/blank/config/site.yml.tt +16 -0
- data/generators/blank/config/translations.yml +8 -0
- data/generators/blank/config.ru +3 -0
- data/generators/blank/data/.empty_directory +1 -0
- data/generators/blank/public/fonts/.empty_directory +1 -0
- data/generators/blank/public/images/.empty_directory +1 -0
- data/generators/blank/public/javascripts/.empty_directory +1 -0
- data/generators/blank/public/samples/.empty_directory +1 -0
- data/generators/blank/public/stylesheets/.empty_directory +1 -0
- data/generators/bootstrap/Gemfile.tt +20 -0
- data/generators/bootstrap/app/content_types/.empty_directory +1 -0
- data/generators/bootstrap/app/views/pages/404.liquid +13 -0
- data/generators/bootstrap/app/views/pages/404.liquid.haml +10 -0
- data/generators/bootstrap/app/views/pages/index.liquid +85 -0
- data/generators/bootstrap/app/views/pages/index.liquid.haml +72 -0
- data/generators/bootstrap/app/views/snippets/footer.liquid +3 -0
- data/generators/bootstrap/app/views/snippets/footer.liquid.haml +2 -0
- data/generators/bootstrap/config/deploy.yml +12 -0
- data/generators/bootstrap/config/site.yml.tt +16 -0
- data/generators/bootstrap/config/translations.yml +8 -0
- data/generators/bootstrap/config.ru +3 -0
- data/generators/bootstrap/data/.empty_directory +1 -0
- data/generators/bootstrap/public/fonts/FontAwesome.otf +0 -0
- data/generators/bootstrap/public/fonts/font-awesome-ie7.min.css +23 -0
- data/generators/bootstrap/public/fonts/font-awesome.css +469 -0
- data/generators/bootstrap/public/fonts/font-awesome.min.css +34 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.eot +0 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.ttf +0 -0
- data/generators/bootstrap/public/fonts/fontawesome-webfont.woff +0 -0
- data/generators/bootstrap/public/javascripts/bootstrap.js +2159 -0
- data/generators/bootstrap/public/javascripts/bootstrap.min.js +6 -0
- data/generators/bootstrap/public/samples/.empty_directory +1 -0
- data/generators/bootstrap/public/stylesheets/application.css.scss +39 -0
- data/generators/bootstrap/public/stylesheets/bootstrap-responsive.css +1092 -0
- data/generators/bootstrap/public/stylesheets/bootstrap-responsive.min.css +9 -0
- data/generators/bootstrap/public/stylesheets/bootstrap.css +5652 -0
- data/generators/bootstrap/public/stylesheets/bootstrap.min.css +726 -0
- data/generators/content_type/app/content_types/%name%.yml.tt +58 -0
- data/generators/content_type/data/%name%.yml.tt +24 -0
- data/generators/page/template.liquid.haml.tt +35 -0
- data/generators/page/template.liquid.tt +1 -0
- data/generators/snippet/template.liquid.haml.tt +4 -0
- data/generators/snippet/template.liquid.tt +4 -0
- data/lib/locomotive/builder/cli.rb +225 -0
- data/lib/locomotive/builder/exceptions.rb +17 -0
- data/lib/locomotive/builder/generators/content_type.rb +47 -0
- data/lib/locomotive/builder/generators/page.rb +57 -0
- data/lib/locomotive/builder/generators/site/base.rb +30 -0
- data/lib/locomotive/builder/generators/site/blank.rb +23 -0
- data/lib/locomotive/builder/generators/site/bootstrap.rb +35 -0
- data/lib/locomotive/builder/generators/site.rb +97 -0
- data/lib/locomotive/builder/generators/snippet.rb +54 -0
- data/lib/locomotive/builder/liquid/drops/base.rb +44 -0
- data/lib/locomotive/builder/liquid/drops/content_entry.rb +48 -0
- data/lib/locomotive/builder/liquid/drops/content_types.rb +121 -0
- data/lib/locomotive/builder/liquid/drops/page.rb +36 -0
- data/lib/locomotive/builder/liquid/drops/site.rb +21 -0
- data/lib/locomotive/builder/liquid/errors.rb +7 -0
- data/lib/locomotive/builder/liquid/filters/date.rb +98 -0
- data/lib/locomotive/builder/liquid/filters/html.rb +154 -0
- data/lib/locomotive/builder/liquid/filters/misc.rb +28 -0
- data/lib/locomotive/builder/liquid/filters/resize.rb +18 -0
- data/lib/locomotive/builder/liquid/filters/text.rb +50 -0
- data/lib/locomotive/builder/liquid/filters/translate.rb +24 -0
- data/lib/locomotive/builder/liquid/patches.rb +47 -0
- data/lib/locomotive/builder/liquid/tags/consume.rb +58 -0
- data/lib/locomotive/builder/liquid/tags/csrf.rb +34 -0
- data/lib/locomotive/builder/liquid/tags/editable/base.rb +46 -0
- data/lib/locomotive/builder/liquid/tags/editable/control.rb +19 -0
- data/lib/locomotive/builder/liquid/tags/editable/file.rb +15 -0
- data/lib/locomotive/builder/liquid/tags/editable/long_text.rb +15 -0
- data/lib/locomotive/builder/liquid/tags/editable/short_text.rb +15 -0
- data/lib/locomotive/builder/liquid/tags/editable.rb +5 -0
- data/lib/locomotive/builder/liquid/tags/extends.rb +25 -0
- data/lib/locomotive/builder/liquid/tags/google_analytics.rb +28 -0
- data/lib/locomotive/builder/liquid/tags/inline_editor.rb +16 -0
- data/lib/locomotive/builder/liquid/tags/locale_switcher.rb +180 -0
- data/lib/locomotive/builder/liquid/tags/nav.rb +167 -0
- data/lib/locomotive/builder/liquid/tags/paginate.rb +105 -0
- data/lib/locomotive/builder/liquid/tags/seo.rb +74 -0
- data/lib/locomotive/builder/liquid/tags/snippet.rb +42 -0
- data/lib/locomotive/builder/liquid/tags/with_scope.rb +43 -0
- data/lib/locomotive/builder/liquid.rb +19 -0
- data/lib/locomotive/builder/listen.rb +48 -0
- data/lib/locomotive/builder/misc/core_ext.rb +29 -0
- data/lib/locomotive/builder/misc/dragonfly.rb +82 -0
- data/lib/locomotive/builder/misc/httparty.rb +47 -0
- data/lib/locomotive/builder/misc/i18n.rb +2 -0
- data/lib/locomotive/builder/misc/will_paginate.rb +16 -0
- data/lib/locomotive/builder/misc.rb +5 -0
- data/lib/locomotive/builder/server/dynamic_assets.rb +31 -0
- data/lib/locomotive/builder/server/entry_submission.rb +116 -0
- data/lib/locomotive/builder/server/favicon.rb +17 -0
- data/lib/locomotive/builder/server/locale.rb +42 -0
- data/lib/locomotive/builder/server/middleware.rb +54 -0
- data/lib/locomotive/builder/server/not_found.rb +18 -0
- data/lib/locomotive/builder/server/page.rb +59 -0
- data/lib/locomotive/builder/server/path.rb +34 -0
- data/lib/locomotive/builder/server/renderer.rb +105 -0
- data/lib/locomotive/builder/server/templatized_page.rb +32 -0
- data/lib/locomotive/builder/server.rb +78 -0
- data/lib/locomotive/builder/standalone_server.rb +33 -0
- data/lib/locomotive/builder/version.rb +5 -0
- data/lib/locomotive/builder.rb +167 -0
- data/locales/de.yml +143 -0
- data/locales/en.yml +164 -0
- data/locales/es.yml +119 -0
- data/locales/et.yml +140 -0
- data/locales/fr.yml +133 -0
- data/locales/it.yml +141 -0
- data/locales/nb.yml +177 -0
- data/locales/nl.yml +148 -0
- data/locales/pl.yml +189 -0
- data/locales/pt-BR.yml +125 -0
- data/locales/ru.yml +210 -0
- data/locomotivecms_builder.gemspec +42 -0
- data/spec/integration/cassettes/pull.yml +590 -0
- data/spec/integration/cassettes/push.yml +775 -0
- data/spec/integration/integration_helper.rb +15 -0
- data/spec/integration/server_spec.rb +37 -0
- data/spec/integration/sites_spec.rb +27 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/helpers.rb +13 -0
- 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,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,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'
|