theme 0.0.1 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.gems +8 -0
- data/.gitignore +2 -0
- data/Makefile +44 -0
- data/lib/theme/assets/middleware.rb +133 -0
- data/lib/theme/assets/render.rb +45 -0
- data/lib/theme/assets.rb +82 -0
- data/lib/theme/component.rb +103 -0
- data/lib/theme/event.rb +13 -0
- data/lib/theme/events.rb +66 -0
- data/lib/theme/file.rb +52 -0
- data/lib/theme/mab.rb +5 -0
- data/lib/theme/middleware.rb +59 -0
- data/lib/theme/version.rb +1 -1
- data/lib/theme.rb +144 -2
- data/test/dummy/components/header.rb +62 -0
- data/test/dummy/components/some_component.rb +3 -0
- data/test/dummy/index.html +386 -0
- data/test/events_test.rb +30 -0
- data/test/helper.rb +5 -0
- data/test/theme_test.rb +56 -0
- data/theme.gemspec +5 -2
- metadata +76 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 254228666c499ec52897053c19a69dc1ac3cf10c
|
4
|
+
data.tar.gz: ecc08329901e61dcdbbae73a82a1ee87f7c342a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc532e11312b41cbbd2e0aa1bffeab09937543308aa0dddc5c6d56965233cf7ebe859e268be11130e41b7fd1ee409ef7340cc6aef7b5c221e724c0d57f43fa05
|
7
|
+
data.tar.gz: 56a8e8f3c276a3848ee5e6973de0edfe1ddeabb5b7d01da8175015fa40a512b9a660b1e8b519ea243a06603ccfbbbd97fdd21b3162103057fdec7a32d33eb161
|
data/.gems
ADDED
data/.gitignore
CHANGED
data/Makefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
GEMSPEC=$(shell ls *.gemspec | head -1)
|
2
|
+
VERSION=$(shell ruby -rubygems -e 'puts Gem::Specification.load("$(GEMSPEC)").version')
|
3
|
+
PROJECT=$(shell ruby -rubygems -e 'puts Gem::Specification.load("$(GEMSPEC)").name')
|
4
|
+
GEM=$(PROJECT)-$(VERSION).gem
|
5
|
+
|
6
|
+
.PHONY: install package publish test server $(GEM)
|
7
|
+
|
8
|
+
define install_bs
|
9
|
+
which bs || (wget https://raw.githubusercontent.com/educabilia/bs/master/bin/bs && chmod +x bs && sudo mv bs /usr/local/bin)
|
10
|
+
|
11
|
+
@if [ -s .gs ]; then \
|
12
|
+
true; \
|
13
|
+
else \
|
14
|
+
mkdir .gs; \
|
15
|
+
touch .env; \
|
16
|
+
echo 'GEM_HOME=$$(pwd)/.gs' >> .env; \
|
17
|
+
echo 'GEM_PATH=$$(pwd)/.gs' >> .env; \
|
18
|
+
echo 'PATH=$$(pwd)/.gs/bin:$$PATH' >> .env; \
|
19
|
+
echo 'RACK_ENV=development' >> .env; \
|
20
|
+
fi;
|
21
|
+
|
22
|
+
bs gem list dep-cj -i || bs gem install dep-cj
|
23
|
+
bs gem list cutest-cj -i || bs gem install cutest-cj
|
24
|
+
bs gem list pry -i || bs gem install pry
|
25
|
+
bs gem list awesome_print -i || bs gem install awesome_print
|
26
|
+
endef
|
27
|
+
|
28
|
+
install:
|
29
|
+
$(call install_bs)
|
30
|
+
bs dep install
|
31
|
+
bs gem cleanup
|
32
|
+
|
33
|
+
test:
|
34
|
+
bs env $$(cat .env.test) cutest test/**/*_test.rb
|
35
|
+
|
36
|
+
package: $(GEM)
|
37
|
+
|
38
|
+
# Always build the gem
|
39
|
+
$(GEM):
|
40
|
+
gem build $(PROJECT).gemspec
|
41
|
+
|
42
|
+
publish: $(GEM)
|
43
|
+
gem push $(GEM)
|
44
|
+
make clean
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rack/mime'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Theme
|
5
|
+
module Assets
|
6
|
+
class Middleware
|
7
|
+
attr_reader :app, :env, :res
|
8
|
+
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call env
|
14
|
+
dup.call! env
|
15
|
+
end
|
16
|
+
|
17
|
+
def call! env
|
18
|
+
@env = env
|
19
|
+
|
20
|
+
if assets_path
|
21
|
+
render_assets
|
22
|
+
else
|
23
|
+
res
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def res
|
30
|
+
@res ||= begin
|
31
|
+
if not assets_path
|
32
|
+
app.call(req.env)
|
33
|
+
else
|
34
|
+
Cuba::Response.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def req
|
40
|
+
@req ||= Rack::Request.new env
|
41
|
+
end
|
42
|
+
|
43
|
+
def assets_path
|
44
|
+
path[Regexp.new("^#{Theme.config.asset_url}($|.*)")]
|
45
|
+
end
|
46
|
+
|
47
|
+
def path
|
48
|
+
env['PATH_INFO']
|
49
|
+
end
|
50
|
+
|
51
|
+
def type
|
52
|
+
if matched = path.match(/(?<=#{Theme.config.asset_url}\/).*(?=\/)/)
|
53
|
+
matched[0]
|
54
|
+
else
|
55
|
+
''
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def name
|
60
|
+
@name ||= begin
|
61
|
+
cleaned = path.gsub(/\.#{ext}$/, '')
|
62
|
+
cleaned = cleaned.gsub(/^#{Theme.config.asset_url}\//, '')
|
63
|
+
cleaned = cleaned.gsub(/^#{type}\//, '')
|
64
|
+
cleaned
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def ext
|
69
|
+
if matched = path.match(/(?<=\.).*$/)
|
70
|
+
matched[0]
|
71
|
+
else
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def render_assets
|
77
|
+
case type
|
78
|
+
when 'css', 'stylesheet', 'stylesheets'
|
79
|
+
content_type = 'text/css; charset=utf-8'
|
80
|
+
when 'js', 'javascript', 'javascripts'
|
81
|
+
content_type = 'text/javascript; charset=utf-8'
|
82
|
+
else
|
83
|
+
content_type = Rack::Mime.mime_type ext
|
84
|
+
end
|
85
|
+
|
86
|
+
res.headers.merge!({
|
87
|
+
"Content-Type" => content_type,
|
88
|
+
"Cache-Control" => 'public, max-age=2592000, no-transform',
|
89
|
+
'Connection' => 'keep-alive',
|
90
|
+
'Age' => '25637',
|
91
|
+
'Strict-Transport-Security' => 'max-age=31536000',
|
92
|
+
'Content-Disposition' => 'inline'
|
93
|
+
})
|
94
|
+
|
95
|
+
if name == "all-#{sha}"
|
96
|
+
@name = 'dominate-compiled'
|
97
|
+
res.write render_single_file
|
98
|
+
elsif name == 'all'
|
99
|
+
res.write render_all_files
|
100
|
+
else
|
101
|
+
res.write render_single_file
|
102
|
+
end
|
103
|
+
|
104
|
+
res.finish
|
105
|
+
end
|
106
|
+
|
107
|
+
def render_all_files
|
108
|
+
content = ''
|
109
|
+
files = Theme.config.assets[ext]
|
110
|
+
path = "#{Theme.config.asset_path}/#{type}"
|
111
|
+
|
112
|
+
files.each do |file|
|
113
|
+
if file[/^http/]
|
114
|
+
content += open(file).string
|
115
|
+
else
|
116
|
+
content += Theme.load_file("#{path}/#{file}")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
content
|
121
|
+
end
|
122
|
+
|
123
|
+
def render_single_file
|
124
|
+
path = "#{Theme.config.asset_path}/#{type}"
|
125
|
+
Theme.load_file "#{path}/#{name}.#{ext}"
|
126
|
+
end
|
127
|
+
|
128
|
+
def sha
|
129
|
+
Thread.current[:_sha] ||= (Theme.config.sha || `git rev-parse HEAD`.strip)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Theme
|
2
|
+
module Assets
|
3
|
+
module Render
|
4
|
+
def self.setup app
|
5
|
+
app.settings[:render] ||= {}
|
6
|
+
load_engines
|
7
|
+
end
|
8
|
+
|
9
|
+
def view file, options = {}
|
10
|
+
path = "#{settings[:render][:views] || Theme.config.view_path}"
|
11
|
+
Theme.load_file "#{path}/#{file}", options, self
|
12
|
+
end
|
13
|
+
|
14
|
+
def render file, options = {}
|
15
|
+
path = "#{settings[:render][:views] || Theme.config.view_path}"
|
16
|
+
layout_path = settings[:layout_path] || Theme.config.layout_path
|
17
|
+
layout = "#{layout_path}/#{settings[:render][:layout] || Theme.config.layout}"
|
18
|
+
content = Theme.load_file "#{path}/#{file}", options, self
|
19
|
+
options[:content] = content
|
20
|
+
Theme.load_file layout, options, self
|
21
|
+
end
|
22
|
+
|
23
|
+
def partial file, options = {}
|
24
|
+
file.gsub! PARTIAL_REGEX, '_\1'
|
25
|
+
path = "#{settings[:render][:views] || Theme.config.view_path}"
|
26
|
+
Theme.load_file "#{path}/#{file}", options, self
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.load_engines
|
32
|
+
if defined? Slim
|
33
|
+
Slim::Engine.set_default_options \
|
34
|
+
disable_escape: true,
|
35
|
+
use_html_safe: true,
|
36
|
+
disable_capture: false
|
37
|
+
|
38
|
+
if ENV['RACK_ENV'] == 'development'
|
39
|
+
Slim::Engine.set_default_options pretty: true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/theme/assets.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'theme/mab'
|
2
|
+
|
3
|
+
module Theme
|
4
|
+
module Assets
|
5
|
+
autoload :Middleware, 'theme/assets/middleware'
|
6
|
+
autoload :Render, 'theme/assets/render'
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def setup app
|
10
|
+
app.plugin Render
|
11
|
+
app.use Middleware
|
12
|
+
end
|
13
|
+
|
14
|
+
def css_assets options = {}
|
15
|
+
options = {
|
16
|
+
'data-turbolinks-track' => 'true',
|
17
|
+
rel: 'stylesheet',
|
18
|
+
type: 'text/css',
|
19
|
+
media: 'all'
|
20
|
+
}.merge options
|
21
|
+
|
22
|
+
url = Theme.config.asset_url
|
23
|
+
|
24
|
+
if Theme.config.assets_compiled
|
25
|
+
options[:href] = "#{url}/css/all-#{sha}.css"
|
26
|
+
else
|
27
|
+
options[:href] = "#{url}/css/all.css"
|
28
|
+
end
|
29
|
+
|
30
|
+
mab { link options }
|
31
|
+
end
|
32
|
+
|
33
|
+
def js_assets options = {}
|
34
|
+
options = {
|
35
|
+
'data-turbolinks-track' => 'true',
|
36
|
+
}.merge options
|
37
|
+
|
38
|
+
url = Theme.config.asset_url
|
39
|
+
|
40
|
+
if Theme.config.assets_compiled
|
41
|
+
options[:src] = "#{url}/js/all-#{sha}.js"
|
42
|
+
else
|
43
|
+
options[:src] = "#{url}/js/all.js"
|
44
|
+
end
|
45
|
+
|
46
|
+
mab { script options }
|
47
|
+
end
|
48
|
+
|
49
|
+
def compile
|
50
|
+
Theme.config.assets.to_h.each do |type, assets|
|
51
|
+
content = ''
|
52
|
+
|
53
|
+
if assets.length > 0
|
54
|
+
type_path = "#{Theme.config.asset_path}/#{Theme.config[:"asset_#{type}_folder"]}"
|
55
|
+
assets.each do |file|
|
56
|
+
path = "#{type_path}/#{file}"
|
57
|
+
content += Theme.load_file path
|
58
|
+
end
|
59
|
+
tmp_path = "#{type_path}/tmp.dominate-compiled.#{type}"
|
60
|
+
File.write tmp_path, content
|
61
|
+
system "minify #{tmp_path} > #{type_path}/dominate-compiled.#{type}"
|
62
|
+
File.delete tmp_path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def css_assets options = {}
|
69
|
+
Theme::Assets.css_assets options
|
70
|
+
end
|
71
|
+
|
72
|
+
def js_assets options = {}
|
73
|
+
Theme::Assets.js_assets options
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def sha
|
79
|
+
Thread.current[:_sha] ||= (Theme.config.sha || `git rev-parse HEAD`.strip)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'hashr'
|
3
|
+
|
4
|
+
Hashr.raise_missing_keys = true
|
5
|
+
|
6
|
+
module Theme
|
7
|
+
class Component < SimpleDelegator
|
8
|
+
include Theme::Events
|
9
|
+
|
10
|
+
attr_reader :instance
|
11
|
+
|
12
|
+
def initialize instance = false
|
13
|
+
@instance = instance
|
14
|
+
@node = self.class.node.clone if self.class.node
|
15
|
+
@name = self.class.name
|
16
|
+
|
17
|
+
instance.instance_variables.each do |name|
|
18
|
+
instance_variable_set name, instance.instance_variable_get(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
super instance
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_reader :html, :path, :id
|
26
|
+
attr_accessor :node
|
27
|
+
|
28
|
+
def id name
|
29
|
+
Theme.config.components[name] = self.to_s
|
30
|
+
@id = name
|
31
|
+
end
|
32
|
+
|
33
|
+
def src path
|
34
|
+
if path[/^\./]
|
35
|
+
@path = path
|
36
|
+
else
|
37
|
+
@path = "#{Theme.config.path}/#{path}"
|
38
|
+
end
|
39
|
+
|
40
|
+
@html = Theme.load_file @path
|
41
|
+
end
|
42
|
+
|
43
|
+
def dom location
|
44
|
+
node = Theme.cache.dom.fetch(path) do
|
45
|
+
n = Nokogiri::HTML html
|
46
|
+
Theme.cache.dom[path] = n
|
47
|
+
end
|
48
|
+
|
49
|
+
if location.is_a? String
|
50
|
+
@node = node.at location
|
51
|
+
else
|
52
|
+
@node = node.send location.keys.first, location.values.last
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def clean &block
|
57
|
+
block.call node
|
58
|
+
end
|
59
|
+
alias :setup :clean
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_accessor :node
|
63
|
+
|
64
|
+
def method_missing method, *args, &block
|
65
|
+
# respond_to?(symbol, include_all=false)
|
66
|
+
if instance.respond_to? method, true
|
67
|
+
instance.send method, *args, &block
|
68
|
+
else
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def node
|
74
|
+
@node ||= self.class.node.clone
|
75
|
+
end
|
76
|
+
|
77
|
+
def render meth = 'display', options = {}
|
78
|
+
if method(meth).parameters.length > 0
|
79
|
+
opts = Hashr.new(options)
|
80
|
+
resp = send meth, opts
|
81
|
+
else
|
82
|
+
resp = send meth
|
83
|
+
end
|
84
|
+
|
85
|
+
options.clear
|
86
|
+
|
87
|
+
if resp.is_a? Nokogiri::XML::Element
|
88
|
+
resp.to_html
|
89
|
+
else
|
90
|
+
resp
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def set_locals options
|
95
|
+
options.to_h.each do |key, value|
|
96
|
+
(class << self; self; end).send(:attr_accessor, key.to_sym)
|
97
|
+
instance_variable_set("@#{key}", value)
|
98
|
+
end
|
99
|
+
|
100
|
+
self
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/theme/event.rb
ADDED
data/lib/theme/events.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Theme
|
2
|
+
module Events
|
3
|
+
def self.included(other)
|
4
|
+
other.extend(Macros)
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_listener(listener)
|
8
|
+
(@listeners ||= []) << listener
|
9
|
+
end
|
10
|
+
|
11
|
+
def notify_listeners(event, *args)
|
12
|
+
id = self.class.instance_variable_get :@id
|
13
|
+
|
14
|
+
(@listeners || []).each do |listener|
|
15
|
+
if id
|
16
|
+
listener.trigger(:"#{id}_#{event}", *args)
|
17
|
+
else
|
18
|
+
listener.trigger(event, *args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def trigger(name, options = {})
|
24
|
+
if self.class._event_blocks && callback = self.class._event_blocks[name]
|
25
|
+
if callback.is_a? Proc
|
26
|
+
callback.call options
|
27
|
+
else
|
28
|
+
if method(callback).parameters.length > 0
|
29
|
+
send callback, options
|
30
|
+
else
|
31
|
+
send callback
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
notify_listeners(name, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
module Macros
|
40
|
+
attr_accessor :_event_blocks, :_listeners
|
41
|
+
|
42
|
+
def on_event(name, options = {}, &block)
|
43
|
+
if id = options[:for]
|
44
|
+
(@_listeners ||= []) << id
|
45
|
+
name = :"#{id}_#{name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
@_event_blocks ||= {}
|
49
|
+
@_event_blocks[name] = options.fetch(:use) { block }
|
50
|
+
|
51
|
+
mod = if const_defined?(:Events, false)
|
52
|
+
const_get(:Events)
|
53
|
+
else
|
54
|
+
new_mod = Module.new do
|
55
|
+
def self.to_s
|
56
|
+
"Events(#{instance_methods(false).join(', ')})"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
const_set(:Events, new_mod)
|
60
|
+
end
|
61
|
+
|
62
|
+
include mod
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/theme/file.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Theme
|
2
|
+
module File
|
3
|
+
extend self
|
4
|
+
|
5
|
+
IMAGE_TYPES = %w(png gif jpg jpeg)
|
6
|
+
FONT_TYPES = %w(eot woff ttf svg)
|
7
|
+
STATIC_TYPES = %w(html js css map)
|
8
|
+
VIEW_TYPES = %w(html slim haml erb md markdown mkd mab)
|
9
|
+
|
10
|
+
def load path, c = {}, instance = self
|
11
|
+
cache = Theme.cache.file.fetch(path) {
|
12
|
+
template = false
|
13
|
+
|
14
|
+
ext = path[/\.[^.]*$/][1..-1]
|
15
|
+
|
16
|
+
if ext && ::File.file?(path)
|
17
|
+
if STATIC_TYPES.include? ext
|
18
|
+
template = Tilt::PlainTemplate.new nil, 1, outvar: '@_output', default_encoding: 'UTF-8' do |t|
|
19
|
+
::File.read(path)
|
20
|
+
end
|
21
|
+
elsif FONT_TYPES.include?(ext) || IMAGE_TYPES.include?(ext)
|
22
|
+
template = ::File.read path
|
23
|
+
else
|
24
|
+
template = Tilt.new path, 1, outvar: '@_output'
|
25
|
+
end
|
26
|
+
else
|
27
|
+
VIEW_TYPES.each do |type|
|
28
|
+
f = "#{path}.#{type}"
|
29
|
+
|
30
|
+
if ::File.file? f
|
31
|
+
template = Tilt.new f, 1, outvar: '@_output'
|
32
|
+
break
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
unless template
|
38
|
+
raise Theme::No::FileFound,
|
39
|
+
"Could't find file: #{path} with any of these extensions: #{VIEW_TYPES.join(', ')}."
|
40
|
+
end
|
41
|
+
|
42
|
+
template
|
43
|
+
}
|
44
|
+
|
45
|
+
if defined? cache.render
|
46
|
+
cache.render instance, c.to_h
|
47
|
+
else
|
48
|
+
cache.to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/theme/mab.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rack/mime'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Theme
|
5
|
+
class Middleware
|
6
|
+
attr_reader :app, :env, :res
|
7
|
+
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call env
|
13
|
+
dup.call! env
|
14
|
+
end
|
15
|
+
|
16
|
+
def call! env
|
17
|
+
@env = env
|
18
|
+
|
19
|
+
if component_path
|
20
|
+
render_component
|
21
|
+
else
|
22
|
+
res
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def res
|
29
|
+
@res ||= begin
|
30
|
+
if not component_path
|
31
|
+
app.call(req.env)
|
32
|
+
else
|
33
|
+
Cuba::Response.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def req
|
39
|
+
@req ||= Rack::Request.new env
|
40
|
+
end
|
41
|
+
|
42
|
+
def component_path
|
43
|
+
path[Regexp.new("^#{Theme.config.component_url}($|.*)")]
|
44
|
+
end
|
45
|
+
|
46
|
+
def path
|
47
|
+
env['PATH_INFO']
|
48
|
+
end
|
49
|
+
|
50
|
+
def render_component
|
51
|
+
app.instance_variable_set :@res, res
|
52
|
+
app.instance_variable_set :@req, req
|
53
|
+
name = req.params['component_name'].to_sym
|
54
|
+
event = req.params['component_event'].to_sym
|
55
|
+
app.theme_components[name].trigger event, Hashr.new(req.params)
|
56
|
+
res.finish
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/theme/version.rb
CHANGED