bhf 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.
- data/README.md +0 -0
- data/app/controllers/bhf/application_controller.rb +77 -0
- data/app/controllers/bhf/entries_controller.rb +123 -0
- data/app/controllers/bhf/pages_controller.rb +49 -0
- data/app/helpers/bhf/application_helper.rb +22 -0
- data/app/helpers/bhf/entries_helper.rb +16 -0
- data/app/helpers/bhf/pages_helper.rb +30 -0
- data/app/views/bhf/_footer.haml +11 -0
- data/app/views/bhf/application/index.haml +3 -0
- data/app/views/bhf/entries/_form.haml +14 -0
- data/app/views/bhf/entries/_validation_errors.haml +5 -0
- data/app/views/bhf/entries/edit.haml +2 -0
- data/app/views/bhf/entries/form/belongs_to/_radio.haml +7 -0
- data/app/views/bhf/entries/form/belongs_to/_select.haml +6 -0
- data/app/views/bhf/entries/form/belongs_to/_static.haml +9 -0
- data/app/views/bhf/entries/form/column/_boolean.haml +2 -0
- data/app/views/bhf/entries/form/column/_date.haml +2 -0
- data/app/views/bhf/entries/form/column/_file.haml +2 -0
- data/app/views/bhf/entries/form/column/_markdown.haml +3 -0
- data/app/views/bhf/entries/form/column/_number.haml +2 -0
- data/app/views/bhf/entries/form/column/_static.haml +8 -0
- data/app/views/bhf/entries/form/column/_string.haml +2 -0
- data/app/views/bhf/entries/form/column/_text.haml +2 -0
- data/app/views/bhf/entries/form/column/_wysiwyg.haml +3 -0
- data/app/views/bhf/entries/form/has_and_belongs_to_many/_check_box.haml +4 -0
- data/app/views/bhf/entries/form/has_and_belongs_to_many/_static.haml +12 -0
- data/app/views/bhf/entries/form/has_many/_static.haml +12 -0
- data/app/views/bhf/entries/form/has_one/_static.haml +9 -0
- data/app/views/bhf/entries/new.haml +2 -0
- data/app/views/bhf/helper/_field_errors.haml +4 -0
- data/app/views/bhf/helper/_flash.haml +4 -0
- data/app/views/bhf/helper/_info.haml +2 -0
- data/app/views/bhf/helper/_node.haml +6 -0
- data/app/views/bhf/helper/_reflection_node.haml +7 -0
- data/app/views/bhf/pages/_platform.haml +41 -0
- data/app/views/bhf/pages/macro/belongs_to/_default.haml +2 -0
- data/app/views/bhf/pages/macro/column/_boolean.haml +1 -0
- data/app/views/bhf/pages/macro/column/_date.haml +1 -0
- data/app/views/bhf/pages/macro/column/_number.haml +1 -0
- data/app/views/bhf/pages/macro/column/_primary_key.haml +1 -0
- data/app/views/bhf/pages/macro/column/_string.haml +1 -0
- data/app/views/bhf/pages/macro/column/_text.haml +1 -0
- data/app/views/bhf/pages/macro/has_and_belongs_to_many/_default.haml +2 -0
- data/app/views/bhf/pages/macro/has_many/_default.haml +2 -0
- data/app/views/bhf/pages/macro/has_one/_default.haml +2 -0
- data/app/views/bhf/pages/show.haml +3 -0
- data/app/views/layouts/bhf/default.haml +27 -0
- data/app/views/layouts/bhf/quick_edit.haml +5 -0
- data/config/locales/en.yml +56 -0
- data/config/routes.rb +14 -0
- data/lib/bhf/active_record.rb +18 -0
- data/lib/bhf/data.rb +127 -0
- data/lib/bhf/form.rb +35 -0
- data/lib/bhf/pagination.rb +111 -0
- data/lib/bhf/platform.rb +202 -0
- data/lib/bhf/settings.rb +40 -0
- data/lib/bhf.rb +13 -0
- data/lib/engine.rb +19 -0
- data/lib/rails/generators/bhf/templates/initializer.rb +9 -0
- data/public/javascripts/bhf.js +0 -0
- data/public/stylesheets/bhf.css +1 -0
- data/test/test_helper.rb +55 -0
- metadata +169 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
en:
|
2
|
+
bhf:
|
3
|
+
pages:
|
4
|
+
headline: Content
|
5
|
+
|
6
|
+
helpers:
|
7
|
+
searchform:
|
8
|
+
placeholder: Search
|
9
|
+
promts:
|
10
|
+
confirm: Are you sure?
|
11
|
+
entry:
|
12
|
+
new: "Create new %{platform_name}"
|
13
|
+
edit: "Edit %{platform_name}"
|
14
|
+
delete: "Delete %{platform_name}"
|
15
|
+
empty: Empty
|
16
|
+
entries:
|
17
|
+
empty: Empty
|
18
|
+
login:
|
19
|
+
success: "Login was successful"
|
20
|
+
error: "Can't login"
|
21
|
+
activated:
|
22
|
+
success: "%{model} was activated successfuly"
|
23
|
+
error: "%{model} error"
|
24
|
+
validation:
|
25
|
+
header: "%{error} prohibited this %{name} from being saved:"
|
26
|
+
error: error
|
27
|
+
|
28
|
+
quick_edit:
|
29
|
+
buttons:
|
30
|
+
cancel: Cancel
|
31
|
+
open: Open
|
32
|
+
save: Save
|
33
|
+
save_and_next: Save and go to next
|
34
|
+
|
35
|
+
pagination:
|
36
|
+
previous_label: « Previous
|
37
|
+
next_label: Next »
|
38
|
+
load_more: Show more entries
|
39
|
+
load_less: Show less entries
|
40
|
+
info:
|
41
|
+
default: "Displaying <strong>%{offset_start} - %{offset_end}</strong> of <strong>%{total_count}</strong> %{name} in total"
|
42
|
+
nothing_found: "No %{name} found"
|
43
|
+
one_found: "Displaying <strong>1</strong> %{name}"
|
44
|
+
all_displayed: "Displaying <strong>all %{total_count}</strong> %{name}"
|
45
|
+
activerecord:
|
46
|
+
notices:
|
47
|
+
messages:
|
48
|
+
create:
|
49
|
+
success: "%{model} was created successfuly"
|
50
|
+
error: "%{model} error"
|
51
|
+
update:
|
52
|
+
success: "%{model} was updated successfuly"
|
53
|
+
error: "%{model} error"
|
54
|
+
destory:
|
55
|
+
success: "%{model} was deleted successfuly"
|
56
|
+
error: "%{model} error"
|
data/config/routes.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
|
3
|
+
namespace :bhf, :path => Bhf::Engine.config.mount_at do
|
4
|
+
root :to => 'application#index'
|
5
|
+
|
6
|
+
get 'page/:page', :to => 'pages#show', :as => :page
|
7
|
+
|
8
|
+
scope ':platform' do
|
9
|
+
resources :entries, :except => [:index, :show]
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Bhf
|
2
|
+
module ActiveRecord
|
3
|
+
|
4
|
+
def to_bhf_s
|
5
|
+
return title if self.respond_to? :title
|
6
|
+
return name if self.respond_to? :name
|
7
|
+
|
8
|
+
if self.respond_to? :attributes
|
9
|
+
return title if attributes['title']
|
10
|
+
return name if attributes['name']
|
11
|
+
return "#{self.class.to_s.humanize} ID: #{send(self.class.primary_key)}" if attributes[self.class.primary_key]
|
12
|
+
end
|
13
|
+
|
14
|
+
self.to_s.humanize
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/bhf/data.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Bhf
|
2
|
+
module Data
|
3
|
+
|
4
|
+
class Field
|
5
|
+
|
6
|
+
attr_reader :info
|
7
|
+
|
8
|
+
def initialize(props, options = {}, pk = 'id')
|
9
|
+
@props = props
|
10
|
+
@info = options[:info] if options[:info]
|
11
|
+
|
12
|
+
@overwrite_type = options[:overwrite_type].to_sym if options[:overwrite_type]
|
13
|
+
|
14
|
+
@primary_key = pk
|
15
|
+
end
|
16
|
+
|
17
|
+
def macro
|
18
|
+
:column
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
return @overwrite_type if @overwrite_type
|
23
|
+
|
24
|
+
@props.type
|
25
|
+
end
|
26
|
+
|
27
|
+
def form_type
|
28
|
+
return @overwrite_type if @overwrite_type
|
29
|
+
|
30
|
+
if name === @primary_key || name === 'updated_at' || name === 'created_at'
|
31
|
+
:static
|
32
|
+
else
|
33
|
+
supported_types(@props.type)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def display_type
|
38
|
+
if name === @primary_key
|
39
|
+
:primary_key
|
40
|
+
elsif name === 'updated_at' || name === 'created_at'
|
41
|
+
:date
|
42
|
+
else
|
43
|
+
supported_types(@props.type)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def name
|
48
|
+
@props.name
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def supported_types(check_type)
|
54
|
+
if [:boolean, :text].include?(check_type)
|
55
|
+
check_type
|
56
|
+
elsif type_sym = group_types(check_type)
|
57
|
+
type_sym
|
58
|
+
else
|
59
|
+
:string
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def group_types(type_sym)
|
64
|
+
return :date if [:date, :datetime, :timestamp, :time, :year].include?(type_sym)
|
65
|
+
return :number if [:integer, :float].include?(type_sym)
|
66
|
+
return :file if type_sym === :file
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
class Reflection
|
73
|
+
|
74
|
+
attr_reader :reflection, :info, :link
|
75
|
+
|
76
|
+
def initialize(reflection, options = {})
|
77
|
+
@reflection = reflection
|
78
|
+
@info = options[:info] if options[:info]
|
79
|
+
@link = options[:link].to_sym if options[:link]
|
80
|
+
|
81
|
+
@overwrite_type = options[:overwrite_type].to_sym if options[:overwrite_type]
|
82
|
+
end
|
83
|
+
|
84
|
+
def macro
|
85
|
+
@reflection.macro
|
86
|
+
end
|
87
|
+
|
88
|
+
def type
|
89
|
+
return @overwrite_type if @overwrite_type
|
90
|
+
|
91
|
+
if macro === :has_and_belongs_to_many
|
92
|
+
:check_box
|
93
|
+
elsif macro === :belongs_to
|
94
|
+
:select
|
95
|
+
else
|
96
|
+
:static
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def form_type
|
101
|
+
type
|
102
|
+
end
|
103
|
+
|
104
|
+
def display_type
|
105
|
+
:default
|
106
|
+
end
|
107
|
+
|
108
|
+
def name
|
109
|
+
@reflection.name.to_s
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
class Column
|
116
|
+
|
117
|
+
attr_reader :name, :field
|
118
|
+
|
119
|
+
def initialize(field)
|
120
|
+
@name = field.name
|
121
|
+
@field = field
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
data/lib/bhf/form.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bhf
|
2
|
+
module Form
|
3
|
+
|
4
|
+
class Builder < ActionView::Helpers::FormBuilder
|
5
|
+
include ActionView::Helpers::FormTagHelper
|
6
|
+
|
7
|
+
def error_label(name, message)
|
8
|
+
label name, "#{object.class.human_attribute_name(name)} #{message}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def field_errors(field)
|
12
|
+
object.errors[field.to_sym]
|
13
|
+
end
|
14
|
+
|
15
|
+
def field_has_errors?(field)
|
16
|
+
field_errors(field).any?
|
17
|
+
end
|
18
|
+
|
19
|
+
def many_to_many_check_box(obj, ref_name, params)
|
20
|
+
mm = :has_and_belongs_to_many
|
21
|
+
checked = if params[mm] && params[mm][ref_name]
|
22
|
+
params[mm][ref_name][obj.id.to_s] != ''
|
23
|
+
else
|
24
|
+
object.send(ref_name).include?(obj)
|
25
|
+
end
|
26
|
+
|
27
|
+
hidden_field_tag("#{mm}[#{ref_name}][#{obj.id}]", '', :id => "hidden_has_and_belongs_to_many_#{ref_name}_#{obj.id}")+' '+
|
28
|
+
check_box_tag("#{mm}[#{ref_name}][#{obj.id}]", obj.id, checked)+' '+
|
29
|
+
label_tag("#{mm}_#{ref_name}_#{obj.id}", obj.to_bhf_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Bhf
|
2
|
+
|
3
|
+
class Pagination
|
4
|
+
|
5
|
+
attr_accessor :template
|
6
|
+
attr_reader :offset_per_page, :offset_to_add
|
7
|
+
|
8
|
+
def initialize(offset_per_page = 10, offset_to_add = 5)
|
9
|
+
@offset_per_page = offset_per_page
|
10
|
+
@offset_to_add = offset_to_add
|
11
|
+
end
|
12
|
+
|
13
|
+
def paginate(platform)
|
14
|
+
platform_params = template.params[platform.name] || {}
|
15
|
+
|
16
|
+
if page_links = template.will_paginate(platform.paginated_objects, {
|
17
|
+
:previous_label => I18n.t('bhf.pagination.previous_label'),
|
18
|
+
:next_label => I18n.t('bhf.pagination.next_label'),
|
19
|
+
:renderer => LinkRenderer.new(self, platform),
|
20
|
+
:container => false
|
21
|
+
})
|
22
|
+
links = "#{load_more(platform)} #{page_links}"
|
23
|
+
elsif platform.paginated_objects.total_pages == 1 && platform.paginated_objects.size > @offset_to_add
|
24
|
+
links = load_less(platform)
|
25
|
+
end
|
26
|
+
|
27
|
+
if links
|
28
|
+
template.content_tag(:div, links.html_safe, {:class => 'pagination'})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def info(platform, options = {})
|
33
|
+
collection = platform.paginated_objects
|
34
|
+
|
35
|
+
entry_name = options[:entry_name] ||
|
36
|
+
(collection.empty?? 'entry' : collection.first.class.model_name.human)
|
37
|
+
|
38
|
+
info = if collection.total_pages < 2
|
39
|
+
case collection.size
|
40
|
+
when 0
|
41
|
+
I18n.t 'bhf.pagination.info.nothing_found', :name => entry_name.pluralize
|
42
|
+
when 1
|
43
|
+
I18n.t 'bhf.pagination.info.one_found', :name => entry_name
|
44
|
+
else
|
45
|
+
I18n.t 'bhf.pagination.info.all_displayed', :total_count => collection.size, :name => entry_name.pluralize
|
46
|
+
end
|
47
|
+
else
|
48
|
+
I18n.t('bhf.pagination.info.default', {
|
49
|
+
:name => entry_name.pluralize,
|
50
|
+
:total_count => collection.total_entries,
|
51
|
+
:offset_start => collection.offset + 1,
|
52
|
+
:offset_end => collection.offset + collection.length
|
53
|
+
})
|
54
|
+
end
|
55
|
+
|
56
|
+
info.html_safe
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_more(platform, attributes = {}, plus = true)
|
60
|
+
platform_params = template.params[platform.name] || {}
|
61
|
+
load_offset = @offset_per_page
|
62
|
+
load_offset = platform_params[:per_page].to_i if platform_params[:per_page]
|
63
|
+
if plus
|
64
|
+
load_offset += @offset_to_add
|
65
|
+
else
|
66
|
+
load_offset -= @offset_to_add
|
67
|
+
end
|
68
|
+
|
69
|
+
platform_params.delete(:page)
|
70
|
+
platform_params[:per_page] = load_offset
|
71
|
+
|
72
|
+
direction = (plus ? 'more' : 'less')
|
73
|
+
template.link_to(
|
74
|
+
I18n.t("bhf.pagination.load_#{direction}"),
|
75
|
+
template.bhf_page_path(
|
76
|
+
platform.page_name,
|
77
|
+
template.params.merge(platform.name => platform_params)
|
78
|
+
), attributes.merge(:class => "load_#{direction}")
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def load_less(platform, attributes = {})
|
83
|
+
load_more(platform, attributes, false)
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
class LinkRenderer < WillPaginate::LinkRenderer
|
88
|
+
|
89
|
+
def initialize(bhf_pagination, platform)
|
90
|
+
@b_p = bhf_pagination
|
91
|
+
@platform = platform
|
92
|
+
end
|
93
|
+
|
94
|
+
def page_link(page, text, attributes = {})
|
95
|
+
platform_params = @b_p.template.params[@platform.name] || {}
|
96
|
+
platform_params[:page] = page
|
97
|
+
|
98
|
+
@b_p.template.link_to(
|
99
|
+
text,
|
100
|
+
@b_p.template.bhf_page_path(
|
101
|
+
@platform.page_name,
|
102
|
+
@b_p.template.params.merge(@platform.name => platform_params)
|
103
|
+
), attributes
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/lib/bhf/platform.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
module Bhf
|
2
|
+
class Platform
|
3
|
+
|
4
|
+
attr_accessor :paginated_objects
|
5
|
+
attr_reader :name, :title, :page_name
|
6
|
+
|
7
|
+
def initialize(options, page_name)
|
8
|
+
@paginated_objects = []
|
9
|
+
|
10
|
+
if options.is_a?(String)
|
11
|
+
options = {options => nil}
|
12
|
+
end
|
13
|
+
@name = options.keys[0]
|
14
|
+
@data = options.values[0] || {}
|
15
|
+
@collection = get_collection
|
16
|
+
|
17
|
+
human_title = if model.to_s === @name.singularize.camelize
|
18
|
+
model.model_name.human
|
19
|
+
else
|
20
|
+
@name.humanize
|
21
|
+
end
|
22
|
+
|
23
|
+
@title = I18n.t("bhf.platforms.#{@name}.title", :platform_title => human_title, :default => human_title).pluralize
|
24
|
+
@page_name = page_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def search?
|
28
|
+
table_options(:search) != false
|
29
|
+
end
|
30
|
+
|
31
|
+
def custom_columns?
|
32
|
+
table_options(:columns).is_a?(Array)
|
33
|
+
end
|
34
|
+
|
35
|
+
def search
|
36
|
+
table_options(:search) || :where
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_objects(options)
|
40
|
+
chain = model
|
41
|
+
|
42
|
+
if options[:order]
|
43
|
+
chain = chain.order("#{options[:order]} #{options[:direction]}")
|
44
|
+
end
|
45
|
+
|
46
|
+
if search? && options[:search].present?
|
47
|
+
chain = do_search(chain, options[:search])
|
48
|
+
end
|
49
|
+
|
50
|
+
@objects = chain.send(data_source)
|
51
|
+
end
|
52
|
+
|
53
|
+
def model
|
54
|
+
return @data['model'].constantize if @data['model']
|
55
|
+
@name.singularize.camelize.constantize
|
56
|
+
end
|
57
|
+
|
58
|
+
def model_name
|
59
|
+
ActiveModel::Naming.singular(model)
|
60
|
+
end
|
61
|
+
|
62
|
+
def fields
|
63
|
+
default_attrs(form_options(:display))
|
64
|
+
end
|
65
|
+
|
66
|
+
def columns
|
67
|
+
default_attrs(table_options(:columns)).
|
68
|
+
each_with_object([]) do |field, obj|
|
69
|
+
obj << Bhf::Data::Column.new(field)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def has_file_upload?
|
74
|
+
@collection.each do |field|
|
75
|
+
return true if field.form_type === :file
|
76
|
+
end
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
def table
|
81
|
+
@data['table']
|
82
|
+
end
|
83
|
+
|
84
|
+
def form
|
85
|
+
@data['form']
|
86
|
+
end
|
87
|
+
|
88
|
+
def hooks(method)
|
89
|
+
@data['hooks'][method.to_s] if @data['hooks']
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def do_search(chain, search_term)
|
95
|
+
search_condition = if table_options(:search)
|
96
|
+
search_term
|
97
|
+
else
|
98
|
+
where_statement = []
|
99
|
+
model.columns_hash.each_pair do |name, props|
|
100
|
+
if props.type === :string
|
101
|
+
where_statement << "#{name} LIKE '%#{search_term}%'"
|
102
|
+
elsif props.type === :integer
|
103
|
+
where_statement << "#{name} = #{search_term.to_i}"
|
104
|
+
elsif props.type === :float
|
105
|
+
where_statement << "#{name} = #{search_term.to_f}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
where_statement.join(' OR ')
|
110
|
+
end
|
111
|
+
|
112
|
+
chain.send search, search_condition
|
113
|
+
end
|
114
|
+
|
115
|
+
def data_source
|
116
|
+
table_options(:source) || :all
|
117
|
+
end
|
118
|
+
|
119
|
+
def default_attrs(attrs)
|
120
|
+
if attrs
|
121
|
+
model_respond_to?(attrs)
|
122
|
+
@collection.select do |field|
|
123
|
+
attrs.include?(field.name)
|
124
|
+
end
|
125
|
+
else
|
126
|
+
@collection
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_collection
|
131
|
+
all = {}
|
132
|
+
|
133
|
+
model.columns_hash.each_pair do |name, props|
|
134
|
+
all[name] = Bhf::Data::Field.new(props, {
|
135
|
+
:overwrite_type => form_options(:types, name),
|
136
|
+
:info => I18n.t("bhf.platforms.#{@name}.infos.#{name}", :default => '')
|
137
|
+
}, model.primary_key)
|
138
|
+
end
|
139
|
+
|
140
|
+
model.reflections.each_pair do |name, props|
|
141
|
+
all[name.to_s] = Bhf::Data::Reflection.new(props, {
|
142
|
+
:overwrite_type => form_options(:types, name),
|
143
|
+
:info => I18n.t("bhf.platforms.#{@name}.infos.#{name}", :default => ''),
|
144
|
+
:link => form_options(:links, name)
|
145
|
+
})
|
146
|
+
|
147
|
+
fk = all[name.to_s].reflection.association_foreign_key
|
148
|
+
if all.has_key?(fk)
|
149
|
+
all.delete(fk)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
default_sort(all)
|
154
|
+
end
|
155
|
+
|
156
|
+
def default_sort(attrs)
|
157
|
+
id = []
|
158
|
+
static_dates = []
|
159
|
+
output = []
|
160
|
+
|
161
|
+
attrs.each_pair do |key, value|
|
162
|
+
if key === model.primary_key
|
163
|
+
id << value
|
164
|
+
elsif key === 'created_at' || key === 'updated_at'
|
165
|
+
static_dates << value
|
166
|
+
else
|
167
|
+
output << value
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
id + output.sort_by(&:name) + static_dates
|
172
|
+
end
|
173
|
+
|
174
|
+
def model_respond_to?(field_names)
|
175
|
+
new_obj = model.new
|
176
|
+
field_names.each do |field_name|
|
177
|
+
unless new_obj.respond_to?(field_name)
|
178
|
+
raise Exception.new("Model '#{model}' does not respond to '#{field_name}'")
|
179
|
+
return false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
true
|
183
|
+
end
|
184
|
+
|
185
|
+
def form_options(key, attribute = nil)
|
186
|
+
if form
|
187
|
+
if attribute === nil
|
188
|
+
form[key.to_s]
|
189
|
+
elsif form[key.to_s]
|
190
|
+
form[key.to_s][attribute.to_s]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def table_options(key)
|
196
|
+
if table
|
197
|
+
return table[key.to_s]
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
data/lib/bhf/settings.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Bhf
|
2
|
+
|
3
|
+
class Settings
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def pages
|
10
|
+
@options['pages'].each_with_object([]) do |page, obj|
|
11
|
+
if page.is_a?(String)
|
12
|
+
page = {page => nil}
|
13
|
+
end
|
14
|
+
obj << page.keys[0]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def content_for_page(selected_page)
|
19
|
+
@options['pages'].each do |page|
|
20
|
+
if page.is_a?(String)
|
21
|
+
page = {page => nil}
|
22
|
+
end
|
23
|
+
if selected_page == page.keys[0]
|
24
|
+
return page.values.flatten
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_platform(platform_name)
|
30
|
+
pages.each do |page|
|
31
|
+
content_for_page(page).each do |platform|
|
32
|
+
bhf_platform = Bhf::Platform.new(platform, page)
|
33
|
+
return bhf_platform if bhf_platform.name == platform_name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/bhf.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
def d(var)
|
2
|
+
raise var.inspect.split(', ').join(", \n")
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
6
|
+
require 'bhf/active_record'
|
7
|
+
require 'bhf/data'
|
8
|
+
require 'bhf/platform'
|
9
|
+
require 'bhf/settings'
|
10
|
+
require 'bhf/pagination'
|
11
|
+
require 'bhf/form'
|
12
|
+
|
13
|
+
::ActiveRecord::Base.send :include, Bhf::ActiveRecord
|
data/lib/engine.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'will_paginate'
|
3
|
+
|
4
|
+
module Bhf
|
5
|
+
class Engine < Rails::Engine
|
6
|
+
|
7
|
+
# Config defaults
|
8
|
+
config.page_title = nil
|
9
|
+
config.mount_at = 'bhf'
|
10
|
+
config.auth_logic_from = 'ApplicationController'
|
11
|
+
|
12
|
+
# config.bhf_logic = YAML::load(IO.read('config/bhf.yml'))
|
13
|
+
|
14
|
+
initializer 'static assets' do |app|
|
15
|
+
app.middleware.use ::ActionDispatch::Static, "#{root}/public"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}ins{text-decoration:none}del{text-decoration:line-through}table{border-spacing:0}textarea,input,button,body{font:14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif}a:focus{outline:1px dotted}hr{border:0 #C8C8C8 solid;border-top-width:1px;clear:both;height:0;margin-bottom:20px}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}html{min-width:700px}body{background:url(/images/bg.png);margin-right:-40px;overflow-x:hidden}a{text-decoration:none;color:inherit}header{display:block;overflow:hidden;clear:both;padding:20px 20px 0 20px}header h1{float:left;display:none}header li{float:left;font-weight:bold;margin-right:30px}header li.active a{text-shadow:#fff 0px -1px 0px;background:#d5d5d5;background:-moz-linear-gradient(top, #d5d5d5, #fff);background:-webkit-gradient(linear, left top, left bottom, from(#d5d5d5), to(#fff));box-shadow:0px 1px 4px #000;-moz-box-shadow:0px 1px 4px #000;-webkit-box-shadow:0px 1px 4px #000;color:#414756}header li.active a:hover{background:#fff;background:-moz-linear-gradient(top, #fff, #d5d5d5);background:-webkit-gradient(linear, left top, left bottom, from(#fff), to(#d5d5d5));border-color:#fff;text-shadow:#fff 0px 1px 0px;box-shadow:inset 0px 0px 3px #fff;-moz-box-shadow:inset 0px 0px 3px #fff;-webkit-box-shadow:inset 0px 0px 3px #fff}header li a{text-decoration:none;display:block;padding:5px 20px;border:1px solid transparent;color:#d8d8d8;text-shadow:#000 0px -1px 0px}header li a:hover{border-color:#2b303c;box-shadow:inset 0px 0px 35px #2b303c;-moz-box-shadow:inset 0px 0px 35px #2b303c;-webkit-box-shadow:inset 0px 0px 35px #2b303c}#content{display:table;width:100%;box-sizing:border-box;margin-left:-20px;border-spacing:20px}.quick_edit_holder,#main{display:table-cell;background:#eaeaea;border:3px solid #fff;padding:10px 20px;box-shadow:0px 1px 4px rgba(0,0,0,0.5);-moz-box-shadow:0px 1px 4px rgba(0,0,0,0.5);-webkit-box-shadow:0px 1px 4px rgba(0,0,0,0.5)}#content #main{border-right:none;border-left:none}#content .quick_edit_holder{border-right:none;position:relative;width:400px}#content .quick_edit_holder .node,#content .quick_edit_holder .input,#content .quick_edit_holder .label{display:block}#content .quick_edit_holder .input{padding-top:0}#content .quick_edit_holder textarea{width:300px;height:100px}#content .quick_edit_holder > .button.cancel,#content .quick_edit_holder > .cancel.alt_button,#content .quick_edit_holder > .pagination a.cancel,.pagination #content .quick_edit_holder > a.cancel,#content .quick_edit_holder > .pagination span.cancel,.pagination #content .quick_edit_holder > span.cancel,#content .quick_edit_holder > .pagination em.cancel,.pagination #content .quick_edit_holder > em.cancel,#content .quick_edit_holder > .button.open,#content .quick_edit_holder > .open.alt_button,#content .quick_edit_holder > .pagination a.open,.pagination #content .quick_edit_holder > a.open,#content .quick_edit_holder > .pagination span.open,.pagination #content .quick_edit_holder > span.open,#content .quick_edit_holder > .pagination em.open,.pagination #content .quick_edit_holder > em.open{float:right}#content .quick_edit_holder > .button.open,#content .quick_edit_holder > .open.alt_button,#content .quick_edit_holder > .pagination a.open,.pagination #content .quick_edit_holder > a.open,#content .quick_edit_holder > .pagination span.open,.pagination #content .quick_edit_holder > span.open,#content .quick_edit_holder > .pagination em.open,.pagination #content .quick_edit_holder > em.open{margin-right:10px}table{margin-top:40px;width:100%}table caption{height:60px;background-image:url(/images/button_bg_2.png)}table caption h4,table caption .info{float:left}table caption .info{padding:5px 20px;text-transform:uppercase;font-size:12px}table caption .create{float:right}table caption form{float:left}table thead th{padding:4px 0;padding-left:5px;text-align:left;border-top:1px solid #fff;border-bottom:1px solid #c6c6c6;white-space:nowrap}table thead th.primary_key{text-transform:uppercase}table thead th.sorted{background:#414756}table thead th.sorted a:after,table thead th.sorted.desc:hover a:after{content:" ▼"}table thead th.sorted:hover a:after,table thead th.sorted.desc a:after{content:" ▲"}table thead th.sorted a{color:#fff;text-shadow:#000 0px 1px 0px}table tbody td{border-top:1px solid #fff;border-bottom:1px solid #c6c6c6}table tbody td.has_many,table tbody td.has_and_belongs_to_many,table tbody td.text{max-width:200px;white-space:nowrap;overflow:hidden}table tbody td.has_many a,table tbody td.has_and_belongs_to_many a,table tbody td.text a{-webkit-mask-image:-webkit-gradient(linear, left top, right top, color-stop(50%, #000), to(rgba(255,255,255,0)))}table tbody a{display:block;padding:5px 3px}table tbody a.edit,table tbody a.delete{padding:0;margin-right:5px;display:inline-block;text-indent:-9999px;width:20px;height:20px}table tbody a.edit:active,table tbody a.delete:active{background-position:0 1px}table tbody a.edit{background:url(/images/icon_edit.png)}table tbody a.edit:hover{background-image:url(/images/icon_edit_a.png)}table tbody a.delete{background:url(/images/icon_delete.png)}table tbody a.delete:hover{background-image:url(/images/icon_delete_a.png)}table tbody tr:hover td,table tbody tr.live_edit td{background:#0f8fdd;color:#fff}table tbody tr:hover td:first-child,table tbody tr.live_edit td:first-child{border-radius:0px;border-top-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius:0px;-moz-border-radius-topleft:4px;-moz-border-radius-bottomleft:4px}table tbody tr:hover td:last-child,table tbody tr.live_edit td:last-child{border-radius:0px;border-top-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius:0px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}table tbody tr.live_edit td{background:red}table tfoot td{padding-top:10px;border-top:1px solid #fff}table thead .primary_key,table thead .number,table tbody .primary_key,table tbody .number{padding-right:10px;text-align:right}table thead .primary_key,table tbody .primary_key{width:30px}table thead .action,table tbody .action{width:50px}.default_input,.search input,form .node .input input[type="password"],form .node .input input[type="text"],form .node .input textarea{border:1px solid #bbb;background:#fff;border-radius:2px;-moz-border-radius:2px;box-shadow:0px 1px 0px #fff;-moz-box-shadow:0px 1px 0px #fff;-webkit-box-shadow:0px 1px 0px #fff;padding:3px 5px 1px 5px;width:300px}.default_input:focus,.search input:focus,form .node .input input[type="password"]:focus,form .node .input input[type="text"]:focus,form .node .input textarea:focus{outline:0;transition-duration:1s;-moz-transition-duration:1s;-webkit-transition-duration:1s;-webkit-box-shadow:0 1px 12px #0f8fdd;border-color:#0f8fdd}.search input{width:200px}form .node{display:table-row}form .node.string .input,form .node.string .label,form .node.text .input,form .node.text .label,form .node.password .input,form .node.password .label{padding-top:5px}form .node.string .label label,form .node.text .label label,form .node.password .label label{padding-top:5px}form .node .label{width:200px}form .node .label label{display:block}form .node .label .field_with_errors{color:red}form .node.primary_key .label{text-transform:uppercase}form .node .input,form .node .label{padding-top:10px;vertical-align:top;display:table-cell}form .node .input textarea{width:500px;height:200px}form .node .input .errors{color:red}form .node .input .field_with_errors input{border-color:red}form .error_explanation label{color:red;cursor:pointer;display:block}form .error_explanation label:hover{color:#f90}footer{text-shadow:#000 0px -1px 0px;text-align:center;color:gray;font-size:12px;line-height:20px}footer a{text-decoration:none}footer a:hover{text-decoration:underline}input[type="submit"],button,.button,.alt_button,.pagination a,.pagination a,.pagination span,.pagination span,.pagination em,.pagination em{display:inline-block;border:0;padding:12px 50px;background:url(/images/button_bg.png);border-radius:4px;-moz-border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.5),inset 0 2px 0 rgba(255,255,255,0.3),inset 0 1px 0 rgba(0,0,0,0.9);text-decoration:none;font-weight:bold;color:#f1f1f1;font-size:13px;text-shadow:0 -1px 0 #000;cursor:pointer;transition-duration:0.8s;-moz-transition-duration:0.8s;-webkit-transition-duration:0.8s;transition-property:color;-moz-transition-property:color;-webkit-transition-property:color}input[type="submit"]:hover,button:hover,.button:hover,.alt_button:hover,.pagination a:hover,.pagination a:hover,.pagination span:hover,.pagination span:hover,.pagination em:hover,.pagination em:hover{-webkit-box-shadow:inset 0 10px 20px 5px #000,inset 0 -2px 0 rgba(255,255,255,0.5),inset 0 -1px 0 #000;color:#38a5e9;text-shadow:0 1px 0 #000}input[type="submit"]:active,button:active,.button:active,.alt_button:active,.pagination a:active,.pagination a:active,.pagination span:active,.pagination span:active,.pagination em:active,.pagination em:active{-webkit-box-shadow:inset 0 1px 6px rgba(0,0,0,0.3),inset 0 -1px 0 #0f8fdd,inset 0 -2px 0 rgba(255,255,255,0.6);background:url(/images/button_bg_a.png);color:#fff}input[type="submit"]:focus,button:focus,.button:focus,.alt_button:focus,.pagination a:focus,.pagination a:focus,.pagination span:focus,.pagination span:focus,.pagination em:focus,.pagination em:focus{outline:0;padding:10px 48px;transition-duration:1s;-moz-transition-duration:1s;-webkit-transition-duration:1s;transition-property:-webkit-box-shadow;-moz-transition-property:-webkit-box-shadow;-webkit-transition-property:-webkit-box-shadow;-webkit-box-shadow:0 1px 12px #0f8fdd;border:2px solid #0f8fdd}.alt_button,.pagination a,.pagination span,.pagination em{background-image:url(/images/button_bg_2.png);padding:5px 10px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.7);color:#000;text-shadow:#fff 0px 1px 0px}@media (max-width: 800px){body{overflow-x:auto}}@media (max-width: 960px){.default_columns thead th:nth-last-child(2),.default_columns tbody td:nth-last-child(2),.default_columns thead th:nth-last-child(3),.default_columns tbody td:nth-last-child(3){display:none}}
|