tanuki 0.1.3 → 0.2.1
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 +6 -3
- data/app/tanuki/attribute/attribute.rb +19 -0
- data/app/tanuki/base/base.rb +3 -0
- data/app/tanuki/controller/controller.rb +1 -1
- data/app/tanuki/controller/link.thtml +6 -6
- data/app/tanuki/meta_model/manager.ttxt +2 -0
- data/app/tanuki/meta_model/manager_base.ttxt +2 -0
- data/app/tanuki/meta_model/meta_model.rb +3 -0
- data/app/tanuki/meta_model/model.ttxt +2 -0
- data/app/tanuki/meta_model/model_base.ttxt +12 -0
- data/app/tanuki/model/model.rb +3 -0
- data/app/tanuki/page/missing/default.thtml +61 -2
- data/app/user/page/index/default.thtml +120 -120
- data/app/user/page/index/index.rb +1 -1
- data/bin/tanuki +185 -53
- data/config/common.rb +7 -0
- data/config/common_application.rb +31 -0
- data/config/development_application.rb +8 -0
- data/config/production_application.rb +2 -0
- data/lib/tanuki/application.rb +15 -19
- data/lib/tanuki/argument/base.rb +2 -2
- data/lib/tanuki/argument/integer.rb +2 -2
- data/lib/tanuki/argument/integer_range.rb +3 -3
- data/lib/tanuki/argument/string.rb +2 -2
- data/lib/tanuki/argument.rb +3 -3
- data/lib/tanuki/{controller_behavior.rb → behavior/controller_behavior.rb} +22 -21
- data/lib/tanuki/behavior/meta_model_behavior.rb +43 -0
- data/lib/tanuki/behavior/model_behavior.rb +112 -0
- data/lib/tanuki/{object_behavior.rb → behavior/object_behavior.rb} +6 -6
- data/lib/tanuki/configurator.rb +39 -76
- data/lib/tanuki/context.rb +31 -19
- data/lib/tanuki/{module_extensions.rb → extensions/module.rb} +3 -3
- data/lib/tanuki/extensions/object.rb +12 -0
- data/lib/tanuki/extensions/rack/static_dir.rb +18 -0
- data/lib/tanuki/i18n.rb +3 -1
- data/lib/tanuki/launcher.rb +3 -2
- data/lib/tanuki/loader.rb +37 -46
- data/lib/tanuki/template_compiler.rb +8 -7
- data/lib/tanuki/version.rb +1 -1
- data/lib/tanuki.rb +14 -8
- data/schema/tanuki/models/controller.yml +2 -3
- data/schema/tanuki/models/page.yml +7 -8
- metadata +35 -27
- data/app/tanuki/object/object.rb +0 -3
data/lib/tanuki/configurator.rb
CHANGED
@@ -4,90 +4,53 @@ module Tanuki
|
|
4
4
|
# Use Tanuki::development_application and Tanuki::production_application to create such a block.
|
5
5
|
class Configurator
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def set(option, value)
|
18
|
-
Application.set(option, value)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Invokes Tanuki::Application.use.
|
22
|
-
def use(middleware, *args, &block)
|
23
|
-
Application.use(middleware, *args, &block)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Invokes Tanuki::Application.discard.
|
27
|
-
def discard(middleware)
|
28
|
-
Application.discard(middleware)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Invokes Tanuki::Application.visitor.
|
32
|
-
def visitor(sym, &block)
|
33
|
-
Application.visitor(sym, &block)
|
34
|
-
end
|
7
|
+
# Configuration root.
|
8
|
+
attr_writer :config_root
|
9
|
+
|
10
|
+
# Creates a new configurator in context +ctx+ and +root+ directory.
|
11
|
+
# Configuration root +config_root+ defaults to _config_ directory in +root+.
|
12
|
+
def initialize(ctx, root, config_root=nil)
|
13
|
+
@context = ctx
|
14
|
+
set :root, root ? root : Dir.pwd
|
15
|
+
@config_root = config_root ? config_root : File.join(@context.root, 'config')
|
16
|
+
end
|
35
17
|
|
36
|
-
|
18
|
+
# Loads and executes a given configuraion file with symbolic name +config+.
|
19
|
+
# If +silent+ is +true+, exception is not raised on missing file.
|
20
|
+
def load_config(config, silent=false)
|
21
|
+
file = File.join(@config_root, config.to_s) << '.rb'
|
22
|
+
return if silent && !(File.file? file)
|
23
|
+
instance_eval File.read(file)
|
24
|
+
true
|
25
|
+
end
|
37
26
|
|
38
|
-
|
27
|
+
private
|
39
28
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
Application.instance_eval do
|
44
|
-
use Rack::CommonLogger
|
45
|
-
use Rack::Lint
|
46
|
-
use Rack::Reloader, 0
|
47
|
-
use Rack::ShowExceptions
|
29
|
+
# Invokes Tanuki::Argument::store.
|
30
|
+
def argument(klass, arg_class)
|
31
|
+
Argument.store(klass, arg_class)
|
48
32
|
end
|
49
|
-
common_application(&block)
|
50
|
-
end
|
51
33
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
34
|
+
# Sets an +option+ to +value+ in the current context.
|
35
|
+
def set(option, value)
|
36
|
+
@context.send("#{option}=".to_sym, value)
|
37
|
+
end
|
57
38
|
|
58
|
-
|
39
|
+
# Invokes Tanuki::Application::use.
|
40
|
+
def use(middleware, *args, &block)
|
41
|
+
Application.use(middleware, *args, &block)
|
42
|
+
end
|
59
43
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
use Rack::Head
|
64
|
-
use Rack::ShowStatus
|
65
|
-
set :server, [:thin, :mongrel, :webrick]
|
66
|
-
set :host, '0.0.0.0'
|
67
|
-
set :port, 3000
|
68
|
-
set :root, File.expand_path('..', $0)
|
69
|
-
set :app_root, proc { File.join(root, 'app') }
|
70
|
-
set :cache_root, proc { File.join(root, 'cache') }
|
71
|
-
set :schema_root, proc { File.join(root, 'schema') }
|
72
|
-
set :root_page, ::User_Page_Index
|
73
|
-
set :missing_page, ::Tanuki_Page_Missing
|
74
|
-
set :i18n, false
|
75
|
-
set :language, nil
|
76
|
-
set :language_fallback, {}
|
77
|
-
set :languages, proc { language_fallback.keys }
|
78
|
-
set :best_language, proc {|lngs| language_fallback[language].each {|lng| return lng if lngs.include? lng }; nil }
|
79
|
-
set :best_translation, proc {|trn| language_fallback[language].each {|lng| return trn[lng] if trn.include? lng }; nil }
|
80
|
-
visitor :string do s = ''; proc {|out| s << out.to_s } end
|
44
|
+
# Invokes Tanuki::Application::discard.
|
45
|
+
def discard(middleware)
|
46
|
+
Application.discard(middleware)
|
81
47
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
store String, Argument::String
|
48
|
+
|
49
|
+
# Invokes Tanuki::Application::visitor.
|
50
|
+
def visitor(sym, &block)
|
51
|
+
Application.visitor(sym, &block)
|
87
52
|
end
|
88
|
-
|
89
|
-
|
90
|
-
Application.run
|
91
|
-
end
|
53
|
+
|
54
|
+
end # end Configurator
|
92
55
|
|
93
56
|
end # end Tanuki
|
data/lib/tanuki/context.rb
CHANGED
@@ -1,36 +1,48 @@
|
|
1
1
|
module Tanuki
|
2
2
|
|
3
3
|
# Tanuki::Context is used to create unique environments for each request.
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# Use Tanuki::Context#child to create new contexts.
|
4
|
+
# Child contexts inherit parent context entries and can override them without modifying the parent context.
|
5
|
+
# Use Tanuki::Context::child to create new contexts.
|
7
6
|
class Context
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
@_defined = {}
|
9
|
+
|
10
|
+
# Creates and returns child context object.
|
11
|
+
# This object's superclass is going to be current context class.
|
12
|
+
def self.child
|
13
|
+
child = Class.new(self)
|
14
|
+
child.instance_variable_set(:@_defined, {})
|
15
|
+
child
|
12
16
|
end
|
13
17
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
# Allowes arbitary values to be assigned to context with a +key=+ method.
|
19
|
+
# A reader in context object class is created for each assigned value.
|
20
|
+
def self.method_missing(sym, arg=nil)
|
21
|
+
match = sym.to_s.match(/\A(?!(?:child|method_missing)=\Z)([^=]+)(=)?\Z/)
|
22
|
+
raise "`#{sym}' method cannot be called for Context and its descendants" unless match
|
23
|
+
defined = @_defined
|
24
|
+
class << self; self; end.instance_eval do
|
18
25
|
method_sym = match[1].to_sym
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
if defined.include? method_sym
|
27
|
+
undef_method method_sym
|
28
|
+
else
|
29
|
+
defined[method_sym] = nil
|
30
|
+
end
|
31
|
+
if arg.is_a? Proc
|
32
|
+
define_method(method_sym, &arg)
|
26
33
|
else
|
27
|
-
|
34
|
+
define_method(method_sym) { arg }
|
28
35
|
end
|
36
|
+
return arg
|
29
37
|
end if match[2]
|
30
|
-
warn "#{__FILE__}:#{__LINE__}: warning: undefined context entry `#{sym}' for #{self}"
|
31
38
|
super
|
32
39
|
end
|
33
40
|
|
41
|
+
# Disallow context instantiation
|
42
|
+
def self.new
|
43
|
+
raise "contexts cannot be instantiated"
|
44
|
+
end
|
45
|
+
|
34
46
|
end # end Context
|
35
47
|
|
36
48
|
end # end Tanuki
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class Module
|
2
2
|
|
3
|
-
# Creates a reader +sym+ and a writer +sym=+ for the instance variable
|
3
|
+
# Creates a reader +sym+ and a writer +sym=+ for the instance variable @_sym.
|
4
4
|
def internal_attr_accessor(*syms)
|
5
5
|
internal_attr_reader(*syms)
|
6
6
|
internal_attr_writer(*syms)
|
7
7
|
end
|
8
8
|
|
9
|
-
# Creates a reader +sym+ for the instance variable
|
9
|
+
# Creates a reader +sym+ for the instance variable @_sym.
|
10
10
|
def internal_attr_reader(*syms)
|
11
11
|
syms.each do |sym|
|
12
12
|
ivar = "@_#{sym}".to_sym
|
@@ -15,7 +15,7 @@ class Module
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
# Creates a writer +sym=+ for the instance variable
|
18
|
+
# Creates a writer +sym=+ for the instance variable @_sym.
|
19
19
|
def internal_attr_writer(*syms)
|
20
20
|
syms.each do |sym|
|
21
21
|
ivar = "@_#{sym}".to_sym
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
# Runs Tanuki::Loader for every missing constant in main namespace.
|
4
|
+
def self.const_missing(sym)
|
5
|
+
unless (paths = Dir.glob(Tanuki::Loader.combined_class_path(sym))).empty?
|
6
|
+
paths.reverse_each {|path| require path }
|
7
|
+
return const_get(sym)
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
end # end Object
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rack
|
2
|
+
class StaticDir
|
3
|
+
|
4
|
+
# Initializes a +Rack::File+ server at +root+ or +Dir.pwd+.
|
5
|
+
def initialize(app, root=nil)
|
6
|
+
@app = app
|
7
|
+
@file_server = Rack::File.new(root || Dir.pwd)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns file contents, if requested file exists.
|
11
|
+
def call(env)
|
12
|
+
result = @file_server.call(env)
|
13
|
+
return result if result[0] == 200
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
end # end
|
18
|
+
end # end Rack
|
data/lib/tanuki/i18n.rb
CHANGED
@@ -7,12 +7,14 @@ module Tanuki
|
|
7
7
|
|
8
8
|
# Adds language routes of root controller class when invoked.
|
9
9
|
def configure
|
10
|
+
raise 'languages are not configured' if @_ctx.languages.size == 0
|
10
11
|
root_page = @_ctx.root_page
|
11
12
|
@_ctx.languages.each {|lng| has_child root_page, lng }
|
12
13
|
end
|
13
14
|
|
14
15
|
# Returns default route according to default language.
|
15
16
|
def default_route
|
17
|
+
raise 'default language is not configured' unless @_ctx.language
|
16
18
|
{:route => @_ctx.language.to_s, :args => {}}
|
17
19
|
end
|
18
20
|
|
@@ -21,7 +23,7 @@ module Tanuki
|
|
21
23
|
@_visual_child.default_view
|
22
24
|
end
|
23
25
|
|
24
|
-
# Adds child language to its context.
|
26
|
+
# Adds child controller language to its context.
|
25
27
|
def process_child_context(ctx, route)
|
26
28
|
ctx = ctx.child
|
27
29
|
ctx.language = route.to_sym
|
data/lib/tanuki/launcher.rb
CHANGED
@@ -2,15 +2,16 @@ module Tanuki
|
|
2
2
|
|
3
3
|
# Tanuki::Launcher is called on every request.
|
4
4
|
# It is used to build output starting with the default view of the root controller.
|
5
|
+
# Rack iterates over an instance of this object on every request.
|
5
6
|
class Launcher
|
6
7
|
|
7
|
-
# Creates a new Tanuki::Launcher with root controller ctrl in context ctx
|
8
|
+
# Creates a new Tanuki::Launcher with root controller +ctrl+ in context +ctx+.
|
8
9
|
def initialize(ctrl, ctx)
|
9
10
|
@ctrl = ctrl
|
10
11
|
@ctx = ctx
|
11
12
|
end
|
12
13
|
|
13
|
-
# Passes a given block to the requested page template tree.
|
14
|
+
# Passes a given +block+ to the requested page template tree.
|
14
15
|
def each(&block)
|
15
16
|
@ctrl.default_view.call(proc {|out| block.call(out.to_s) }, @ctx)
|
16
17
|
end
|
data/lib/tanuki/loader.rb
CHANGED
@@ -5,30 +5,46 @@ module Tanuki
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
8
|
-
# Returns the path to a source file containing class klass
|
9
|
-
def class_path(klass)
|
10
|
-
path = const_to_path(klass,
|
8
|
+
# Returns the path to a source file in +root+ containing class +klass+.
|
9
|
+
def class_path(klass, root)
|
10
|
+
path = const_to_path(klass, root)
|
11
11
|
File.join(path, path.match("#{File::SEPARATOR}([^#{File::SEPARATOR}]*)$")[1] << '.rb')
|
12
12
|
end
|
13
13
|
|
14
|
+
# Returns the path to a source file containing class +klass+.
|
15
|
+
# Seatches across all common roots.
|
16
|
+
def combined_class_path(klass)
|
17
|
+
class_path(klass, @app_root ||= combined_app_root)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a glob pattern of all common roots.
|
21
|
+
def combined_app_root
|
22
|
+
local_app_root = File.expand_path(File.join('..', '..', '..', 'app'), __FILE__)
|
23
|
+
app_root = "{#{context_app_root = @context.app_root},#{@context.gen_root}"
|
24
|
+
app_root << ",#{local_app_root}" if local_app_root != context_app_root
|
25
|
+
app_root << '}'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Assigns a context to Tanuki::Loader.
|
29
|
+
# This context should have common framework paths defined in it.
|
14
30
|
def context=(ctx)
|
15
31
|
@context = ctx
|
16
32
|
end
|
17
33
|
|
18
|
-
# Checks if templates contain a compiled template sym for class klass
|
34
|
+
# Checks if +templates+ contain a compiled template +sym+ for class +klass+.
|
19
35
|
def has_template?(templates, klass, sym)
|
20
36
|
templates.include? "#{klass}##{sym}"
|
21
37
|
end
|
22
38
|
|
23
|
-
# Runs template sym from obj
|
39
|
+
# Runs template +sym+ with optional +args+ and +block+ from object +obj+.
|
40
|
+
#
|
24
41
|
# Template is recompiled from source on two conditions:
|
25
42
|
# * template source modification time is older than compiled template modification time,
|
26
43
|
# * Tanuki::TemplateCompiler source modification time is older than compiled template modification time.
|
27
44
|
def run_template(templates, obj, sym, *args, &block)
|
28
|
-
st_path =
|
45
|
+
owner, st_path = *template_owner(obj.class, sym)
|
29
46
|
if st_path
|
30
|
-
|
31
|
-
ct_path = compiled_template_path(obj.class, sym)
|
47
|
+
ct_path = compiled_template_path(owner, sym)
|
32
48
|
ct_file_exists = File.file?(ct_path)
|
33
49
|
ct_file_mtime = ct_file_exists ? File.mtime(ct_path) : nil
|
34
50
|
st_file = File.new(st_path, 'r:UTF-8')
|
@@ -55,14 +71,14 @@ module Tanuki
|
|
55
71
|
private
|
56
72
|
|
57
73
|
# Path to Tanuki::TemplateCompiler for internal use.
|
58
|
-
COMPILER_PATH = File.
|
74
|
+
COMPILER_PATH = File.expand_path(File.join('..', 'template_compiler.rb'), __FILE__)
|
59
75
|
|
60
76
|
# Extension glob for template files.
|
61
77
|
TEMPLATE_EXT = '.t{html,txt}'
|
62
78
|
|
63
|
-
# Compiles template sym from owner class using source in st_file to ct_path
|
79
|
+
# Compiles template +sym+ from +owner+ class using source in +st_file+ to +ct_path+.
|
64
80
|
# Compilation is only done if destination file modification time has not changed
|
65
|
-
# (is equal to ct_file_mtime) since file locking was initiated.
|
81
|
+
# (is equal to +ct_file_mtime+) since file locking was initiated.
|
66
82
|
def compile_template(st_file, ct_path, ct_file_mtime, owner, sym)
|
67
83
|
no_refresh = true
|
68
84
|
st_file.flock(File::LOCK_EX)
|
@@ -79,53 +95,28 @@ module Tanuki
|
|
79
95
|
no_refresh
|
80
96
|
end
|
81
97
|
|
82
|
-
# Returns the path to a compiled template file containing template method_name for class klass
|
98
|
+
# Returns the path to a compiled template file containing template +method_name+ for class +klass+.
|
83
99
|
def compiled_template_path(klass, method_name)
|
84
|
-
File.join(const_to_path(klass, @context.
|
85
|
-
end
|
86
|
-
|
87
|
-
# Transforms a given constant klass to path with a given root and separated by sep.
|
88
|
-
def const_to_path(klass, root, sep)
|
89
|
-
File.join(root, klass.to_s.split('_').map {|item| item.gsub(/(?!^)([A-Z])/, '_\1') }.join(sep).downcase)
|
100
|
+
File.join(const_to_path(klass, @context.gen_root), method_name.to_s << '.tpl.rb')
|
90
101
|
end
|
91
102
|
|
92
|
-
#
|
93
|
-
def
|
94
|
-
|
103
|
+
# Transforms a given constant +klass+ to a path with a given +root+.
|
104
|
+
def const_to_path(klass, root)
|
105
|
+
File.join(root, klass.to_s.split('_').map {|item| item.gsub(/(?!^)([A-Z])/, '_\1') }.join(File::SEPARATOR).downcase)
|
95
106
|
end
|
96
107
|
|
97
|
-
# Finds the direct template method_name owner among ancestors of class klass
|
108
|
+
# Finds the direct template +method_name+ owner among ancestors of class +klass+.
|
98
109
|
def template_owner(klass, method_name)
|
99
110
|
method_file = method_name.to_s << TEMPLATE_EXT
|
100
111
|
klass.ancestors.each do |ancestor|
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
end
|
105
|
-
nil
|
106
|
-
end
|
107
|
-
|
108
|
-
# Returns the path to a file containing template method_name for class klass.
|
109
|
-
# This is done with a given root, extension ext, and separated by sep.
|
110
|
-
def template_path(klass, method_name, root, sep, ext)
|
111
|
-
if owner = template_owner(klass, method_name)
|
112
|
-
return Dir.glob(File.join(const_to_path(owner, root, sep), method_name.to_s << ext))[0]
|
112
|
+
files = Dir.glob(File.join(const_to_path(ancestor, @app_root ||= combined_app_root), method_file))
|
113
|
+
return ancestor, files[0] unless files.empty?
|
113
114
|
end
|
114
|
-
nil
|
115
|
+
[nil, nil]
|
115
116
|
end
|
116
117
|
|
117
118
|
end # end class << self
|
118
119
|
|
119
120
|
end # end Path
|
120
121
|
|
121
|
-
end # end Tanuki
|
122
|
-
|
123
|
-
|
124
|
-
# Runs Tanuki::Loader for every missing constant in main namespace.
|
125
|
-
def Object.const_missing(sym)
|
126
|
-
if File.file?(path = Tanuki::Loader.class_path(sym))
|
127
|
-
require path
|
128
|
-
return const_get(sym)
|
129
|
-
end
|
130
|
-
super
|
131
|
-
end
|
122
|
+
end # end Tanuki
|
@@ -5,7 +5,7 @@ module Tanuki
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
8
|
-
# Compiles a template from a given src string to ios for method sym in class klass
|
8
|
+
# Compiles a template from a given +src+ string to +ios+ for method +sym+ in class +klass+.
|
9
9
|
def compile_template(ios, src, klass, sym)
|
10
10
|
ios << "# encoding: #{src.encoding}\nclass #{klass}\ndef #{sym}_view(*args,&block)\nproc do|_,ctx|\n" \
|
11
11
|
"if _has_tpl ctx,self.class,:#{sym}\nctx=_ctx(ctx)"
|
@@ -14,7 +14,7 @@ module Tanuki
|
|
14
14
|
ios << "\nelse\n(_run_tpl ctx,self,:#{sym},*args,&block).call(_,ctx)\nend\nend\nend\nend"
|
15
15
|
end
|
16
16
|
|
17
|
-
# Compiles code from a given src string to ios
|
17
|
+
# Compiles code from a given +src+ string to +ios+.
|
18
18
|
def compile(ios, src)
|
19
19
|
state = :outer
|
20
20
|
last_state = nil
|
@@ -68,9 +68,10 @@ module Tanuki
|
|
68
68
|
# Scanner states that output the evaluated result.
|
69
69
|
PRINT_STATES = [:outer, :code_print]
|
70
70
|
|
71
|
+
# Generates code for Ruby template bits from a given +src+ to +ios+ for a given +state+.
|
71
72
|
def process_code_state(ios, src, state)
|
72
73
|
src.strip!
|
73
|
-
src.gsub!
|
74
|
+
src.gsub!(/^[ \t]+/, '')
|
74
75
|
case state
|
75
76
|
when :code_line, :code_span then
|
76
77
|
ios << "\n#{src}"
|
@@ -79,14 +80,14 @@ module Tanuki
|
|
79
80
|
when :code_template then
|
80
81
|
ios << "\n(#{src}).call(_,ctx)"
|
81
82
|
when :code_visitor
|
82
|
-
inner_m = src.match
|
83
|
+
inner_m = src.match(/^([^ \(]+)?(\([^\)]*\))?\s*(.*)$/)
|
83
84
|
ios << "\n#{inner_m[1]}_result=(#{inner_m[3]}).call(#{inner_m[1]}_visitor#{inner_m[2]},ctx)"
|
84
85
|
when :l10n then
|
85
86
|
localize(ios, src)
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
# Returns the next expected pattern for a given state
|
90
|
+
# Returns the next expected pattern for a given +state+.
|
90
91
|
def expect_pattern(state)
|
91
92
|
case state
|
92
93
|
when :outer then %r{^\s*%%?|<%[=!_#%]?|<l10n>}
|
@@ -96,7 +97,7 @@ module Tanuki
|
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
99
|
-
# Returns the next state for a given match and
|
100
|
+
# Returns the next state for a given +match+ and a given +state+.
|
100
101
|
def next_state(state, match)
|
101
102
|
case state
|
102
103
|
when :outer then
|
@@ -121,7 +122,7 @@ module Tanuki
|
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
124
|
-
# Generates localization code from src
|
125
|
+
# Generates localization code from +src+ to +ios+.
|
125
126
|
def localize(ios, src)
|
126
127
|
index = 0
|
127
128
|
lngs = []
|
data/lib/tanuki/version.rb
CHANGED
data/lib/tanuki.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$:.unshift(libdir) unless $:.include?(libdir)
|
4
|
-
end
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
5
3
|
|
6
4
|
require 'rack'
|
7
5
|
require 'fileutils'
|
6
|
+
require 'sequel'
|
8
7
|
require 'yaml'
|
9
8
|
require 'escape_utils'
|
10
9
|
require 'escape_utils/url/rack'
|
11
10
|
require 'tanuki/version'
|
12
|
-
require 'tanuki/
|
11
|
+
require 'tanuki/extensions/module'
|
12
|
+
require 'tanuki/extensions/object'
|
13
|
+
require 'tanuki/extensions/rack/static_dir'
|
14
|
+
require 'tanuki/behavior/controller_behavior'
|
15
|
+
require 'tanuki/behavior/meta_model_behavior'
|
16
|
+
require 'tanuki/behavior/model_behavior'
|
17
|
+
require 'tanuki/behavior/object_behavior'
|
13
18
|
require 'tanuki/argument'
|
14
19
|
require 'tanuki/configurator'
|
15
20
|
require 'tanuki/context'
|
16
|
-
require 'tanuki/controller_behavior'
|
17
21
|
require 'tanuki/launcher'
|
18
22
|
require 'tanuki/loader'
|
19
23
|
require 'tanuki/i18n'
|
20
|
-
require 'tanuki/object_behavior'
|
21
24
|
require 'tanuki/template_compiler'
|
22
|
-
require 'tanuki/application'
|
25
|
+
require 'tanuki/application'
|
26
|
+
|
27
|
+
module Tanuki
|
28
|
+
end
|
@@ -3,13 +3,12 @@ namespaces:
|
|
3
3
|
default: Tanuki
|
4
4
|
source:
|
5
5
|
table: tanuki_pages
|
6
|
-
|
7
|
-
|
8
|
-
to_s: [tp.long_title, tp.title]
|
6
|
+
key: id
|
7
|
+
to_s: [long_title, title]
|
9
8
|
order:
|
10
9
|
by:
|
11
|
-
|
12
|
-
|
10
|
+
parent_id: asc
|
11
|
+
order: asc
|
13
12
|
reorder: tp.order
|
14
13
|
attributes:
|
15
14
|
parent: { type: Object, required: true }
|
@@ -28,9 +27,9 @@ relations:
|
|
28
27
|
type: one-to-many
|
29
28
|
inverse: children
|
30
29
|
join:
|
31
|
-
alias:
|
30
|
+
alias: tp
|
32
31
|
on:
|
33
|
-
|
32
|
+
tp.id: parent_id
|
34
33
|
controller:
|
35
34
|
class: Controller
|
36
35
|
type: one-to-many
|
@@ -38,7 +37,7 @@ relations:
|
|
38
37
|
join:
|
39
38
|
alias: tc
|
40
39
|
on:
|
41
|
-
tc.id:
|
40
|
+
tc.id: parent_id
|
42
41
|
list:
|
43
42
|
parent: ~
|
44
43
|
title: { link: true }
|