welltreat-store-framework 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +25 -0
- data/lib/generators/flexi_model/install/install_generator.rb +20 -0
- data/lib/generators/flexi_model/install/templates/create_flexi_model_collections.rb +17 -0
- data/lib/generators/flexi_model/install/templates/create_flexi_model_collections_fields.rb +11 -0
- data/lib/generators/flexi_model/install/templates/create_flexi_model_fields.rb +18 -0
- data/lib/generators/flexi_model/install/templates/create_flexi_model_records.rb +12 -0
- data/lib/generators/flexi_model/install/templates/create_flexi_model_values.rb +18 -0
- data/lib/welltreat_store_framework/configuration.rb +17 -0
- data/lib/welltreat_store_framework/controller.rb +131 -0
- data/lib/welltreat_store_framework/core.rb +66 -0
- data/lib/welltreat_store_framework/haml_renderer/lorem_helper.rb +29 -0
- data/lib/welltreat_store_framework/haml_renderer/partial.rb +31 -0
- data/lib/welltreat_store_framework/haml_renderer/paths.rb +51 -0
- data/lib/welltreat_store_framework/haml_renderer/tags_helper.rb +74 -0
- data/lib/welltreat_store_framework/haml_renderer.rb +163 -0
- data/lib/welltreat_store_framework/rack_server.rb +56 -0
- data/lib/welltreat_store_framework/store_app.rb +282 -0
- data/lib/welltreat_store_framework.rb +9 -0
- data/sample/hello-store/assets/javascripts/app.js +1 -0
- data/sample/hello-store/controllers/home.rb +15 -0
- data/sample/hello-store/controllers/products.rb +18 -0
- data/sample/hello-store/models/product.rb +9 -0
- data/sample/hello-store/mount.rb +0 -0
- data/sample/hello-store/views/home/index.haml +14 -0
- data/sample/hello-store/views/layouts/default.html.haml +10 -0
- data/sample/hello-store/views/products/_product.html.haml +1 -0
- data/sample/hello-store/views/products/index.haml +4 -0
- data/sample/hello-store/views/products/show.html.haml +10 -0
- data/spec/fixtures/schema.rb +78 -0
- data/spec/lib/welltreat_store_framework/configuration_spec.rb +5 -0
- data/spec/lib/welltreat_store_framework/core_spec.rb +190 -0
- data/spec/lib/welltreat_store_framework/haml_renderer/context_spec.rb +73 -0
- data/spec/lib/welltreat_store_framework/store_app_spec.rb +85 -0
- data/spec/lib/welltreat_store_framework_spec.rb +5 -0
- data/spec/sample/controllers/products_spec.rb +140 -0
- data/spec/spec_helper/active_record.rb +8 -0
- data/spec/spec_helper/models.rb +0 -0
- data/spec/spec_helper/rspec.rb +3 -0
- data/spec/spec_helper.rb +19 -0
- metadata +129 -0
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Well Treat Store Framework
|
2
|
+
===========
|
3
|
+
|
4
|
+
Build store just like your another web site building project
|
5
|
+
|
6
|
+
Features
|
7
|
+
===========
|
8
|
+
|
9
|
+
Micro framework
|
10
|
+
|
11
|
+
Relation
|
12
|
+
|
13
|
+
Filter
|
14
|
+
|
15
|
+
Dynamic Filter
|
16
|
+
|
17
|
+
Dynamic Attributes
|
18
|
+
|
19
|
+
Validations
|
20
|
+
|
21
|
+
TODOS
|
22
|
+
=====
|
23
|
+
|
24
|
+
* Abstract persistent api
|
25
|
+
* Expose
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module FlexiModel
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
# Implement the required interface for Rails::Generators::Migration.
|
8
|
+
def self.next_migration_number(dirname) #:nodoc:
|
9
|
+
next_migration_number = current_migration_number(dirname) + 1
|
10
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_install
|
14
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'templates/*.rb')).each do |file|
|
15
|
+
migration_template file, "db/migrate/#{file.split('/').last}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateFlexiModelCollections < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table "flexi_model_collections" do |t|
|
4
|
+
t.string 'name'
|
5
|
+
t.string 'singular_label'
|
6
|
+
t.string 'plural_label'
|
7
|
+
t.string 'namespace'
|
8
|
+
t.integer 'partition_id'
|
9
|
+
|
10
|
+
t.datetime "created_at"
|
11
|
+
t.datetime "updated_at"
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index "flexi_model_collections", [:namespace, :name]
|
15
|
+
add_index "flexi_model_collections", [:namespace, :name, :partition_id], name: 'index_ns_name_pi'
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateFlexiModelCollectionsFields < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table 'flexi_model_collections_fields', :force => true do |t|
|
4
|
+
t.integer 'collection_id'
|
5
|
+
t.integer 'field_id'
|
6
|
+
end
|
7
|
+
|
8
|
+
add_index 'flexi_model_collections_fields', [:collection_id]
|
9
|
+
add_index 'flexi_model_collections_fields', [:field_id]
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateFlexiModelFields < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table 'flexi_model_fields', :force => true do |t|
|
4
|
+
t.string 'name'
|
5
|
+
t.string 'singular_label'
|
6
|
+
t.string 'plural_label'
|
7
|
+
t.string 'namespace'
|
8
|
+
t.integer 'partition_id'
|
9
|
+
|
10
|
+
t.string 'field_type'
|
11
|
+
t.text 'default_value'
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index 'flexi_model_fields', [:namespace, :name]
|
15
|
+
add_index 'flexi_model_fields', [:namespace, :name, :field_type]
|
16
|
+
add_index 'flexi_model_fields', [:namespace, :name, :field_type, :partition_id], name: 'index_ns_name_ft_pi'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateFlexiModelRecords < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table 'flexi_model_records', :force => true do |t|
|
4
|
+
t.integer 'collection_id'
|
5
|
+
t.string 'namespace'
|
6
|
+
t.datetime "created_at"
|
7
|
+
t.datetime "updated_at"
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index 'flexi_model_records', [:namespace, :collection_id]
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateFlexiModelValues < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table 'flexi_model_values', :force => true do |t|
|
4
|
+
t.integer 'record_id'
|
5
|
+
t.integer 'field_id'
|
6
|
+
t.boolean 'bool_value'
|
7
|
+
t.integer 'int_value'
|
8
|
+
t.decimal 'dec_value'
|
9
|
+
t.string 'str_value'
|
10
|
+
t.text 'txt_value'
|
11
|
+
t.datetime 'dt_value'
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index 'flexi_model_values', [:record_id]
|
15
|
+
add_index 'flexi_model_values', [:field_id]
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :store_path, :haml_options, :database_config,
|
4
|
+
:database_schema_file, :auto_reload, :sprockets_enabled
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@auto_reload = false
|
8
|
+
@store_path = nil
|
9
|
+
@sprockets_enabled = false
|
10
|
+
@haml_options = {
|
11
|
+
encoding: 'utf-8',
|
12
|
+
format: :html5
|
13
|
+
}
|
14
|
+
@database_connection = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
attr_reader :app
|
6
|
+
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def serve(request)
|
12
|
+
end
|
13
|
+
|
14
|
+
[:notice, :alert, :success].map(&:to_s).each do |_kind|
|
15
|
+
module_eval <<-CODE
|
16
|
+
def set_flash_#{_kind}(session, msg)
|
17
|
+
_flash_from(session)[:#{_kind}] = msg
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_flash_#{_kind}(session)
|
21
|
+
_flash_from(session)[:#{_kind}]
|
22
|
+
end
|
23
|
+
CODE
|
24
|
+
end
|
25
|
+
|
26
|
+
def _flash_from(session)
|
27
|
+
session[:flash] ||= { }
|
28
|
+
end
|
29
|
+
|
30
|
+
class Request
|
31
|
+
attr_accessor :path, :params, :headers, :rack_request, :env
|
32
|
+
|
33
|
+
def initialize(attrs = { })
|
34
|
+
@headers = { }
|
35
|
+
@params = { }
|
36
|
+
@path = nil
|
37
|
+
@rack_request = nil
|
38
|
+
attrs.each do |k, v|
|
39
|
+
self.send(:"#{k.to_s}=", v)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_header(k)
|
44
|
+
self.headers[k]
|
45
|
+
end
|
46
|
+
|
47
|
+
def [](k)
|
48
|
+
self.params[k]
|
49
|
+
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
def initialize_from_env(env)
|
53
|
+
request = Rack::Request.new(env)
|
54
|
+
self.new(
|
55
|
+
:params => request.params,
|
56
|
+
:headers => env,
|
57
|
+
:rack_request => request,
|
58
|
+
:path => request.path,
|
59
|
+
:env => env
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def set_param(k, v)
|
67
|
+
self.params[k] = v
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Response
|
72
|
+
|
73
|
+
STATUS_OK = 200
|
74
|
+
attr_accessor :status, :headers, :content, :values,
|
75
|
+
:controller_name, :template, :layout
|
76
|
+
|
77
|
+
def initialize
|
78
|
+
@status = STATUS_OK
|
79
|
+
@headers = { 'Content-Type' => 'text/html' }
|
80
|
+
@content = nil
|
81
|
+
@template = nil
|
82
|
+
@layout = :default
|
83
|
+
@values = { }
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_header(k, v)
|
87
|
+
case k.to_s
|
88
|
+
when 'content_type', 'format'
|
89
|
+
@headers['Content-Type'] = v
|
90
|
+
else
|
91
|
+
@headers[k] = v
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_header(k)
|
96
|
+
@headers[k]
|
97
|
+
end
|
98
|
+
|
99
|
+
def set(k, v)
|
100
|
+
@values[k] = v
|
101
|
+
end
|
102
|
+
|
103
|
+
def get(k)
|
104
|
+
@values[k]
|
105
|
+
end
|
106
|
+
|
107
|
+
def [](k)
|
108
|
+
self.get(k)
|
109
|
+
end
|
110
|
+
|
111
|
+
def exists?(k)
|
112
|
+
@values.include?(k)
|
113
|
+
end
|
114
|
+
|
115
|
+
def present?(k)
|
116
|
+
exists?(k) && get(k).present?
|
117
|
+
end
|
118
|
+
|
119
|
+
def redirect_to(path, status = 302)
|
120
|
+
self.status = status
|
121
|
+
self.add_header("Location", path)
|
122
|
+
self.content = ''
|
123
|
+
end
|
124
|
+
|
125
|
+
def redirect?
|
126
|
+
[301, 302, 303, 307].include? self.status
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
class Core
|
3
|
+
@@configuration = WelltreatStoreFramework::Configuration.new
|
4
|
+
cattr_accessor :configuration
|
5
|
+
|
6
|
+
@@stores = nil
|
7
|
+
cattr_accessor :stores
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Reset internal cached data
|
12
|
+
def reset!
|
13
|
+
self.stores = nil
|
14
|
+
self.configuration = WelltreatStoreFramework::Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# Configure through passing block. block will be yield with
|
18
|
+
# configuration instance
|
19
|
+
def setup(&block)
|
20
|
+
block.call(self.configuration)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Find all stores from the configured path
|
24
|
+
# return an array of instance StoreApp
|
25
|
+
def find_stores(partition_object = nil)
|
26
|
+
self.stores ||= _detect_stores(partition_object)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Find store by the given name
|
30
|
+
# Return StoreApp instance
|
31
|
+
def find_store_by_name(name, partition_object = nil)
|
32
|
+
find_stores(partition_object)[name]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Establish database connection
|
36
|
+
def connect_database!
|
37
|
+
ActiveRecord::Base.establish_connection configuration.database_config
|
38
|
+
|
39
|
+
if configuration.database_schema_file.present?
|
40
|
+
puts "Importing database schema - "
|
41
|
+
require configuration.database_schema_file
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def _detect_stores(partition_object = nil)
|
47
|
+
_stores = { }
|
48
|
+
Dir.glob(File.join(configuration.store_path, '*')).each do |_path|
|
49
|
+
_name = _path.split('/').last
|
50
|
+
_stores[_name] = StoreApp.new.tap do |inst|
|
51
|
+
inst.partition_object = partition_object
|
52
|
+
inst.path = _path
|
53
|
+
inst.name = _name
|
54
|
+
inst.config_path = File.join(_path, 'config')
|
55
|
+
inst.controllers_path = File.join(_path, 'controllers')
|
56
|
+
inst.models_path = File.join(_path, 'models')
|
57
|
+
inst.views_path = File.join(_path, 'views')
|
58
|
+
inst.assets_path = File.join(_path, 'assets')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
_stores
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
module HamlRenderer
|
3
|
+
module LoremHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def lorem
|
7
|
+
Lorem
|
8
|
+
end
|
9
|
+
|
10
|
+
class Lorem
|
11
|
+
TEXTS = %{Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.}
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def name
|
15
|
+
TEXTS.split(',').shuffle.first[0..20]
|
16
|
+
end
|
17
|
+
|
18
|
+
def sentence
|
19
|
+
TEXTS.split(',').shuffle.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def paragraph
|
23
|
+
TEXTS
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
module HamlRenderer
|
3
|
+
module Partial
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Render partial template
|
7
|
+
# template - Template file name
|
8
|
+
# By default look for relative path to current action path
|
9
|
+
# Otherwise check by relative path to views path
|
10
|
+
#
|
11
|
+
# variables - Define local variables
|
12
|
+
#
|
13
|
+
# Return string content
|
14
|
+
def partial(template, variables = { })
|
15
|
+
_template_key = [
|
16
|
+
self.response.controller_name,
|
17
|
+
self.response.layout.to_s,
|
18
|
+
self.response.template.to_s,
|
19
|
+
template.to_s
|
20
|
+
].join('_')
|
21
|
+
_file = self.app._full_partial_template_path(self.response, template)
|
22
|
+
|
23
|
+
# Set local variables
|
24
|
+
variables.each { |k, v| self.set_local(k, v) } if variables.present?
|
25
|
+
|
26
|
+
# Render partial
|
27
|
+
self.app._singleton_haml_instance(_template_key, _file).render(self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
module HamlRenderer
|
3
|
+
module Paths
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def asset_path(*_paths)
|
7
|
+
UrlJoin.new('/assets').join(_paths)
|
8
|
+
end
|
9
|
+
|
10
|
+
def image_path(_path)
|
11
|
+
if _path.to_s.match(/^\//)
|
12
|
+
_path
|
13
|
+
elsif sprockets_enabled?
|
14
|
+
asset_path _path
|
15
|
+
else
|
16
|
+
asset_path 'images', _path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def stylesheet_path(_path)
|
21
|
+
_path = _path.to_s
|
22
|
+
_path << '.css' unless _path.to_s.match(/\.css$/)
|
23
|
+
|
24
|
+
if _path.to_s.match(/^\//)
|
25
|
+
_path
|
26
|
+
elsif sprockets_enabled?
|
27
|
+
asset_path _path
|
28
|
+
else
|
29
|
+
asset_path 'stylesheets', _path
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def javascript_path(_path)
|
34
|
+
_path = _path.to_s
|
35
|
+
_path << '.js' unless _path.to_s.match(/\.js$/)
|
36
|
+
|
37
|
+
if _path.to_s.match(/^\//)
|
38
|
+
_path
|
39
|
+
elsif sprockets_enabled?
|
40
|
+
asset_path _path
|
41
|
+
else
|
42
|
+
asset_path 'javascripts', _path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def sprockets_enabled?
|
47
|
+
WelltreatStoreFramework::Core.configuration.sprockets_enabled
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module WelltreatStoreFramework
|
2
|
+
module HamlRenderer
|
3
|
+
module TagsHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Render image tag
|
7
|
+
def image_tag(_path, attrs = { })
|
8
|
+
attrs[:src] = self.image_path(_path.to_s)
|
9
|
+
content_tag 'img', nil, attrs
|
10
|
+
end
|
11
|
+
|
12
|
+
# Render link tag
|
13
|
+
def link_to(label, link, attrs = { })
|
14
|
+
attrs[:href] = link
|
15
|
+
content_tag 'a', label, attrs
|
16
|
+
end
|
17
|
+
|
18
|
+
# Render stylesheet tags
|
19
|
+
def stylesheet_link_tag(*_files)
|
20
|
+
_files.map { |_f| stylesheet_path(_f) }.map do |_css_path|
|
21
|
+
content_tag('link', nil, {
|
22
|
+
rel: 'stylesheet',
|
23
|
+
type: 'text/css',
|
24
|
+
href: _css_path
|
25
|
+
})
|
26
|
+
end.join('')
|
27
|
+
end
|
28
|
+
|
29
|
+
# Render stylesheet tags
|
30
|
+
def javascript_include_tag(*_files)
|
31
|
+
_files.map { |_f| javascript_path(_f) }.map do |_js_path|
|
32
|
+
content_tag('script', '', {
|
33
|
+
type: 'text/javascript',
|
34
|
+
src: _js_path
|
35
|
+
})
|
36
|
+
end.join('')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Truncate text
|
40
|
+
def truncate(text, options = {})
|
41
|
+
length = options[:length] || 100
|
42
|
+
text[0..length - 1]
|
43
|
+
end
|
44
|
+
|
45
|
+
def strip_tags(text, options = {})
|
46
|
+
text.gsub(/<\/?[\w\d\s\-_'="]+>/, '')
|
47
|
+
end
|
48
|
+
|
49
|
+
def content_tag(tag_name, content, attrs = { })
|
50
|
+
html = "<#{tag_name} #{_generate_attributes(attrs)}"
|
51
|
+
|
52
|
+
if content
|
53
|
+
html << ">"
|
54
|
+
html << ERB::Util.html_escape(content)
|
55
|
+
html << "</#{tag_name}>"
|
56
|
+
|
57
|
+
elsif block_given?
|
58
|
+
html << ">"
|
59
|
+
html << ERB::Util.html_escape(yield)
|
60
|
+
html << "</#{tag_name}>"
|
61
|
+
else
|
62
|
+
html << ' />'
|
63
|
+
end
|
64
|
+
|
65
|
+
html
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def _generate_attributes(_attrs)
|
70
|
+
_attrs.map { |k, v| "#{k}='#{v}'" }.join(' ')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'welltreat_store_framework/haml_renderer/paths'
|
2
|
+
require 'welltreat_store_framework/haml_renderer/partial'
|
3
|
+
require 'welltreat_store_framework/haml_renderer/tags_helper'
|
4
|
+
require 'welltreat_store_framework/haml_renderer/lorem_helper'
|
5
|
+
|
6
|
+
module WelltreatStoreFramework
|
7
|
+
module HamlRenderer
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# Render HAML template and set content in response.content variable
|
11
|
+
def render!(request, response, options)
|
12
|
+
return if response.redirect?
|
13
|
+
return if response.content.present?
|
14
|
+
|
15
|
+
_layout_key = response.layout.to_s
|
16
|
+
_template_key = [
|
17
|
+
response.controller_name,
|
18
|
+
response.layout.to_s,
|
19
|
+
response.template.to_s,
|
20
|
+
].join('_')
|
21
|
+
_template_file = _full_template_path(response)
|
22
|
+
_layout_file = _full_layout_path(response)
|
23
|
+
|
24
|
+
raise StoreApp::TemplateNotFound.new(_template_key) if _template_file.nil?
|
25
|
+
|
26
|
+
# Render view with layout
|
27
|
+
context = Context.new(self, request, response, options)
|
28
|
+
|
29
|
+
# Render sub view
|
30
|
+
context.set :body, _singleton_haml_instance(_template_key, _template_file).render(context)
|
31
|
+
|
32
|
+
# Render layout
|
33
|
+
response.content = _singleton_haml_instance(_layout_key, _layout_file).render(context)
|
34
|
+
end
|
35
|
+
|
36
|
+
def _singleton_haml_instance(_key, _file)
|
37
|
+
raise StoreApp::TemplateNotFound.new(_file) if _file.nil? || !File.exist?(_file)
|
38
|
+
|
39
|
+
if WelltreatStoreFramework::Core.configuration.auto_reload
|
40
|
+
Haml::Engine.new(File.read(_file), filename: _file)
|
41
|
+
else
|
42
|
+
_haml_engines[_key] ||=
|
43
|
+
Haml::Engine.new(File.read(_file), filename: _file)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def _haml_engines
|
48
|
+
@_haml_engines ||= { }
|
49
|
+
end
|
50
|
+
|
51
|
+
def _full_layout_path(response)
|
52
|
+
Dir.glob(File.join(self.views_path,
|
53
|
+
'layouts',
|
54
|
+
"#{response.layout.to_s}.*"
|
55
|
+
)).first
|
56
|
+
end
|
57
|
+
|
58
|
+
def _full_template_path(response)
|
59
|
+
Dir.glob(File.join(self.views_path,
|
60
|
+
response.controller_name.to_s.underscore,
|
61
|
+
"#{response.template.to_s}.*"
|
62
|
+
)).first
|
63
|
+
end
|
64
|
+
|
65
|
+
def _full_partial_template_path(response, _partial)
|
66
|
+
Dir.glob(File.join(self.views_path,
|
67
|
+
response.controller_name.to_s.underscore,
|
68
|
+
"#{_partial.to_s}.*"
|
69
|
+
)).first ||
|
70
|
+
Dir.glob(File.join(self.views_path,
|
71
|
+
"#{_partial.to_s}.*"
|
72
|
+
)).first
|
73
|
+
end
|
74
|
+
|
75
|
+
class Context
|
76
|
+
include Paths, Partial, TagsHelper, LoremHelper
|
77
|
+
|
78
|
+
attr_accessor :request, :response, :options
|
79
|
+
|
80
|
+
def initialize(app, request, response, options)
|
81
|
+
@app = app
|
82
|
+
@request = request
|
83
|
+
@response = response
|
84
|
+
@options = options || { }
|
85
|
+
@locals = { }
|
86
|
+
end
|
87
|
+
|
88
|
+
def app;
|
89
|
+
@app
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_local(k, v)
|
93
|
+
@locals[k] = v
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_local(k)
|
97
|
+
@locals[k]
|
98
|
+
end
|
99
|
+
|
100
|
+
def local_exists?(k)
|
101
|
+
@locals.include?(k)
|
102
|
+
end
|
103
|
+
|
104
|
+
def local_present?(k)
|
105
|
+
local_exists?(k) && get_local(k).present?
|
106
|
+
end
|
107
|
+
|
108
|
+
def session
|
109
|
+
options[:session]
|
110
|
+
end
|
111
|
+
|
112
|
+
def notice
|
113
|
+
get_flash :notice
|
114
|
+
end
|
115
|
+
|
116
|
+
def alert
|
117
|
+
get_flash :alert
|
118
|
+
end
|
119
|
+
|
120
|
+
def success
|
121
|
+
get_flash :success
|
122
|
+
end
|
123
|
+
|
124
|
+
def flash_exist?
|
125
|
+
notice || alert || success
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_flash(k)
|
129
|
+
@flash_values ||= { }
|
130
|
+
@flash_values[k] ||= flash[k]
|
131
|
+
flash[k] = nil if @flash_values[k].present?
|
132
|
+
|
133
|
+
@flash_values[k]
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_flash(k, v)
|
137
|
+
flash[k] = v
|
138
|
+
end
|
139
|
+
|
140
|
+
def flash
|
141
|
+
options[:session][:flash] ||= { }
|
142
|
+
end
|
143
|
+
|
144
|
+
delegate :exists?, :present?, :set, :get, :to => :response
|
145
|
+
end
|
146
|
+
|
147
|
+
class UrlJoin
|
148
|
+
def initialize(*_base_paths)
|
149
|
+
@paths = []
|
150
|
+
join(_base_paths)
|
151
|
+
end
|
152
|
+
|
153
|
+
def join(*_paths)
|
154
|
+
@paths += _paths
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
def to_s
|
159
|
+
@paths.join('/')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|