loyal_core 0.0.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 (139) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +3 -0
  3. data/Rakefile +27 -0
  4. data/app/assets/images/loyal_core/down_rating.gif +0 -0
  5. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/ico_missing.gif +0 -0
  6. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/medium_missing.gif +0 -0
  7. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/mini_missing.gif +0 -0
  8. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/missing.gif +0 -0
  9. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/small_missing.gif +0 -0
  10. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/thumb_missing.gif +0 -0
  11. data/app/assets/images/loyal_core/fallbacks/loyal_core/skin/recipe/avatar/tiny_missing.gif +0 -0
  12. data/app/assets/images/loyal_core/fallbacks/user/avatar/ico_missing.gif +0 -0
  13. data/app/assets/images/loyal_core/fallbacks/user/avatar/medium_missing.gif +0 -0
  14. data/app/assets/images/loyal_core/fallbacks/user/avatar/mini_missing.gif +0 -0
  15. data/app/assets/images/loyal_core/fallbacks/user/avatar/missing.gif +0 -0
  16. data/app/assets/images/loyal_core/fallbacks/user/avatar/small_missing.gif +0 -0
  17. data/app/assets/images/loyal_core/fallbacks/user/avatar/thumb_missing.gif +0 -0
  18. data/app/assets/images/loyal_core/fallbacks/user/avatar/tiny_missing.gif +0 -0
  19. data/app/assets/images/loyal_core/liked.gif +0 -0
  20. data/app/assets/images/loyal_core/unlike.gif +0 -0
  21. data/app/assets/images/loyal_core/up_rating.gif +0 -0
  22. data/app/assets/javascripts/jquery.cookie.js +95 -0
  23. data/app/assets/javascripts/loyal_core/admin/skin/folders.js +2 -0
  24. data/app/assets/javascripts/loyal_core/admin/skin/recipes.js +2 -0
  25. data/app/assets/javascripts/loyal_core/ajax/captchas.js +2 -0
  26. data/app/assets/javascripts/loyal_core/ajax/like_tracks.js +2 -0
  27. data/app/assets/javascripts/loyal_core/ajax/rating_tracks.js +3 -0
  28. data/app/assets/javascripts/loyal_core/ajax/users/sessions.js +2 -0
  29. data/app/assets/javascripts/loyal_core/ajax.js +124 -0
  30. data/app/assets/javascripts/loyal_core/application.js +6 -0
  31. data/app/assets/javascripts/loyal_core/jumps.js +2 -0
  32. data/app/assets/javascripts/loyal_core/tools/append_params_return_to.js +21 -0
  33. data/app/assets/javascripts/loyal_core/tools/editor_content_mode_selector.js +8 -0
  34. data/app/assets/javascripts/loyal_core/tools/font_selector.js +83 -0
  35. data/app/assets/stylesheets/loyal_core/admin/skin/folders.css +4 -0
  36. data/app/assets/stylesheets/loyal_core/admin/skin/recipes.css +4 -0
  37. data/app/assets/stylesheets/loyal_core/ajax/captchas.css +4 -0
  38. data/app/assets/stylesheets/loyal_core/ajax/like_tracks.css +4 -0
  39. data/app/assets/stylesheets/loyal_core/ajax/rating_tracks.css +4 -0
  40. data/app/assets/stylesheets/loyal_core/ajax/users/sessions.css +4 -0
  41. data/app/assets/stylesheets/loyal_core/application.css.scss +18 -0
  42. data/app/assets/stylesheets/loyal_core/jumps.css +4 -0
  43. data/app/controllers/loyal_core/admin/skin/folders_controller.rb +54 -0
  44. data/app/controllers/loyal_core/admin/skin/recipes_controller.rb +52 -0
  45. data/app/controllers/loyal_core/ajax/captchas_controller.rb +26 -0
  46. data/app/controllers/loyal_core/ajax/like_tracks_controller.rb +33 -0
  47. data/app/controllers/loyal_core/ajax/rating_tracks_controller.rb +41 -0
  48. data/app/controllers/loyal_core/ajax/users/sessions_controller.rb +8 -0
  49. data/app/controllers/loyal_core/ajax_controller.rb +14 -0
  50. data/app/controllers/loyal_core/application_controller.rb +6 -0
  51. data/app/controllers/loyal_core/jumps_controller.rb +10 -0
  52. data/app/helpers/loyal_core/admin/skin/folders_helper.rb +5 -0
  53. data/app/helpers/loyal_core/admin/skin/recipes_helper.rb +5 -0
  54. data/app/helpers/loyal_core/ajax/captchas_helper.rb +6 -0
  55. data/app/helpers/loyal_core/ajax/like_tracks_helper.rb +6 -0
  56. data/app/helpers/loyal_core/ajax/rating_tracks_helper.rb +6 -0
  57. data/app/helpers/loyal_core/ajax/users/sessions_helper.rb +5 -0
  58. data/app/helpers/loyal_core/application_helper.rb +6 -0
  59. data/app/helpers/loyal_core/jumps_helper.rb +5 -0
  60. data/app/models/kindeditor/asset.rb +14 -0
  61. data/app/models/kindeditor/file.rb +4 -0
  62. data/app/models/kindeditor/flash.rb +4 -0
  63. data/app/models/kindeditor/image.rb +4 -0
  64. data/app/models/kindeditor/media.rb +4 -0
  65. data/app/models/loyal_core/like_track.rb +15 -0
  66. data/app/models/loyal_core/rating_track.rb +32 -0
  67. data/app/models/loyal_core/skin/dish.rb +10 -0
  68. data/app/models/loyal_core/skin/folder.rb +26 -0
  69. data/app/models/loyal_core/skin/recipe.rb +31 -0
  70. data/app/models/loyal_core/skin.rb +8 -0
  71. data/app/uploaders/loyal_core/asset_uploader.rb +128 -0
  72. data/app/uploaders/loyal_core/avatar_uploader.rb +37 -0
  73. data/app/views/layouts/loyal_core/application.html.erb +14 -0
  74. data/app/views/loyal_core/admin/skin/folders/_form.html.erb +9 -0
  75. data/app/views/loyal_core/admin/skin/folders/edit.html.erb +11 -0
  76. data/app/views/loyal_core/admin/skin/folders/index.html.erb +25 -0
  77. data/app/views/loyal_core/admin/skin/folders/new.html.erb +11 -0
  78. data/app/views/loyal_core/admin/skin/folders/show.html.erb +32 -0
  79. data/app/views/loyal_core/admin/skin/recipes/_form.html.erb +25 -0
  80. data/app/views/loyal_core/admin/skin/recipes/edit.html.erb +11 -0
  81. data/app/views/loyal_core/admin/skin/recipes/index.html.erb +37 -0
  82. data/app/views/loyal_core/admin/skin/recipes/new.html.erb +11 -0
  83. data/app/views/loyal_core/admin/skin/recipes/show.html.erb +16 -0
  84. data/app/views/loyal_core/ajax/captchas/_new.html.erb +1 -0
  85. data/app/views/loyal_core/ajax/captchas/new.html.erb +1 -0
  86. data/app/views/loyal_core/jumps/show.html.erb +12 -0
  87. data/app/views/simple_captcha/_simple_captcha.erb +16 -0
  88. data/config/locales/en/default.en.yml +139 -0
  89. data/config/locales/en/loyal_simple_captcha.en.yml +8 -0
  90. data/config/locales/zh-CN/action_view.zh-CN.yml +8 -0
  91. data/config/locales/zh-CN/default.zh-CN.yml +199 -0
  92. data/config/locales/zh-CN/loyal_simple_captcha.zh-CN.yml +8 -0
  93. data/config/locales/zh-CN/paginate.zh-CN.yml +8 -0
  94. data/config/routes.rb +24 -0
  95. data/db/migrate/20130331104216_create_loyal_core_rating_tracks.rb +19 -0
  96. data/db/migrate/20130331104822_create_loyal_core_like_tracks.rb +19 -0
  97. data/db/migrate/20130413061851_create_kindeditor_assets.rb +17 -0
  98. data/db/migrate/20130610091558_create_loyal_core_skin_folders.rb +48 -0
  99. data/db/migrate/20130610095635_create_loyal_core_skin_recipes.rb +28 -0
  100. data/db/migrate/20130610095938_create_loyal_core_skin_dishes.rb +13 -0
  101. data/lib/loyal_core/action_controller/request_init.rb +33 -0
  102. data/lib/loyal_core/action_controller/seo_methods.rb +47 -0
  103. data/lib/loyal_core/action_controller.rb +4 -0
  104. data/lib/loyal_core/action_helper/ajax/like_tracks_helper.rb +26 -0
  105. data/lib/loyal_core/action_helper/ajax/rating_tracks_helper.rb +35 -0
  106. data/lib/loyal_core/action_helper/font_selector_helper.rb +25 -0
  107. data/lib/loyal_core/action_helper.rb +27 -0
  108. data/lib/loyal_core/action_view/labeled_builder.rb +127 -0
  109. data/lib/loyal_core/action_view.rb +7 -0
  110. data/lib/loyal_core/active_model/fix_counter_cache.rb +39 -0
  111. data/lib/loyal_core/active_model/human_display_able.rb +26 -0
  112. data/lib/loyal_core/active_model/strip_whitespace.rb +27 -0
  113. data/lib/loyal_core/active_model.rb +16 -0
  114. data/lib/loyal_core/acts/bit_able.rb +139 -0
  115. data/lib/loyal_core/acts/content_depart_able.rb +102 -0
  116. data/lib/loyal_core/acts/content_mode_able.rb +88 -0
  117. data/lib/loyal_core/acts/has_avatar.rb +31 -0
  118. data/lib/loyal_core/acts/has_permalink.rb +43 -0
  119. data/lib/loyal_core/acts/like_track_able.rb +90 -0
  120. data/lib/loyal_core/acts/named_filter_able.rb +40 -0
  121. data/lib/loyal_core/acts/rating_track_able.rb +76 -0
  122. data/lib/loyal_core/acts/skin_dish_able.rb +56 -0
  123. data/lib/loyal_core/acts/tree.rb +104 -0
  124. data/lib/loyal_core/acts/uuid_ful.rb +39 -0
  125. data/lib/loyal_core/acts/views_count_able.rb +33 -0
  126. data/lib/loyal_core/acts.rb +35 -0
  127. data/lib/loyal_core/config.rb +116 -0
  128. data/lib/loyal_core/core_ext/singleton_class.rb +9 -0
  129. data/lib/loyal_core/engine.rb +11 -0
  130. data/lib/loyal_core/memoist.rb +204 -0
  131. data/lib/loyal_core/utils/array_util.rb +16 -0
  132. data/lib/loyal_core/utils/config_util.rb +186 -0
  133. data/lib/loyal_core/utils/data_util.rb +181 -0
  134. data/lib/loyal_core/utils/text_util.rb +49 -0
  135. data/lib/loyal_core/utils.rb +8 -0
  136. data/lib/loyal_core/version.rb +4 -0
  137. data/lib/loyal_core.rb +17 -0
  138. data/lib/tasks/loyal_core_tasks.rake +11 -0
  139. metadata +231 -0
@@ -0,0 +1,47 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore::ActionController
3
+ module SeoMethods
4
+ def self.included base
5
+ base.class_eval do
6
+ helper_method :page_title, :page_keywords, :page_description
7
+ helper_method :page_title_set, :page_keywords_set, :page_description_set
8
+
9
+ include InstanceMethods
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ [:title, :keywords, :description].each do |name|
15
+ define_method :"page_#{name}" do
16
+ (@__loyal_core_page_info ||= {})[name]
17
+ end
18
+ end
19
+
20
+ def page_title_set title=nil, &block
21
+ if block_given?
22
+ (@__loyal_core_page_info ||= {})[:title] = block.call
23
+ else
24
+ (@__loyal_core_page_info ||= {})[:title] = title
25
+ end
26
+ end
27
+
28
+ def page_keywords_set keywords=nil, &block
29
+ if block_given?
30
+ (@__loyal_core_page_info ||= {})[:keywords] = block.call
31
+ else
32
+ (@__loyal_core_page_info ||= {})[:keywords] = keywords
33
+ end
34
+ end
35
+
36
+ def page_description_set description=nil, &block
37
+ if block_given?
38
+ (@__loyal_core_page_info ||= {})[:description] = block.call
39
+ else
40
+ (@__loyal_core_page_info ||= {})[:description] = description
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require "#{File.dirname(__FILE__)}/action_controller/seo_methods"
3
+ require "#{File.dirname(__FILE__)}/action_controller/request_init"
4
+
@@ -0,0 +1,26 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module Ajax
4
+ module LikeTracksHelper
5
+ def loyal_core_helper_ajax_liker_link_to target, options={}
6
+ link_to "javascript:;", {
7
+ 'march-on' => 'ajax',
8
+ 'march-type' => 'march-type',
9
+ 'march-id' => target.uuid,
10
+ 'march-action' => 'like'
11
+ }.merge(options) do
12
+ html = ""
13
+ html << (
14
+ image_tag image_path("loyal_core/liked.gif"), :class => 'liked', :style => "display: #{target.liked_by?(current_user) ? 'inline' : 'none'};"
15
+ )
16
+
17
+ html << (
18
+ image_tag image_path("loyal_core/unlike.gif"), :class => 'unlike', :style => "display: #{target.liked_by?(current_user) ? 'none' : 'inline'};"
19
+ )
20
+ html << "<span class='count'>#{target.liked_count}</span>"
21
+ raw html
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module Ajax
4
+ module RatingTracksHelper
5
+ def loyal_core_helper_ajax_up_rating_link_to target, options={}
6
+ link_to "javascript:;", {
7
+ 'march-on' => 'ajax',
8
+ 'march-type' => 'target-type',
9
+ 'march-id' => target.uuid,
10
+ 'march-action' => 'up'
11
+ }.merge(options) do
12
+ html = ''
13
+ html << (image_tag image_path("loyal_core/up_rating.gif"))
14
+ html << "<span class='count'>#{target.up_rating}</span>"
15
+ raw html
16
+ end
17
+ end
18
+
19
+ def loyal_core_helper_ajax_down_rating_link_to target, options={}
20
+ link_to "javascript:;", {
21
+ 'march-on' => 'ajax',
22
+ 'march-type' => 'target-type',
23
+ 'march-id' => target.uuid,
24
+ 'march-action' => 'down'
25
+ }.merge(options) do
26
+ html = ''
27
+ html << (image_tag image_path("loyal_core/down_rating.gif"))
28
+ html << "<span class='count'>#{target.down_rating}</span>"
29
+ raw html
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module FontSelectorHelper
4
+ def loyal_core_helper_font_selector *args
5
+ options = args.extract_options!
6
+
7
+ selector = args.first || 'body'
8
+
9
+ html = ''
10
+
11
+ html << <<-HTML
12
+ <span class='loyal-core-font-size-selector'>
13
+ 字体
14
+ <input type='hidden' name='font-selector-size' value='#{selector.html_safe}'/>
15
+ <a href='javascript:;' loyal-data-type-size='small'>小</a>
16
+ <a href='javascript:;' loyal-data-type-size='medium'>中</a>
17
+ <a href='javascript:;' loyal-data-type-size='large'>大</a>
18
+ </span>
19
+ HTML
20
+
21
+ html.html_safe
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require "#{File.dirname(__FILE__)}/action_helper/ajax/like_tracks_helper"
3
+ require "#{File.dirname(__FILE__)}/action_helper/ajax/rating_tracks_helper"
4
+ require "#{File.dirname(__FILE__)}/action_helper/font_selector_helper"
5
+
6
+ module LoyalCore
7
+ module ActionHelper
8
+ include ::LoyalCore::Ajax::RatingTracksHelper
9
+ include ::LoyalCore::Ajax::LikeTracksHelper
10
+ include ::LoyalCore::FontSelectorHelper
11
+
12
+
13
+
14
+
15
+ def render_new_simple_captcha_partial options={}
16
+ render :partial => '/loyal_core/ajax/captchas/new', :locals => {
17
+ :options => generate_simple_captcha_options(options)
18
+ }
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+ if defined?(ActionController::Base)
25
+ ActionController::Base.send :helper, ::LoyalCore::ActionHelper
26
+ end
27
+
@@ -0,0 +1,127 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore::ActionView
3
+ class LabeledBuilder < ::ActionView::Helpers::FormBuilder
4
+ # 选择编辑器的类型
5
+ def select_editor_content_mode name, *args
6
+ (field_label name, *args) + @template.tag(:br) + self.select(
7
+ name,
8
+ object.class.send(:"content_mode_config").to_select_options,
9
+ {},
10
+ {
11
+ :class => 'loyal-editor-content-mode-selector'
12
+ }
13
+ )
14
+ end
15
+
16
+ %w[kindeditor url_field text_field text_area password_field collection_select].each do |method_name|
17
+ define_method method_name do |name, *args|
18
+ @template.content_tag :div, class: "field" do
19
+ (field_label name, *args) + @template.tag(:br) + super(name, *args)
20
+ end
21
+ end
22
+ end
23
+
24
+ def select_with_label name, *args
25
+ @template.content_tag :div, class: "field" do
26
+ (field_label name, *args) + @template.tag(:br) + self.select(name, *args)
27
+ end
28
+ end
29
+
30
+ def filter_named_select name, *args
31
+ (field_label name, *args) + @template.tag(:br) + select(
32
+ name, object.class.send(:"#{name}_named_filter_config").to_select_options
33
+ )
34
+ end
35
+
36
+ def bit_able_check_box name, *args
37
+ result = (field_label name, *args) + @template.tag(:br)
38
+
39
+ config = object.class.send(:"#{name}_bit_config")
40
+
41
+ config.keys.each do |_name|
42
+ _config = config[_name]
43
+
44
+ if _config.value > 0
45
+ _checkbox_options = {
46
+ :type => :checkbox,
47
+ :value => _config.key,
48
+ :name => "#{name}_values[]"
49
+ }
50
+
51
+ if object.send(:"#{name}_bit?", _name)
52
+ _checkbox_options[:checked] = :checked
53
+ end
54
+
55
+ result << (
56
+ @template.tag :input, _checkbox_options
57
+ )
58
+
59
+ result << "#{_config.desc}"
60
+ end
61
+ end
62
+
63
+ result
64
+ end
65
+
66
+ def submit value=nil, options={}
67
+ @template.submit_tag (value || I18n.t('loyal_core.action_view.form_builder.submit.default_value')),
68
+ options.reverse_merge(
69
+ :data => {
70
+ :disable_with => I18n.t('loyal_core.action_view.form_builder.submit.disable_with')
71
+ }
72
+ )
73
+ end
74
+
75
+ # def check_box(name, *args)
76
+ # @template.content_tag :div, class: 'field' do
77
+ # super + ' ' + field_label(name, *args)
78
+ # end
79
+ # end
80
+
81
+ def nested_parent_select name, class_or_item, *args
82
+ impl_nested_belongs_to_select_with_mover name, object, class_or_item, object.class, *args
83
+
84
+ # @template.content_tag :div, class: "field" do
85
+ # (field_label name, *args) + @template.tag(:br) + select(
86
+ # name, *([object.class.nested_set_select_options(nil, object, :include_blank => true)] + args)
87
+ # )
88
+ # end
89
+ end
90
+
91
+ def nested_belongs_to_select name, clazz, class_or_item, *args
92
+ impl_nested_belongs_to_select_with_mover name, nil, class_or_item, clazz, *args
93
+ end
94
+
95
+ def error_messages
96
+ if object.errors.full_messages.any?
97
+ @template.content_tag(:div, :class => 'error_messages') do
98
+ @template.content_tag :h2, (
99
+ "#{@template.pluralize(object.errors.count, "error")} #{I18n.t('views.form.prohibited_being_saved')}:"
100
+ )
101
+
102
+ @template.content_tag :ul do
103
+ object.errors.full_messages.map do |msg|
104
+ @template.content_tag :li, msg
105
+ end.join.html_safe
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ def impl_nested_belongs_to_select_with_mover name, mover, class_or_item, clazz, *args
114
+ @template.content_tag :div, class: "field" do
115
+ (field_label name, *args) + @template.tag(:br) + select(
116
+ name, *([clazz.nested_set_select_options(class_or_item, mover, :include_blank => true)] + args)
117
+ )
118
+ end
119
+ end
120
+
121
+ def field_label(name, *args)
122
+ options = args.extract_options!
123
+ label(name, options[:label])
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,7 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActionView
4
+ autoload :LabeledBuilder, "#{File.dirname(__FILE__)}/action_view/labeled_builder"
5
+ end
6
+ end
7
+
@@ -0,0 +1,39 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActiveModel
4
+ module FixCounterCache
5
+ def self.included base
6
+ base.class_eval do
7
+ extend ClassMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ #
13
+ # usage:
14
+ # self.loyal_core_fix_counter_cache :folder_id => {
15
+ # :counter => :articles_count,
16
+ # :class => ::Ruby800::Juice::Folder
17
+ # }
18
+ #
19
+ def loyal_core_fix_counter_cache *args
20
+ options = args.extract_options!
21
+
22
+ options.each do |key, opts|
23
+ before_save do |r|
24
+ _id = key
25
+ _counter = opts[:counter]
26
+ _class = opts[:class]
27
+
28
+ if !(r.new_record?) && r.send(:"#{_id}_changed?")
29
+ _class.decrement_counter(:"#{_counter}", r.send(:"#{_id}_was"))
30
+ _class.increment_counter(:"#{_counter}", r.send(:"#{_id}"))
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,26 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActiveModel
4
+ module HumanDisplayAble
5
+ def self.included base
6
+ base.class_eval do
7
+ extend ClassMethods
8
+ include InstanceMethods
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def human_name
14
+ self.model_name.human
15
+ end
16
+ end
17
+
18
+ module InstanceMethods
19
+ def class_human_name
20
+ self.class.human_name
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActiveModel
4
+ # 用于在校验的时候去除首尾的空格
5
+ module StripWhitespace
6
+ def self.included base
7
+ base.class_eval do
8
+ extend ClassMethods
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def strip_whitespace_before_validation *args
15
+ options = args.extract_options!
16
+
17
+ before_validation do |r|
18
+ args.each do |field|
19
+ self.send :"#{field}=", self.send(field).to_s.strip
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActiveModel
4
+ autoload :StripWhitespace, "#{File.dirname(__FILE__)}/active_model/strip_whitespace"
5
+ autoload :FixCounterCache, "#{File.dirname(__FILE__)}/active_model/fix_counter_cache"
6
+ autoload :HumanDisplayAble, "#{File.dirname(__FILE__)}/active_model/human_display_able"
7
+ end
8
+ end
9
+
10
+ if defined?(::ActiveRecord::Base)
11
+ ::ActiveRecord::Base.send :include, ::LoyalCore::ActiveModel::StripWhitespace
12
+ ::ActiveRecord::Base.send :include, ::LoyalCore::ActiveModel::FixCounterCache
13
+ ::ActiveRecord::Base.send :include, ::LoyalCore::ActiveModel::HumanDisplayAble
14
+ end
15
+
16
+
@@ -0,0 +1,139 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ module ActsAsBitAble
4
+ def self.included(base)
5
+ base.class_eval do
6
+ extend ClassMethods
7
+ end
8
+ end
9
+
10
+ module ClassMethods
11
+ def loyal_core_acts_as_bit_able_util_get_values *names, config
12
+ values = []
13
+
14
+ ::LoyalCore::ArrayUtil.init(names).each do |_name|
15
+ _config = config.at _name
16
+
17
+ if _config && (_val = _config.value)
18
+ (1.upto(2 ** config.max_value)).each do |__val|
19
+ if __val & _val == _val
20
+ values << __val
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ values.uniq.sort
27
+ end
28
+
29
+ #
30
+ # field_name
31
+ # options:
32
+ # - config:
33
+ #
34
+ # 定义了:
35
+ # - filter_by_bit_color *names
36
+ # - color_bit_set name
37
+ # - color_bit_unset name
38
+ # - color_bit? name
39
+ # - color_bit_reset!
40
+ # - color_bit_list
41
+ # - color_bit_list= *names
42
+ #
43
+ def loyal_core_acts_as_bit_able *args
44
+ options = args.extract_options!
45
+
46
+ field_name = args.first
47
+
48
+ if field_name.nil?
49
+ raise "#{self}.loyal_core_acts_as_bit_able field_name can not be nil"
50
+ end
51
+
52
+ config = options[:config] || ::LoyalCore::ConfigUtil.new
53
+
54
+ scope :"filter_by_bit_#{field_name}", ->(*names_args) do
55
+ _values = loyal_core_acts_as_bit_able_util_get_values *names_args, config
56
+
57
+ if _values.any?
58
+ where :"#{field_name}" => _values
59
+ end
60
+ end
61
+
62
+ # attr_accessor :"#{field_name}_values"
63
+
64
+ self.class.send :define_method, :"#{field_name}_bit_config" do
65
+ config
66
+ end
67
+
68
+ # level_bit_set name
69
+ # level_bit? name
70
+ # level_bit_unset name
71
+
72
+ define_method :"#{field_name}_bit_set" do |name, saved=false|
73
+ _config = config.at name
74
+
75
+ result = self.send("#{field_name}=", (self.send(field_name) | _config.value))
76
+ self.save if saved
77
+ result
78
+ end
79
+
80
+ define_method :"#{field_name}_bit?" do |name, saved=false|
81
+ _config = config.at name
82
+ value = _config.value
83
+
84
+ result = (self.send(field_name) & value) == value
85
+ self.save if saved
86
+ result
87
+ end
88
+
89
+ define_method :"#{field_name}_bit_unset" do |name, saved=false|
90
+ _config = config.at name
91
+ value = _config.value
92
+
93
+ result = if self.send("#{field_name}_bit?", name)
94
+ self.send("#{field_name}=", (self.send(field_name) - value))
95
+ else
96
+ self.send("#{field_name}")
97
+ end
98
+
99
+ self.save if saved
100
+
101
+ result
102
+ end
103
+
104
+ # 重置
105
+ define_method :"#{field_name}_bit_reset!" do |saved=false|
106
+ result = self.send("#{field_name}=", 0)
107
+
108
+ self.save if saved
109
+
110
+ result
111
+ end
112
+
113
+ #
114
+ # colors_bit_list: 获取bit配置列表
115
+ #
116
+ define_method :"#{field_name}_bit_list" do
117
+ config.keys.inject([]) do |result, name|
118
+ if config.at(name).value.to_i > 0 && self.send(:"#{field_name}_bit?", name)
119
+ result << name
120
+ end
121
+
122
+ result
123
+ end
124
+ end
125
+
126
+ define_method :"#{field_name}_bit_list=" do |names|
127
+ self.send :"#{field_name}_bit_reset!", false
128
+
129
+ names.each do |name|
130
+ self.send :"#{field_name}_bit_set", name, false
131
+ end
132
+
133
+ self.send :"#{field_name}_bit_list"
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
@@ -0,0 +1,102 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalCore
3
+ # 大字段分离
4
+ module ActsAsContentDepartAble
5
+ def self.included base
6
+ base.class_eval do
7
+ extend ClassMethods
8
+ end
9
+ end
10
+
11
+ LOYAL_CORE_OUTLINE_MAX_LENGTH = 255.freeze
12
+
13
+ module ClassMethods
14
+ #
15
+ # options:
16
+ # - worker_class
17
+ #
18
+ def loyal_core_acts_as_content_owner *args
19
+ options = args.extract_options!
20
+
21
+ self.attr_accessible :content, :outline, :content_code, :content_mode, :content_mode_was_cache
22
+
23
+ worker_class = options[:worker_class]
24
+
25
+ belongs_to :content_worker, :class_name => "#{worker_class.to_s}", :dependent => :destroy,
26
+ :foreign_key => options[:foreign_key]
27
+
28
+ before_validation do |r|
29
+ # FIXME: 大纲该如何生成呢?
30
+
31
+ r.outline = ::Sanitize.clean(
32
+ r.content_text,
33
+ ::LoyalCore.config.sanitize_config[:text]
34
+ ).to_s[0...LOYAL_CORE_OUTLINE_MAX_LENGTH]
35
+ end
36
+
37
+ # validates_length_of :outline, :maximum => LOYAL_CORE_OUTLINE_MAX_LENGTH
38
+
39
+ after_save do |r|
40
+ r.lastest_content_worker.target = r
41
+ r.lastest_content_worker.save!
42
+ end
43
+
44
+ define_method :lastest_content_worker do
45
+ self.content_worker ||= worker_class.new
46
+ end
47
+
48
+ ###############################################
49
+ define_singleton_method :content_mode_config do
50
+ worker_class.content_mode_config
51
+ end
52
+
53
+ delegate :words_amount_more?, :content=, :content, :content_text, :words_amount,
54
+ :content_code=, :content_code,
55
+ :content_mode, :content_mode=,
56
+
57
+ :content_mode_was_cache, :content_mode_was_cache=,
58
+ :content_mode_was_cache_changed?,
59
+ :content_mode_was_cache_reset!,
60
+
61
+ :content_mode_name=, :content_mode_name,
62
+ :to => :lastest_content_worker
63
+
64
+ validate do |r|
65
+ # 如果正文的格式改变了,需要提示
66
+ if r.content_mode_was_cache_changed?
67
+ r.errors.add(:content_mode, '变化了, 请检查正文格式')
68
+ r.content_mode_was_cache_reset!
69
+ end
70
+ end
71
+
72
+ include ContentOwnerInstanceMethods
73
+ end
74
+
75
+ module ContentOwnerInstanceMethods
76
+
77
+ end
78
+
79
+ #
80
+ # options:
81
+ # - owner_class
82
+ #
83
+ def loyal_core_acts_as_conent_worker *args
84
+ options = args.extract_options!
85
+
86
+ belongs_to :target, :polymorphic => true
87
+
88
+ before_validation do |r|
89
+ r.words_amount = r.content_text.size
90
+ end
91
+
92
+ include ContentWorkerMethods
93
+ end
94
+
95
+ module ContentWorkerMethods
96
+ def words_amount_more? count=LOYAL_CORE_OUTLINE_MAX_LENGTH
97
+ self.words_amount > count
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end