OMG it's happening ~*Collections*~
This commit is contained in:
		
							parent
							
								
									a77c92aebe
								
							
						
					
					
						commit
						50b46d7bee
					
				| 
						 | 
				
			
			@ -35,6 +35,7 @@ require 'jekyll/stevenson'
 | 
			
		|||
require 'jekyll/deprecator'
 | 
			
		||||
require 'jekyll/configuration'
 | 
			
		||||
require 'jekyll/document'
 | 
			
		||||
require 'jekyll/collection'
 | 
			
		||||
require 'jekyll/plugin_manager'
 | 
			
		||||
require 'jekyll/site'
 | 
			
		||||
require 'jekyll/convertible'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
module Jekyll
 | 
			
		||||
  class Collection
 | 
			
		||||
    attr_reader :site, :label
 | 
			
		||||
 | 
			
		||||
    def initialize(site, label)
 | 
			
		||||
      @site  = site
 | 
			
		||||
      @label = label
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def docs
 | 
			
		||||
      @docs ||= []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def read
 | 
			
		||||
      Dir.glob(File.join(directory, "**", "*.*")).each do |file_path|
 | 
			
		||||
        if allowed_document?(file_path)
 | 
			
		||||
          doc = Jekyll::Document.new(file_path, { site: site, collection: self })
 | 
			
		||||
          docs << doc
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      docs
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def directory
 | 
			
		||||
      Jekyll.sanitized_path(site.source, "_#{label}")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def allowed_document?(path)
 | 
			
		||||
      !(site.safe && File.symlink?(path))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ module Jekyll
 | 
			
		|||
      'data_source'   =>  '_data',
 | 
			
		||||
      'keep_files'    => ['.git','.svn'],
 | 
			
		||||
      'gems'          => [],
 | 
			
		||||
      'collections'   => nil,
 | 
			
		||||
 | 
			
		||||
      'timezone'      => nil,           # use the local timezone
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +1,19 @@
 | 
			
		|||
module Jekyll
 | 
			
		||||
  class Document
 | 
			
		||||
 | 
			
		||||
    attr_reader   :path
 | 
			
		||||
    attr_accessor :content
 | 
			
		||||
    attr_reader   :path, :site
 | 
			
		||||
    attr_accessor :content, :collection
 | 
			
		||||
 | 
			
		||||
    # Create a new Document.
 | 
			
		||||
    #
 | 
			
		||||
    # site - the Jekyll::Site instance to which this Document belongs
 | 
			
		||||
    # shit - the Jekyll::Site instance to which this Document belongs
 | 
			
		||||
    # path - the path to the file
 | 
			
		||||
    #
 | 
			
		||||
    # Returns nothing.
 | 
			
		||||
    def initialize(site, path)
 | 
			
		||||
      @site = site
 | 
			
		||||
    def initialize(path, relations)
 | 
			
		||||
      @site = relations[:site]
 | 
			
		||||
      @path = path
 | 
			
		||||
      @collection = relations[:collection]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Fetch the Document's data.
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,10 @@ module Jekyll
 | 
			
		|||
      @data ||= Hash.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def relative_path
 | 
			
		||||
      Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def extname
 | 
			
		||||
      File.extname(path)
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ module Jekyll
 | 
			
		|||
                  :exclude, :include, :source, :dest, :lsi, :highlighter,
 | 
			
		||||
                  :permalink_style, :time, :future, :unpublished, :safe, :plugins, :limit_posts,
 | 
			
		||||
                  :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems,
 | 
			
		||||
                  :plugin_manager
 | 
			
		||||
                  :plugin_manager, :collections
 | 
			
		||||
 | 
			
		||||
    attr_accessor :converters, :generators
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,9 @@ module Jekyll
 | 
			
		|||
    def initialize(config)
 | 
			
		||||
      self.config = config.clone
 | 
			
		||||
 | 
			
		||||
      %w[safe lsi highlighter baseurl exclude include future unpublished show_drafts limit_posts keep_files gems].each do |opt|
 | 
			
		||||
      %w[
 | 
			
		||||
        safe lsi highlighter baseurl exclude include future unpublished
 | 
			
		||||
        show_drafts limit_posts keep_files gems collections].each do |opt|
 | 
			
		||||
        self.send("#{opt}=", config[opt])
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +92,7 @@ module Jekyll
 | 
			
		|||
      self.layouts = LayoutReader.new(self).read
 | 
			
		||||
      read_directories
 | 
			
		||||
      read_data(config['data_source'])
 | 
			
		||||
      read_collections
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Recursively traverse directories to find posts, pages and static files
 | 
			
		||||
| 
						 | 
				
			
			@ -171,13 +174,24 @@ module Jekyll
 | 
			
		|||
 | 
			
		||||
      entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
 | 
			
		||||
      entries.delete_if { |e| File.directory?(File.join(base, e)) }
 | 
			
		||||
      data_collection = Jekyll::Collection.new(self, "data")
 | 
			
		||||
 | 
			
		||||
      entries.each do |entry|
 | 
			
		||||
        path = File.join(source, dir, entry)
 | 
			
		||||
        next if File.symlink?(path) && safe
 | 
			
		||||
 | 
			
		||||
        key = sanitize_filename(File.basename(entry, '.*'))
 | 
			
		||||
        (self.data[key] = Jekyll::Document.new(self, path)).read
 | 
			
		||||
        (self.data[key] = Jekyll::Document.new(path, { site: self, collection: data_collection })).read
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Read in all collections specified in the configuration
 | 
			
		||||
    #
 | 
			
		||||
    # Returns nothing.
 | 
			
		||||
    def read_collections
 | 
			
		||||
      if collections
 | 
			
		||||
        self.collections = Hash[collections.map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
 | 
			
		||||
        collections.each { |_, collection| collection.read }
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
---
 | 
			
		||||
title: "Jekyll.configuration"
 | 
			
		||||
whatever: foo.bar
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Use `{{ page.title }}` to build a full configuration for use w/Jekyll.
 | 
			
		||||
 | 
			
		||||
Whatever: {{ page.whatever }}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
---
 | 
			
		||||
title: "Jekyll.sanitized_path"
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
`{{ page.title }}` is used to make sure your path is in your source.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
---
 | 
			
		||||
title: "Site#generate"
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Run your generators!
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
---
 | 
			
		||||
title: "Site#initialize"
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Create dat site.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
test/source/_methods/sanitized_path.md
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
require 'helper'
 | 
			
		||||
 | 
			
		||||
class TestCollections < Test::Unit::TestCase
 | 
			
		||||
 | 
			
		||||
  context "with no collections specified" do
 | 
			
		||||
    setup do
 | 
			
		||||
      @site = Site.new(Jekyll.configuration({
 | 
			
		||||
        "source"      => source_dir,
 | 
			
		||||
        "destination" => dest_dir
 | 
			
		||||
      }))
 | 
			
		||||
      @site.process
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should "not contain any collections" do
 | 
			
		||||
      assert_nil @site.collections
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "with a collection" do
 | 
			
		||||
    setup do
 | 
			
		||||
      @site = Site.new(Jekyll.configuration({
 | 
			
		||||
        "collections" => ["methods"],
 | 
			
		||||
        "source"      => source_dir,
 | 
			
		||||
        "destination" => dest_dir
 | 
			
		||||
      }))
 | 
			
		||||
      @site.process
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should "create a Hash on Site with the label mapped to the instance of the Collection" do
 | 
			
		||||
      assert @site.collections.is_a?(Hash)
 | 
			
		||||
      assert_not_nil @site.collections["methods"]
 | 
			
		||||
      assert @site.collections["methods"].is_a? Jekyll::Collection
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should "collects docs in an array on the Collection object" do
 | 
			
		||||
      assert @site.collections["methods"].docs.is_a? Array
 | 
			
		||||
      @site.collections["methods"].docs.each do |doc|
 | 
			
		||||
        assert doc.is_a? Jekyll::Document
 | 
			
		||||
        assert_include %w[
 | 
			
		||||
          _methods/configuration.md
 | 
			
		||||
          _methods/sanitized_path.md
 | 
			
		||||
          _methods/site/generate.md
 | 
			
		||||
          _methods/site/initialize.md
 | 
			
		||||
          _methods/um_hi.md
 | 
			
		||||
        ], doc.relative_path
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "in safe mode" do
 | 
			
		||||
    setup do
 | 
			
		||||
      @site = Site.new(Jekyll.configuration({
 | 
			
		||||
        "collections" => ["methods"],
 | 
			
		||||
        "safe"        => true,
 | 
			
		||||
        "source"      => source_dir,
 | 
			
		||||
        "destination" => dest_dir
 | 
			
		||||
      }))
 | 
			
		||||
      @site.process
 | 
			
		||||
      @collection = @site.collections["methods"]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should "not allow symlinks" do
 | 
			
		||||
      assert !@collection.allowed_document?(File.join(@collection.directory, "um_hi.md"))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should "not include the symlinked file in the list of docs" do
 | 
			
		||||
      assert_not_include %w[_methods/um_hi.md], @collection.docs.map(&:relative_path)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
		Reference in New Issue