sitepress-core 2.0.0.beta8 → 2.0.0.beta9

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: 9a7a004d33fe5e05c2e1831ebcd902dc9c6bbcbf4650437b6e36984a1eb0e263
4
+ data.tar.gz: 9bd65a5f76ee6b166337887619e825c48c4580cb082448c63c8d78d1c549759b
5
5
  SHA512:
6
- metadata.gz: 68622942e6fb27b292154b2ab5b344b6ba6a34008d151aef31d0b69989c732ad9c5eefdc69f335f31650d8c8652fdad9fe935e0c02c63910648194b0123f45dc
7
- data.tar.gz: aa63c9d8b7fdb3c9dda60503192799d00cdd4ca8219047b04d632d21dc8ada33a61305ec9059ef0753a8dbbebd7e04a3aadf1a5f1e27cec71407cd2361edcbc2
6
+ metadata.gz: 213d67af29c1e88c03f3ad72cb81001a2a938f418ca41717288f757581a409ec6daba877bdca903bb0a650c140d71e7252c113d2b4e0d9334b2e2726122ddb54
7
+ data.tar.gz: 68e40ac58a005c54262b050a3bc430eb3d2b81124705ce8aca39a87a3f0d07dd0fe9ab43283ead764c8afa9a00bf611fe6a903c2beb24d91b7eced7226b3ca7a
@@ -17,41 +17,13 @@ module Sitepress
17
17
 
18
18
  extend Forwardable
19
19
  def_delegators :frontmatter, :data, :body
20
+ def_delegators :path, :handler, :node_name, :format, :exists?
20
21
 
21
22
  def initialize(path: , mime_type: nil)
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
55
27
  end
56
28
 
57
29
  # Treat resources with the same request path as equal.
@@ -63,19 +35,22 @@ module Sitepress
63
35
  @mime_type ||= inferred_mime_type || DEFAULT_MIME_TYPE
64
36
  end
65
37
 
66
- def exists?
67
- File.exist? path
38
+ # Used by the Rails controller to short circuit additional processing if the
39
+ # asset is not renderable (e.g. is it erb or haml?)
40
+ def renderable?
41
+ !!handler
68
42
  end
69
43
 
70
44
  private
71
- def frontmatter
72
- Frontmatter.new File.read @path
73
- end
74
-
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
45
+ def frontmatter
46
+ Frontmatter.new File.read path
47
+ end
48
+
49
+ # Returns the mime type of the file extension. If a type can't
50
+ # be resolved then we'll just grab the first type.
51
+ def inferred_mime_type
52
+ format_extension = path.format&.to_s
53
+ MIME::Types.type_for(format_extension).first if format_extension
54
+ end
80
55
  end
81
56
  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
@@ -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)
@@ -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
@@ -6,7 +6,7 @@ module Sitepress
6
6
  # and may be altered by the resource proxy.
7
7
  class Resource
8
8
  extend Forwardable
9
- def_delegators :asset, :mime_type
9
+ def_delegators :asset, :mime_type, :handler
10
10
 
11
11
  attr_writer :body, :data
12
12
  attr_reader :node, :asset, :format
@@ -14,8 +14,6 @@ module Sitepress
14
14
  # Default scope for querying parent/child/sibling resources.
15
15
  DEFAULT_FILTER_SCOPE = :same
16
16
 
17
- RENDERABLE_MEDIA_TYPE = "text".freeze
18
-
19
17
  def initialize(asset:, node:, format: nil)
20
18
  @asset = asset
21
19
  @node = node
@@ -67,7 +65,7 @@ module Sitepress
67
65
  # parse. When this returns true in some cases, a reference to the file will be
68
66
  # passed and skip all the overhead of trying to parse and render.
69
67
  def renderable?
70
- asset.mime_type.media_type == RENDERABLE_MEDIA_TYPE
68
+ asset.renderable?
71
69
  end
72
70
 
73
71
  private
@@ -4,10 +4,11 @@ module Sitepress
4
4
  class SourceNodeMapper
5
5
  # Exclude swap files created by Textmate and vim from being added
6
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.
7
+ IGNORE_FILE_PATTERNS = [
8
+ "*~", # Created by many editors when things crash
9
+ "*.swp", # Created by vim
10
+ ".DS_Store", # Created by our friends at Apple
11
+ "*.orig" # Created when there's a git conflict
11
12
  ]
12
13
 
13
14
  # Partial rails prefix.
@@ -22,12 +23,13 @@ module Sitepress
22
23
 
23
24
  # Mounts the source files from the path to the given node.
24
25
  def mount(node)
25
- paths.each do |path, name, format|
26
+ paths.each do |path|
26
27
  if path.directory?
28
+ name = File.basename path
27
29
  SourceNodeMapper.new(path: path).mount node.add_child(name)
28
30
  else
29
31
  asset = Asset.new(path: path)
30
- node.add_child(name).formats.add(format: format, asset: asset)
32
+ node.add_child(asset.node_name).formats.add(format: asset.format, asset: asset)
31
33
  end
32
34
  end
33
35
  end
@@ -37,21 +39,22 @@ module Sitepress
37
39
  def paths
38
40
  Enumerator.new do |y|
39
41
  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 ]
42
+ next if ignore_file? path
43
+ y << path
45
44
  end
46
45
  end
47
46
  end
48
47
 
48
+ def ignore_file?(path)
49
+ is_partial_file?(path) or matches_ignore_file_pattern?(path)
50
+ end
51
+
49
52
  def is_partial_file?(path)
50
53
  path.basename.to_s.start_with? PARTIAL_PREFIX
51
54
  end
52
55
 
53
- def is_swap_file?(path)
54
- SWAP_FILE_EXTENSIONS.any? { |ext| path.to_s.end_with? ext }
56
+ def matches_ignore_file_pattern?(path)
57
+ IGNORE_FILE_PATTERNS.any? { |pattern| path.fnmatch? pattern }
55
58
  end
56
59
  end
57
60
  end
@@ -1,3 +1,3 @@
1
1
  module Sitepress
2
- VERSION = "2.0.0.beta8".freeze
2
+ VERSION = "2.0.0.beta9".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.beta9
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-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -89,7 +89,8 @@ files:
89
89
  - lib/sitepress/version.rb
90
90
  - sitepress-core.gemspec
91
91
  homepage: https://github.com/sitepress/sitepress
92
- licenses: []
92
+ licenses:
93
+ - MIT
93
94
  metadata: {}
94
95
  post_install_message:
95
96
  rdoc_options: []