breeze_cms 0.9.5

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 (151) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +24 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/config/breeze_manifest.js +2 -0
  6. data/app/assets/images/breeze/breeze_logo.png +0 -0
  7. data/app/assets/images/breeze/card_preview/card_feature_box.png +0 -0
  8. data/app/assets/images/breeze/card_preview/card_feature_normal.png +0 -0
  9. data/app/assets/images/breeze/card_preview/card_full_image.png +0 -0
  10. data/app/assets/images/breeze/card_preview/card_gap_square.png +0 -0
  11. data/app/assets/images/breeze/card_preview/card_large_image.png +0 -0
  12. data/app/assets/images/breeze/card_preview/card_normal_round.png +0 -0
  13. data/app/assets/images/breeze/card_preview/card_normal_square.png +0 -0
  14. data/app/assets/images/breeze/card_preview/card_wide_square.png +0 -0
  15. data/app/assets/images/breeze/card_preview/form_field.png +0 -0
  16. data/app/assets/images/breeze/home.jpg +0 -0
  17. data/app/assets/images/breeze/section_preview/blog_header.png +0 -0
  18. data/app/assets/images/breeze/section_preview/form_section.png +0 -0
  19. data/app/assets/images/breeze/section_preview/section_cards.png +0 -0
  20. data/app/assets/images/breeze/section_preview/section_feature.png +0 -0
  21. data/app/assets/images/breeze/section_preview/section_full_image.png +0 -0
  22. data/app/assets/images/breeze/section_preview/section_full_up.png +0 -0
  23. data/app/assets/images/breeze/section_preview/section_half_image.png +0 -0
  24. data/app/assets/images/breeze/section_preview/section_large_image.png +0 -0
  25. data/app/assets/images/breeze/section_preview/section_news.png +0 -0
  26. data/app/assets/images/breeze/section_preview/section_slider.png +0 -0
  27. data/app/assets/images/breeze/section_preview/section_small_image.png +0 -0
  28. data/app/assets/images/breeze/section_preview/section_spacer.png +0 -0
  29. data/app/assets/images/breeze/section_preview/section_text.png +0 -0
  30. data/app/assets/javascript/breeze_application.js.rb +101 -0
  31. data/app/assets/javascript/marked.js +6 -0
  32. data/app/assets/stylesheets/breeze/breeze.css +3633 -0
  33. data/app/assets/stylesheets/breeze/breeze.email.css +1344 -0
  34. data/app/assets/stylesheets/breeze.tailwind.css +2 -0
  35. data/app/assets/stylesheets/breeze_tailwind_styles.css +21 -0
  36. data/app/assets/stylesheets/tailwind_base.css +3 -0
  37. data/app/controllers/breeze/application_controller.rb +4 -0
  38. data/app/controllers/breeze/breeze_controller.rb +16 -0
  39. data/app/controllers/breeze/cards_controller.rb +58 -0
  40. data/app/controllers/breeze/changes_controller.rb +45 -0
  41. data/app/controllers/breeze/form_controller.rb +67 -0
  42. data/app/controllers/breeze/images_controller.rb +100 -0
  43. data/app/controllers/breeze/pages_controller.rb +66 -0
  44. data/app/controllers/breeze/sections_controller.rb +96 -0
  45. data/app/controllers/breeze/styles_controller.rb +11 -0
  46. data/app/controllers/breeze/translations_controller.rb +56 -0
  47. data/app/controllers/breeze/view_controller.rb +10 -0
  48. data/app/helpers/breeze/breeze_helper.rb +54 -0
  49. data/app/helpers/breeze/cards_helper.rb +11 -0
  50. data/app/helpers/breeze/changes_helper.rb +29 -0
  51. data/app/helpers/breeze/form_helper.rb +5 -0
  52. data/app/helpers/breeze/images_helper.rb +57 -0
  53. data/app/helpers/breeze/options_helper.rb +120 -0
  54. data/app/helpers/breeze/pages_helper.rb +5 -0
  55. data/app/helpers/breeze/sections_helper.rb +14 -0
  56. data/app/helpers/breeze/styles_helper.rb +4 -0
  57. data/app/helpers/breeze/translations_helper.rb +14 -0
  58. data/app/helpers/breeze/view_helper.rb +74 -0
  59. data/app/jobs/breeze/application_job.rb +4 -0
  60. data/app/mailers/breeze/application_mailer.rb +6 -0
  61. data/app/models/breeze/active_base.rb +34 -0
  62. data/app/models/breeze/active_yaml.rb +143 -0
  63. data/app/models/breeze/card.rb +90 -0
  64. data/app/models/breeze/card_style.rb +12 -0
  65. data/app/models/breeze/change_set.rb +58 -0
  66. data/app/models/breeze/image.rb +104 -0
  67. data/app/models/breeze/option_definition.rb +43 -0
  68. data/app/models/breeze/page.rb +97 -0
  69. data/app/models/breeze/page_style.rb +12 -0
  70. data/app/models/breeze/section.rb +137 -0
  71. data/app/models/breeze/section_style.rb +17 -0
  72. data/app/models/breeze/shared_base.rb +20 -0
  73. data/app/models/breeze/style.rb +17 -0
  74. data/app/models/breeze/translation.rb +83 -0
  75. data/app/models/breeze/view_base.rb +134 -0
  76. data/app/views/breeze/cards/index.haml +84 -0
  77. data/app/views/breeze/changes/index.haml +52 -0
  78. data/app/views/breeze/form/_editor.haml +33 -0
  79. data/app/views/breeze/form/form.haml +8 -0
  80. data/app/views/breeze/images/_editor.haml +144 -0
  81. data/app/views/breeze/images/index.haml +83 -0
  82. data/app/views/breeze/images/new.haml +12 -0
  83. data/app/views/breeze/images/show.haml +60 -0
  84. data/app/views/breeze/pages/_sections.rabl +4 -0
  85. data/app/views/breeze/pages/index.haml +49 -0
  86. data/app/views/breeze/pages/show.haml +85 -0
  87. data/app/views/breeze/sections/_option_form_date.haml +4 -0
  88. data/app/views/breeze/sections/_option_form_select.haml +4 -0
  89. data/app/views/breeze/sections/_option_form_text.haml +4 -0
  90. data/app/views/breeze/sections/_overlay.haml +33 -0
  91. data/app/views/breeze/sections/_section.rabl +5 -0
  92. data/app/views/breeze/sections/_sections_pagination.haml +29 -0
  93. data/app/views/breeze/sections/index.haml +88 -0
  94. data/app/views/breeze/sections/new.haml +12 -0
  95. data/app/views/breeze/sections/select_card_template.haml +13 -0
  96. data/app/views/breeze/sections/select_template.haml +15 -0
  97. data/app/views/breeze/sections/show.haml +91 -0
  98. data/app/views/breeze/styles/_options.haml +9 -0
  99. data/app/views/breeze/styles/index.haml +84 -0
  100. data/app/views/breeze/translations/_row.haml +29 -0
  101. data/app/views/breeze/translations/show.haml +79 -0
  102. data/app/views/breeze/view/_blog_header.haml +13 -0
  103. data/app/views/breeze/view/_form_section.haml +21 -0
  104. data/app/views/breeze/view/_section_cards.haml +17 -0
  105. data/app/views/breeze/view/_section_feature.haml +13 -0
  106. data/app/views/breeze/view/_section_full_image.haml +10 -0
  107. data/app/views/breeze/view/_section_full_up.haml +11 -0
  108. data/app/views/breeze/view/_section_half_image.haml +13 -0
  109. data/app/views/breeze/view/_section_large_image.haml +13 -0
  110. data/app/views/breeze/view/_section_news.haml +16 -0
  111. data/app/views/breeze/view/_section_slider.haml +51 -0
  112. data/app/views/breeze/view/_section_small_image.haml +11 -0
  113. data/app/views/breeze/view/_section_spacer.haml +1 -0
  114. data/app/views/breeze/view/_section_text.haml +17 -0
  115. data/app/views/breeze/view/cards/_card_feature_box.haml +13 -0
  116. data/app/views/breeze/view/cards/_card_feature_normal.haml +7 -0
  117. data/app/views/breeze/view/cards/_card_full_image.haml +10 -0
  118. data/app/views/breeze/view/cards/_card_gap_square.haml +11 -0
  119. data/app/views/breeze/view/cards/_card_large_image.haml +6 -0
  120. data/app/views/breeze/view/cards/_card_normal_round.haml +8 -0
  121. data/app/views/breeze/view/cards/_card_normal_square.haml +9 -0
  122. data/app/views/breeze/view/cards/_card_wide_square.haml +8 -0
  123. data/app/views/breeze/view/cards/_form_field.haml +8 -0
  124. data/app/views/breeze/view/elements/_button.haml +4 -0
  125. data/app/views/breeze/view/page.haml +2 -0
  126. data/app/views/layouts/breeze/_header.haml +37 -0
  127. data/app/views/layouts/breeze/_messages.haml +28 -0
  128. data/app/views/layouts/breeze/application.haml +20 -0
  129. data/app/views/layouts/mailer.html.haml +8 -0
  130. data/app/views/layouts/mailer.text.erb +1 -0
  131. data/config/breeze/card_styles.yml +129 -0
  132. data/config/breeze/option_definitions.yml +129 -0
  133. data/config/breeze/page_styles.yml +12 -0
  134. data/config/breeze/section_styles.yml +199 -0
  135. data/config/initializers/breeze.rb +13 -0
  136. data/config/initializers/rabl.rb +31 -0
  137. data/config/initializers/simple_form.rb +212 -0
  138. data/config/routes.rb +40 -0
  139. data/config/tailwind.config.js +17 -0
  140. data/config/tailwind.email.js +14 -0
  141. data/lib/breeze/engine.rb +97 -0
  142. data/lib/breeze/shared_helper.rb +44 -0
  143. data/lib/breeze/version.rb +3 -0
  144. data/lib/breeze.rb +104 -0
  145. data/lib/generators/breeze/install/install_generator.rb +19 -0
  146. data/lib/generators/breeze/install/templates/empty.yml +1 -0
  147. data/lib/generators/breeze/install/templates/initializer.rb +70 -0
  148. data/lib/generators/breeze/update/update_generator.rb +11 -0
  149. data/lib/tasks/condense.rake +60 -0
  150. data/lib/tasks/consistency.rake +84 -0
  151. metadata +371 -0
@@ -0,0 +1,104 @@
1
+ require "mini_magick"
2
+ require "fileutils"
3
+
4
+ module Breeze
5
+ class Image < ActiveBase
6
+
7
+ set_root_path Rails.root
8
+
9
+ fields :name , :tags , :type , :size , :height , :width
10
+
11
+ def change_name
12
+ name
13
+ end
14
+
15
+ def aspect_ratio
16
+ ratio = self.ratio
17
+ ratios = (1..9).collect{ |i| ((ratio * i) - (ratio * i).round(0)).abs }
18
+ min , min_index = ratios.each_with_index.min
19
+ [(ratio * (min_index + 1) ).round(0).to_i , (min_index + 1) ]
20
+ end
21
+
22
+ def ratio
23
+ return 0 unless self.height
24
+ self.width.to_f / self.height
25
+ end
26
+
27
+ def copy()
28
+ image = Image.new_image_for( name: "#{name}_copy" , type: type ,
29
+ tags: (tags || "") , width: width ,
30
+ height: height, size: size )
31
+ FileUtils.cp full_filename , image.full_filename
32
+ image
33
+ end
34
+
35
+ def scale( new_size )
36
+ mini = MiniMagick::Image.new( full_filename)
37
+ mini.resize( new_size.to_s + "%")
38
+ init_file_size
39
+ end
40
+
41
+ def crop( to_size )
42
+ mini = MiniMagick::Image.new(full_filename)
43
+ mini.crop( to_size )
44
+ init_file_size
45
+ end
46
+ #save an io as new image. The filename is the id, type taken from io
47
+ def self.create_new(name , tags, io)
48
+ original , end_ = io.original_filename.split("/").last.split(".")
49
+ magick_image = MiniMagick::Image.read(io).auto_orient
50
+ ending = magick_image.type.downcase
51
+ ending = "jpg" if ending == "jpeg"
52
+ name = original if( name.blank? )
53
+ image = self.new_image_for( name: name , type: ending , tags: (tags || "") ,
54
+ width: magick_image.width, height: magick_image.height ,
55
+ size: (magick_image.size/1024).to_i )
56
+ magick_image.write(image.full_filename)
57
+ image
58
+ end
59
+
60
+ def self.new_image_for( image_data )
61
+ new_id = Image.append(image_data)
62
+ Image.new(image_data)
63
+ end
64
+ def destroy(editor)
65
+ File.delete self.full_filename
66
+ delete_save!(editor)
67
+ end
68
+
69
+ def asset_name
70
+ Breeze.images_dir + "/" + self.id.to_s + "." + self.type
71
+ end
72
+
73
+ def full_filename
74
+ full_filename = self.id.to_s + "." + self.type
75
+ Rails.root.join(Image.asset_root, full_filename)
76
+ end
77
+
78
+ def self.transform
79
+ Image.all.each do |image|
80
+ last = image.name.split.last
81
+ image.tags = ""
82
+ ["wide", "small" , "big" , "room"].each do |tag|
83
+ if(last == tag)
84
+ image.name = image.name.gsub(last,"").strip
85
+ image.tags = last
86
+ end
87
+ end
88
+ image.save
89
+ end
90
+ end
91
+
92
+ def init_file_size
93
+ magick_image = MiniMagick::Image.open(full_filename)
94
+ self.width = magick_image.width
95
+ self.height = magick_image.height
96
+ self.size = (magick_image.size/1024).to_i
97
+ end
98
+
99
+ def self.asset_root
100
+ "app/assets/images/" + Breeze.images_dir
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,43 @@
1
+ module Breeze
2
+
3
+ # Quite simple mapping from name to usually a selection of values.
4
+ # Options have type that can be set but usually is inferred from
5
+ # wether there is one values (select) other wise text.
6
+ # date is also supported.
7
+ #
8
+ # a corresponding ./app/views/breeze/sections/_option_form_TYPE.haml
9
+ # nust exist to render the type.
10
+ #
11
+ # Also values may be provided by a module function/attribute on Breeze.
12
+ # eg option text_color (also shade_color) have a Breeze.text_color that return a
13
+ # hash. In this case so it is easy to customize the colors of the app.
14
+ #
15
+ class OptionDefinition < SharedBase
16
+
17
+ set_root_path Rails.root.join(Breeze.data_dir)
18
+
19
+ fields :name , :default , :description , :values , :type
20
+
21
+ def type
22
+ return data[:type] unless data[:type].blank?
23
+ if has_values?
24
+ "select"
25
+ else
26
+ "text"
27
+ end
28
+ end
29
+
30
+ def has_values?
31
+ return true if Breeze.respond_to?( name.to_sym )
32
+ return false if data[:values].nil?
33
+ ! data[:values].empty?
34
+ end
35
+
36
+ def values
37
+ return Breeze.send(name.to_sym).keys if Breeze.respond_to?( name.to_sym )
38
+ return [] unless has_values?
39
+ data[:values].split(" ")
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,97 @@
1
+ module Breeze
2
+ class Page < ViewBase
3
+ set_root_path Rails.root.join(Breeze.data_dir)
4
+
5
+ fields :name , :type , :options, :redirects , :section_template
6
+
7
+ alias :template :section_template
8
+
9
+ def change_name
10
+ self.name
11
+ end
12
+
13
+ def set_name new_name
14
+ new_name = Page.fix_name(new_name)
15
+ olds = self.redirects.to_s.split(" ")
16
+ olds << self.name unless olds.include?(self.name)
17
+ self.redirects = olds.join(" ")
18
+ self.name = new_name
19
+ end
20
+
21
+ def missing_translations
22
+ sum = 0
23
+ sections.collect{ |s | sum += s.missing_translations }
24
+ sum
25
+ end
26
+
27
+ def sections
28
+ Section.find_all(:page_id, id).sort_by{|obj| obj.index }
29
+ end
30
+
31
+ def sections_update
32
+ last_update_for( sections )
33
+ end
34
+
35
+ def template_style
36
+ PageStyle.find_by_type( type )
37
+ end
38
+
39
+ def new_section(section_template = nil)
40
+ section_template = "section_spacer" if section_template.blank?
41
+ section = Section.new_section(section_template, self.id , sections.length + 1)
42
+ section
43
+ end
44
+
45
+ def remove_section(section)
46
+ from_index = section.index
47
+ @sections.delete_at(from_index)
48
+ @content.delete_at(from_index)
49
+ @sections.each_with_index do |section, index|
50
+ section.set_index(index)
51
+ end
52
+ end
53
+
54
+ def first_template
55
+ return "none" unless @content[0]
56
+ @content[0]["template"]
57
+ end
58
+
59
+ def reset_index
60
+ sections.each_with_index{|section, index| section.index = index + 1}
61
+ end
62
+
63
+ def delete(editor)
64
+ sections.each {|section| section.delete(editor) }
65
+ delete_save!(editor)
66
+ end
67
+
68
+ def save(editor)
69
+ olds = self.redirects.to_s.split(" ")
70
+ olds.delete( self.name.to_s )
71
+ self.redirects = olds.join(" ")
72
+ super
73
+ end
74
+
75
+ def previous_page
76
+ return Page.all.last if(self.id == 1)
77
+ Page.all[self.id - 2]
78
+ end
79
+
80
+ def next_page
81
+ all = Page.all
82
+ return all.first if(self.id == all.length)
83
+ all[self.id]
84
+ end
85
+
86
+ def self.fix_name(name)
87
+ name.gsub(" ", "_").downcase
88
+ end
89
+
90
+ def self.new_page(name , type)
91
+ data = { name: self.fix_name(name) , updated_at: Time.now , type: type}
92
+ new_id = Page.append(data)
93
+ Page.new(data)
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ module Breeze
2
+ class PageStyle < Style
3
+ set_root_path Rails.root.join(Breeze.data_dir)
4
+
5
+ fields :type , :description , :section_template
6
+
7
+ def section_preview
8
+ "breeze/section_preview/" + section_template
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,137 @@
1
+ module Breeze
2
+ class Section < ViewBase
3
+
4
+ set_root_path Rails.root.join(Breeze.data_dir)
5
+
6
+ fields :id , :page_id , :index
7
+ fields :template , :card_template
8
+ fields :header, :text , :image_name
9
+
10
+ def page_name
11
+ page ? page.name : "missing page"
12
+ end
13
+
14
+ def change_name
15
+ "#{page_name}:#{header}"
16
+ end
17
+
18
+ def index_name
19
+ "#{self.index}"
20
+ end
21
+
22
+ def object_type
23
+ "Section"
24
+ end
25
+
26
+ def missing_translations
27
+ sum = 0
28
+ cards.collect{ |s | sum += s.missing_translations }
29
+ Breeze.language_strings.each do |lang|
30
+ sum += 1 if get_translation(lang)&.is_old?
31
+ end
32
+ sum
33
+ end
34
+
35
+ def cards
36
+ Card.find_all(:section_id, id).sort_by{|obj| obj.index }
37
+ end
38
+
39
+ def cards_update
40
+ last_update_for( cards )
41
+ end
42
+
43
+ def template_style
44
+ SectionStyle.find_by_template( template )
45
+ end
46
+
47
+ def card_template_style
48
+ CardStyle.find_by_template( card_template )
49
+ end
50
+
51
+ def set_template(new_template)
52
+ self.template = new_template
53
+ new_style = template_style
54
+ if(new_style.has_cards?)
55
+ if card_template.blank?
56
+ self.card_template = CardStyle.first.template
57
+ end
58
+ end
59
+ end
60
+
61
+ def allowed_fields
62
+ super + [:page_id]
63
+ end
64
+
65
+ def has_cards?
66
+ template_style.has_cards?
67
+ end
68
+
69
+ def move_up
70
+ swap_index_with(previous_section)
71
+ end
72
+
73
+ def move_down
74
+ swap_index_with(next_section)
75
+ end
76
+
77
+ def previous_section
78
+ page.sections.find{|s| s.index == index - 1 }
79
+ end
80
+
81
+ def next_section
82
+ page.sections.find{|s| s.index == index + 1 }
83
+ end
84
+
85
+ def new_card
86
+ card = Card.new_card(card_template, self.id , cards.length + 1)
87
+ card
88
+ end
89
+
90
+ def reset_index
91
+ cards.each_with_index{|card, index| card.index = index + 1}
92
+ end
93
+
94
+ def delete(editor)
95
+ cards.each {|card| card.delete(editor) }
96
+ delete_translations(editor)
97
+ delete_save!(editor)
98
+ end
99
+
100
+ def delete_and_reset_index(editor)
101
+ delete(editor)
102
+ Page.find(page_id).reset_index
103
+ Section.save_all
104
+ end
105
+
106
+ def self.new_section(template , page_id , index)
107
+ data = { template: template , index: index , page_id: page_id}
108
+ style = SectionStyle.find_by_template( template)
109
+ style.fields.each do |key|
110
+ data[key.to_sym] = key.upcase
111
+ end unless style.fields.blank?
112
+ if(style.has_cards?)
113
+ data[:card_template] = CardStyle.first.template
114
+ end
115
+ new_id = Section.append(data)
116
+ s = Section.new(data)
117
+ s.add_default_options
118
+ s
119
+ end
120
+
121
+ def self.fix_cards
122
+ Section.all.each do |section|
123
+ next if section.template_style.has_cards?
124
+ puts "#{section.id}: #{section.card_template}"
125
+ section.card_template = nil if section.card_template
126
+ end
127
+ Section.save_all
128
+ nil
129
+ end
130
+
131
+ def self.reload
132
+ res = super()
133
+ self.fix_translations
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,17 @@
1
+ module Breeze
2
+ class SectionStyle < Style
3
+
4
+ set_root_path Rails.root.join(Breeze.data_dir)
5
+
6
+ fields :template , :text , :header, :fields , :cards
7
+
8
+ def has_cards?
9
+ cards
10
+ end
11
+
12
+ def section_preview
13
+ "breeze/section_preview/" + template
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Breeze
2
+ # shared data across engine and app
3
+ # takes a little footwork, as seen below
4
+ # and does not work with saving anymore.
5
+
6
+ class SharedBase < ActiveYaml
7
+
8
+ def self.load_file
9
+ # does super work ? Copied, wet wet wet
10
+ mod , filename = self.name.split("::").collect{|p| p.underscore}
11
+ fullname = mod + "/" + filename.tableize + ".yml"
12
+ res = YAML.load(File.read(File.join(self.path , fullname )))
13
+
14
+ breeze_path = Breeze::Engine.root.join("config")
15
+ breeze_res = YAML.load(File.read(File.join(breeze_path , fullname )))
16
+
17
+ res + breeze_res
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Breeze
2
+ class Style < SharedBase
3
+
4
+ fields :options
5
+
6
+ def options_definitions
7
+ option_defs = []
8
+ options.each do |name|
9
+ option = OptionDefinition.find_by_name(name)
10
+ raise "no option for #{name}:#{name.class}" if option.blank?
11
+ option_defs << option
12
+ end if options
13
+ option_defs
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,83 @@
1
+ module Breeze
2
+ class Translation < ActiveBase
3
+
4
+ set_root_path Rails.root.join(Breeze.data_dir)
5
+
6
+ fields :id
7
+ fields :objectid , :object_type # poly: card or section (id without _, no association)
8
+ fields :language # the language for which the is a translation
9
+ fields :text , :header, :sub_header #actual text fields
10
+
11
+ def initialize(data)
12
+ super(data)
13
+ raise "no object type" unless self.object_type
14
+ raise "no object id" unless lang = self.objectid
15
+ raise "no language" unless lang = self.language
16
+ raise "not configured language #{lang}" unless Breeze.has_language(lang)
17
+ end
18
+
19
+ def object
20
+ clazz = "Breeze::#{object_type}".constantize
21
+ clazz.find( objectid )
22
+ end
23
+
24
+ def is_old?
25
+ return true unless self.updated_at
26
+ object.updated_at > self.updated_at
27
+ end
28
+
29
+ def change_name
30
+ "Translation: #{object.change_name}"
31
+ end
32
+
33
+ def update(hash , user)
34
+ return unless hash
35
+ [:text , :header ].each do |key|
36
+ data[key] = hash[key] if hash.has_key?(key)
37
+ end
38
+ add_save(user)
39
+ end
40
+
41
+ class << self
42
+
43
+ def fill_data(object, data = {})
44
+ data[:text] = object.text
45
+ data[:header] = object.header
46
+ data[:objectid] = object.id
47
+ data[:object_type] = object.object_type
48
+ data
49
+ end
50
+
51
+ def find_translation(objectid , object_type, language)
52
+ find_all(:objectid, objectid).each do |o|
53
+ return o if (objectid == o.objectid ) &&
54
+ (object_type == o.object_type) &&
55
+ (language == o.language)
56
+ end
57
+ nil
58
+ end
59
+
60
+ def ensure_translation(object , language)
61
+ found = self.find_translation(object.id , object.object_type , language)
62
+ return nil if found
63
+ data = fill_data(object)
64
+ data[:updated_at] = object.updated_at - 1.day
65
+ data[:language] = language
66
+ data[:id] = "#{object.object_type}_#{object.id}"
67
+ data
68
+ end
69
+
70
+ def new_object_translation(object, data)
71
+ self.fill_data(object,data)
72
+ self.new_translation(data)
73
+ end
74
+
75
+ # append data and create new object.
76
+ def new_translation( data )
77
+ new_id = Translation.append(data)
78
+ Translation.new(data)
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,134 @@
1
+ module Breeze
2
+
3
+ # base class for viewable elements: ie page, section and casrd
4
+ # they share the template idea, options , change tracking,
5
+ # and the fact that they persist in ActiveYaml
6
+
7
+ class ViewBase < ActiveBase
8
+
9
+ fields :options , :image_id
10
+
11
+ def header_text(lang)
12
+ return self.header if lang.blank?
13
+ get_translation(lang).header
14
+ end
15
+
16
+ def text_text(lang)
17
+ return self.text if lang.blank?
18
+ get_translation(lang).text
19
+ end
20
+
21
+ def type_id
22
+ "#{object_type}_#{self.id}"
23
+ end
24
+
25
+ def last_update_for(elements)
26
+ last = Time.now
27
+ last_section = nil
28
+ elements.each do |section|
29
+ if( section.updated_at < last )
30
+ last = section.updated_at
31
+ last_section = section
32
+ end
33
+ end
34
+ last_section
35
+ end
36
+
37
+ def has_option?(option)
38
+ safe_options.has_key?(option) and !safe_options[option].blank?
39
+ end
40
+
41
+ def option_definitions
42
+ template_style.options_definitions
43
+ end
44
+
45
+ def option(name)
46
+ opts = safe_options
47
+ opts[name]
48
+ end
49
+
50
+ def safe_options
51
+ return data[:options] unless data[:options].blank?
52
+ data[:options] = {}
53
+ end
54
+
55
+ def set_option( option , value)
56
+ if( option.ends_with?"_date" )
57
+ puts "date is #{value}"
58
+ year = value[:year] || Time.new.year
59
+ value = Time.new( year.to_i , value[:month] , value[:day]).to_date
60
+ end
61
+ safe_options[option] = value
62
+ end
63
+
64
+ def add_default_options( definitions = nil )
65
+ definitions = option_definitions if definitions.nil?
66
+ definitions.each do |option|
67
+ next unless option.default
68
+ set_option( option.name , option.default)
69
+ end
70
+ end
71
+
72
+ def update(hash)
73
+ return unless hash
74
+ hash.each do |key , value|
75
+ value = value.to_i if key.to_s.include?("_id")
76
+ key = key.to_sym
77
+ raise "unsuported field :#{key} for #{template}:#{allowed_fields}" unless allowed_fields.include?(key)
78
+ if(! data[key].nil? ) # first setting ok, types not (yet?) specified
79
+ if( data[key].class != value.class )
80
+ raise "Type mismatch #{key} #{data[key].class}!=#{value.class}"
81
+ end
82
+ end
83
+ data[key] = value
84
+ end
85
+ end
86
+
87
+ def update_options( options )
88
+ return unless options
89
+ option_definitions.each do |option|
90
+ set_option(option.name, options[option.name])
91
+ end
92
+ end
93
+ #other may be nil
94
+ def swap_index_with(other)
95
+ return unless other
96
+ old_index = self.index
97
+ self.index = other.index
98
+ other.index = old_index
99
+ end
100
+
101
+ def allowed_fields
102
+ template_style.fields.collect{|f| f.to_sym}
103
+ end
104
+
105
+ def image_old
106
+ Image.find_by_name(self.image_name)
107
+ end
108
+
109
+ def get_translation(lang)
110
+ Translation.find_translation(self.id , self.object_type , lang)
111
+ end
112
+
113
+ def delete_translations(editor)
114
+ Breeze.language_strings.each do |lang|
115
+ trans = Translation.find_translation(self.id, self.object_type , lang)
116
+ trans.delete_save!(editor) if trans
117
+ end
118
+ end
119
+
120
+ def self.fix_translations
121
+ create = []
122
+ Breeze.language_strings.each do |lang|
123
+ self.all.each do |object|
124
+ data = Translation.ensure_translation(object , lang)
125
+ (create << data) unless data.nil?
126
+ end
127
+ end
128
+ #puts "#{self.name} create #{create.length} Translations"
129
+ create.each{ |data| Translation.new_translation(data) }
130
+ Translation.save_all
131
+ end
132
+
133
+ end
134
+ end