sitepress-core 3.2.2 → 4.0.0.beta1

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: 50ca4e44a7c1383550c83bb286a68f8232319d35da955324fdfd64e04e47979c
4
- data.tar.gz: 1f9fb14a2bcee3766f5ad2e7d7e7a37034e8fc6731866db61c33020f17261fe0
3
+ metadata.gz: 28ce680cdd4f344d39f26ae0697f10fd24122c8e3bea5c3206da25fd0565f88e
4
+ data.tar.gz: 4526b2a2968248ce14ba65e2a09ae33764debb4001d85c1e0507f176bf18c257
5
5
  SHA512:
6
- metadata.gz: 89a792c19463316b3e56b47a66158b974b05640419a767d8496ca96defa28e63151d63050c6fabc24a5ed96a2ff367c0f0b34522c4b02cef0fedf02e391ff3ff
7
- data.tar.gz: 024ac0f23d3df04fd80ee8a9d141ee12610394b635a6e3ee661f313b5ee1ae7ab65b8bec6c9fdaf191c5c36f42fb6f059e515b5d2d380b8d136a0c53adbd1a54
6
+ metadata.gz: 14fbfe33e54f23887d1d3c14b5edcfb263f50277a2e4f596c059baa04ac35d41ae70bd542564e198e17453862202cec785d6debea3a6a89269946674f4cd6455
7
+ data.tar.gz: 1ae6cc0347519f583c693fffea97c1f702c6dd1fedf7146cc7dead11012c7c73d7426f086cdf16fe07542a998135dee8dabe52ae49078129cab8d60e614be89a
@@ -18,6 +18,7 @@ module Sitepress
18
18
  DEFAULT_PARSER = Parsers::Frontmatter
19
19
 
20
20
  attr_reader :path
21
+ attr_writer :body
21
22
 
22
23
  extend Forwardable
23
24
  def_delegators :renderer, :render
@@ -32,7 +33,11 @@ module Sitepress
32
33
  end
33
34
 
34
35
  def data
35
- @data ||= exists? ? parse_error { parser.data } : {}
36
+ @data ||= Data.manage(exists? ? parse_error { parser.data } : {})
37
+ end
38
+
39
+ def data=(data)
40
+ @data = Data.manage(data)
36
41
  end
37
42
 
38
43
  def body
@@ -55,7 +60,7 @@ module Sitepress
55
60
  !!handler
56
61
  end
57
62
 
58
- # Set the parser equal to a thing.
63
+ # Mmm.... that's the smell of cache busting, which means the hiearchy of this is wrong.
59
64
  def parser=(parser_klass)
60
65
  @parser = nil
61
66
  @parser_klass = parser_klass
@@ -70,7 +75,7 @@ module Sitepress
70
75
  end
71
76
 
72
77
  def destroy
73
- FIleUtils.rm path
78
+ FileUtils.rm path
74
79
  end
75
80
 
76
81
  def save
@@ -28,12 +28,12 @@ module Sitepress
28
28
 
29
29
  def process_directory(path)
30
30
  node_name = File.basename path
31
- node_mapper path: path, node: node.add_child(node_name)
31
+ node_mapper path: path, node: node.child(node_name)
32
32
  end
33
33
 
34
34
  def process_asset(path)
35
35
  asset = Asset.new(path: path)
36
- node.add_child(asset.node_name).formats.add(format: asset.format, asset: asset)
36
+ node.child(asset.node_name).resources.add_asset(asset, format: asset.format)
37
37
  end
38
38
 
39
39
  private
@@ -6,13 +6,13 @@ module Sitepress
6
6
  class AssetPaths
7
7
  include Enumerable
8
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
9
+ # Exclude swap files created by Textmate and vim from being added to the sitemap.
10
+ IGNORE_PATTERNS = [
11
+ "**/*~", # Created by many editors when things crash
12
+ "**/*.swp", # Created by vim
13
+ "**/.DS_Store", # Created by our friends at Apple
14
+ "**/*.orig", # Created when there's a git conflict
15
+ "**/.git*" # This is a problem when a git repo is nested in a project's `./pages` folder.
16
16
  ]
17
17
 
18
18
  # Template files that start with `_user.html.erb` are partials that we want
@@ -43,7 +43,7 @@ module Sitepress
43
43
  end
44
44
 
45
45
  def matches_ignore_file_pattern?(path)
46
- IGNORE_FILE_PATTERNS.any? { |pattern| path.basename.fnmatch? pattern }
46
+ IGNORE_PATTERNS.any? { |pattern| path.fnmatch? pattern }
47
47
  end
48
48
  end
49
49
  end
@@ -1,47 +1,94 @@
1
1
  module Sitepress
2
- class Data
3
- def initialize(data)
4
- @data = data
2
+ module Data
3
+ def self.manage(value)
4
+ case value
5
+ when Hash
6
+ Record.new value
7
+ when Array
8
+ Collection.new value
9
+ else
10
+ value
11
+ end
5
12
  end
6
13
 
7
- def fetch(key, *args, &block)
8
- wrap_value { @data.fetch(key.to_s, *args, &block) }
14
+ def self.unmanage(data)
15
+ case data
16
+ when Record, Collection
17
+ data.unmanage
18
+ else
19
+ data
20
+ end
9
21
  end
10
22
 
11
- def [](key)
12
- wrap_value { @data[key.to_s] }
23
+ # Wraps an array and returns managed elements
24
+ class Collection
25
+ include Enumerable
26
+ extend Forwardable
27
+
28
+ def_delegators :@array, :each, :[]
29
+
30
+ def initialize(array)
31
+ @array = array.map { |element| Data.manage(element) }
32
+ end
33
+
34
+ def unmanage
35
+ @array.map { |value| Data.unmanage(value) }
36
+ end
13
37
  end
14
38
 
15
- def method_missing(name, *args, **kwargs, &block)
16
- if respond_to? name
17
- self.send name, *args, **kwargs, &block
18
- else
19
- key, modifier, _ = name.to_s.partition("!")
20
- wrap_value do
39
+ # Wraps a hash and returns managed elements
40
+ class Record
41
+ include Enumerable
42
+ extend Forwardable
43
+
44
+ def_delegators :@hash, :keys, :values, :key?
45
+
46
+ def initialize(hash)
47
+ @hash = hash
48
+ end
49
+
50
+ def fetch(key, *args, &block)
51
+ Data.manage(@hash.fetch(key.to_s, *args, &block))
52
+ end
53
+
54
+ def [](key)
55
+ Data.manage(@hash[key.to_s])
56
+ end
57
+
58
+ def []=(key, value)
59
+ Data.manage(@hash[key.to_s] = value)
60
+ end
61
+
62
+ def each
63
+ @hash.each do |key, value|
64
+ yield key, Data.manage(value)
65
+ end
66
+ end
67
+
68
+ def unmanage
69
+ @hash.transform_values { |value| Data.unmanage(value) }
70
+ end
71
+
72
+ def method_missing(name, *args, **kwargs, &block)
73
+ if respond_to? name
74
+ self.send name, *args, **kwargs, &block
75
+ else
76
+ key, modifier, _ = name.to_s.partition(/[!?]/)
77
+
21
78
  case modifier
22
79
  when ""
23
- @data[key]
80
+ self[key]
24
81
  when "!"
25
- @data.fetch(key)
82
+ self.fetch(key, *args, &block)
83
+ when "?"
84
+ !!self[key]
26
85
  end
27
86
  end
28
87
  end
29
- end
30
-
31
- def dig(*args, **kwargs, &block)
32
- wrap_value { @data.dig(*args, **kwargs, &block) }
33
- end
34
88
 
35
- private
36
- def wrap_value(&block)
37
- case value = block.call
38
- when Hash
39
- self.class.new value
40
- when Array
41
- value.map { |v| wrap_value { v } }
42
- else
43
- value
44
- end
89
+ def dig(*args, **kwargs, &block)
90
+ Data.manage @hash.dig(*args, **kwargs, &block)
45
91
  end
92
+ end
46
93
  end
47
94
  end
@@ -14,7 +14,7 @@ module Sitepress
14
14
  end
15
15
 
16
16
  def process_resources(node)
17
- node.flatten.each do |resource|
17
+ node.resources.flatten.each do |resource|
18
18
  @rules.each do |rule|
19
19
  if rule.processor.call(resource)
20
20
  resource.data["layout"] ||= rule.layout
@@ -6,13 +6,7 @@ module Sitepress
6
6
  end
7
7
 
8
8
  def process_resources(node)
9
- node.flatten.each do |resource|
10
- if @block.arity == 1
11
- @block.call resource
12
- else # This will blow up if 0 or greater than 2.
13
- @block.call resource, node
14
- end
15
- end
9
+ @block.call node
16
10
  end
17
11
  end
18
12
  end
@@ -5,28 +5,28 @@ module Sitepress
5
5
  # a leaf node. The actual `buz.html` asset is then stored on the leaf node as a resource. This tree structure
6
6
  # makes it possible to reason through path relationships from code to build out elements in a website like tree navigation.
7
7
  class Node
8
- attr_reader :parent, :name, :default_format, :default_name
8
+ extend Forwardable
9
+ def_delegators :resources, :formats
9
10
 
10
- # Default extension
11
- DEFAULT_EXTENSION = :html
11
+ attr_reader :parent, :name, :default_format, :default_name, :resources
12
+
13
+ DEFAULT_FORMAT = :html
12
14
 
13
15
  DEFAULT_NAME = "index".freeze
14
16
 
15
- def initialize(parent: nil, name: nil, default_format: DEFAULT_EXTENSION, default_name: DEFAULT_NAME)
16
- @parent = parent
17
+ def initialize(parent: nil, name: nil, default_format: DEFAULT_FORMAT, default_name: DEFAULT_NAME)
17
18
  @name = name.freeze
19
+ @parent = parent
20
+ @children = Hash.new
21
+ @resources = Resources.new(node: self)
18
22
  @default_format = default_format
19
23
  @default_name = default_name
20
24
  yield self if block_given?
21
25
  end
22
26
 
23
- def formats
24
- @formats ||= Formats.new(node: self)
25
- end
26
-
27
27
  # Returns the immediate children nodes.
28
28
  def children
29
- child_nodes.values
29
+ @children.values
30
30
  end
31
31
 
32
32
  # Returns sibling nodes and self.
@@ -36,13 +36,7 @@ module Sitepress
36
36
 
37
37
  # Returns all parents up to the root node.
38
38
  def parents
39
- parents = []
40
- node = parent
41
- while node do
42
- parents << node
43
- node = node.parent
44
- end
45
- parents
39
+ Enumerator.produce(parent, &:parent).take_while(&:itself)
46
40
  end
47
41
 
48
42
  def root?
@@ -50,45 +44,64 @@ module Sitepress
50
44
  end
51
45
 
52
46
  def leaf?
53
- child_nodes.empty?
54
- end
55
-
56
- def flatten(resources: [])
57
- formats.each{ |resource| resources << resource }
58
- children.each do |child|
59
- child.flatten.each{ |resource| resources << resource }
47
+ @children.empty?
48
+ end
49
+
50
+ def parent=(parent)
51
+ child = self
52
+
53
+ if parent == @parent
54
+ return
55
+ elsif parent.nil?
56
+ remove
57
+ return
58
+ # Make sure we don't change the parent of this node to one if its children; otherwise
59
+ # we'd have to jump into a time machine and do some really weird stuff with Doc Whatever-his-name-is.
60
+ elsif child.children.include? parent
61
+ raise Sitepress::Error, "Parent node can't be changed to one of its children"
62
+ # Check if the name of this node exists as a child on the new parent.
63
+ elsif parent.child? child.name
64
+ raise Sitepress::Error, "Node exists with the name #{child.name.inspect} in #{parent.inspect}. Remove existing node."
65
+ else
66
+ @parent = parent
67
+ parent.overwrite_child child
60
68
  end
61
- resources
62
69
  end
63
70
 
64
71
  def remove
65
- formats.clear
66
- parent.remove_child(name) if leaf?
72
+ return if @parent.nil?
73
+ @parent.remove_child name
74
+ @parent = nil
67
75
  end
68
76
 
69
77
  def get(path)
70
78
  path = Path.new(path)
71
79
  node = dig(*path.node_names)
72
- node.formats.get(path.format) if node
80
+ node.resources.format(path.format) if node
73
81
  end
74
82
 
75
- def add_child(name)
83
+ def child(name)
76
84
  return self if name == default_name
77
- child_nodes[name].tap do |node|
78
- yield node if block_given?
85
+
86
+ @children.fetch(name){ @children[name] = build_child(name: name) }.tap do |child|
87
+ yield child if block_given?
79
88
  end
80
89
  end
81
90
 
91
+ def child?(name)
92
+ @children.key? name
93
+ end
94
+
82
95
  def inspect
83
- "<#{self.class}: name=#{name.inspect}, formats=#{formats.extensions.inspect}, children=#{children.map(&:name).inspect}, resource_request_paths=#{formats.map(&:request_path)}>"
96
+ "<#{self.class}: name=#{name.inspect}, formats=#{formats.inspect}, children=#{children.map(&:name).inspect}, resource_request_paths=#{resources.map(&:request_path)}>"
84
97
  end
85
98
 
86
99
  def dig(*args)
87
100
  head, *tail = args
88
101
  if (head.nil? or head.empty? or head == default_name) and tail.empty?
89
102
  self
90
- elsif child_nodes.has_key?(head)
91
- child_nodes[head].dig(*tail)
103
+ elsif child?(head)
104
+ @children[head].dig(*tail)
92
105
  else
93
106
  nil
94
107
  end
@@ -96,16 +109,16 @@ module Sitepress
96
109
 
97
110
  protected
98
111
  def remove_child(name)
99
- child_nodes.delete(name)
112
+ @children.delete(name)
100
113
  end
101
114
 
102
- private
103
- def build_child(name)
104
- Node.new(parent: self, name: name, default_format: default_format, default_name: default_name)
115
+ def overwrite_child(node)
116
+ @children[node.name] = node
105
117
  end
106
118
 
107
- def child_nodes
108
- @child_nodes ||= Hash.new { |hash, key| hash[key] = build_child(key) }
119
+ private
120
+ def build_child(**kwargs)
121
+ Node.new(parent: self, default_format: default_format, default_name: default_name, **kwargs)
109
122
  end
110
123
  end
111
124
  end
@@ -24,7 +24,7 @@ module Sitepress
24
24
 
25
25
  def render
26
26
  [
27
- dump_yaml(data),
27
+ dump_yaml(Data.unmanage(data)),
28
28
  Frontmatter::DELIMITER,
29
29
  $/,
30
30
  $/,
@@ -60,6 +60,10 @@ module Sitepress
60
60
  (handler_is_format? ? handler : @format)&.to_sym
61
61
  end
62
62
 
63
+ def relative_path_from(target)
64
+ Pathname.new(@path).relative_path_from(target).to_s
65
+ end
66
+
63
67
  private
64
68
  # TODO: I don't want to look this up everytime I try to figure out the
65
69
  # extension. I'll have to create an extension registry .
@@ -6,9 +6,8 @@ module Sitepress
6
6
  # and may be altered by the resource proxy.
7
7
  class Resource
8
8
  extend Forwardable
9
- def_delegators :asset, :renderable?
9
+ def_delegators :asset, :body, :data, :renderable?
10
10
 
11
- attr_writer :body, :data
12
11
  attr_reader :node, :asset
13
12
 
14
13
  attr_accessor :format, :mime_type, :handler
@@ -28,12 +27,51 @@ module Sitepress
28
27
  File.join("/", *lineage, request_filename)
29
28
  end
30
29
 
31
- def data
32
- @data ||= asset.data
30
+ # Eugh, I really don't like this because it's not a full URL. To get a full URL though this thing
31
+ # needs to be put into `url_for(request_path)` in Rails to get the hostname. I don't want to inject
32
+ # that dependency into this thing, so here it is.
33
+ alias :url :request_path
34
+
35
+ def node=(destination)
36
+ if destination.resources.format? format
37
+ raise Sitepress::Error, "#{destination.inspect} already has a resource with a #{format} format"
38
+ end
39
+ remove
40
+ destination.resources.add self
41
+ @node = destination
42
+ end
43
+
44
+ # Moves the resource to a destination node. Moving a resource to a Sitepress::Node
45
+ # is a little weird for people who are accustomed to working with files, which is pretty
46
+ # much everybody (including myself). A child node has to be created on the destination node
47
+ # with the name of the resource node.
48
+ #
49
+ # Or just ignore all of that and use the `move_to` method so you can feel like you're
50
+ # moving files around.
51
+ def move_to(destination)
52
+ raise Sitepress::Error, "#{destination.inspect} is not a Sitepress::Node" unless destination.is_a? Sitepress::Node
53
+ self.tap do |resource|
54
+ resource.node = destination.child(node.name)
55
+ end
56
+ end
57
+
58
+ # Creates a duplicate of the resource and moves it to the destination.
59
+ def copy_to(destination)
60
+ raise Sitepress::Error, "#{destination.inspect} is not a Sitepress::Node" unless destination.is_a? Sitepress::Node
61
+ self.clone.tap do |resource|
62
+ resource.node = destination.child(node.name)
63
+ end
64
+ end
65
+
66
+ # Clones should be initialized with a nil node. Initializing with a node would mean that multiple resources
67
+ # are pointing to the same node, which shouldn't be possible.
68
+ def clone
69
+ self.class.new(asset: @asset, node: nil, format: @format, mime_type: @mime_type, handler: @handler)
33
70
  end
34
71
 
35
- def body
36
- @body ||= asset.body
72
+ # Removes the resource from the node's resources list.
73
+ def remove
74
+ node.resources.remove format if node
37
75
  end
38
76
 
39
77
  def inspect
@@ -62,9 +100,16 @@ module Sitepress
62
100
 
63
101
  # Used internally to construct paths from the current node up to the root node.
64
102
  def lineage
65
- @lineage ||= node.parents.reject(&:root?).reverse.map(&:name)
103
+ node.parents.reject(&:root?).reverse.map(&:name)
66
104
  end
67
105
 
106
+ class << self
107
+ attr_accessor :path_suffix_hack_that_you_should_not_use
108
+
109
+ def path_suffix_hack_that_you_should_not_use
110
+ @path_suffix_hack_that_you_should_not_use ||= ""
111
+ end
112
+ end
68
113
 
69
114
  private
70
115
  # Filters parent/child/sibling resources by a type. The default behavior is to only return
@@ -83,13 +128,13 @@ module Sitepress
83
128
 
84
129
  case type
85
130
  when :all
86
- nodes.map{ |node| node.formats }
131
+ nodes.map{ |node| node.resources }
87
132
  when :same
88
- nodes.map{ |n| n.formats.get(format) }.flatten
133
+ nodes.map{ |n| n.resources.format(format) }.flatten
89
134
  when String, Symbol, NilClass
90
- nodes.map{ |n| n.formats.get(type) }.flatten
135
+ nodes.map{ |n| n.resources.format(type) }.flatten
91
136
  when MIME::Type
92
- nodes.map{ |n| n.formats.mime_type(type) }.flatten
137
+ nodes.map{ |n| n.resources.mime_type(type) }.flatten
93
138
  else
94
139
  raise ArgumentError, "Invalid type argument #{type}. Must be either :same, :all, an extension string, or a Mime::Type"
95
140
  end
@@ -102,9 +147,9 @@ module Sitepress
102
147
  elsif node.root? and format
103
148
  "#{node.default_name}.#{format}"
104
149
  elsif node.root?
105
- node.default_name
150
+ "#{node.default_name}#{self.class.path_suffix_hack_that_you_should_not_use}"
106
151
  elsif format.nil? or node.default_format == format
107
- node.name
152
+ "#{node.name}#{self.class.path_suffix_hack_that_you_should_not_use}"
108
153
  else
109
154
  "#{node.name}.#{format}"
110
155
  end
@@ -1,7 +1,7 @@
1
1
  module Sitepress
2
- # Represents a collection of resources. Provides interfaces to query
3
- # resource via globbing, paths, etc.
4
- class ResourceCollection
2
+ # Flattens a tree of Sitepress::Node and Sitepress:Resource classes into a collection of
3
+ # resources that can be quickly globbed, queried, or accessed.
4
+ class ResourceIndexer
5
5
  extend Forwardable
6
6
  def_delegators :resources, :each, :size, :index, :[], :last, :length, :fetch, :count, :at
7
7
 
@@ -27,7 +27,7 @@ module Sitepress
27
27
 
28
28
  private
29
29
  def resources
30
- @node.flatten
30
+ @node.resources.flatten
31
31
  end
32
32
  end
33
33
  end
@@ -0,0 +1,73 @@
1
+ require "forwardable"
2
+
3
+ module Sitepress
4
+ # Manages collections of resources that share the same Node. Given the files `/a.html` and `/a.gif`,
5
+ # both of these assets would be stored in the `Node#name = "a"` under `Node#formats` with
6
+ # the formats `.gif`, and `.html`.
7
+ class Resources
8
+ include Enumerable
9
+
10
+ extend Forwardable
11
+ def_delegators :@registry, :size, :clear, :empty?
12
+ def_delegators :@node, :default_format
13
+
14
+ def initialize(node:)
15
+ @node = node
16
+ @registry = Hash.new
17
+ end
18
+
19
+ def each(&block)
20
+ @registry.values.each(&block)
21
+ end
22
+
23
+ def remove(extension)
24
+ @registry.delete symbolize(extension)
25
+ end
26
+
27
+ def format(extension)
28
+ @registry[symbolize(extension || default_format)]
29
+ end
30
+
31
+ def formats
32
+ @registry.keys
33
+ end
34
+
35
+ def format?(key)
36
+ @registry.key? key
37
+ end
38
+
39
+ def mime_type(mime_type)
40
+ find { |f| f.mime_type == mime_type }
41
+ end
42
+
43
+ def add(resource)
44
+ if @registry.key? resource.format
45
+ raise Sitepress::ExistingRequestPathError, "Resource at #{resource.request_path} already set with format #{resource.format.inspect}"
46
+ else
47
+ @registry[resource.format] = resource
48
+ end
49
+ end
50
+
51
+ def flatten(resources: [])
52
+ each { |resource| resources << resource }
53
+ @node.children.each do |child|
54
+ child.resources.flatten.each { |resource| resources << resource }
55
+ end
56
+ resources
57
+ end
58
+
59
+ def add_asset(asset, format: nil)
60
+ format = symbolize(format || default_format)
61
+ add Resource.new(asset: asset, node: @node, format: format)
62
+ end
63
+
64
+ def inspect
65
+ "<#{self.class}: resources=#{map(&:request_path)}>"
66
+ end
67
+
68
+ private
69
+ def symbolize(format)
70
+ format&.to_sym
71
+ end
72
+ end
73
+ end
@@ -5,17 +5,10 @@ require "forwardable"
5
5
  module Sitepress
6
6
  # A collection of pages from a directory.
7
7
  class Site
8
- # Default file pattern to pick up in site
9
- DEFAULT_GLOB = "**/**".freeze
10
-
11
8
  # Default root_path for site.
12
9
  DEFAULT_ROOT_PATH = Pathname.new(".").freeze
13
10
 
14
- # Maps Rail-ish template files & structures into the site's node tree.
15
- DEFAULT_NODE_MAPPER = AssetNodeMapper
16
-
17
11
  attr_reader :root_path
18
- attr_accessor :node_mapper
19
12
  attr_writer :resources_pipeline
20
13
 
21
14
  # TODO: Get rid of these so that folks have ot call site.resources.get ...
@@ -24,21 +17,25 @@ module Sitepress
24
17
 
25
18
  def initialize(root_path: DEFAULT_ROOT_PATH)
26
19
  self.root_path = root_path
27
- self.node_mapper = DEFAULT_NODE_MAPPER
28
20
  end
29
21
 
30
22
  # A tree representation of the resourecs wthin the site. The root is a node that's
31
23
  # processed by the `resources_pipeline`.
32
24
  def root
33
- @root ||= Node.new.tap do |node|
34
- node_mapper.new(path: pages_path, node: node).map
35
- resources_pipeline.process node
25
+ @root ||= Node.new.tap do |root|
26
+ asset_node_mapper(root).map
27
+ resources_pipeline.process root
36
28
  end
37
29
  end
38
30
 
31
+ # Maps a path of directories and files into the root node.
32
+ def asset_node_mapper(root_node)
33
+ AssetNodeMapper.new(path: pages_path, node: root_node)
34
+ end
35
+
39
36
  # Returns a list of all the resources within #root.
40
37
  def resources
41
- @resources ||= ResourceCollection.new(node: root, root_path: pages_path)
38
+ @resources ||= ResourceIndexer.new(node: root, root_path: pages_path)
42
39
  end
43
40
 
44
41
  def reload!
@@ -94,8 +91,8 @@ module Sitepress
94
91
  # certain path:
95
92
  #
96
93
  # ```ruby
97
- # Sitepress.site.manipulate do |resource, root|
98
- # if resource.request_path.start_with? "/videos/"
94
+ # Sitepress.site.manipulate do |root|
95
+ # root.get("videos").each do |resource|
99
96
  # resource.data["layout"] = "video"
100
97
  # end
101
98
  # end
@@ -105,7 +102,11 @@ module Sitepress
105
102
  # in the site:
106
103
  #
107
104
  # ```ruby
108
- # Sitepress.site.manipulate do |resource, root|
105
+ # Sitepress.site.manipulate do |root|
106
+ # root.get("blog").each do |post|
107
+ # post.move_to root
108
+ # end
109
+ #
109
110
  # if resource.request_path == "/index"
110
111
  # # Remove the HTML format of index from the current resource level
111
112
  # # so we can level it up.
@@ -1,3 +1,3 @@
1
1
  module Sitepress
2
- VERSION = "3.2.2".freeze
2
+ VERSION = "4.0.0.beta1".freeze
3
3
  end
@@ -1,6 +1,9 @@
1
1
  require "sitepress/version"
2
2
 
3
3
  module Sitepress
4
+ # Errors raised by Sitepress
5
+ Error = Class.new(StandardError)
6
+
4
7
  # Raised by Resources if a path is added that's not a valid path.
5
8
  InvalidRequestPathError = Class.new(RuntimeError)
6
9
 
@@ -10,12 +13,13 @@ module Sitepress
10
13
  autoload :Asset, "sitepress/asset"
11
14
  autoload :AssetNodeMapper, "sitepress/asset_node_mapper"
12
15
  autoload :AssetPaths, "sitepress/asset_paths"
13
- autoload :Formats, "sitepress/formats"
16
+ autoload :Data, "sitepress/data"
14
17
  autoload :Node, "sitepress/node"
15
18
  autoload :Path, "sitepress/path"
16
19
  autoload :Parsers, "sitepress/parsers"
17
20
  autoload :Resource, "sitepress/resource"
18
- autoload :ResourceCollection, "sitepress/resource_collection"
21
+ autoload :Resources, "sitepress/resources"
22
+ autoload :ResourceIndexer, "sitepress/resource_indexer"
19
23
  autoload :ResourcesPipeline, "sitepress/resources_pipeline"
20
24
  autoload :Site, "sitepress/site"
21
25
  end
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: 3.2.2
4
+ version: 4.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-11 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,7 +80,6 @@ files:
80
80
  - lib/sitepress/data.rb
81
81
  - lib/sitepress/extensions/layouts.rb
82
82
  - lib/sitepress/extensions/proc_manipulator.rb
83
- - lib/sitepress/formats.rb
84
83
  - lib/sitepress/node.rb
85
84
  - lib/sitepress/parsers.rb
86
85
  - lib/sitepress/parsers/base.rb
@@ -88,7 +87,8 @@ files:
88
87
  - lib/sitepress/parsers/notion.rb
89
88
  - lib/sitepress/path.rb
90
89
  - lib/sitepress/resource.rb
91
- - lib/sitepress/resource_collection.rb
90
+ - lib/sitepress/resource_indexer.rb
91
+ - lib/sitepress/resources.rb
92
92
  - lib/sitepress/resources_pipeline.rb
93
93
  - lib/sitepress/site.rb
94
94
  - lib/sitepress/version.rb
@@ -111,11 +111,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  required_rubygems_version: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - ">="
114
+ - - ">"
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: 1.3.1
117
117
  requirements: []
118
- rubygems_version: 3.4.1
118
+ rubygems_version: 3.4.6
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: An embeddable file-backed content management system.
@@ -1,59 +0,0 @@
1
- require "forwardable"
2
-
3
- module Sitepress
4
- # Manages collections of resources that share the same Node. Given the files `/a.html` and `/a.gif`,
5
- # both of these assets would be stored in the `Node#name = "a"` under `Node#formats` with
6
- # the extensions `.gif`, and `.html`.
7
- class Formats
8
- include Enumerable
9
-
10
- extend Forwardable
11
- def_delegators :@formats, :size, :clear
12
- def_delegators :@node, :default_format
13
-
14
- def initialize(node: )
15
- @node = node
16
- @formats = Hash.new
17
- end
18
-
19
- def each(&block)
20
- @formats.values.each(&block)
21
- end
22
-
23
- def remove(extension)
24
- @formats.delete symbolize(extension)
25
- end
26
-
27
- def get(extension)
28
- @formats[symbolize(extension || default_format)]
29
- end
30
-
31
- def extensions
32
- @formats.keys
33
- end
34
-
35
- def mime_type(mime_type)
36
- find { |f| f.mime_type == mime_type }
37
- end
38
-
39
- def add(asset:, format: nil)
40
- format = symbolize(format || default_format)
41
-
42
- resource = Resource.new(asset: asset, node: @node, format: format)
43
- if @formats.has_key? format
44
- raise Sitepress::ExistingRequestPathError, "Resource at #{resource.request_path} already set with format #{format.inspect}"
45
- else
46
- @formats[format] = resource
47
- end
48
- end
49
-
50
- def inspect
51
- "<#{self.class}: resources=#{map(&:request_path)}>"
52
- end
53
-
54
- private
55
- def symbolize(format)
56
- format&.to_sym
57
- end
58
- end
59
- end