class ContentFS::Database
Structured content database, loaded from the filesystem.
Constants
- METADATA_FILE
Attributes
metadata[R]
namespace[R]
prefix[R]
slug[R]
Public Class Methods
load(path, parent: nil, namespace: [], root: true, &block)
click to toggle source
# File lib/contentfs/database.rb, line 14 def load(path, parent: nil, namespace: [], root: true, &block) new(path: path, parent: parent, namespace: namespace, root: root, &block) end
new(path:, parent: nil, namespace: [], root: false, &block)
click to toggle source
# File lib/contentfs/database.rb, line 23 def initialize(path:, parent: nil, namespace: [], root: false, &block) path = Pathname.new(path) name = path.basename(path.extname) prefix, remainder = Prefix.build(name) @prefix = prefix @namespace = namespace.dup @parent = parent unless root @slug = Slug.build(remainder) @namespace << @slug end metadata_path = path.join(METADATA_FILE) @metadata = if metadata_path.exist? YAML.safe_load(metadata_path.read).to_h else {} end content_path = path.join.glob("_content.*")[0] if content_path&.exist? @content = Content.load(content_path, database: self, metadata: @metadata, namespace: @namespace, &block) @metadata = @content.metadata.dup end children, nested, includes = {}, {}, {} Pathname.new(path).glob("*") do |path| underscored = path.basename.to_s.start_with?("_") next if underscored && path.directory? if path.directory? database = Database.load(path, parent: self, namespace: @namespace, root: false, &block) nested[database.slug] = database elsif underscored content = Content.load(path, database: self, metadata: @metadata, namespace: @namespace, &block) includes[content.slug.to_s[1..].to_sym] = content else content = Content.load(path, database: self, metadata: @metadata, namespace: @namespace, &block) children[content.slug] = content end end @children = Hash[ children.sort_by { |key, content| (content.prefix || content.slug).to_s } ] @nested = Hash[ nested.sort_by { |key, database| (database.prefix || database.slug).to_s } ] @includes = Hash[ includes.sort_by { |key, content| (content.prefix || content.slug).to_s } ] end
Public Instance Methods
content() { |value| ... }
click to toggle source
# File lib/contentfs/database.rb, line 89 def content return to_enum(:content) unless block_given? @children.each_value do |value| yield value end end
filter(**filters) { |content| ... }
click to toggle source
# File lib/contentfs/database.rb, line 105 def filter(**filters) return to_enum(:filter, **filters) unless block_given? filters = filters.each_with_object({}) { |(key, value), hash| hash[key.to_s] = value } @children.each_value.select { |content| yield content if content.metadata.all? { |key, value| filters[key] == value } } end
find(name, *nested)
click to toggle source
# File lib/contentfs/database.rb, line 119 def find(name, *nested) if @children.key?(name) @children[name] elsif @nested.key?(name) nested.inject(@nested[name]) { |database, next_nested| database.find(next_nested.to_sym) } end end
find_include(path)
click to toggle source
# File lib/contentfs/database.rb, line 129 def find_include(path) @includes[path.to_sym] || find_child_include(path) || find_parent_include(path) || find_include_from_toplevel(path) end
method_missing(name, *nested, **)
click to toggle source
Calls superclass method
# File lib/contentfs/database.rb, line 166 def method_missing(name, *nested, **) find(name, *nested) || super end
nested() { |value| ... }
click to toggle source
# File lib/contentfs/database.rb, line 97 def nested return to_enum(:nested) unless block_given? @nested.each_value do |value| yield value end end
render()
click to toggle source
# File lib/contentfs/database.rb, line 162 def render @content&.render end
respond_to_missing?(name, *)
click to toggle source
Calls superclass method
# File lib/contentfs/database.rb, line 170 def respond_to_missing?(name, *) @children.key?(name) || super end
to_s()
click to toggle source
# File lib/contentfs/database.rb, line 158 def to_s @content&.to_s.to_s end
toplevel()
click to toggle source
# File lib/contentfs/database.rb, line 133 def toplevel @parent ? @parent.toplevel : self end
Private Instance Methods
find_child_include(path)
click to toggle source
# File lib/contentfs/database.rb, line 137 def find_child_include(path) return unless path.include?("/") path_parts = path.split("/", 2) @nested[path_parts[0].to_sym]&.find_include(path_parts[1]) end
find_include_from_toplevel(path)
click to toggle source
# File lib/contentfs/database.rb, line 152 def find_include_from_toplevel(path) return if @parent.nil? toplevel.find_include(path) end
find_parent_include(path)
click to toggle source
# File lib/contentfs/database.rb, line 144 def find_parent_include(path) return if @parent.nil? return unless path.start_with?("../") path_parts = path.split("../", 2) @parent.find_include(path_parts[1]) end