2011-04-15 00:35:41 +02:00
|
|
|
require "yaml"
|
2011-09-12 19:20:34 +02:00
|
|
|
require "active_support/json"
|
2011-04-29 20:58:07 +02:00
|
|
|
require "thor"
|
2011-04-15 00:35:41 +02:00
|
|
|
|
2011-07-06 18:50:34 +02:00
|
|
|
module Middleman::CoreExtensions::Data
|
2011-04-15 00:35:41 +02:00
|
|
|
class << self
|
|
|
|
def registered(app)
|
2011-07-06 19:30:24 +02:00
|
|
|
app.set :data_dir, "data"
|
2011-04-29 20:58:07 +02:00
|
|
|
app.extend ClassMethods
|
2011-07-06 18:50:34 +02:00
|
|
|
app.helpers Helpers
|
2011-11-10 06:19:11 +01:00
|
|
|
|
2011-11-17 22:21:05 +01:00
|
|
|
app.file_changed DataStore.matcher do |file|
|
|
|
|
data.touch_file(file) if file.match(%r{^#{settings.data_dir}\/})
|
2011-11-10 06:19:11 +01:00
|
|
|
end
|
|
|
|
|
2011-11-17 22:21:05 +01:00
|
|
|
app.file_deleted DataStore.matcher do |file|
|
|
|
|
data.remove_file(file) if file.match(%r{^#{settings.data_dir}\/})
|
2011-11-10 06:19:11 +01:00
|
|
|
end
|
2011-04-15 00:35:41 +02:00
|
|
|
end
|
2011-04-15 18:57:45 +02:00
|
|
|
alias :included :registered
|
|
|
|
end
|
|
|
|
|
|
|
|
module Helpers
|
|
|
|
def data
|
2011-11-17 22:21:05 +01:00
|
|
|
settings.data
|
2011-04-15 18:57:45 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-11-17 22:21:05 +01:00
|
|
|
class DataStore
|
|
|
|
def self.matcher
|
|
|
|
%r{[\w-]+\.(yml|yaml|json)$}
|
|
|
|
end
|
|
|
|
|
2011-04-15 18:57:45 +02:00
|
|
|
def initialize(app)
|
|
|
|
@app = app
|
2011-11-10 06:19:11 +01:00
|
|
|
@local_data = {}
|
2011-11-10 21:26:20 +01:00
|
|
|
|
2011-11-10 06:19:11 +01:00
|
|
|
data_path = File.join(@app.root, @app.data_dir)
|
|
|
|
local_path = File.join(data_path, "*.{yaml,yml,json}")
|
|
|
|
Dir[local_path].each do |f|
|
2011-11-10 21:26:20 +01:00
|
|
|
touch_file(f)
|
2011-11-10 06:19:11 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def touch_file(file)
|
|
|
|
extension = File.extname(file)
|
|
|
|
basename = File.basename(file, extension)
|
|
|
|
|
|
|
|
if %w(.yaml .yml).include?(extension)
|
|
|
|
data = YAML.load_file(file)
|
|
|
|
elsif extension == ".json"
|
|
|
|
data = ActiveSupport::JSON.decode(File.read(file))
|
|
|
|
else
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
@local_data[basename] = recursively_enhance(data)
|
|
|
|
end
|
|
|
|
|
|
|
|
def remove_file(file)
|
|
|
|
extension = File.extname(file)
|
|
|
|
basename = File.basename(file, extension)
|
|
|
|
@local_data.delete(basename) if @local_data.has_key?(basename)
|
2011-04-15 00:35:41 +02:00
|
|
|
end
|
|
|
|
|
2011-09-06 20:12:20 +02:00
|
|
|
def data_for_path(path)
|
2011-04-29 20:58:07 +02:00
|
|
|
response = nil
|
|
|
|
|
2011-06-06 03:59:04 +02:00
|
|
|
@@local_sources ||= {}
|
2011-08-21 01:38:45 +02:00
|
|
|
@@callback_sources ||= {}
|
2011-04-29 20:58:07 +02:00
|
|
|
|
2011-06-06 03:59:04 +02:00
|
|
|
if @@local_sources.has_key?(path.to_s)
|
|
|
|
response = @@local_sources[path.to_s]
|
2011-08-21 01:38:45 +02:00
|
|
|
elsif @@callback_sources.has_key?(path.to_s)
|
|
|
|
response = @@callback_sources[path.to_s].call()
|
2011-04-29 20:58:07 +02:00
|
|
|
end
|
2011-09-12 19:13:13 +02:00
|
|
|
|
|
|
|
response
|
2011-09-06 20:12:20 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def method_missing(path)
|
2011-11-10 06:19:11 +01:00
|
|
|
if @local_data.has_key?(path.to_s)
|
|
|
|
return @local_data[path.to_s]
|
2011-09-06 20:12:20 +02:00
|
|
|
else
|
2011-11-10 06:19:11 +01:00
|
|
|
result = data_for_path(path)
|
|
|
|
|
|
|
|
if result
|
|
|
|
return recursively_enhance(result)
|
|
|
|
end
|
2011-09-06 20:12:20 +02:00
|
|
|
end
|
2011-11-10 06:19:11 +01:00
|
|
|
|
|
|
|
super
|
2011-09-06 20:12:20 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def to_h
|
|
|
|
data = {}
|
|
|
|
|
2011-09-09 08:06:22 +02:00
|
|
|
@@local_sources ||= {}
|
|
|
|
@@callback_sources ||= {}
|
|
|
|
|
2011-09-06 20:12:20 +02:00
|
|
|
(@@local_sources || {}).each do |k, v|
|
|
|
|
data[k] = data_for_path(k)
|
|
|
|
end
|
2011-04-29 20:58:07 +02:00
|
|
|
|
2011-09-06 20:12:20 +02:00
|
|
|
(@@callback_sources || {}).each do |k, v|
|
|
|
|
data[k] = data_for_path(k)
|
2011-04-29 20:58:07 +02:00
|
|
|
end
|
2011-09-06 20:12:20 +02:00
|
|
|
|
2011-11-10 06:19:11 +01:00
|
|
|
(@local_data || {}).each do |k, v|
|
|
|
|
data[k] = v
|
2011-09-12 19:20:34 +02:00
|
|
|
end
|
|
|
|
|
2011-09-06 20:12:20 +02:00
|
|
|
data
|
2011-04-29 20:58:07 +02:00
|
|
|
end
|
2011-06-06 03:59:04 +02:00
|
|
|
|
|
|
|
def self.data_content(name, content)
|
|
|
|
@@local_sources ||= {}
|
|
|
|
@@local_sources[name.to_s] = content
|
|
|
|
end
|
2011-08-21 01:38:45 +02:00
|
|
|
|
|
|
|
def self.data_callback(name, proc)
|
|
|
|
@@callback_sources ||= {}
|
|
|
|
@@callback_sources[name.to_s] = proc
|
|
|
|
end
|
2011-04-29 20:58:07 +02:00
|
|
|
|
|
|
|
private
|
|
|
|
def recursively_enhance(data)
|
|
|
|
if data.is_a? Hash
|
|
|
|
data = Thor::CoreExt::HashWithIndifferentAccess.new(data)
|
|
|
|
data.each do |key, val|
|
|
|
|
data[key] = recursively_enhance(val)
|
|
|
|
end
|
|
|
|
data
|
|
|
|
elsif data.is_a? Array
|
|
|
|
data.each_with_index do |val, i|
|
|
|
|
data[i] = recursively_enhance(val)
|
|
|
|
end
|
|
|
|
data
|
|
|
|
else
|
|
|
|
data
|
2011-04-15 18:57:45 +02:00
|
|
|
end
|
|
|
|
end
|
2011-04-15 00:35:41 +02:00
|
|
|
end
|
2011-04-15 18:57:45 +02:00
|
|
|
|
2011-04-29 20:58:07 +02:00
|
|
|
module ClassMethods
|
2011-08-31 22:15:59 +02:00
|
|
|
def data
|
2011-11-17 22:21:05 +01:00
|
|
|
@data ||= DataStore.new(self)
|
2011-08-31 22:15:59 +02:00
|
|
|
end
|
|
|
|
|
2011-08-21 01:38:45 +02:00
|
|
|
# Makes a hash available on the data var with a given name
|
2011-06-06 03:59:04 +02:00
|
|
|
def data_content(name, content)
|
2011-11-17 22:21:05 +01:00
|
|
|
DataStore.data_content(name, content)
|
2011-06-06 03:59:04 +02:00
|
|
|
end
|
2011-08-21 01:38:45 +02:00
|
|
|
|
|
|
|
# Makes a hash available on the data var with a given name
|
|
|
|
def data_callback(name, &block)
|
2011-11-17 22:21:05 +01:00
|
|
|
DataStore.data_callback(name, block)
|
2011-08-21 01:38:45 +02:00
|
|
|
end
|
2011-04-29 20:58:07 +02:00
|
|
|
end
|
2011-04-15 00:35:41 +02:00
|
|
|
end
|