middleman/middleman-core/lib/middleman-core/sitemap/resource.rb

147 lines
4.1 KiB
Ruby
Raw Normal View History

require "middleman-core/sitemap/extensions/traversal"
module Middleman
# Sitemap namespace
module Sitemap
2012-04-04 19:26:07 +02:00
# Sitemap Resource class
class Resource
include Middleman::Sitemap::Extensions::Traversal
2012-04-04 19:26:07 +02:00
# @return [Middleman::Application]
attr_reader :app
2012-04-04 19:26:07 +02:00
# @return [Middleman::Sitemap::Store]
attr_reader :store
2012-04-04 19:26:07 +02:00
# The source path of this resource (relative to the source directory,
# without template extensions)
# @return [String]
attr_reader :path
2012-04-04 19:26:07 +02:00
# Set the on-disk source file for this resource
# @return [String]
# attr_reader :source_file
2012-04-04 19:26:07 +02:00
def source_file
@source_file || get_source_file
end
2012-04-04 19:26:07 +02:00
# Initialize resource with parent store and URL
# @param [Middleman::Sitemap::Store] store
# @param [String] path
# @param [String] source_file
def initialize(store, path, source_file=nil)
@store = store
@app = @store.app
@path = path
@source_file = source_file
2012-04-04 19:26:07 +02:00
@destination_paths = [@path]
@local_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] }
end
2012-04-04 19:26:07 +02:00
# Whether this resource has a template file
# @return [Boolean]
def template?
return false if source_file.nil?
!::Tilt[source_file].nil?
end
2012-04-04 19:26:07 +02:00
# Get the metadata for both the current source_file and the current path
# @return [Hash]
def metadata
result = store.metadata_for_file(source_file).dup
path_meta = store.metadata_for_path(path).dup
if path_meta.has_key?(:blocks)
result[:blocks] << path_meta[:blocks]
path_meta.delete(:blocks)
end
result.deep_merge!(path_meta)
local_meta = @local_metadata.dup
if local_meta.has_key?(:blocks)
result[:blocks] << local_meta[:blocks]
local_meta.delete(:blocks)
end
result.deep_merge!(local_meta)
result
end
# Merge in new metadata specific to this resource.
# @param [Hash] metadata A metadata block like provides_metadata_for_path takes
def add_metadata(metadata={}, &block)
if metadata.has_key?(:blocks)
@local_metadata[:blocks] << metadata[:blocks]
metadata.delete(:blocks)
end
@local_metadata.deep_merge!(metadata)
@local_metadata[:blocks] << block if block_given?
end
2012-04-04 19:26:07 +02:00
# Get the output/preview URL for this resource
# @return [String]
def destination_path
@destination_paths.last
end
2012-04-04 19:26:07 +02:00
# Set the output/preview URL for this resource
# @param [String] path
# @return [void]
def destination_path=(path)
@destination_paths << path
end
2012-04-04 19:26:07 +02:00
# Extension of the path (i.e. '.js')
# @return [String]
def ext
File.extname(path)
end
2012-04-04 19:26:07 +02:00
# Mime type of the path
# @return [String]
def mime_type
app.mime_type ext
end
2012-04-04 19:26:07 +02:00
# Render this resource
# @return [String]
def render(opts={}, locs={}, &block)
return File.open(source_file).read unless template?
2012-04-04 19:26:07 +02:00
start_time = Time.now
puts "== Render Start: #{source_file}" if app.logging?
2012-04-04 19:26:07 +02:00
md = metadata.dup
opts = md[:options].deep_merge(opts)
locs = md[:locals].deep_merge(locs)
2012-04-04 19:26:07 +02:00
# Forward remaining data to helpers
if md.has_key?(:page)
app.data.store("page", md[:page])
end
2012-04-04 19:26:07 +02:00
md[:blocks].flatten.compact.each do |block|
app.instance_eval(&block)
end
app.instance_eval(&block) if block_given?
result = app.render_template(source_file, locs, opts)
2012-04-04 19:26:07 +02:00
puts "== Render End: #{source_file} (#{(Time.now - start_time).round(2)}s)" if app.logging?
result
end
2012-04-04 19:26:07 +02:00
# A path without the directory index - so foo/index.html becomes
# just foo. Best for linking.
# @return [String]
def url
'/' + destination_path.sub(/#{Regexp.escape(app.index_file)}$/, '')
end
2012-04-04 19:26:07 +02:00
end
end
end