locomotivecms_mounter 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/lib/locomotive/mounter/config.rb +21 -0
  2. data/lib/locomotive/mounter/engine_api.rb +40 -0
  3. data/lib/locomotive/mounter/exceptions.rb +38 -0
  4. data/lib/locomotive/mounter/extensions/compass.rb +36 -0
  5. data/lib/locomotive/mounter/extensions/httmultiparty.rb +22 -0
  6. data/lib/locomotive/mounter/extensions/tilt/css.rb +31 -0
  7. data/lib/locomotive/mounter/extensions/tilt/haml.rb +27 -0
  8. data/lib/locomotive/mounter/extensions/tilt/liquid.rb +23 -0
  9. data/lib/locomotive/mounter/extensions/tilt/template.rb +11 -0
  10. data/lib/locomotive/mounter/fields.rb +250 -0
  11. data/lib/locomotive/mounter/models/base.rb +41 -0
  12. data/lib/locomotive/mounter/models/content_asset.rb +84 -0
  13. data/lib/locomotive/mounter/models/content_entry.rb +290 -0
  14. data/lib/locomotive/mounter/models/content_field.rb +128 -0
  15. data/lib/locomotive/mounter/models/content_select_option.rb +29 -0
  16. data/lib/locomotive/mounter/models/content_type.rb +217 -0
  17. data/lib/locomotive/mounter/models/editable_element.rb +27 -0
  18. data/lib/locomotive/mounter/models/page.rb +377 -0
  19. data/lib/locomotive/mounter/models/site.rb +27 -0
  20. data/lib/locomotive/mounter/models/snippet.rb +55 -0
  21. data/lib/locomotive/mounter/models/theme_asset.rb +135 -0
  22. data/lib/locomotive/mounter/models/translation.rb +28 -0
  23. data/lib/locomotive/mounter/mounting_point.rb +49 -0
  24. data/lib/locomotive/mounter/reader/api/base.rb +49 -0
  25. data/lib/locomotive/mounter/reader/api/content_assets_reader.rb +40 -0
  26. data/lib/locomotive/mounter/reader/api/content_entries_reader.rb +141 -0
  27. data/lib/locomotive/mounter/reader/api/content_types_reader.rb +74 -0
  28. data/lib/locomotive/mounter/reader/api/pages_reader.rb +174 -0
  29. data/lib/locomotive/mounter/reader/api/site_reader.rb +37 -0
  30. data/lib/locomotive/mounter/reader/api/snippets_reader.rb +59 -0
  31. data/lib/locomotive/mounter/reader/api/theme_assets_reader.rb +42 -0
  32. data/lib/locomotive/mounter/reader/api/translations_reader.rb +28 -0
  33. data/lib/locomotive/mounter/reader/api.rb +49 -0
  34. data/lib/locomotive/mounter/reader/file_system/base.rb +65 -0
  35. data/lib/locomotive/mounter/reader/file_system/content_assets_reader.rb +88 -0
  36. data/lib/locomotive/mounter/reader/file_system/content_entries_reader.rb +101 -0
  37. data/lib/locomotive/mounter/reader/file_system/content_types_reader.rb +88 -0
  38. data/lib/locomotive/mounter/reader/file_system/pages_reader.rb +206 -0
  39. data/lib/locomotive/mounter/reader/file_system/site_reader.rb +24 -0
  40. data/lib/locomotive/mounter/reader/file_system/snippets_reader.rb +78 -0
  41. data/lib/locomotive/mounter/reader/file_system/theme_assets_reader.rb +78 -0
  42. data/lib/locomotive/mounter/reader/file_system/translations_reader.rb +36 -0
  43. data/lib/locomotive/mounter/reader/file_system.rb +42 -0
  44. data/lib/locomotive/mounter/reader/runner.rb +89 -0
  45. data/lib/locomotive/mounter/utils/hash.rb +31 -0
  46. data/lib/locomotive/mounter/utils/string.rb +17 -0
  47. data/lib/locomotive/mounter/utils/yaml.rb +125 -0
  48. data/lib/locomotive/mounter/version.rb +8 -0
  49. data/lib/locomotive/mounter/writer/api/base.rb +323 -0
  50. data/lib/locomotive/mounter/writer/api/content_assets_writer.rb +74 -0
  51. data/lib/locomotive/mounter/writer/api/content_entries_writer.rb +223 -0
  52. data/lib/locomotive/mounter/writer/api/content_types_writer.rb +151 -0
  53. data/lib/locomotive/mounter/writer/api/pages_writer.rb +225 -0
  54. data/lib/locomotive/mounter/writer/api/site_writer.rb +164 -0
  55. data/lib/locomotive/mounter/writer/api/snippets_writer.rb +111 -0
  56. data/lib/locomotive/mounter/writer/api/theme_assets_writer.rb +152 -0
  57. data/lib/locomotive/mounter/writer/api/translations_writer.rb +83 -0
  58. data/lib/locomotive/mounter/writer/api.rb +62 -0
  59. data/lib/locomotive/mounter/writer/file_system/base.rb +61 -0
  60. data/lib/locomotive/mounter/writer/file_system/content_assets_writer.rb +33 -0
  61. data/lib/locomotive/mounter/writer/file_system/content_entries_writer.rb +29 -0
  62. data/lib/locomotive/mounter/writer/file_system/content_types_writer.rb +27 -0
  63. data/lib/locomotive/mounter/writer/file_system/pages_writer.rb +73 -0
  64. data/lib/locomotive/mounter/writer/file_system/site_writer.rb +25 -0
  65. data/lib/locomotive/mounter/writer/file_system/snippets_writer.rb +54 -0
  66. data/lib/locomotive/mounter/writer/file_system/theme_assets_writer.rb +35 -0
  67. data/lib/locomotive/mounter/writer/file_system/translations_writer.rb +22 -0
  68. data/lib/locomotive/mounter/writer/file_system.rb +69 -0
  69. data/lib/locomotive/mounter/writer/runner.rb +68 -0
  70. data/lib/locomotive/mounter.rb +97 -0
  71. metadata +487 -0
@@ -0,0 +1,65 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class Base
7
+
8
+ attr_accessor :runner, :items
9
+
10
+ delegate :default_locale, :locales, to: :mounting_point
11
+
12
+ def initialize(runner)
13
+ self.runner = runner
14
+ self.items = {}
15
+ end
16
+
17
+ def mounting_point
18
+ self.runner.mounting_point
19
+ end
20
+
21
+ protected
22
+
23
+ # Return the locale of a file based on its extension.
24
+ #
25
+ # Ex:
26
+ # about_us/john_doe.fr.liquid.haml => 'fr'
27
+ # about_us/john_doe.liquid.haml => 'en' (default locale)
28
+ #
29
+ # @param [ String ] filepath The path to the file
30
+ #
31
+ # @return [ String ] The locale (ex: fr, en, ...etc) or nil if it has no information about the locale
32
+ #
33
+ def filepath_locale(filepath)
34
+ locale = File.basename(filepath).split('.')[1]
35
+
36
+ if locale.nil?
37
+ # no locale, use the default one
38
+ self.default_locale
39
+ elsif self.locales.include?(locale)
40
+ # the locale is registered
41
+ locale
42
+ elsif locale.size == 2
43
+ # unregistered locale
44
+ nil
45
+ else
46
+ self.default_locale
47
+ end
48
+ end
49
+
50
+ # Open a YAML file and returns the content of the file
51
+ #
52
+ # @param [ String ] filepath The path to the file
53
+ #
54
+ # @return [ Object ] The content of the file
55
+ #
56
+ def read_yaml(filepath)
57
+ YAML::load(File.open(filepath).read.force_encoding('utf-8'))
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,88 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class ContentAssetsReader < Base
7
+
8
+ # Build the list of contents assets
9
+ #
10
+ # @return [ Array ] The list of content assets
11
+ #
12
+ def read
13
+ self.items = [] # prefer an array over a hash
14
+
15
+ self.fetch_from_pages
16
+
17
+ self.fetch_from_content_entries
18
+
19
+ self.items
20
+ end
21
+
22
+ protected
23
+
24
+ # Fetch the files from the template of all the pages
25
+ #
26
+ def fetch_from_pages
27
+ self.mounting_point.pages.values.each do |page|
28
+ page.translated_in.each do |locale|
29
+ Locomotive::Mounter.with_locale(locale) do
30
+ unless page.template.blank?
31
+ self.add_assets_from_string(page.source)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ # Fetch the files from the content entries
39
+ #
40
+ def fetch_from_content_entries
41
+ self.mounting_point.content_entries.values.each do |content_entry|
42
+ content_entry.translated_in.each do |locale|
43
+ Locomotive::Mounter.with_locale(locale) do
44
+ # get the string, text, file fields...
45
+ content_entry.content_type.fields.each do |field|
46
+ case field.type.to_sym
47
+ when :string, :text
48
+ self.add_assets_from_string(content_entry.dynamic_getter(field.name))
49
+ when :file
50
+ self.add_assets_from_string(content_entry.dynamic_getter(field.name)['url'])
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ # Parse the string passed in parameter in order to
59
+ # look for content assets. If found, then add them.
60
+ #
61
+ # @param [ String ] source The string to parse
62
+ #
63
+ def add_assets_from_string(source)
64
+ return if source.blank?
65
+
66
+ source.to_s.match(/\/samples\/.*\.[a-zA-Z0-9]+/) do |match|
67
+ filepath = File.join(self.root_dir, match.to_s)
68
+ folder = File.dirname(match.to_s)
69
+ self.items << Locomotive::Mounter::Models::ContentAsset.new(filepath: filepath, folder: folder)
70
+ end
71
+ end
72
+
73
+ # Return the directory where all the theme assets
74
+ # are stored in the filesystem.
75
+ #
76
+ # @return [ String ] The theme assets directory
77
+ #
78
+ def root_dir
79
+ File.join(self.runner.path, 'public')
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,101 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class ContentEntriesReader < Base
7
+
8
+ # Build the list of content types from the folder on the file system.
9
+ #
10
+ # @return [ Array ] The un-ordered list of content types
11
+ #
12
+ def read
13
+ self.fetch_from_filesystem
14
+
15
+ self.items
16
+ end
17
+
18
+ protected
19
+
20
+ def fetch_from_filesystem
21
+ Dir.glob(File.join(self.root_dir, '*.yml')).each do |filepath|
22
+ attributes = self.read_yaml(filepath)
23
+
24
+ content_type = self.get_content_type(File.basename(filepath, '.yml'))
25
+
26
+ content_type.entries.try(:clear)
27
+
28
+ attributes.each_with_index do |_attributes, index|
29
+ self.add(content_type, _attributes, index)
30
+ end
31
+ end
32
+ end
33
+
34
+ # Get the content type identified by the slug from the mounting point.
35
+ # Raise an UnknownContentTypeException exception if such a content type
36
+ # does not exist.
37
+ #
38
+ # @param [ String ] slug The slug of the content type
39
+ #
40
+ # @return [ Object ] The instance of the content type
41
+ #
42
+ def get_content_type(slug)
43
+ self.mounting_point.content_types[slug.to_s].tap do |content_type|
44
+ if content_type.nil?
45
+ raise UnknownContentTypeException.new("unknow content type #{slug.inspect}")
46
+ end
47
+ end
48
+ end
49
+
50
+ # Add a content entry for a content type.
51
+ #
52
+ # @param [ Object ] content_type The content type
53
+ # @param [ Hash ] attributes The attributes of the content entry
54
+ # @param [ Integer ] position The position of the entry in the list
55
+ #
56
+ def add(content_type, attributes, position)
57
+ if attributes.is_a?(String)
58
+ label, _attributes = attributes, {}
59
+ else
60
+ label, _attributes = attributes.keys.first, attributes.values.first
61
+ end
62
+
63
+ # check if the label_field is localized or not
64
+ label_field_name = content_type.label_field_name
65
+
66
+ if content_type.label_field.localized && _attributes.key?(label_field_name) && _attributes[label_field_name].is_a?(Hash)
67
+ _attributes[label_field_name].merge!(Locomotive::Mounter.locale => label).symbolize_keys!
68
+ else
69
+ _attributes[label_field_name] = label
70
+ end
71
+
72
+ _attributes[:_position] = position
73
+
74
+ entry = content_type.build_entry(_attributes)
75
+
76
+ # puts "entry._slug = #{entry._slug.inspect}"
77
+ # entry.main_locale = Locomotive::Mounter.locale
78
+ # puts entry.to_hash.inspect
79
+ # puts entry.dynamic_attributes.inspect
80
+ # puts entry.send(:sync_translations)
81
+
82
+ key = File.join(content_type.slug, entry._slug)
83
+
84
+ self.items[key] = entry
85
+ end
86
+
87
+ # Return the directory where all the entries
88
+ # of the content types are stored.
89
+ #
90
+ # @return [ String ] The content entries root directory
91
+ #
92
+ def root_dir
93
+ File.join(self.runner.path, 'data')
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,88 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class ContentTypesReader < Base
7
+
8
+ # Build the list of content types from the folder in the file system.
9
+ #
10
+ # @return [ Array ] The un-ordered list of content types
11
+ #
12
+ def read
13
+ self.fetch_from_filesystem
14
+
15
+ self.items
16
+ end
17
+
18
+ protected
19
+
20
+ def fetch_from_filesystem
21
+ Dir.glob(File.join(self.root_dir, '*.yml')).each do |filepath|
22
+ attributes = self.read_yaml(filepath)
23
+
24
+ self.add(attributes)
25
+ end
26
+ end
27
+
28
+ # Add a new content type in the global hash of content types.
29
+ # If the content type exists, it returns it.
30
+ #
31
+ # @param [ Hash ] attributes The attributes of the content type
32
+ #
33
+ # @return [ Object ] A newly created content type or the existing one
34
+ #
35
+ def add(attributes)
36
+ slug = attributes['slug']
37
+
38
+ # TODO: raise an error if no fields
39
+
40
+ attributes.delete('fields').each_with_index do |_attributes, index|
41
+ hash = { name: _attributes.keys.first, position: index }.merge(_attributes.values.first)
42
+
43
+ if options = hash.delete('select_options')
44
+ hash['select_options'] = self.sanitize_select_options(options)
45
+ end
46
+
47
+ (attributes['fields'] ||= []) << hash
48
+ end
49
+
50
+ attributes[:mounting_point] = self.mounting_point
51
+
52
+ unless self.items.key?(slug)
53
+ self.items[slug] = Locomotive::Mounter::Models::ContentType.new(attributes)
54
+ end
55
+
56
+ self.items[slug]
57
+ end
58
+
59
+ # Take the list of options described in the YAML file
60
+ # and convert it into a nice array of hashes
61
+ #
62
+ # @params [ Array ] options The list of raw options
63
+ #
64
+ # @return [ Array ] The sanitized list of options
65
+ #
66
+ def sanitize_select_options(options)
67
+ [].tap do |array|
68
+ options.each_with_index do |object, position|
69
+ array << { name: object, position: position }
70
+ end
71
+ end
72
+ end
73
+
74
+ # Return the directory where all the definition of
75
+ # the content types are stored.
76
+ #
77
+ # @return [ String ] The content types directory
78
+ #
79
+ def root_dir
80
+ File.join(self.runner.path, 'app', 'content_types')
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,206 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class PagesReader < Base
7
+
8
+ attr_accessor :pages
9
+
10
+ def initialize(runner)
11
+ self.pages = {}
12
+ super
13
+ end
14
+
15
+ # Build the tree of pages based on the filesystem structure
16
+ #
17
+ # @return [ Hash ] The pages organized as a Hash (using the fullpath as the key)
18
+ #
19
+ def read
20
+ self.fetch
21
+
22
+ index, not_found = self.pages['index'], self.pages['404']
23
+
24
+ # localize the fullpath for the 2 core pages: index and 404
25
+ [index, not_found].each { |p| p.localize_fullpath(self.locales) }
26
+
27
+ self.build_relationships(index, self.pages_to_list)
28
+
29
+ # Locomotive::Mounter.with_locale(:en) { self.to_s } # DEBUG
30
+
31
+ # Locomotive::Mounter.with_locale(:fr) { self.to_s } # DEBUG
32
+
33
+ self.pages
34
+ end
35
+
36
+ protected
37
+
38
+ # Create a ordered list of pages from the Hash
39
+ #
40
+ # @return [ Array ] An ordered list of pages
41
+ #
42
+ def pages_to_list
43
+ # sort by fullpath first
44
+ list = self.pages.values.sort { |a, b| a.fullpath <=> b.fullpath }
45
+ # sort finally by depth
46
+ list.sort { |a, b| a.depth <=> b.depth }
47
+ end
48
+
49
+ def build_relationships(parent, list)
50
+ # do not use an empty template for other locales than the default one
51
+ parent.set_default_template_for_each_locale(self.default_locale)
52
+
53
+ list.dup.each do |page|
54
+ next unless self.is_subpage_of?(page.fullpath, parent.fullpath)
55
+
56
+ # attach the page to the parent (order by position), also set the parent
57
+ parent.add_child(page)
58
+
59
+ # localize the fullpath in all the locales
60
+ page.localize_fullpath
61
+
62
+ # remove the page from the list
63
+ list.delete(page)
64
+
65
+ # go under
66
+ self.build_relationships(page, list)
67
+ end
68
+ end
69
+
70
+ # Record pages found in file system
71
+ def fetch
72
+ folders = []
73
+
74
+ Dir.glob(File.join(self.root_dir, '**/*')).each do |filepath|
75
+ fullpath = self.filepath_to_fullpath(filepath)
76
+
77
+ folders.push(fullpath) && next if File.directory?(filepath)
78
+
79
+ next unless filepath =~ /\.(#{Locomotive::Mounter::TEMPLATE_EXTENSIONS.join('|')})$/
80
+
81
+ page = self.add(fullpath)
82
+
83
+ if locale = self.filepath_locale(filepath)
84
+ Locomotive::Mounter.with_locale(locale) do
85
+ self.set_attributes_from_header(page, filepath)
86
+ end
87
+ else
88
+ Locomotive::Mounter.logger.warn "Unknown locale in the '#{File.basename(filepath)}' file."
89
+ end
90
+ end
91
+
92
+ folders.each do |fullpath|
93
+ next if self.pages.key?(fullpath)
94
+ self.add(fullpath)
95
+ end
96
+ end
97
+
98
+ # Add a new page in the global hash of pages.
99
+ # If the page exists, then do nothing.
100
+ #
101
+ # @param [ String ] fullpath The fullpath used as the key for the hash
102
+ # @param [ Hash ] attributes The attributes of the new page
103
+ #
104
+ # @return [ Object ] A newly created page or the existing one
105
+ #
106
+ def add(fullpath, attributes = {})
107
+ unless self.pages.key?(fullpath)
108
+ attributes[:title] = File.basename(fullpath).humanize
109
+ attributes[:fullpath] = fullpath
110
+
111
+ self.pages[fullpath] = Locomotive::Mounter::Models::Page.new(attributes)
112
+ end
113
+
114
+ self.pages[fullpath]
115
+ end
116
+
117
+ # Set attributes of a page from the information
118
+ # stored in the header of the template (YAML matters).
119
+ # It also stores the template.
120
+ #
121
+ # @param [ Object ] page The page
122
+ # @param [ String ] filepath The path of the template
123
+ #
124
+ def set_attributes_from_header(page, filepath)
125
+ template = Tilt.new(filepath)
126
+
127
+ if template.respond_to?(:attributes)
128
+ return if template.attributes.blank?
129
+
130
+ attributes = template.attributes.clone
131
+
132
+ # set the editable elements
133
+ page.set_editable_elements(attributes.delete('editable_elements'))
134
+
135
+ # set the content type
136
+ if content_type_slug = attributes.delete('content_type')
137
+ attributes['templatized'] = true
138
+ attributes['content_type'] = self.mounting_point.content_types.values.find { |ct| ct.slug == content_type_slug }
139
+ end
140
+
141
+ page.attributes = attributes
142
+ end
143
+
144
+ page.template = template
145
+ end
146
+
147
+ # Return the directory where all the templates of
148
+ # pages are stored in the filesystem.
149
+ #
150
+ # @return [ String ] The root directory
151
+ #
152
+ def root_dir
153
+ File.join(self.runner.path, 'app', 'views', 'pages')
154
+ end
155
+
156
+ # Take the path to a file on the filesystem
157
+ # and return its matching value for a Page.
158
+ #
159
+ # @param [ String ] filepath The path to the file
160
+ #
161
+ # @return [ String ] The fullpath of the page
162
+ #
163
+ def filepath_to_fullpath(filepath)
164
+ fullpath = filepath.gsub(File.join(self.root_dir, '/'), '')
165
+
166
+ fullpath.gsub!(/^\.\//, '')
167
+
168
+ fullpath.split('.').first.dasherize
169
+ end
170
+
171
+ # Tell is a page described by its fullpath is a sub page of a parent page
172
+ # also described by its fullpath
173
+ #
174
+ # @param [ String ] fullpath The full path of the page to test
175
+ # @param [ String ] parent_fullpath The full path of the parent page
176
+ #
177
+ # @return [ Boolean] True if the page is a sub page of the parent one
178
+ #
179
+ def is_subpage_of?(fullpath, parent_fullpath)
180
+ return false if %w(index 404).include?(fullpath)
181
+
182
+ if parent_fullpath == 'index' && fullpath.split('/').size == 1
183
+ return true
184
+ end
185
+
186
+ File.dirname(fullpath.dasherize) == parent_fullpath.dasherize
187
+ end
188
+
189
+ # Output simply the tree structure of the pages.
190
+ #
191
+ # Note: only for debug purpose
192
+ #
193
+ def to_s(page = nil)
194
+ page ||= self.pages['index']
195
+
196
+ puts "#{" " * (page.try(:depth) + 1)} #{page.fullpath.inspect} (#{page.title}, position=#{page.position})"
197
+
198
+ (page.children || []).each { |child| self.to_s(child) }
199
+ end
200
+
201
+ end
202
+
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,24 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class SiteReader < Base
7
+
8
+ def read
9
+ config_path = File.join(self.runner.path, 'config', 'site.yml')
10
+
11
+ site = self.read_yaml(config_path)
12
+
13
+ # set the default locale first
14
+ Locomotive::Mounter.locale = site['locales'].first.to_sym rescue Locomotive::Mounter.locale
15
+
16
+ Locomotive::Mounter::Models::Site.new(site)
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,78 @@
1
+ module Locomotive
2
+ module Mounter
3
+ module Reader
4
+ module FileSystem
5
+
6
+ class SnippetsReader < Base
7
+
8
+ # Build the list of snippets from the folder on the file system.
9
+ #
10
+ # @return [ Array ] The un-ordered list of snippets
11
+ #
12
+ def read
13
+ self.fetch_from_filesystem
14
+
15
+ self.items
16
+ end
17
+
18
+ protected
19
+
20
+ # Record snippets found in file system
21
+ def fetch_from_filesystem
22
+ Dir.glob(File.join(self.root_dir, "*.{#{Locomotive::Mounter::TEMPLATE_EXTENSIONS.join(',')}}")).each do |filepath|
23
+ fullpath = File.basename(filepath)
24
+
25
+ snippet = self.add(filepath)
26
+
27
+ Locomotive::Mounter.with_locale(self.filepath_locale(filepath)) do
28
+ snippet.template = Tilt.new(filepath)
29
+ end
30
+ end
31
+ end
32
+
33
+ # Return the directory where all the templates of
34
+ # snippets are stored in the filesystem.
35
+ #
36
+ # @return [ String ] The snippets directory
37
+ #
38
+ def root_dir
39
+ File.join(self.runner.path, 'app', 'views', 'snippets')
40
+ end
41
+
42
+ # Add a new snippet in the global hash of snippets.
43
+ # If the snippet exists, it returns it.
44
+ #
45
+ # @param [ String ] filepath The path to the file
46
+ #
47
+ # @return [ Object ] A newly created snippet or the existing one
48
+ #
49
+ def add(filepath)
50
+ slug = self.filepath_to_slug(filepath)
51
+
52
+ unless self.items.key?(slug)
53
+ self.items[slug] = Locomotive::Mounter::Models::Snippet.new({
54
+ name: slug.humanize,
55
+ slug: slug,
56
+ template: Tilt.new(filepath)
57
+ })
58
+ end
59
+
60
+ self.items[slug]
61
+ end
62
+
63
+ # Convert a filepath to a slug
64
+ #
65
+ # @param [ String ] filepath The path to the file
66
+ #
67
+ # @return [ String ] The slug
68
+ #
69
+ def filepath_to_slug(filepath)
70
+ File.basename(filepath).split('.').first
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+ end
77
+ end
78
+ end