constructor-pages 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.
Files changed (69) hide show
  1. data/app/assets/images/constructor_pages/arrow_down.png +0 -0
  2. data/app/assets/images/constructor_pages/arrow_up.png +0 -0
  3. data/app/assets/images/constructor_pages/information.png +0 -0
  4. data/app/assets/images/constructor_pages/page_white_edit.png +0 -0
  5. data/app/assets/images/constructor_pages/photos.png +0 -0
  6. data/app/controllers/constructor_pages/fields_controller.rb +60 -0
  7. data/app/controllers/constructor_pages/pages_controller.rb +207 -0
  8. data/app/controllers/constructor_pages/templates_controller.rb +71 -0
  9. data/app/helpers/constructor_pages/fields_helper.rb +18 -0
  10. data/app/helpers/constructor_pages/pages_helper.rb +15 -0
  11. data/app/helpers/constructor_pages/templates_helper.rb +11 -0
  12. data/app/models/constructor_pages/field.rb +60 -0
  13. data/app/models/constructor_pages/page.rb +117 -0
  14. data/app/models/constructor_pages/template.rb +30 -0
  15. data/app/models/constructor_pages/types/boolean_type.rb +12 -0
  16. data/app/models/constructor_pages/types/date_type.rb +16 -0
  17. data/app/models/constructor_pages/types/float_type.rb +12 -0
  18. data/app/models/constructor_pages/types/html_type.rb +12 -0
  19. data/app/models/constructor_pages/types/image_type.rb +18 -0
  20. data/app/models/constructor_pages/types/integer_type.rb +12 -0
  21. data/app/models/constructor_pages/types/string_type.rb +12 -0
  22. data/app/models/constructor_pages/types/text_type.rb +12 -0
  23. data/app/views/constructor_pages/fields/_form.haml +28 -0
  24. data/app/views/constructor_pages/fields/edit.haml +6 -0
  25. data/app/views/constructor_pages/fields/new.haml +6 -0
  26. data/app/views/constructor_pages/fields/types/_boolean.haml +1 -0
  27. data/app/views/constructor_pages/fields/types/_date.haml +1 -0
  28. data/app/views/constructor_pages/fields/types/_float.haml +1 -0
  29. data/app/views/constructor_pages/fields/types/_html.haml +1 -0
  30. data/app/views/constructor_pages/fields/types/_image.haml +4 -0
  31. data/app/views/constructor_pages/fields/types/_integer.haml +1 -0
  32. data/app/views/constructor_pages/fields/types/_string.haml +1 -0
  33. data/app/views/constructor_pages/fields/types/_text.haml +1 -0
  34. data/app/views/constructor_pages/pages/_breadcrumbs.haml +7 -0
  35. data/app/views/constructor_pages/pages/_form.haml +98 -0
  36. data/app/views/constructor_pages/pages/_menu.haml +8 -0
  37. data/app/views/constructor_pages/pages/_submenu.haml +6 -0
  38. data/app/views/constructor_pages/pages/edit.haml +6 -0
  39. data/app/views/constructor_pages/pages/error_404.haml +23 -0
  40. data/app/views/constructor_pages/pages/index.haml +50 -0
  41. data/app/views/constructor_pages/pages/new.haml +6 -0
  42. data/app/views/constructor_pages/pages/show.haml +5 -0
  43. data/app/views/constructor_pages/pages/sitemap.haml +12 -0
  44. data/app/views/constructor_pages/templates/_form.haml +48 -0
  45. data/app/views/constructor_pages/templates/edit.haml +6 -0
  46. data/app/views/constructor_pages/templates/index.haml +38 -0
  47. data/app/views/constructor_pages/templates/new.haml +6 -0
  48. data/config/initializers/dragonfly.rb +9 -0
  49. data/config/locales/ru.yml +39 -0
  50. data/config/routes.rb +34 -0
  51. data/constructor-pages.gemspec +21 -0
  52. data/db/migrate/10_create_html_types.rb +15 -0
  53. data/db/migrate/11_create_image_types.rb +16 -0
  54. data/db/migrate/12_add_default_template.rb +13 -0
  55. data/db/migrate/1_create_pages.rb +27 -0
  56. data/db/migrate/2_create_templates.rb +18 -0
  57. data/db/migrate/3_create_fields.rb +17 -0
  58. data/db/migrate/4_create_string_types.rb +15 -0
  59. data/db/migrate/5_create_float_types.rb +15 -0
  60. data/db/migrate/6_create_boolean_types.rb +15 -0
  61. data/db/migrate/7_create_integer_types.rb +15 -0
  62. data/db/migrate/8_create_text_types.rb +15 -0
  63. data/db/migrate/9_create_date_types.rb +15 -0
  64. data/lib/constructor-pages.rb +7 -0
  65. data/lib/constructor_pages/engine.rb +6 -0
  66. data/public/hello.txt +1 -0
  67. data/spec/factories.rb +7 -0
  68. data/spec/models/page_model_spec.rb +113 -0
  69. metadata +210 -0
@@ -0,0 +1,117 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ class Page < ActiveRecord::Base
5
+ attr_accessible :name, :title, :keywords, :description,
6
+ :url, :full_url, :active, :auto_url,
7
+ :parent_id, :link, :in_menu, :in_map,
8
+ :in_nav, :template_id
9
+
10
+ has_many :string_types,:dependent => :destroy, :class_name => "Types::StringType"
11
+ has_many :float_types, :dependent => :destroy, :class_name => "Types::FloatType"
12
+ has_many :boolean_types, :dependent => :destroy, :class_name => "Types::BooleanType"
13
+ has_many :integer_types, :dependent => :destroy, :class_name => "Types::IntegerType"
14
+ has_many :text_types, :dependent => :destroy, :class_name => "Types::TextType"
15
+ has_many :date_types, :dependent => :destroy, :class_name => "Types::DateType"
16
+ has_many :html_types, :dependent => :destroy, :class_name => "Types::HtmlType"
17
+ has_many :image_types, :dependent => :destroy, :class_name => "Types::ImageType"
18
+
19
+ belongs_to :template
20
+
21
+ default_scope order(:lft)
22
+
23
+ before_save :url_prepare, :content_filter
24
+ after_update :full_url_descendants_change
25
+
26
+ before_update :full_url_change
27
+ before_create :full_url_create
28
+
29
+ after_create :create_fields
30
+
31
+ acts_as_nested_set
32
+
33
+ def self.children_of(page)
34
+ Page.where(:parent_id => page)
35
+ end
36
+
37
+ def field(code_name, meth = "value")
38
+ field = ConstructorPages::Field.where(:code_name => code_name, :template_id => self.template_id).first
39
+
40
+ if field
41
+ f = "constructor_pages/types/#{field.type_value}_type".classify.constantize.where(:field_id => field.id, :page_id => self.id).first
42
+ f.send(meth) if f
43
+ end
44
+ end
45
+
46
+ def method_missing(name, *args, &block)
47
+ name = name.to_s
48
+
49
+ if field(name).nil?
50
+ _template = Template.find_by_code_name(name.singularize)
51
+ template_id = _template.id if _template
52
+
53
+ if template_id
54
+ result = []
55
+ result = descendants.where(:template_id => template_id) if name == name.pluralize
56
+ result = ancestors.where(:template_id => template_id).first if result.empty?
57
+ result || []
58
+ end
59
+ else
60
+ field(name)
61
+ end
62
+ end
63
+
64
+ def as_json(options = {})
65
+ options = {
66
+ :name => self.name,
67
+ :title => self.title
68
+ }.merge options
69
+
70
+ self.template.fields.each do |field|
71
+ unless self.send(field.code_name)
72
+ options = {field.code_name => self.send(field.code_name)}.merge options
73
+ end
74
+ end
75
+
76
+ options
77
+ end
78
+
79
+ private
80
+
81
+ def full_url_change
82
+ if parent_id
83
+ self.full_url = '/' + Page.find(parent_id).self_and_ancestors.map {|c| c.url}.append(self.url).join('/')
84
+ else
85
+ self.full_url = '/' + self.url
86
+ end
87
+ end
88
+
89
+ def full_url_create
90
+ if self.parent.nil?
91
+ self.full_url = '/' + self.url
92
+ else
93
+ self.full_url = self.parent.full_url + '/' + self.url
94
+ end
95
+ end
96
+
97
+ def full_url_descendants_change
98
+ self.descendants.each { |c| c.save }
99
+ end
100
+
101
+ def url_prepare
102
+ if self.auto_url or self.url.empty?
103
+ self.url = self.name.parameterize
104
+ else
105
+ self.url = self.url.parameterize
106
+ end
107
+ end
108
+
109
+ def create_fields
110
+ template.fields.each do |field|
111
+ "constructor_pages/types/#{field.type_value}_type".classify.constantize.create(
112
+ :page_id => id,
113
+ :field_id => field.id)
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ class Template < ActiveRecord::Base
5
+ attr_accessible :name, :code_name, :child_id, :parent_id
6
+ validates_presence_of :name
7
+ validates_uniqueness_of :code_name
8
+
9
+ validate :method_uniqueness
10
+
11
+ default_scope order(:lft)
12
+
13
+ has_many :pages
14
+ has_many :fields
15
+
16
+ acts_as_nested_set
17
+
18
+ private
19
+
20
+ def method_uniqueness
21
+ if Page.first.respond_to?(code_name.pluralize) \
22
+ or Page.first.respond_to?(code_name.singularize) \
23
+ or root.self_and_descendants.map{|t| t.code_name}.include?(code_name.pluralize) \
24
+ or root.self_and_descendants.map{|t| t.code_name}.include?(code_name.singularize) \
25
+
26
+ errors.add(:base, "Такой метод уже используется")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class BooleanType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class DateType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+
11
+ def russian
12
+ Russian::strftime(self.value, "%d %B %Y").gsub(/0(\d\D)/, '\1')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class FloatType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class HtmlType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class ImageType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+
11
+ image_accessor :value
12
+
13
+ validates :value, :presence => true
14
+ validates_size_of :value, :maximum => 5.megabytes, :message => :incorrect_size
15
+ validates_property :mime_type, :of => :value, :in => %w(image/jpeg image/png image/gif), :message => :incorrect_format
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class IntegerType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class StringType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module ConstructorPages
4
+ module Types
5
+ class TextType < ActiveRecord::Base
6
+ attr_accessible :value, :field_id, :page_id
7
+
8
+ belongs_to :field
9
+ belongs_to :page
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ = form_for @field do |f|
2
+ - if @field.errors.any?
3
+ .alert.alert-error.fade.in.span12
4
+ = link_to "×", "#", :class => "close", 'data-dismiss' => 'alert'
5
+ - @field.errors.full_messages.each do |m|
6
+ = m
7
+
8
+ .form-horizontal
9
+ .control-group
10
+ = f.label :name, :class => 'control-label'
11
+ .controls= f.text_field :name, :class => "span4"
12
+
13
+ .control-group
14
+ = f.label :code_name, :class => 'control-label'
15
+ .controls= f.text_field :code_name, :class => "span4"
16
+ = f.hidden_field :template_id, :value => @field.template.id, :class => "span4"
17
+
18
+ .control-group
19
+ = f.label :type_value, :class => 'control-label'
20
+ .controls
21
+ = f.select :type_value, options_for_select(types_value, :selected => @field.type_value), :class => "span4"
22
+
23
+ .row-fluid
24
+ .span12
25
+ .form-actions
26
+ .btn-group
27
+ = f.submit :class => "btn btn-primary"
28
+ = link_to "Отмена", template_url(@field.template), :class => "btn"
@@ -0,0 +1,6 @@
1
+ - content_for :page_title do
2
+ Редактирование поля
3
+
4
+ %section.span12
5
+ = render 'form'
6
+
@@ -0,0 +1,6 @@
1
+ - content_for :page_title do
2
+ Создание поля
3
+
4
+ %section.span12
5
+ = render 'form'
6
+
@@ -0,0 +1 @@
1
+ = check_box_tag "fields[#{field.type_value}][#{field.id}]", nil, page.boolean_types.where(:field_id => field.id).first.value
@@ -0,0 +1 @@
1
+ = date_select "fields[#{field.type_value}][#{field.id}]", "date", :default => page.date_types.where(:field_id => field.id).first.value
@@ -0,0 +1 @@
1
+ = text_field_tag "fields[#{field.type_value}][#{field.id}]", page.float_types.where(:field_id => field.id).first.value, :class => "span2"
@@ -0,0 +1 @@
1
+ = text_area_tag "fields[#{field.type_value}][#{field.id}]", page.html_types.where(:field_id => field.id).first.value, :rows => 10, :class => "span9 ckeditor"
@@ -0,0 +1,4 @@
1
+ - page.image_types.where(:field_id => field.id).each do |image|
2
+ = image_tag image.value.thumb("200x200").url
3
+ %br/
4
+ = file_field_tag "fields[#{field.type_value}][#{field.id}]", :class => "span6"
@@ -0,0 +1 @@
1
+ = text_field_tag "fields[#{field.type_value}][#{field.id}]", page.integer_types.where(:field_id => field.id).first.value, :class => "span2"
@@ -0,0 +1 @@
1
+ = text_field_tag "fields[#{field.type_value}][#{field.id}]", page.string_types.where(:field_id => field.id).first.value, :class => "span6"
@@ -0,0 +1 @@
1
+ = text_area_tag "fields[#{field.type_value}][#{field.id}]", page.text_types.where(:field_id => field.id).first.value, :rows => 10, :class => "span6"
@@ -0,0 +1,7 @@
1
+ - unless page.ancestors.empty?
2
+ %ul.breadcrumb
3
+ - page.ancestors.each do |i|
4
+ - if i.in_nav
5
+ %li
6
+ = link_to i.name, i.full_url, :title => i.name, :class => 'b-page-json'
7
+ %span{:class => "divider"} /
@@ -0,0 +1,98 @@
1
+ = form_for @page, :html => {:multipart => @multipart} do |f|
2
+ - if @page.errors.any?
3
+ .alert.alert-error.fade.in.span12
4
+ = link_to "×", "#", :class => "close", 'data-dismiss' => 'alert'
5
+ - @page.errors.full_messages.each do |m|
6
+ = m
7
+
8
+ .form-horizontal
9
+ .control-group
10
+ = f.label :active, :class => 'control-label'
11
+ .controls= f.check_box :active, :class => "span6"
12
+
13
+ .control-group
14
+ = f.label :name, :class => 'control-label'
15
+ .controls= f.text_field :name, :class => "span4"
16
+
17
+ .control-group.auto_url
18
+ = f.label :auto_url, :class => 'control-label'
19
+ .controls
20
+ = f.check_box :auto_url, :class => "span9"
21
+
22
+ .control-group.url
23
+ = f.label :url, :class => 'control-label'
24
+ .controls
25
+ .full_url
26
+ %span.path>= @page.parent.full_url unless @page.parent.nil?
27
+ \/
28
+ %span.address>= @page.url
29
+ = f.text_field :url, :class => "span3"
30
+ %i.address_icon.icon-pencil
31
+
32
+ - unless @page.new_record?
33
+ - @page.template.fields.each do |field|
34
+ .control-group
35
+ = label_tag "", field.name, :class => 'control-label'
36
+ .controls
37
+ = render :partial => "constructor_pages/fields/types/#{field.type_value}", :locals => {:field => field, :page => @page}
38
+
39
+ .accordion
40
+ .accordion-group
41
+ .accordion-heading.text-center
42
+ = link_to 'Настройки', '#collapse', :class => 'accordion-toggle', 'data-toggle' => 'collapse'
43
+ .accordion-body.in.collapse#collapse
44
+ .accordion-inner
45
+ .control-group
46
+ = f.label :parent, :class => 'control-label'
47
+ .controls
48
+ = f.select :parent_id, options_for_select(for_select(@roots), :selected => @page.parent_id, :disabled => @page.self_and_descendants.map{|p| p.id}), :include_blank => 'Нет'
49
+
50
+ .control-group
51
+ = f.label :template, :class => 'control-label'
52
+ .controls
53
+ = f.select :template_id, options_for_select(templates, :selected => @template)
54
+ .control-group
55
+ = f.label :link, :class => 'control-label'
56
+ .controls
57
+ = f.text_field :link, :class => "span9"
58
+ .control-group
59
+ %label.control-label Отображать в
60
+ .controls
61
+ %label.checkbox.inline.span2{:for => 'in_menu'}
62
+ = f.check_box :in_menu
63
+ Меню
64
+
65
+ %label.checkbox.inline.span2{:for => 'in_map'}
66
+ = f.check_box :in_map
67
+ Карта сайта
68
+
69
+ %label.checkbox.inline.span2{:for => 'in_nav'}
70
+ = f.check_box :in_nav
71
+ Хлебные крошки
72
+
73
+ .accordion
74
+ .accordion-group
75
+ .accordion-heading.text-center
76
+ = link_to 'Поисковая оптимизация', '#collapse-three', :class => 'accordion-toggle', 'data-toggle' => 'collapse'
77
+ .accordion-body.in.collapse#collapse-three
78
+ .accordion-inner
79
+ .control-group
80
+ = f.label :title, :class => 'control-label'
81
+ .controls
82
+ = f.text_field :title, :class => "span9"
83
+ .control-group
84
+ = f.label :keywords, :class => 'control-label'
85
+ .controls
86
+ = f.text_field :keywords, :class => "span9"
87
+ .control-group
88
+ = f.label :description, :class => 'control-label'
89
+ .controls
90
+ = f.text_area :description, :class => "span9", :rows => 8
91
+
92
+ .row-fluid
93
+ .span12
94
+ .form-actions
95
+ .btn-group
96
+ = f.submit :class => "btn btn-primary"
97
+ = link_to "Отмена", pages_url, :class => "btn"
98
+ = link_to "Удалить страницу", @page, :confirm => 'Вы уверены?', :method => :delete, :class => "btn btn-danger pull-right" unless @page.new_record?