diff --git a/lib/jekyll/drops/collection_drop.rb b/lib/jekyll/drops/collection_drop.rb index ccb3045a..009635a4 100644 --- a/lib/jekyll/drops/collection_drop.rb +++ b/lib/jekyll/drops/collection_drop.rb @@ -1,11 +1,13 @@ # encoding: UTF-8 -require "jekyll/drops/immutable_drop" +require "jekyll/drops/drop" module Jekyll module Drops - class CollectionDrop < ImmutableDrop + class CollectionDrop < Drop extend Forwardable + mutable false + def_delegator :@obj, :write?, :output def_delegators :@obj, :label, :docs, :files, :directory, :relative_directory diff --git a/lib/jekyll/drops/document_drop.rb b/lib/jekyll/drops/document_drop.rb index 81c9bcd2..f6e03fec 100644 --- a/lib/jekyll/drops/document_drop.rb +++ b/lib/jekyll/drops/document_drop.rb @@ -2,9 +2,11 @@ module Jekyll module Drops - class DocumentDrop < ImmutableDrop + class DocumentDrop < Drop extend Forwardable + mutable false + def_delegator :@obj, :next_doc, :next def_delegator :@obj, :previous_doc, :previous def_delegator :@obj, :relative_path, :path diff --git a/lib/jekyll/drops/drop.rb b/lib/jekyll/drops/drop.rb new file mode 100644 index 00000000..09bdb2d2 --- /dev/null +++ b/lib/jekyll/drops/drop.rb @@ -0,0 +1,74 @@ +# encoding: UTF-8 + +module Jekyll + module Drops + class Drop < Liquid::Drop + # Get or set whether the drop class is mutable. + # Mutability determines whether or not pre-defined fields may be + # overwritten. + # + # is_mutable - Boolean set mutability of the class (default: nil) + # + # Returns the mutability of the class + def self.mutable(is_mutable = nil) + if is_mutable + @is_mutable = is_mutable + end + @is_mutable || false + end + + # Create a new Drop + # + # obj - the Jekyll Site, Collection, or Document required by the + # drop. + # + # Returns nothing + def initialize(obj) + @obj = obj + @mutations = {} # only if mutable: true + end + + # Access a method in the Drop or a field in the underlying hash data. + # If mutable, checks the mutations first. Then checks the methods, + # and finally check the underlying hash (e.g. document front matter) + # if all the previous places didn't match. + # + # key - the string key whose value to fetch + # + # Returns the value for the given key, or nil if none exists + def [](key) + if self.class.mutable && @mutations.key?(key) + @mutations[key] + elsif respond_to? key + public_send key + else + fallback_data[key] + end + end + + # Set a field in the Drop. If mutable, sets in the mutations and + # returns. If not mutable, checks first if it's trying to override a + # Drop method and raises a DropMutationException if so. If not + # mutable and the key is not a method on the Drop, then it sets the + # key to the value in the underlying hash (e.g. document front + # matter) + # + # key - the String key whose value to set + # val - the Object to set the key's value to + # + # Returns the value the key was set to unless the Drop is not mutable + # and the key matches a method in which case it raises a + # DropMutationException. + def []=(key, val) + if self.class.mutable + @mutations[key] = val + elsif respond_to? key + raise Errors::DropMutationException, "Key #{key} cannot be set in the drop." + else + fallback_data[key] = val + end + end + + end + end +end diff --git a/lib/jekyll/drops/immutable_drop.rb b/lib/jekyll/drops/immutable_drop.rb deleted file mode 100644 index 5440aa00..00000000 --- a/lib/jekyll/drops/immutable_drop.rb +++ /dev/null @@ -1,28 +0,0 @@ -# encoding: UTF-8 - -module Jekyll - module Drops - class ImmutableDrop < Liquid::Drop - def initialize(obj) - @obj = obj - end - - def [](key) - if respond_to? key - public_send key - else - fallback_data[key] - end - end - - def []=(key, val) - if respond_to? key - raise DropMutationException, "Key #{key} cannot be set in the drop." - else - fallback_data[key] = val - end - end - - end - end -end diff --git a/lib/jekyll/drops/mutable_drop.rb b/lib/jekyll/drops/mutable_drop.rb deleted file mode 100644 index 9dd4048d..00000000 --- a/lib/jekyll/drops/mutable_drop.rb +++ /dev/null @@ -1,28 +0,0 @@ -# encoding: UTF-8 - -module Jekyll - module Drops - class MutableDrop < Liquid::Drop - - def initialize(obj) - @obj = obj - @mutations = {} - end - - def [](key) - if @mutations.key? key - @mutations[key] - elsif respond_to? key - public_send key - else - fallback_data[key] - end - end - - def []=(key, val) - @mutations[key] = val - end - - end - end -end diff --git a/lib/jekyll/drops/site_drop.rb b/lib/jekyll/drops/site_drop.rb index 61ac8098..ec4f0910 100644 --- a/lib/jekyll/drops/site_drop.rb +++ b/lib/jekyll/drops/site_drop.rb @@ -2,9 +2,11 @@ module Jekyll module Drops - class SiteDrop < ImmutableDrop + class SiteDrop < Drop extend Forwardable + mutable false + def_delegator :@obj, :site_data, :data def_delegators :@obj, :time, :pages, :static_files, :documents, :tags, :categories diff --git a/lib/jekyll/drops/unified_payload_drop.rb b/lib/jekyll/drops/unified_payload_drop.rb index 6db48f66..3c593ba6 100644 --- a/lib/jekyll/drops/unified_payload_drop.rb +++ b/lib/jekyll/drops/unified_payload_drop.rb @@ -2,7 +2,8 @@ module Jekyll module Drops - class UnifiedPayloadDrop < ImmutableDrop + class UnifiedPayloadDrop < Drop + mutable false attr_accessor :page, :layout, :content, :paginator attr_accessor :highlighter_prefix, :highlighter_suffix diff --git a/lib/jekyll/drops/url_drop.rb b/lib/jekyll/drops/url_drop.rb index 163591dd..a2bf6262 100644 --- a/lib/jekyll/drops/url_drop.rb +++ b/lib/jekyll/drops/url_drop.rb @@ -2,9 +2,11 @@ module Jekyll module Drops - class UrlDrop < ImmutableDrop + class UrlDrop < Drop extend Forwardable + mutable false + def_delegator :@obj, :cleaned_relative_path, :path def_delegator :@obj, :output_ext, :output_ext