sitepress-core 2.0.0.beta8 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83c9ae67ef108b15908409feb2d555c718019e667c187713969372910e688580
4
- data.tar.gz: 077afc29c48638240747ba35f3be4dda71f038645d1de08411d5337698d45b6a
3
+ metadata.gz: 4bf0b2c774c66fac3d6b12d4a9e8ca07ad774ebb06efa966bc38b9a04c6d08e2
4
+ data.tar.gz: 92e2f384ddf2b34592494f9e25ad52fb386e0e2516ec9129defb12bcb5653717
5
5
  SHA512:
6
- metadata.gz: 68622942e6fb27b292154b2ab5b344b6ba6a34008d151aef31d0b69989c732ad9c5eefdc69f335f31650d8c8652fdad9fe935e0c02c63910648194b0123f45dc
7
- data.tar.gz: aa63c9d8b7fdb3c9dda60503192799d00cdd4ca8219047b04d632d21dc8ada33a61305ec9059ef0753a8dbbebd7e04a3aadf1a5f1e27cec71407cd2361edcbc2
6
+ metadata.gz: de0131d58b1c69251b3cb2d0fe253b44f75e8af2e671f5d41772bd7c07f0cc2381045883f4a474267b84db5d0e35667b437e7e6fef3274578a3557febfea6b37
7
+ data.tar.gz: e9a0171d0b66a8b6985022203ac82a9b2860f1f62bed26b5fdc6910caf64049e9d1e90b3c68ef6a5f4d480b002d92f814bba343bdea63f336de3f59104c46780
@@ -8,13 +8,14 @@ module Sitepress
8
8
  ExistingRequestPathError = Class.new(InvalidRequestPathError)
9
9
 
10
10
  autoload :Asset, "sitepress/asset"
11
+ autoload :AssetNodeMapper, "sitepress/asset_node_mapper"
12
+ autoload :AssetPaths, "sitepress/asset_paths"
11
13
  autoload :Formats, "sitepress/formats"
12
- autoload :Frontmatter, "sitepress/frontmatter"
13
14
  autoload :Node, "sitepress/node"
14
15
  autoload :Path, "sitepress/path"
16
+ autoload :Parsers, "sitepress/parsers"
15
17
  autoload :Resource, "sitepress/resource"
16
18
  autoload :ResourceCollection, "sitepress/resource_collection"
17
19
  autoload :ResourcesPipeline, "sitepress/resources_pipeline"
18
20
  autoload :Site, "sitepress/site"
19
- autoload :SourceNodeMapper, "sitepress/source_node_mapper"
20
21
  end
@@ -4,7 +4,7 @@ require "pathname"
4
4
 
5
5
  module Sitepress
6
6
  # Represents a file on a web server that may be parsed to extract
7
- # frontmatter or be renderable via a template. Multiple resources
7
+ # metadata or be renderable via a template. Multiple resources
8
8
  # may point to the same asset. Properties of an asset should be mutable.
9
9
  # The Resource object is immutable and may be modified by the Resources proxy.
10
10
  class Asset
@@ -16,42 +16,15 @@ module Sitepress
16
16
  attr_reader :path
17
17
 
18
18
  extend Forwardable
19
- def_delegators :frontmatter, :data, :body
19
+ def_delegators :parser, :data, :body
20
+ def_delegators :path, :handler, :node_name, :format, :exists?
20
21
 
21
- def initialize(path: , mime_type: nil)
22
+ def initialize(path:, mime_type: nil, parser: Parsers::Frontmatter)
22
23
  # The MIME::Types gem returns an array when types are looked up.
23
24
  # This grabs the first one, which is likely the intent on these lookups.
24
25
  @mime_type = Array(mime_type).first
25
- @path = Pathname.new path
26
- end
27
-
28
- # List of all file extensions.
29
- def extensions
30
- path.basename.to_s.split(".").drop(1)
31
- end
32
-
33
- def basename
34
- path.basename.to_s.split(".").first
35
- end
36
- alias :node_name :basename
37
-
38
- def format_basename
39
- [basename, format_extension].join(".")
40
- end
41
-
42
- # Returns the format extension.
43
- def format_extension
44
- extensions.first
45
- end
46
-
47
- # The base name with the format extension.
48
- def format_name
49
- [basename, format_extension].join(".")
50
- end
51
-
52
- # Returns a list of the rendering extensions.
53
- def template_extensions
54
- extensions.drop(1)
26
+ @path = Path.new path
27
+ @parser_klass = parser
55
28
  end
56
29
 
57
30
  # Treat resources with the same request path as equal.
@@ -63,19 +36,28 @@ module Sitepress
63
36
  @mime_type ||= inferred_mime_type || DEFAULT_MIME_TYPE
64
37
  end
65
38
 
66
- def exists?
67
- File.exist? path
39
+ # Used by the Rails controller to short circuit additional processing if the
40
+ # asset is not renderable (e.g. is it erb or haml?)
41
+ def renderable?
42
+ !!handler
68
43
  end
69
44
 
70
- private
71
- def frontmatter
72
- Frontmatter.new File.read @path
45
+ # Set the parser equal to a thing.
46
+ def parser=(parser_klass)
47
+ @parser = nil
48
+ @parser_klass = parser_klass
73
49
  end
74
50
 
75
- # Returns the mime type of the file extension. If a type can't
76
- # be resolved then we'll just grab the first type.
77
- def inferred_mime_type
78
- MIME::Types.type_for(format_extension).first if format_extension
79
- end
51
+ private
52
+ def parser
53
+ @parser ||= @parser_klass.new File.read path
54
+ end
55
+
56
+ # Returns the mime type of the file extension. If a type can't
57
+ # be resolved then we'll just grab the first type.
58
+ def inferred_mime_type
59
+ format_extension = path.format&.to_s
60
+ MIME::Types.type_for(format_extension).first if format_extension
61
+ end
80
62
  end
81
63
  end
@@ -0,0 +1,45 @@
1
+ module Sitepress
2
+ # Maps a tree of Directory and Asset objects in a a tree of nodes that
3
+ # format the navigational structure of a website. You can override this
4
+ # this in a site to deal with different file systems. For example, Notion
5
+ # has a completely different file structure for its content than Rails, so
6
+ # we could extend this class to properly map those differences into a tree
7
+ # of nodes.
8
+ class AssetNodeMapper
9
+ attr_reader :node, :asset_paths
10
+
11
+ def initialize(path:, node:)
12
+ @asset_paths = AssetPaths.new(path: path)
13
+ @node = node
14
+ end
15
+
16
+ # Mounts the source files from the path to the given node.
17
+ def map
18
+ asset_paths.each do |path|
19
+ if path.directory?
20
+ process_directory path
21
+ else
22
+ process_asset path
23
+ end
24
+ end
25
+ end
26
+
27
+ protected
28
+
29
+ def process_directory(path)
30
+ node_name = File.basename path
31
+ node_mapper path: path, node: node.add_child(node_name)
32
+ end
33
+
34
+ def process_asset(path)
35
+ asset = Asset.new(path: path)
36
+ node.add_child(asset.node_name).formats.add(format: asset.format, asset: asset)
37
+ end
38
+
39
+ private
40
+
41
+ def node_mapper(*args, **kwargs)
42
+ self.class.new(*args, **kwargs).map
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ require "pathname"
2
+
3
+ module Sitepress
4
+ # Iterates through a folder, ignores partials and files that are well known to
5
+ # not be part of the website files, like `.DS_Store`, etc.
6
+ class AssetPaths
7
+ include Enumerable
8
+
9
+ # Exclude swap files created by Textmate and vim from being added
10
+ # to the sitemap.
11
+ IGNORE_FILE_PATTERNS = [
12
+ "*~", # Created by many editors when things crash
13
+ "*.swp", # Created by vim
14
+ ".DS_Store", # Created by our friends at Apple
15
+ "*.orig" # Created when there's a git conflict
16
+ ]
17
+
18
+ # Template files that start with `_user.html.erb` are partials that we want
19
+ # to ignore for the site's navigation tree.
20
+ PARTIAL_PREFIX = "_".freeze
21
+
22
+ attr_reader :path
23
+
24
+ def initialize(path:)
25
+ @path = Pathname.new(path)
26
+ end
27
+
28
+ # Returns a list of files, paths, and node names to iterate through to build out nodes
29
+ def each
30
+ path.each_child do |path|
31
+ yield path unless ignore_file? path
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def ignore_file?(path)
38
+ is_partial_file?(path) or matches_ignore_file_pattern?(path)
39
+ end
40
+
41
+ def is_partial_file?(path)
42
+ path.basename.to_s.start_with? PARTIAL_PREFIX
43
+ end
44
+
45
+ def matches_ignore_file_pattern?(path)
46
+ IGNORE_FILE_PATTERNS.any? { |pattern| path.basename.fnmatch? pattern }
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,5 @@
1
+ require "forwardable"
2
+
1
3
  module Sitepress
2
4
  # Manages collections of resources that share the same Node. Given the files `/a.html` and `/a.gif`,
3
5
  # both of these assets would be stored in the `Node#name = "a"` under `Node#formats` with
@@ -19,7 +21,7 @@ module Sitepress
19
21
  end
20
22
 
21
23
  def remove(extension)
22
- @formats.delete(symbolize(extension))
24
+ @formats.delete symbolize(extension)
23
25
  end
24
26
 
25
27
  def get(extension)
@@ -5,7 +5,7 @@ module Sitepress
5
5
 
6
6
  # TODO: Redo this to use File readline and pos to
7
7
  # perform faster
8
- class Frontmatter
8
+ class Parsers::Frontmatter
9
9
  DELIMITER = "---".freeze
10
10
  NEWLINE = /\r\n?|\n/.freeze
11
11
  PATTERN = /\A(#{DELIMITER}#{NEWLINE}(.+?)#{NEWLINE}#{DELIMITER}#{NEWLINE}*)?(.+)\Z/m
@@ -80,7 +80,7 @@ module Sitepress
80
80
  end
81
81
 
82
82
  def inspect
83
- "<#{self.class}: name=#{name.inspect} formats=#{formats.map(&:request_path)} children=#{children.map(&:name).inspect}>"
83
+ "<#{self.class}: name=#{name.inspect}, formats=#{formats.extensions.inspect}, children=#{children.map(&:name).inspect}, resource_request_paths=#{formats.map(&:request_path)}>"
84
84
  end
85
85
 
86
86
  def dig(*args)
@@ -0,0 +1,12 @@
1
+ require "yaml"
2
+
3
+ module Sitepress
4
+ # Parsers parse the data and the body out of an asset. The resulting
5
+ # data is referenced by `Resource#data`, which is `current_page.data`
6
+ # from page templates.
7
+ module Parsers
8
+ autoload :Base, "sitepress/parsers/base"
9
+ autoload :Frontmatter, "sitepress/parsers/frontmatter"
10
+ autoload :Notion, "sitepress/parsers/notion"
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require "yaml"
2
+
3
+ module Sitepress
4
+ module Parsers
5
+ # Parses nothing. The body is returned and the data is blank.
6
+ class Base
7
+ attr_reader :body, :data
8
+
9
+ def initialize(source)
10
+ @body = source
11
+ @data = {}
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ require "yaml"
2
+
3
+ module Sitepress
4
+ module Parsers
5
+ # Parses metadata from the header of the page.
6
+
7
+ # TODO: Redo this to use File readline and pos to
8
+ # perform faster
9
+ class Frontmatter < Base
10
+ DELIMITER = "---".freeze
11
+ NEWLINE = /\r\n?|\n/.freeze
12
+ PATTERN = /\A(#{DELIMITER}#{NEWLINE}(.+?)#{NEWLINE}#{DELIMITER}#{NEWLINE}*)?(.+)\Z/m
13
+
14
+ def initialize(content)
15
+ _, @data, @body = content.match(PATTERN).captures
16
+ end
17
+
18
+ def data
19
+ @data ? YAML.load(@data) : {}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ require "yaml"
2
+
3
+ module Sitepress
4
+ module Parsers
5
+ # Parses metadata from the header of the page.
6
+ class Notion < Base
7
+ DELIMITER = /\n\n/.freeze
8
+ TITLE_KEY = "Title".freeze
9
+ KEY_DELIMITER = ":".freeze
10
+
11
+ def initialize(content)
12
+ scanner = StringScanner.new(content)
13
+ # Parse title
14
+ scanner.scan(/# (.+)#{DELIMITER}/)
15
+ @title = scanner.captures.first
16
+ # Parse metadata
17
+ @raw_data = []
18
+ while scanner.scan(/(.+?)#{KEY_DELIMITER} (.+)\n/)
19
+ @raw_data.append scanner.captures
20
+ end
21
+ scanner.scan(/\n/)
22
+ # Parse body
23
+ @body = scanner.rest
24
+ end
25
+
26
+ def data
27
+ Hash[@raw_data.prepend([TITLE_KEY, @title])]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,31 +1,127 @@
1
+ require "pathname"
2
+ require "mime-types"
3
+
1
4
  module Sitepress
2
5
  class Path
3
- DELIMITER = "/".freeze
6
+ # Default handler extensions. Handlers are anything that render or
7
+ # manipulate the contents of the file into a different output, like
8
+ # ERB or HAML.
9
+ HANDLER_EXTENSIONS = %i[haml erb md markdown]
10
+
11
+ # The root node name is a blank string.
12
+ ROOT_NODE_NAME = "".freeze
13
+
14
+ # The name of the root path
15
+ ROOT_PATH = "/".freeze
16
+
17
+ attr_reader :handler, :format, :path, :node_name, :dirname, :basename
18
+
19
+ # When Rails boots, it sets the handler extensions so that paths
20
+ # can be properly parsed.
21
+ class << self
22
+ attr_writer :handler_extensions
23
+
24
+ def handler_extensions
25
+ @handler_extensions ||= HANDLER_EXTENSIONS
26
+ end
27
+ end
4
28
 
5
- attr_reader :node_names, :ext
29
+ def initialize(path, path_seperator: File::SEPARATOR, handler_extensions: self.class.handler_extensions)
30
+ @path = path.to_s
31
+ @path_seperator = Regexp.new(path_seperator)
32
+ @handler_extensions = handler_extensions
33
+ parse
34
+ end
35
+
36
+ def node_names
37
+ @node_names ||= node_name_ancestors.push(node_name)
38
+ end
39
+
40
+ # Necessary for operations like `File.read path` where `path` is an instance
41
+ # of this object.
42
+ def to_str
43
+ @path
44
+ end
45
+ alias :to_s :to_str
46
+
47
+ def ==(path)
48
+ to_s == path.to_s
49
+ end
6
50
 
7
- def initialize(path, delimiter: DELIMITER)
8
- @path = path
9
- @delimiter = delimiter
10
- parse_path
51
+ def exists?
52
+ File.exists? path
53
+ end
54
+
55
+ def expand_path
56
+ File.expand_path path
11
57
  end
12
58
 
13
59
  def format
14
- format = @ext.partition(".").last
15
- return nil if format.nil? or format.empty?
16
- format.to_sym
60
+ (handler_is_format? ? handler : @format)&.to_sym
17
61
  end
18
62
 
19
63
  private
20
- def strip_leading_slash(path)
21
- path.to_s.gsub(/^\//, "")
64
+ # TODO: I don't want to look this up everytime I try to figure out the
65
+ # extension. I'll have to create an extension registry .
66
+
67
+ # Rails has handlers, like `:html` and `:raw` that are both
68
+ # handlers and formats. If we don't account for this, then the object
69
+ # would return a `nil` for a file named `blah.html`.
70
+ def handler_is_format?
71
+ return false if @handler.nil?
72
+ @format.nil? and MIME::Types.type_for(@handler.to_s).any?
73
+ end
74
+
75
+ def parse
76
+ @dirname, @basename = File.split(path)
77
+ parse_basename
78
+ end
79
+
80
+ # Given a filename, this will work out the extensions, formats, and node_name.
81
+ def parse_basename
82
+ base = basename
83
+ filename, extname = split_filename(base)
84
+
85
+ # This is a root path, so we have to treat it a little differently
86
+ # so that the node mapper and node names work properly.
87
+ if filename == ROOT_PATH and extname.nil?
88
+ @node_name = ROOT_NODE_NAME
89
+ elsif extname
90
+ extname = extname.to_sym
91
+
92
+ # We have an extension! Let's figure out if its a handler or not.
93
+ if @handler_extensions.include? extname
94
+ # Yup, its a handler. Set those variables accordingly.
95
+ @handler = extname
96
+ base = filename
97
+ end
98
+
99
+ # Now let's get the format (e.g. :html, :xml, :json) for the path and
100
+ # the key, which is just the basename without the format extension.
101
+ @node_name, format = split_filename(base)
102
+ @format = format
103
+ else
104
+ @node_name = filename
105
+ end
106
+ end
107
+
108
+ # If given a path `/a/b/c`, thsi would return `["a", "b", "c"].
109
+ def node_name_ancestors
110
+ strip_leading_prefix(File.dirname(path)).split(@path_seperator)
111
+ end
112
+
113
+ # Make it easier to split the last extension off a filename.
114
+ # For example, if you run `split_filename("c.taco.html")`
115
+ # it would return `["c.taco", "html"]`. If you ran it against
116
+ # something like `split_filename("c")`, it would return `["c"]`
117
+ def split_filename(string)
118
+ base, _, extension = string.rpartition(".")
119
+ base.empty? ? [extension] : [base, extension]
22
120
  end
23
121
 
24
- def parse_path
25
- path, _, file = strip_leading_slash(@path).rpartition(@delimiter)
26
- @ext = File.extname(file)
27
- @file = File.basename(file, @ext)
28
- @node_names = path.split(@delimiter).push(@file)
122
+ # Strips leading `/` or leading `.` if the path is relative.
123
+ def strip_leading_prefix(dirname)
124
+ dirname.to_s.gsub(/^#{@path_seperator}|\./, "")
29
125
  end
30
126
  end
31
127
  end
@@ -5,21 +5,20 @@ module Sitepress
5
5
  # resources that point to the same asset. Resources are immutable
6
6
  # and may be altered by the resource proxy.
7
7
  class Resource
8
- extend Forwardable
9
- def_delegators :asset, :mime_type
10
-
11
8
  attr_writer :body, :data
12
- attr_reader :node, :asset, :format
9
+ attr_reader :node, :asset
10
+
11
+ attr_accessor :format, :mime_type, :handler
13
12
 
14
13
  # Default scope for querying parent/child/sibling resources.
15
14
  DEFAULT_FILTER_SCOPE = :same
16
15
 
17
- RENDERABLE_MEDIA_TYPE = "text".freeze
18
-
19
- def initialize(asset:, node:, format: nil)
16
+ def initialize(asset:, node:, format: nil, mime_type: nil, handler: nil)
20
17
  @asset = asset
21
18
  @node = node
22
- @format = format
19
+ @format = format || asset.format
20
+ @mime_type = mime_type || asset.mime_type
21
+ @handler = handler || asset.handler
23
22
  end
24
23
 
25
24
  def request_path
@@ -67,7 +66,7 @@ module Sitepress
67
66
  # parse. When this returns true in some cases, a reference to the file will be
68
67
  # passed and skip all the overhead of trying to parse and render.
69
68
  def renderable?
70
- asset.mime_type.media_type == RENDERABLE_MEDIA_TYPE
69
+ asset.renderable?
71
70
  end
72
71
 
73
72
  private
@@ -11,8 +11,12 @@ module Sitepress
11
11
  # Default root_path for site.
12
12
  DEFAULT_ROOT_PATH = Pathname.new(".").freeze
13
13
 
14
+ # Maps Rail-ish template files & structures into the site's node tree.
15
+ DEFAULT_NODE_MAPPER = AssetNodeMapper
16
+
14
17
  attr_reader :root_path
15
18
  attr_writer :resources_pipeline
19
+ attr_accessor :node_mapper
16
20
 
17
21
  # TODO: Get rid of these so that folks have ot call site.resources.get ...
18
22
  extend Forwardable
@@ -20,13 +24,14 @@ module Sitepress
20
24
 
21
25
  def initialize(root_path: DEFAULT_ROOT_PATH)
22
26
  self.root_path = root_path
27
+ self.node_mapper = DEFAULT_NODE_MAPPER
23
28
  end
24
29
 
25
30
  # A tree representation of the resourecs wthin the site. The root is a node that's
26
31
  # processed by the `resources_pipeline`.
27
32
  def root
28
33
  @root ||= Node.new.tap do |node|
29
- source_node_mapper.mount node
34
+ node_mapper.new(path: pages_path, node: node).map
30
35
  resources_pipeline.process node
31
36
  end
32
37
  end
@@ -97,11 +102,5 @@ module Sitepress
97
102
  def resources_pipeline
98
103
  @resources_pipeline ||= ResourcesPipeline.new
99
104
  end
100
-
101
- private
102
-
103
- def source_node_mapper
104
- @source_node_mapper ||= SourceNodeMapper.new(path: pages_path)
105
- end
106
105
  end
107
106
  end
@@ -1,3 +1,3 @@
1
1
  module Sitepress
2
- VERSION = "2.0.0.beta8".freeze
2
+ VERSION = "2.0.0".freeze
3
3
  end
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Sitepress::VERSION
9
9
  spec.authors = ["Brad Gessler"]
10
10
  spec.email = ["bradgessler@gmail.com"]
11
+ spec.licenses = ["MIT"]
11
12
 
12
13
  spec.summary = %q{An embeddable file-backed content management system.}
13
14
  spec.homepage = "https://github.com/sitepress/sitepress"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sitepress-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta8
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-16 00:00:00.000000000 Z
11
+ date: 2021-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,21 +75,27 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - lib/sitepress-core.rb
77
77
  - lib/sitepress/asset.rb
78
+ - lib/sitepress/asset_node_mapper.rb
79
+ - lib/sitepress/asset_paths.rb
78
80
  - lib/sitepress/extensions/layouts.rb
79
81
  - lib/sitepress/extensions/proc_manipulator.rb
80
82
  - lib/sitepress/formats.rb
81
83
  - lib/sitepress/frontmatter.rb
82
84
  - lib/sitepress/node.rb
85
+ - lib/sitepress/parsers.rb
86
+ - lib/sitepress/parsers/base.rb
87
+ - lib/sitepress/parsers/frontmatter.rb
88
+ - lib/sitepress/parsers/notion.rb
83
89
  - lib/sitepress/path.rb
84
90
  - lib/sitepress/resource.rb
85
91
  - lib/sitepress/resource_collection.rb
86
92
  - lib/sitepress/resources_pipeline.rb
87
93
  - lib/sitepress/site.rb
88
- - lib/sitepress/source_node_mapper.rb
89
94
  - lib/sitepress/version.rb
90
95
  - sitepress-core.gemspec
91
96
  homepage: https://github.com/sitepress/sitepress
92
- licenses: []
97
+ licenses:
98
+ - MIT
93
99
  metadata: {}
94
100
  post_install_message:
95
101
  rdoc_options: []
@@ -102,11 +108,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
108
  version: '0'
103
109
  required_rubygems_version: !ruby/object:Gem::Requirement
104
110
  requirements:
105
- - - ">"
111
+ - - ">="
106
112
  - !ruby/object:Gem::Version
107
- version: 1.3.1
113
+ version: '0'
108
114
  requirements: []
109
- rubygems_version: 3.1.4
115
+ rubygems_version: 3.2.3
110
116
  signing_key:
111
117
  specification_version: 4
112
118
  summary: An embeddable file-backed content management system.
@@ -1,57 +0,0 @@
1
- module Sitepress
2
- # Maps a directory of assets into a set of routes that correspond with
3
- # the `path` root.
4
- class SourceNodeMapper
5
- # Exclude swap files created by Textmate and vim from being added
6
- # to the sitemap.
7
- SWAP_FILE_EXTENSIONS = [
8
- "~",
9
- ".swp",
10
- ".DS_Store" # TODO: Not a swap file, but something that should be ignored.
11
- ]
12
-
13
- # Partial rails prefix.
14
- PARTIAL_PREFIX = "_".freeze
15
-
16
- attr_reader :assets, :path
17
- alias :root :path
18
-
19
- def initialize(path:)
20
- @path = path
21
- end
22
-
23
- # Mounts the source files from the path to the given node.
24
- def mount(node)
25
- paths.each do |path, name, format|
26
- if path.directory?
27
- SourceNodeMapper.new(path: path).mount node.add_child(name)
28
- else
29
- asset = Asset.new(path: path)
30
- node.add_child(name).formats.add(format: format, asset: asset)
31
- end
32
- end
33
- end
34
-
35
- private
36
- # Returns a list of files, paths, and node names to iterate through to build out nodes
37
- def paths
38
- Enumerator.new do |y|
39
- root.each_child do |path|
40
- next if is_swap_file? path
41
- next if is_partial_file? path
42
-
43
- node_name, node_format, template_handler = path.basename.to_s.split(".")
44
- y << [ path, node_name, node_format&.to_sym ]
45
- end
46
- end
47
- end
48
-
49
- def is_partial_file?(path)
50
- path.basename.to_s.start_with? PARTIAL_PREFIX
51
- end
52
-
53
- def is_swap_file?(path)
54
- SWAP_FILE_EXTENSIONS.any? { |ext| path.to_s.end_with? ext }
55
- end
56
- end
57
- end