motr 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +3 -4
- data/lib/motr.rb +10 -39
- data/lib/motr/controller/helpers.rb +1 -1
- data/lib/motr/dash.rb +33 -0
- data/lib/motr/defaults.rb +1 -1
- data/lib/motr/helpers/elements.rb +6 -4
- data/lib/motr/helpers/navigation.rb +13 -4
- data/lib/motr/mapper.rb +7 -0
- data/lib/motr/modding.rb +98 -0
- data/lib/motr/mods.rb +67 -0
- data/lib/motr/mods/sluggable.rb +65 -0
- data/lib/motr/orm/active_record.rb +3 -3
- data/lib/motr/orm/mongoid.rb +2 -17
- data/lib/motr/rails.rb +5 -4
- data/lib/motr/version.rb +1 -1
- metadata +8 -7
- data/lib/motr/model.rb +0 -134
- data/lib/motr/model/sluggable.rb +0 -45
- data/lib/motr/schema/base.rb +0 -20
- data/lib/motr/schema/generator.rb +0 -79
data/README.rdoc
CHANGED
@@ -2,11 +2,10 @@
|
|
2
2
|
|
3
3
|
{Official Documentation}[http://rubydoc.info/github/kurbmedia/motr/master/frames]
|
4
4
|
|
5
|
-
Motr is a basic Rails engine which adds additional functionality to your applications, and creates the ability to "
|
5
|
+
Motr is a basic Rails engine which adds additional functionality to your applications, and creates the ability to "mod" models and classes
|
6
6
|
easily to support routine functionality. The {core Motr}[http://github.com/kurbmedia/motr] engine
|
7
7
|
provides a number of helpers and functionality geared towards bringing the ease of Rails back-end development, to the front-end. It
|
8
|
-
also implements a
|
9
|
-
models in a similar manner to how Devise adds session management functionality.
|
8
|
+
also implements a "modding" system to support easily adding data functionality to classes/models.
|
10
9
|
|
11
10
|
Rails view helpers and form builders are convenient an easy to use, however some aren't very design/html friendly (whose idea was it to
|
12
11
|
wrap fields with errors in a div?). The goal is to keep html valid and sensible where possible, and make things like javascript integration
|
@@ -23,7 +22,7 @@ feature requests, especially from designers/front-end developers who spend a lot
|
|
23
22
|
|
24
23
|
== Credits
|
25
24
|
|
26
|
-
Thanks to José Valim and {Devise}[https://github.com/plataformatec/devise] which inspired the
|
25
|
+
Thanks to José Valim and {Devise}[https://github.com/plataformatec/devise] which inspired the "modding" concept.
|
27
26
|
|
28
27
|
== License
|
29
28
|
|
data/lib/motr.rb
CHANGED
@@ -3,15 +3,12 @@ require 'active_support/dependencies'
|
|
3
3
|
require 'set'
|
4
4
|
|
5
5
|
require 'motr/forms'
|
6
|
-
require 'motr/
|
6
|
+
require 'motr/modding'
|
7
|
+
require 'motr/mods'
|
8
|
+
require 'motr/dash'
|
7
9
|
|
8
10
|
module Motr
|
9
11
|
|
10
|
-
module Schema
|
11
|
-
autoload :Base, 'motr/schema/base'
|
12
|
-
autoload :Generator, 'motr/schema/generator'
|
13
|
-
end
|
14
|
-
|
15
12
|
module Controller #:nodoc:
|
16
13
|
autoload :Helpers, 'motr/controller/helpers'
|
17
14
|
autoload :Responder, 'motr/controller/responder'
|
@@ -29,52 +26,26 @@ module Motr
|
|
29
26
|
autoload :ModuleMissing, 'motr/errors/module_missing'
|
30
27
|
end
|
31
28
|
|
32
|
-
# Store configurations for included models
|
33
|
-
ALL = []
|
34
|
-
CONFIGS = {}
|
35
29
|
|
36
30
|
##
|
37
31
|
#
|
38
|
-
# Enable
|
39
|
-
# can then be included/initialized using the +motr+ method.
|
32
|
+
# Enable autoloading of mods
|
40
33
|
#
|
41
34
|
# @param [Symbol] module_name The name of the module to be added (underscored)
|
42
|
-
# @param [Hash]
|
43
|
-
#
|
44
|
-
# @option config [String, Boolean] :autoload The path to autoload the module from (optional)
|
35
|
+
# @param [Hash] options Hash including options for the mod
|
45
36
|
#
|
46
|
-
#
|
37
|
+
# @option options [String, Boolean] :autoload The path to autoload the module from (optional)
|
47
38
|
#
|
48
39
|
#
|
49
|
-
def self.
|
40
|
+
def self.add_mod(module_name, options = {})
|
50
41
|
|
51
|
-
# Store a reference to any module loaded
|
52
|
-
ALL << module_name
|
53
|
-
config.assert_valid_keys(:autoload)
|
54
|
-
|
55
42
|
const_name = ActiveSupport::Inflector.camelize(module_name.to_s)
|
56
43
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
Motr::Model.send(:autoload, const_name, path)
|
44
|
+
if autoload_path = options.delete(:autoload)
|
45
|
+
path = (autoload_path == true ? "motr/mods/#{module_name.to_s}" : autoload_path)
|
46
|
+
Motr::Mods.send(:autoload, const_name, path)
|
61
47
|
end
|
62
48
|
|
63
|
-
# Setup placeholder for configuration
|
64
|
-
Motr::CONFIGS[module_name] ||= {}
|
65
|
-
|
66
|
-
# Setup configuration method for module.
|
67
|
-
#
|
68
|
-
self.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
69
|
-
def self.#{module_name.to_s}(options = {})
|
70
|
-
raise Motr::Errors::InvalidOptions.new('Configuration for #{module_name} must be a hash.') unless options.is_a?(Hash)
|
71
|
-
Motr::CONFIGS[:#{module_name.to_s}].merge!(options)
|
72
|
-
end
|
73
|
-
METHOD
|
74
|
-
|
75
|
-
# Apply any defaults
|
76
|
-
Motr.send(:"#{module_name}", config)
|
77
|
-
|
78
49
|
end
|
79
50
|
|
80
51
|
# Support initializer configuration
|
@@ -71,7 +71,7 @@ module Motr
|
|
71
71
|
# @deprecated Use add_response_meta
|
72
72
|
#
|
73
73
|
def enable_script_events(opts = {})
|
74
|
-
ActiveSupport::Deprecation.
|
74
|
+
ActiveSupport::Deprecation.warn("enable_script_events is deprecated. Please use the 'add_response_meta helper'")
|
75
75
|
response_metadata = opts
|
76
76
|
end
|
77
77
|
|
data/lib/motr/dash.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module Motr
|
4
|
+
##
|
5
|
+
# Motr::Dash is basically a dashboard for an entire rails app.
|
6
|
+
# It does things like setting up app-wide configurations etc.
|
7
|
+
#
|
8
|
+
module Dash
|
9
|
+
|
10
|
+
##
|
11
|
+
# Defines an application-wide configuration hash created from config/config.yml
|
12
|
+
#
|
13
|
+
def config
|
14
|
+
return @motr_application_config unless @motr_application_config.nil?
|
15
|
+
begin
|
16
|
+
config_data = YAML::load(File.open("#{Rails.root}/config/config.yml"))
|
17
|
+
rescue
|
18
|
+
warn("Motr::Dash: Application configuration not found, please create a config.yml at #{Rails.root}/config/config.yml")
|
19
|
+
config_data = {}
|
20
|
+
end
|
21
|
+
@motr_application_config = ActiveSupport::HashWithIndifferentAccess::new(config_data[Rails.env] ||= {})
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Force reload of application configuration (without server restart)
|
26
|
+
#
|
27
|
+
def reconfigure!
|
28
|
+
@motr_application_config = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/lib/motr/defaults.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Motr.
|
1
|
+
Motr.add_mod(:sluggable, :autoload => true)
|
@@ -51,6 +51,8 @@ module Motr
|
|
51
51
|
#
|
52
52
|
def flash_messages(attrs = {})
|
53
53
|
|
54
|
+
return if flash.nil? or flash.empty?
|
55
|
+
|
54
56
|
wrapper = attrs.delete(:wrapper) || :div
|
55
57
|
closer = attrs.delete(:closer)
|
56
58
|
unless closer === false
|
@@ -60,10 +62,10 @@ module Motr
|
|
60
62
|
klasses << "flash_message"
|
61
63
|
content = ""
|
62
64
|
|
63
|
-
flash.
|
64
|
-
klasses << "flash_message_#{
|
65
|
-
msg_attrs = attrs.merge(:class => [
|
66
|
-
content.concat content_tag(wrapper, "#{
|
65
|
+
flash.each do |key, value|
|
66
|
+
klasses << "flash_message_#{key.to_s.underscore}"
|
67
|
+
msg_attrs = attrs.merge(:class => [key.to_s, klasses].flatten.join(' '))
|
68
|
+
content.concat content_tag(wrapper, "#{value} #{closer}".html_safe, msg_attrs).html_safe
|
67
69
|
end
|
68
70
|
|
69
71
|
content.html_safe
|
@@ -75,8 +75,8 @@ module Motr
|
|
75
75
|
# @private
|
76
76
|
def update_link_attrs(path, attrs)
|
77
77
|
|
78
|
-
proc = attrs.delete(:proc)
|
79
|
-
regex = attrs.delete(:matcher)
|
78
|
+
proc = attrs.delete(:proc) || false
|
79
|
+
regex = attrs.delete(:matcher) || false
|
80
80
|
klasses = attrs.delete(:class).try(:split, ' ')
|
81
81
|
on_class = attrs.delete(:active_class) || "on"
|
82
82
|
wrapper_attrs = attrs.delete(:wrapper) || {}
|
@@ -85,11 +85,20 @@ module Motr
|
|
85
85
|
klasses ||= []
|
86
86
|
wklasses ||= []
|
87
87
|
|
88
|
-
|
88
|
+
matcher = (proc || regex || request.path)
|
89
|
+
|
90
|
+
active = case matcher
|
91
|
+
when Proc then proc.call(path)
|
92
|
+
when Regexp then request.path.match(regex)
|
93
|
+
when String then (request.path == path || request.path.match(/#{path}\/\w/im))
|
94
|
+
else raise Motr::Errors::InvalidOptions.new('Proc, Regexp or String required... passed #{matcher.class}.')
|
95
|
+
end
|
96
|
+
|
97
|
+
if active
|
89
98
|
klasses << on_class
|
90
99
|
wklasses << on_class
|
91
100
|
end
|
92
|
-
|
101
|
+
|
93
102
|
attrs.merge!(:class => klasses.join(" ")) unless klasses.compact.empty?
|
94
103
|
wrapper_attrs.merge!(:class => wklasses.join(" ")) unless wklasses.compact.empty?
|
95
104
|
|
data/lib/motr/mapper.rb
ADDED
data/lib/motr/modding.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Each mod extends Motr::Mod which provides necessary functionality to
|
4
|
+
# perform setup and configuration.
|
5
|
+
#
|
6
|
+
module Motr
|
7
|
+
module Modding
|
8
|
+
|
9
|
+
def append_features(base)
|
10
|
+
return false if base < self
|
11
|
+
super
|
12
|
+
# Apply any orm specific configurations
|
13
|
+
#
|
14
|
+
if instance_variable_defined?("@_mod_config_for_orm")
|
15
|
+
@_mod_config_for_orm.each do |orm, configs|
|
16
|
+
# Each orm should implement a motr_orm_type value which identifies
|
17
|
+
# itself to mods (ie :active_record, :mongoid)
|
18
|
+
next unless base.respond_to?(:motr_orm_type) && base.__send__(:motr_orm_type).to_s === orm.to_s
|
19
|
+
[configs].flatten.each{ |conf| base.class_eval(&conf) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
|
24
|
+
base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
|
25
|
+
base.class_eval(&@_mod_config_callback) if instance_variable_defined?("@_mod_config_callback")
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Apply is run each time a mod is applied to a model. As opposed to the configure method,
|
31
|
+
# apply blocks are run each time modded_with :your_mod is called.
|
32
|
+
#
|
33
|
+
# @param [Block] &block The callback to be run when the mod is applied
|
34
|
+
#
|
35
|
+
# @example Configure a before_save callback to be applied to each instance
|
36
|
+
#
|
37
|
+
# module MyMod
|
38
|
+
# apply do
|
39
|
+
# before_save :something_each_time
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
def apply(&block)
|
44
|
+
@_mod_apply_callback = block
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
##
|
49
|
+
# Each mod can pass an optional configuration block (or one global config and one per orm) which
|
50
|
+
# is run when a particular class or model implements that mod. Configure methods are only run on first inclusion.
|
51
|
+
# To run functionality each time the mod is applied, see Motr::Mod.apply
|
52
|
+
#
|
53
|
+
# Orm specific functionality can be configured by passing an :orm as the first option
|
54
|
+
#
|
55
|
+
# @param [Symbol] orm The name of the orm in which this configuration applies
|
56
|
+
#
|
57
|
+
# @example Configure a before_filter callback when a model implements your mod
|
58
|
+
#
|
59
|
+
# module MyMod
|
60
|
+
# configure do
|
61
|
+
# before_filter :something_awesome
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# @example Configure mongoid only functionality
|
66
|
+
#
|
67
|
+
# module MyMod
|
68
|
+
# configure(:mongoid) do
|
69
|
+
# embeds_many :somethings
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
def configure(orm = nil, &block)
|
74
|
+
if orm.nil?
|
75
|
+
@_mod_config_callback = block
|
76
|
+
else
|
77
|
+
(@_mod_config_for_orm ||= {})[orm] = block
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Each mod can specify any number of options that may be passed to it
|
83
|
+
# when applied to a class/model.
|
84
|
+
#
|
85
|
+
# @param [Array] *options Argument list of options to create.
|
86
|
+
#
|
87
|
+
# @example Create configuration options on a module
|
88
|
+
# module Motr::Mods::Sample
|
89
|
+
# options(:sample, :option1, :option2)
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
#
|
93
|
+
def options(*options)
|
94
|
+
@_mod_options = options
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
data/lib/motr/mods.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Motr
|
2
|
+
module Mods
|
3
|
+
|
4
|
+
##
|
5
|
+
# modded_with provides the "hook" functionality to mod a model/class with a particular mod.
|
6
|
+
# Multiple mods can be applied at once, with options.
|
7
|
+
#
|
8
|
+
# @param [Array] *mods Argument list of mods, and/or options
|
9
|
+
# @option *mods [Hash] options Options to be applied to each included mod
|
10
|
+
#
|
11
|
+
# @example Mod a model with the sluggable mod
|
12
|
+
#
|
13
|
+
# class Awesome < ActiveRecord::Base
|
14
|
+
# modded_with :sluggable, :fields => :title, :as => :slug
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
#
|
18
|
+
def modded_with(*mods)
|
19
|
+
|
20
|
+
options = mods.extract_options!
|
21
|
+
modules = mods.map(&:to_sym).uniq
|
22
|
+
|
23
|
+
modules.each do |mod|
|
24
|
+
const_name = mod.to_s.classify
|
25
|
+
next unless Motr::Mods.const_defined?(:"#{const_name}")
|
26
|
+
|
27
|
+
const_incl = Motr::Mods.const_get(:"#{const_name}")
|
28
|
+
|
29
|
+
# Apply passed options to modules where applicable.
|
30
|
+
#
|
31
|
+
if const_incl.instance_variable_defined?("@_mod_options")
|
32
|
+
mod_opts = const_incl.instance_variable_get("@_mod_options")
|
33
|
+
|
34
|
+
new_opts = mod_opts.inject({}) do |hsh, option|
|
35
|
+
next hsh unless options.key?(option)
|
36
|
+
hsh.merge!(option => options.delete(option))
|
37
|
+
end
|
38
|
+
|
39
|
+
(class << self; self; end).class_eval do
|
40
|
+
define_method("#{mod}_mod_options"){ motr_mod_options[mod.to_s] }
|
41
|
+
define_method("#{mod}_mod_options="){ |opts| motr_mod_options[mod.to_s] = opts }
|
42
|
+
end
|
43
|
+
|
44
|
+
write_inheritable_attribute(:motr_mod_options, {}) if motr_mod_options.nil?
|
45
|
+
motr_mod_options[mod.to_s] = new_opts
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
if const_incl.instance_variable_defined?("@_mod_apply_callback")
|
50
|
+
self.class_eval(&const_incl.instance_variable_get("@_mod_apply_callback"))
|
51
|
+
end
|
52
|
+
|
53
|
+
include const_incl
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def motr_mod_options
|
60
|
+
read_inheritable_attribute(:motr_mod_options)
|
61
|
+
end
|
62
|
+
|
63
|
+
alias :motr :modded_with
|
64
|
+
alias :mod_with :modded_with
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Motr
|
2
|
+
module Mods
|
3
|
+
##
|
4
|
+
# Sluggable generates a url-friendly "slug" from a particular attribute.
|
5
|
+
# @param [Hash] options Options for generating a slug or slugs
|
6
|
+
# @option options [Hash,Symbol,String] :fields The fields that will be slugged
|
7
|
+
# @option options [Array, Symbol] :on The callback(s) in which slugs will be created (:create, :save, etc)
|
8
|
+
# @option options [Symbol, String] :as The attribute that receives the slugged value
|
9
|
+
# If an array is passed to both :fields and :as, :as will be used in order of the arrays.
|
10
|
+
#
|
11
|
+
# @example Slugify a "title" attribute into the "slug" attribute when new instances are saved
|
12
|
+
# modded_with :sluggable, :fields => :title, :on => :create, :as => :slug
|
13
|
+
#
|
14
|
+
# @example Slugify a "title" as a "slug" and a "subtitle" into itself
|
15
|
+
# modded_with :sluggable, :fields => [:title, :subtitle], :as => [:slug]
|
16
|
+
#
|
17
|
+
module Sluggable
|
18
|
+
extend Motr::Modding
|
19
|
+
|
20
|
+
options(:fields, :on, :as)
|
21
|
+
|
22
|
+
configure do
|
23
|
+
pos = sluggable_mod_options[:on] || "create"
|
24
|
+
send(:"before_#{pos.to_s}", :_create_slugged_fields)
|
25
|
+
end
|
26
|
+
|
27
|
+
def _create_slugged_fields
|
28
|
+
|
29
|
+
slug_opts = self.class.sluggable_mod_options
|
30
|
+
slug_fields = slug_opts[:fields]
|
31
|
+
slug_as = [slug_opts[:as]].flatten
|
32
|
+
|
33
|
+
[slug_fields].flatten.map(&:to_sym).each_with_index do |atr, i|
|
34
|
+
|
35
|
+
next if self.send(atr).nil?
|
36
|
+
unless slug_as.empty? || slug_as[i].nil?
|
37
|
+
self.send(:"#{slug_as[i]}=", self.send(atr).to_slug)
|
38
|
+
else
|
39
|
+
self.send(:"#{atr.to_s}=", self.send(atr).to_slug)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Original implementation by Ludo van den Boom's to_slug plugin
|
52
|
+
# @see to_slug (https://github.com/ludo/to_slug)
|
53
|
+
#
|
54
|
+
module ToSlug #:nodoc:
|
55
|
+
def to_slug
|
56
|
+
value = self.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s
|
57
|
+
value.gsub!(/[']+/, '')
|
58
|
+
value.gsub!(/\W+/, ' ')
|
59
|
+
value.strip!
|
60
|
+
value.downcase!
|
61
|
+
value.gsub!(' ', '-')
|
62
|
+
value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
String.send(:include, ToSlug)
|
data/lib/motr/orm/mongoid.rb
CHANGED
@@ -2,28 +2,13 @@ module Motr
|
|
2
2
|
module Orm
|
3
3
|
|
4
4
|
module Mongoid #:nodoc:
|
5
|
-
def
|
6
|
-
extend Schema
|
7
|
-
yield
|
8
|
-
motrize_schema!
|
9
|
-
end
|
10
|
-
|
11
|
-
module Schema
|
12
|
-
include Motr::Schema::Base
|
13
|
-
|
14
|
-
def apply_motr_schema(field_name, field_type, options = {})
|
15
|
-
field_type = Time if field_type == DateTime
|
16
|
-
field field_name, { :type => field_type }.merge!(options)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
5
|
+
def motr_orm_type; :mongoid; end
|
21
6
|
end
|
22
7
|
|
23
8
|
end
|
24
9
|
end
|
25
10
|
|
26
11
|
Mongoid::Document::ClassMethods.class_eval do
|
27
|
-
include Motr::
|
12
|
+
include Motr::Mods
|
28
13
|
include Motr::Orm::Mongoid
|
29
14
|
end
|
data/lib/motr/rails.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module Motr
|
2
2
|
class Engine < ::Rails::Engine #:nodoc:
|
3
|
-
config.motr = Motr
|
3
|
+
config.motr = Motr
|
4
4
|
|
5
5
|
# Add load paths straight to I18n, so engines and application can overwrite it.
|
6
6
|
require 'active_support/i18n'
|
7
7
|
I18n.load_path << File.expand_path('../../config/locales/en.yml', __FILE__)
|
8
8
|
|
9
9
|
initializer 'motr.initializer' do
|
10
|
+
require 'motr/orm/mongoid' if defined?(Mongoid)
|
11
|
+
|
10
12
|
ActiveSupport.on_load(:action_view) do
|
11
13
|
include Motr::Helpers::LayoutHelpers
|
12
14
|
include Motr::Helpers::Navigation
|
@@ -18,9 +20,8 @@ module Motr
|
|
18
20
|
include Motr::Controller::Helpers
|
19
21
|
self.responder = Motr::Controller::Responder
|
20
22
|
end
|
21
|
-
ActiveSupport.on_load(:
|
22
|
-
require 'motr/orm/
|
23
|
-
require 'motr/orm/active_record' if defined?(ActiveRecord)
|
23
|
+
ActiveSupport.on_load(:active_record) do
|
24
|
+
require 'motr/orm/active_record'
|
24
25
|
end
|
25
26
|
|
26
27
|
end
|
data/lib/motr/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: motr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Brent Kirby
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
13
|
+
date: 2011-05-18 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- lib/generators/templates/post_install
|
126
126
|
- lib/motr/controller/helpers.rb
|
127
127
|
- lib/motr/controller/responder.rb
|
128
|
+
- lib/motr/dash.rb
|
128
129
|
- lib/motr/defaults.rb
|
129
130
|
- lib/motr/errors/invalid_options.rb
|
130
131
|
- lib/motr/errors/module_missing.rb
|
@@ -136,13 +137,13 @@ files:
|
|
136
137
|
- lib/motr/helpers/elements.rb
|
137
138
|
- lib/motr/helpers/layout_helpers.rb
|
138
139
|
- lib/motr/helpers/navigation.rb
|
139
|
-
- lib/motr/
|
140
|
-
- lib/motr/
|
140
|
+
- lib/motr/mapper.rb
|
141
|
+
- lib/motr/modding.rb
|
142
|
+
- lib/motr/mods/sluggable.rb
|
143
|
+
- lib/motr/mods.rb
|
141
144
|
- lib/motr/orm/active_record.rb
|
142
145
|
- lib/motr/orm/mongoid.rb
|
143
146
|
- lib/motr/rails.rb
|
144
|
-
- lib/motr/schema/base.rb
|
145
|
-
- lib/motr/schema/generator.rb
|
146
147
|
- lib/motr/version.rb
|
147
148
|
- lib/motr.rb
|
148
149
|
- config/en.yml
|
@@ -164,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
165
|
requirements:
|
165
166
|
- - ">="
|
166
167
|
- !ruby/object:Gem::Version
|
167
|
-
hash: -
|
168
|
+
hash: -2994942846918813196
|
168
169
|
segments:
|
169
170
|
- 0
|
170
171
|
version: "0"
|
data/lib/motr/model.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
module Motr
|
2
|
-
|
3
|
-
##
|
4
|
-
# Provides a interface for extending models and controllers with additional Motr libraries.
|
5
|
-
# To create a new library, sub-class/module Motr::Model or Motr::Controller depending on the
|
6
|
-
# functionality to include. To 'attach' functionality call motr :module_name
|
7
|
-
#
|
8
|
-
# @example Create a "postable" model using Motr::Model::Postable (see the motr-content gem)
|
9
|
-
# class MyPost
|
10
|
-
# motr :postable
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
module Model
|
14
|
-
##
|
15
|
-
# Stores a list of available options for a model. This way when
|
16
|
-
# options are passed at load-time, they can be applied to the proper modules.
|
17
|
-
#
|
18
|
-
# @param [Class, Module] mod The module to configure
|
19
|
-
# @param [Symbol] cfg_name The name of the configuration to modify
|
20
|
-
# @param [Array] *options Argument list of options to create.
|
21
|
-
#
|
22
|
-
# @example Create configuration options on a module
|
23
|
-
# module Motr::Model::Sample
|
24
|
-
# module ClassMethods
|
25
|
-
# Motr::Model.config(self, :sample, :option1, :option2)
|
26
|
-
# end
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
#
|
30
|
-
def self.config(mod, cfg_name, *options)
|
31
|
-
(class << mod; self; end).send(:attr_accessor_with_default, :motr_options, {})
|
32
|
-
mod.motr_options[cfg_name] ||= []
|
33
|
-
|
34
|
-
options.each do |option|
|
35
|
-
mod.motr_options[cfg_name] << option
|
36
|
-
fullname = [cfg_name, option].map(&:to_s).join("_")
|
37
|
-
|
38
|
-
mod.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
39
|
-
def #{fullname}
|
40
|
-
if defined?(@#{fullname})
|
41
|
-
@#{fullname}
|
42
|
-
elsif superclass.respond_to?(:#{fullname})
|
43
|
-
superclass.#{fullname}
|
44
|
-
else
|
45
|
-
Motr::CONFIGS[:#{cfg_name}][:#{option}]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
def #{fullname}=(value)
|
49
|
-
@#{fullname} = value
|
50
|
-
end
|
51
|
-
METHOD
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
##
|
56
|
-
# The motr method enables loading other motr libraries into application modules/classes.
|
57
|
-
#
|
58
|
-
# @example Create a model include to hook into any model class
|
59
|
-
# module Motr::Model::Sample
|
60
|
-
# def instance_method
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# module ClassMethods
|
64
|
-
# def class_method
|
65
|
-
# end
|
66
|
-
# end
|
67
|
-
# end
|
68
|
-
#
|
69
|
-
# class SomeModel < ActiveRecord::Base
|
70
|
-
# motr :sample
|
71
|
-
# end
|
72
|
-
#
|
73
|
-
#
|
74
|
-
def motr(*mods)
|
75
|
-
|
76
|
-
options = mods.extract_options!
|
77
|
-
modules = mods.map(&:to_sym).uniq
|
78
|
-
|
79
|
-
# Track what modules have been added to each class.
|
80
|
-
self.class_eval do
|
81
|
-
class_attribute :motr_modules, :instance_writer => false unless defined?(self.motr_modules)
|
82
|
-
self.motr_modules ||= []
|
83
|
-
end
|
84
|
-
|
85
|
-
motrize_model! do
|
86
|
-
|
87
|
-
modules.each do |mod|
|
88
|
-
const_name = mod.to_s.classify
|
89
|
-
raise Motr::Model.load_failure("Motr::Model::#{const_name}") unless Motr::ALL.include?(mod)
|
90
|
-
|
91
|
-
begin
|
92
|
-
const_incl = Motr::Model.const_get(:"#{const_name}")
|
93
|
-
rescue NameError
|
94
|
-
raise Motr::Errors.ModuleMissing.new("Motr::Model::#{const_name} could not be found. Perhaps try adding the module with the :autoload option.")
|
95
|
-
end
|
96
|
-
|
97
|
-
if const_incl.const_defined?('ClassMethods')
|
98
|
-
class_incl = const_incl.const_get("ClassMethods")
|
99
|
-
extend class_incl
|
100
|
-
end
|
101
|
-
# # Apply passed options to modules where applicable.
|
102
|
-
#
|
103
|
-
if class_incl.respond_to?(:motr_options)
|
104
|
-
class_incl.motr_options[mod].each do |option|
|
105
|
-
next unless options.key?(option)
|
106
|
-
send(:"#{mod}_#{option}=", options.delete(option))
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
include const_incl
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
self.motr_modules |= modules
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
# Raise a ModuleMissing error if a module cannot be loaded.
|
121
|
-
# @private
|
122
|
-
#
|
123
|
-
def self.load_failure(mod) #:nodoc:
|
124
|
-
Motr::Errors::ModuleMissing.new("The module #{mod} wasn't found. Add it with Motr.add_module(#{mod})") and return
|
125
|
-
end
|
126
|
-
|
127
|
-
# Override motrize_model! to create specific functionality on a model
|
128
|
-
# @private
|
129
|
-
def motrize_model! #:nodoc:
|
130
|
-
yield
|
131
|
-
end
|
132
|
-
|
133
|
-
end
|
134
|
-
end
|
data/lib/motr/model/sluggable.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module Motr
|
2
|
-
module Model
|
3
|
-
|
4
|
-
module Sluggable #:nodoc:
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
callback_opt = (self.sluggable_on || "save")
|
9
|
-
send(:"before_#{callback_opt.to_s}", :make_sluggable_fields)
|
10
|
-
end
|
11
|
-
|
12
|
-
# @private
|
13
|
-
def make_sluggable_fields #:nodoc:
|
14
|
-
[self.class.sluggable_fields].flatten.each do |atr|
|
15
|
-
orig = self.send(:"#{atr}")
|
16
|
-
self.send(:"#{atr}=", orig.to_slug)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# @private
|
21
|
-
module ClassMethods #:nodoc:
|
22
|
-
Motr::Model.config(self, :sluggable, :fields, :on)
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
##
|
31
|
-
# Original implementation by Ludo van den Boom's to_slug plugin
|
32
|
-
# @see to_slug (https://github.com/ludo/to_slug)
|
33
|
-
#
|
34
|
-
module ToSlug #:nodoc:
|
35
|
-
def to_slug
|
36
|
-
value = self.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s
|
37
|
-
value.gsub!(/[']+/, '')
|
38
|
-
value.gsub!(/\W+/, ' ')
|
39
|
-
value.strip!
|
40
|
-
value.downcase!
|
41
|
-
value.gsub!(' ', '-')
|
42
|
-
value
|
43
|
-
end
|
44
|
-
end
|
45
|
-
String.send(:include, ToSlug)
|
data/lib/motr/schema/base.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
module Motr
|
2
|
-
module Schema
|
3
|
-
|
4
|
-
##
|
5
|
-
# Stubs schema methods to ensure ORM's implement them
|
6
|
-
# @private
|
7
|
-
#
|
8
|
-
module Base #:nodoc:
|
9
|
-
|
10
|
-
def motrize_schema!
|
11
|
-
Motr::Schema::Generator.set_target(self)
|
12
|
-
end
|
13
|
-
|
14
|
-
def apply_motr_schema(name, type, options={})
|
15
|
-
raise NotImplementedError
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module Motr
|
2
|
-
module Schema
|
3
|
-
##
|
4
|
-
# Generates a schema for a Motr module. To define a module schema, create a
|
5
|
-
# subclass that implements a "generate" class method. Generator classes
|
6
|
-
# should follow the convention Motr::Schema::ModuleGenerator where "Module" is the module the
|
7
|
-
# schema applies to. For instance if you have a module: Motr::Model::Sample, your generator class
|
8
|
-
# would be called Motr::Schema::SampleGenerator
|
9
|
-
#
|
10
|
-
# @example A generator for the module "sample"
|
11
|
-
#
|
12
|
-
# class Motr::Schema::SampleGenerator < Motr::Schema::Generator
|
13
|
-
# def self.generate
|
14
|
-
# apply(:field_name, String, {}) # => creates the field "field_name" with the type of String
|
15
|
-
#
|
16
|
-
# # only run for mongoid models
|
17
|
-
# apply_for(:mongoid) do
|
18
|
-
# embeds_many :children
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
#
|
24
|
-
class Generator
|
25
|
-
|
26
|
-
# Make er clean
|
27
|
-
instance_methods.each { |m| undef_method m unless m =~ /^(__.*__|object_id)$/ }
|
28
|
-
|
29
|
-
class_attribute :schema_runner, :instance_writer => false
|
30
|
-
|
31
|
-
# @private
|
32
|
-
# Delegates callbacks to a particular class/module. This allows generators to be flexible and
|
33
|
-
# somewhat similar to migrations.
|
34
|
-
#
|
35
|
-
def self.set_target(target) #:nodoc:
|
36
|
-
self.schema_runner = target
|
37
|
-
end
|
38
|
-
|
39
|
-
# Override in subclasses to run.
|
40
|
-
#
|
41
|
-
def self.generate
|
42
|
-
raise NotImplementedError
|
43
|
-
end
|
44
|
-
|
45
|
-
protected
|
46
|
-
|
47
|
-
##
|
48
|
-
# Apply a callback only if the including module implements the specified ORM
|
49
|
-
#
|
50
|
-
# @param [Symbol] orm The ORM which handles the block (ie: :mongoid or :active_record)
|
51
|
-
# @param [Block] &block The block to be run.
|
52
|
-
#
|
53
|
-
# @example Apply an option only to mongoid based models
|
54
|
-
# apply_for(:mongoid) do |model|
|
55
|
-
# model.embeds_many :children
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
def self.apply_for(orm, &block)
|
59
|
-
# TODO: This should maybe be more efficient?
|
60
|
-
puts self.schema_runner.inspect
|
61
|
-
return unless self.schema_runner.ancestors.map(&:to_s).detect{ |a| a.to_s.match(/#{orm.to_s.classify}/) }
|
62
|
-
yield self.schema_runner
|
63
|
-
end
|
64
|
-
|
65
|
-
##
|
66
|
-
# Creates a field on the model (or migration method in ActiveRecord)
|
67
|
-
#
|
68
|
-
# @param [Symbol] name The name of the field to create
|
69
|
-
# @param [Class] type The class type to create (ie: String, DateTime...)
|
70
|
-
# @param [Hash] options Specific options for the class type (ie: :default => nil)
|
71
|
-
#
|
72
|
-
def self.apply(name, type, options = {})
|
73
|
-
self.schema_runner.__send__(:apply_motr_schema, name, type, options)
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|