zen 0.2.4.1 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. data/MANIFEST +42 -33
  2. data/README.md +14 -27
  3. data/ROADMAP.md +20 -2
  4. data/{Thorfile → Rakefile} +2 -3
  5. data/bin/zen +27 -5
  6. data/lib/zen.rb +70 -52
  7. data/lib/zen/asset.rb +258 -0
  8. data/lib/zen/bin/app.rb +42 -0
  9. data/lib/zen/controller/admin_controller.rb +53 -36
  10. data/lib/zen/controller/base_controller.rb +13 -8
  11. data/lib/zen/controller/frontend_controller.rb +4 -3
  12. data/lib/zen/controller/main_controller.rb +17 -33
  13. data/lib/zen/error/validation_error.rb +10 -0
  14. data/lib/zen/ext/string.rb +185 -0
  15. data/lib/zen/helper/acl.rb +120 -92
  16. data/lib/zen/helper/common.rb +1 -3
  17. data/lib/zen/helper/theme.rb +73 -0
  18. data/lib/zen/language.rb +66 -57
  19. data/lib/zen/layout/admin.xhtml +5 -48
  20. data/lib/zen/layout/login.xhtml +4 -44
  21. data/lib/zen/model/methods.rb +1 -1
  22. data/lib/zen/model/settings.rb +0 -3
  23. data/lib/zen/package.rb +101 -83
  24. data/lib/zen/package/base.rb +62 -0
  25. data/lib/zen/package/categories/lib/categories.rb +29 -10
  26. data/lib/zen/package/categories/lib/categories/controller/categories.rb +4 -5
  27. data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +4 -5
  28. data/lib/zen/package/categories/lib/categories/language/en/category_groups.yml +4 -3
  29. data/lib/zen/package/categories/lib/categories/model/category.rb +2 -2
  30. data/lib/zen/package/categories/lib/categories/model/category_group.rb +3 -3
  31. data/lib/zen/package/categories/lib/categories/plugin/categories.rb +130 -0
  32. data/lib/zen/package/categories/lib/categories/view/admin/categories/form.xhtml +1 -1
  33. data/lib/zen/package/categories/lib/categories/view/admin/categories/index.xhtml +2 -2
  34. data/lib/zen/package/categories/lib/categories/view/admin/category-groups/index.xhtml +11 -6
  35. data/lib/zen/package/comments/lib/comments.rb +23 -13
  36. data/lib/zen/package/comments/lib/comments/controller/comments.rb +4 -5
  37. data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +7 -8
  38. data/lib/zen/package/comments/lib/comments/model/comment.rb +4 -4
  39. data/lib/zen/package/comments/lib/comments/plugin/comments.rb +111 -0
  40. data/lib/zen/package/comments/lib/comments/view/admin/comments/form.xhtml +2 -2
  41. data/lib/zen/package/comments/lib/comments/view/admin/comments/index.xhtml +3 -3
  42. data/lib/zen/package/custom_fields/lib/custom_fields.rb +18 -11
  43. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +4 -5
  44. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +4 -5
  45. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +2 -2
  46. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +3 -3
  47. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +3 -3
  48. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-groups/index.xhtml +9 -5
  49. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/form.xhtml +1 -1
  50. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/index.xhtml +3 -3
  51. data/lib/zen/package/menus/lib/menus.rb +25 -43
  52. data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +5 -6
  53. data/lib/zen/package/menus/lib/menus/controller/menus.rb +9 -5
  54. data/lib/zen/package/menus/lib/menus/helper/menu_item.rb +4 -4
  55. data/lib/zen/package/menus/lib/menus/model/menu.rb +2 -2
  56. data/lib/zen/package/menus/lib/menus/model/menu_item.rb +4 -1
  57. data/lib/zen/package/menus/lib/menus/plugin/menus.rb +152 -0
  58. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/form.xhtml +1 -1
  59. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/index.xhtml +3 -3
  60. data/lib/zen/package/menus/lib/menus/view/admin/menus/index.xhtml +7 -7
  61. data/lib/zen/package/sections/lib/sections.rb +32 -16
  62. data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +9 -18
  63. data/lib/zen/package/sections/lib/sections/controller/sections.rb +8 -9
  64. data/lib/zen/package/sections/lib/sections/language/en/section_entries.yml +1 -1
  65. data/lib/zen/package/sections/lib/sections/model/section.rb +4 -4
  66. data/lib/zen/package/sections/lib/sections/model/section_entry.rb +9 -10
  67. data/lib/zen/package/sections/lib/sections/plugin/section_entries.rb +224 -0
  68. data/lib/zen/package/sections/lib/sections/plugin/sections.rb +85 -0
  69. data/lib/zen/package/sections/lib/sections/view/admin/form.xhtml +1 -1
  70. data/lib/zen/package/sections/lib/sections/view/admin/index.xhtml +9 -5
  71. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +2 -2
  72. data/lib/zen/package/settings/lib/settings.rb +145 -10
  73. data/lib/zen/package/settings/lib/settings/controller/settings.rb +28 -24
  74. data/lib/zen/package/settings/lib/settings/language/en/settings.yml +10 -0
  75. data/lib/zen/package/settings/lib/settings/model/setting.rb +3 -64
  76. data/lib/zen/package/settings/lib/settings/plugin/group_base.rb +40 -0
  77. data/lib/zen/package/settings/lib/settings/plugin/setting_base.rb +76 -0
  78. data/lib/zen/package/settings/lib/settings/plugin/settings.rb +236 -0
  79. data/lib/zen/package/settings/lib/settings/view/admin/settings/index.xhtml +20 -49
  80. data/lib/zen/package/settings/migrations/1295597111_create_schema.rb +0 -12
  81. data/lib/zen/package/settings/migrations/1303196915_settings_plugin.rb +31 -0
  82. data/lib/zen/package/users/lib/users.rb +18 -15
  83. data/lib/zen/package/users/lib/users/controller/access_rules.rb +44 -8
  84. data/lib/zen/package/users/lib/users/controller/user_groups.rb +4 -5
  85. data/lib/zen/package/users/lib/users/controller/users.rb +5 -6
  86. data/lib/zen/package/users/lib/users/language/en/access_rules.yml +11 -9
  87. data/lib/zen/package/users/lib/users/model/access_rule.rb +7 -6
  88. data/lib/zen/package/users/lib/users/model/user.rb +4 -4
  89. data/lib/zen/package/users/lib/users/model/user_group.rb +3 -3
  90. data/lib/zen/package/users/lib/users/public/admin/js/users/access_rules.js +50 -0
  91. data/lib/zen/package/users/lib/users/view/admin/access-rules/form.xhtml +32 -29
  92. data/lib/zen/package/users/lib/users/view/admin/access-rules/index.xhtml +8 -6
  93. data/lib/zen/package/users/lib/users/view/admin/user-groups/index.xhtml +3 -3
  94. data/lib/zen/package/users/lib/users/view/admin/users/index.xhtml +2 -2
  95. data/lib/zen/package/users/migrations/1303510943_class_rules.rb +13 -0
  96. data/lib/zen/plugin.rb +110 -104
  97. data/lib/zen/plugin/base.rb +46 -0
  98. data/lib/zen/{liquid/controller_behavior.rb → plugin/controller.rb} +9 -7
  99. data/lib/zen/plugin/helper.rb +47 -0
  100. data/lib/zen/plugin/markup/lib/markup.rb +14 -0
  101. data/lib/zen/plugin/markup/lib/markup/language/en/markup.yml +6 -0
  102. data/lib/zen/plugin/markup/lib/markup/markup.rb +154 -0
  103. data/lib/zen/public/admin/css/forms.css +4 -0
  104. data/lib/zen/public/admin/css/general.css +15 -15
  105. data/lib/zen/public/admin/css/layout.css +10 -10
  106. data/lib/zen/public/admin/css/reset.css +123 -0
  107. data/lib/zen/public/admin/images/icons/accept.png +0 -0
  108. data/lib/zen/public/admin/images/icons/add.png +0 -0
  109. data/lib/zen/public/admin/images/icons/back.png +0 -0
  110. data/lib/zen/public/admin/images/icons/bold.png +0 -0
  111. data/lib/zen/public/admin/images/icons/close.png +0 -0
  112. data/lib/zen/public/admin/images/icons/delete.png +0 -0
  113. data/lib/zen/public/admin/images/icons/edit.png +0 -0
  114. data/lib/zen/public/admin/images/icons/error.png +0 -0
  115. data/lib/zen/public/admin/images/icons/help.png +0 -0
  116. data/lib/zen/public/admin/images/icons/info.png +0 -0
  117. data/lib/zen/public/admin/images/icons/italic.png +0 -0
  118. data/lib/zen/public/admin/images/icons/large/error.png +0 -0
  119. data/lib/zen/public/admin/images/icons/large/notice.png +0 -0
  120. data/lib/zen/public/admin/images/icons/large/success.png +0 -0
  121. data/lib/zen/public/admin/images/icons/link.png +0 -0
  122. data/lib/zen/public/admin/images/icons/logout.png +0 -0
  123. data/lib/zen/public/admin/images/icons/ol.png +0 -0
  124. data/lib/zen/public/admin/images/icons/pdf.png +0 -0
  125. data/lib/zen/public/admin/images/icons/ul.png +0 -0
  126. data/lib/zen/public/admin/images/icons/user.png +0 -0
  127. data/lib/zen/public/admin/images/icons/view.png +0 -0
  128. data/lib/zen/public/admin/js/mootools/core.js +384 -333
  129. data/lib/zen/public/admin/js/mootools/more.js +256 -231
  130. data/lib/zen/public/admin/js/vendor/{datepicker/Picker.Date.js → datepicker.js} +447 -0
  131. data/lib/zen/public/admin/js/vendor/yepnope.js +1 -0
  132. data/lib/zen/public/admin/js/zen/editor/base.js +8 -1
  133. data/lib/zen/public/admin/js/zen/init.js +89 -26
  134. data/lib/zen/public/favicon.ico +0 -0
  135. data/lib/zen/task.rb +7 -0
  136. data/lib/zen/task/build.rake +60 -0
  137. data/lib/zen/task/clean.rake +27 -0
  138. data/lib/zen/task/db.rake +111 -0
  139. data/lib/zen/task/package.rake +67 -0
  140. data/lib/zen/task/plugin.rake +24 -0
  141. data/lib/zen/task/proto.rake +95 -0
  142. data/lib/zen/task/theme.rake +68 -0
  143. data/lib/zen/theme.rb +28 -55
  144. data/lib/zen/theme/base.rb +64 -0
  145. data/lib/zen/validation.rb +149 -0
  146. data/lib/zen/version.rb +1 -1
  147. data/lib/zen/view/bottom.xhtml +6 -0
  148. data/lib/zen/view/main.xhtml +32 -0
  149. data/proto/app/Rakefile +12 -0
  150. data/proto/app/app.rb +6 -6
  151. data/proto/app/config/config.rb +7 -14
  152. data/proto/app/config/database.rb +0 -20
  153. data/proto/app/start.rb +0 -1
  154. data/proto/app/{vendor/themes → task}/.gitkeep +0 -0
  155. data/proto/app/vendor/theme/.gitkeep +0 -0
  156. data/proto/package/lib/package.rb +8 -17
  157. data/proto/package/lib/package/controller/controllers.rb +4 -4
  158. data/proto/package/lib/package/language/en/languages.yml +3 -3
  159. data/proto/package/lib/package/model/model.rb +1 -1
  160. metadata +73 -73
  161. data/lib/zen/bin/base.rb +0 -109
  162. data/lib/zen/helper/asset.rb +0 -106
  163. data/lib/zen/liquid/general.rb +0 -94
  164. data/lib/zen/liquid/redirect.rb +0 -70
  165. data/lib/zen/liquid/strip.rb +0 -60
  166. data/lib/zen/package/categories/lib/categories/liquid/categories.rb +0 -16
  167. data/lib/zen/package/comments/lib/comments/liquid/comment_form.rb +0 -127
  168. data/lib/zen/package/comments/lib/comments/liquid/comments.rb +0 -115
  169. data/lib/zen/package/menus/lib/menus/liquid/menus.rb +0 -152
  170. data/lib/zen/package/sections/lib/sections/liquid/section_entries.rb +0 -228
  171. data/lib/zen/package/sections/lib/sections/liquid/sections.rb +0 -77
  172. data/lib/zen/package/settings/lib/settings/liquid/setting.rb +0 -58
  173. data/lib/zen/package/users/lib/users/liquid/user.rb +0 -77
  174. data/lib/zen/package/users/lib/users/liquid/users.rb +0 -82
  175. data/lib/zen/plugin/markup.rb +0 -30
  176. data/lib/zen/public/admin/css/boilerplate.css +0 -176
  177. data/lib/zen/public/admin/images/general/noise.jpg +0 -0
  178. data/lib/zen/public/admin/js/vendor/datepicker/Picker.Attach.js +0 -137
  179. data/lib/zen/public/admin/js/vendor/datepicker/Picker.js +0 -291
  180. data/lib/zen/public/admin/js/vendor/datepicker/README.md +0 -325
  181. data/lib/zen/public/admin/js/vendor/datepicker/locale.js +0 -16
  182. data/lib/zen/strict_struct.rb +0 -36
  183. data/lib/zen/task/build.rb +0 -123
  184. data/lib/zen/task/clean.rb +0 -46
  185. data/lib/zen/task/db.rb +0 -130
  186. data/lib/zen/task/package.rb +0 -87
  187. data/lib/zen/task/proto.rb +0 -116
  188. data/lib/zen/task/theme.rb +0 -88
  189. data/proto/app/Thorfile +0 -4
@@ -0,0 +1,24 @@
1
+ ##
2
+ # Task group for managing plugins.
3
+ #
4
+ # @author Yorick Peterse
5
+ # @since 0.2.5
6
+ #
7
+ namespace :plugin do
8
+
9
+ desc 'Lists all installed plugins'
10
+ task :list do
11
+ Zen::Plugin::Registered.each do |name, pkg|
12
+ message = <<-MSG
13
+ --------------------------
14
+ Name: #{name}
15
+ Author: #{pkg.author}
16
+
17
+ #{pkg.about}
18
+ MSG
19
+
20
+ puts message
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,95 @@
1
+ require 'fileutils'
2
+ require __DIR__('../ext/string')
3
+
4
+ ##
5
+ # Task group used for creating various prototypes.
6
+ #
7
+ # @author Yorick Peterse
8
+ # @since 0.2.5
9
+ #
10
+ namespace :proto do
11
+
12
+ desc 'Creates a new migration'
13
+ task :migration, :directory, :name do |task, args|
14
+ # Validate the input
15
+ if !args[:directory]
16
+ abort 'You need to specify a directory for the migration.'
17
+ end
18
+
19
+ if !args[:name]
20
+ abort 'You need to specify a name for the migration.'
21
+ end
22
+
23
+ if !File.directory?(args[:directory])
24
+ abort "The directory #{args[:directory]} doesn't exist."
25
+ end
26
+
27
+ proto_path = File.expand_path('../../../../proto/migration.rb', __FILE__)
28
+ new_path = File.join(args[:directory], "#{Time.new.to_i}_#{args[:name]}.rb")
29
+
30
+ # Copy the prototype to the location
31
+ begin
32
+ FileUtils.cp(proto_path, new_path)
33
+ puts "Migration saved in #{new_path}"
34
+ rescue => e
35
+ puts "Failed to create the migration: #{e.message}"
36
+ end
37
+ end
38
+
39
+ desc 'Creates a new package'
40
+ task :package, :directory, :name do |task, args|
41
+ # Validate the input
42
+ if !args[:name]
43
+ abort 'You need to specify the name of your package.'
44
+ end
45
+
46
+ if !args[:directory]
47
+ abort 'You need to specify a directory where the package should be saved.'
48
+ end
49
+
50
+ name = args[:name]
51
+ proto = File.expand_path('../../../../proto/package', __FILE__)
52
+ klass = name.camel_case
53
+ extension_path = File.join(args[:directory], name)
54
+
55
+ FileUtils.rm_rf(extension_path)
56
+
57
+ # Rename all files and folders
58
+ begin
59
+ FileUtils.cp_r(proto, extension_path)
60
+
61
+ lib_path = "#{extension_path}/lib/#{name}"
62
+
63
+ # Rename the base file and directory
64
+ FileUtils.mv("#{extension_path}/lib/package" , lib_path)
65
+ FileUtils.mv("#{extension_path}/lib/package.rb", "#{extension_path}/lib/#{name}.rb")
66
+
67
+ controller_filename = klass.snake_case.pluralize
68
+ model_filename = klass.snake_case.singularize
69
+
70
+ # Generate the controller
71
+ controller = File.open("#{lib_path}/controller/controllers.rb", 'r').read
72
+ controller.gsub!('CONTROLLER', klass.pluralize)
73
+ controller.gsub!('EXTENSION' , klass.pluralize)
74
+
75
+ FileUtils.mv("#{lib_path}/controller/controllers.rb", "#{lib_path}/controller/#{controller_filename}.rb")
76
+ File.open("#{lib_path}/controller/#{controller_filename}.rb", 'w').write(controller)
77
+
78
+ # Move the view directory
79
+ FileUtils.mv("#{lib_path}/view/admin/package", "#{lib_path}/view/admin/#{controller_filename}")
80
+
81
+ # Generate the model
82
+ model = File.open("#{lib_path}/model/model.rb", 'r').read
83
+ model.gsub!('MODEL' , klass.singularize)
84
+ model.gsub!('EXTENSION' , klass.pluralize)
85
+
86
+ FileUtils.mv("#{lib_path}/model/model.rb", "#{lib_path}/model/#{model_filename}.rb")
87
+ File.open("#{lib_path}/model/#{model_filename}.rb", 'w').write(model)
88
+
89
+ puts "Done! Don't forget to rename the controllers/models/etc"
90
+ rescue => e
91
+ abort "Failed to generate the package: #{e}"
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,68 @@
1
+ ##
2
+ # Task group for managing themes.
3
+ #
4
+ # @author Yorick Peterse
5
+ # @since 0.2.5
6
+ #
7
+ namespace :theme do
8
+
9
+ desc 'Lists all installed themes'
10
+ task :list do
11
+ Zen::Theme::Registered.each do |name, pkg|
12
+ message = <<-MSG
13
+ --------------------------
14
+ Name: #{name}
15
+ Author: #{pkg.author}
16
+ Template directory: #{pkg.template_dir}
17
+
18
+ #{pkg.about}
19
+ MSG
20
+
21
+ puts message
22
+ end
23
+ end
24
+
25
+ desc 'Migrates a theme to the given version'
26
+ task :migrate, :name, :version do |task, args|
27
+ if !args[:name]
28
+ abort 'You need to specify the name of the theme.'
29
+ end
30
+
31
+ if !args[:version]
32
+ version = nil
33
+ puts 'No version specified, choosing the most recent version...'
34
+ else
35
+ version = args[:version].to_i
36
+ end
37
+
38
+ name = args[:name].to_sym
39
+
40
+ if !Zen::Theme::Registered[name]
41
+ abort 'The specified theme does not exist.'
42
+ end
43
+
44
+ theme = Zen::Theme::Registered[name]
45
+ table = 'migrations_theme_' + theme.name.to_s
46
+
47
+ # Fetch the migrations directory
48
+ if theme.respond_to?(:migration_dir) and !theme.migration_dir.nil?
49
+ dir = theme.migration_dir
50
+ else
51
+ abort 'The specified theme does not have a migrations directory.'
52
+ end
53
+
54
+ if !File.directory?(dir)
55
+ abort 'The theme\'s migration directory doesn\'t exist.'
56
+ end
57
+
58
+ # Time to migrate the theme
59
+ puts 'Migrating...'
60
+
61
+ Zen::Database.handle.transaction do
62
+ Sequel::Migrator.run(
63
+ Zen::Database.handle, dir, :table => table, :target => version
64
+ )
65
+ end
66
+ end
67
+
68
+ end
@@ -1,4 +1,5 @@
1
1
  require __DIR__('error/theme_error')
2
+ require __DIR__('theme/base')
2
3
  require 'pathname'
3
4
 
4
5
  #:nodoc:
@@ -25,32 +26,22 @@ module Zen
25
26
  # Example:
26
27
  #
27
28
  # Zen::Theme.add do |theme|
28
- # theme.author = 'Yorick Peterse'
29
- # theme.name = 'Default'
30
- # theme.identifier = 'com.yorickpeterse.theme.default'
29
+ # theme.author = 'Yorick Peterse'
30
+ # theme.name = 'default'
31
31
  # end
32
32
  #
33
- # The "identifier" key is very important and just like packages and plugins it should
34
- # always stay the same once it has been set.
35
- #
36
- # ## Identifiers
37
- #
38
- # Theme identifiers should be in the following format:
39
- #
40
- # com.VENDOR.theme.NAME
41
- #
42
- # For example:
43
- #
44
- # com.yorickpeterse.theme.fancy_blog
45
- #
46
33
  # @author Yorick Peterse
47
34
  # @since 0.2.4
48
- # @attr_reader [Array] themes Array of all installed themes.
49
35
  #
50
36
  module Theme
51
- class << self
52
- attr_reader :themes
53
- end
37
+ ##
38
+ # Hash containing all registered themes. The keys are the names of the themes and
39
+ # the values instances of Zen::Theme::Base.
40
+ #
41
+ # @author Yorick Peterse
42
+ # @since 0.2.5
43
+ #
44
+ Registered = {}
54
45
 
55
46
  ##
56
47
  # Adds a new theme to Zen. Note that the theme won't be used unless it has been set
@@ -58,33 +49,15 @@ module Zen
58
49
  #
59
50
  # @author Yorick Peterse
60
51
  # @since 0.2.4
61
- # @yield [theme] Struct object containing all getter/setters for each theme.
62
52
  #
63
53
  def self.add
64
- @themes ||= {}
65
-
66
- required = [:name, :author, :about, :identifier, :template_dir]
67
- theme = Zen::StrictStruct.new(
68
- :name, :author, :about, :url, :identifier, :template_dir, :partial_dir,
69
- :public_dir, :migration_dir
70
- ).new
54
+ theme = Base.new
71
55
 
72
56
  yield theme
73
57
 
74
- # Check if all required items have been set
75
- theme.validate(required) do |k|
76
- raise(Zen::ThemeError, "The following theme key is missing: #{k}")
77
- end
78
-
79
- # Validate all paths set
80
- [:template_dir, :partial_dir, :public_dir, :migration_dir].each do |k|
81
- # Only validate the path if it has been set
82
- if theme.respond_to?(k) and !theme.send(k).nil? and !theme.send(k).empty?
83
- if !File.exist?(theme.send(k))
84
- raise(Zen::ThemeError, "The path #{k} doesn't exist.")
85
- end
86
- end
87
- end
58
+ # Validate the theme
59
+ theme.validate
60
+ theme.name = theme.name.to_sym
88
61
 
89
62
  # Do we have a public directory?
90
63
  if theme.respond_to?(:public_dir) and !theme.public_dir.nil?
@@ -98,11 +71,7 @@ module Zen
98
71
  end
99
72
  end
100
73
 
101
- if !@themes[theme.identifier].nil?
102
- raise(Zen::ThemeError, "The theme #{theme.name} already exists.")
103
- end
104
-
105
- @themes[theme.identifier] = theme
74
+ Registered[theme.name] = theme
106
75
  end
107
76
 
108
77
  ##
@@ -110,19 +79,23 @@ module Zen
110
79
  #
111
80
  # @author Yorick Peterse
112
81
  # @since 0.2.4
113
- # @param [String] ident The identifier of the theme.
114
- # @return [Struct] Instance of the theme.
82
+ # @param [String/Symbol] name The name of the theme to retrieve.
83
+ # @return [Zen::Theme::Base]
115
84
  #
116
- def self.[](ident)
117
- if @themes.nil?
118
- raise(Zen::ThemeError, "No themes have been added.")
85
+ def self.[](name)
86
+ if name.class != Symbol
87
+ name = name.to_sym
88
+ end
89
+
90
+ if Registered.nil?
91
+ raise(Zen::ThemeError, "No themes have been added yet.")
119
92
  end
120
93
 
121
- if !@themes[ident]
122
- raise(Zen::ThemeError, "The theme #{ident} doesn't exist.")
94
+ if !Registered[name]
95
+ raise(Zen::ThemeError, "The theme #{name} doesn't exist.")
123
96
  end
124
97
 
125
- return @themes[ident]
98
+ return Registered[name]
126
99
  end
127
100
 
128
101
  end
@@ -0,0 +1,64 @@
1
+ #:nodoc:
2
+ module Zen
3
+ #:nodoc:
4
+ module Theme
5
+ ##
6
+ # Base class used for all themes.
7
+ #
8
+ # @author Yorick Peterse
9
+ # @since 0.2.5
10
+ #
11
+ class Base
12
+ include ::Zen::Validation
13
+
14
+ # The name of the theme
15
+ attr_accessor :name
16
+
17
+ # The author of the theme
18
+ attr_accessor :author
19
+
20
+ # A small description of the theme
21
+ attr_accessor :about
22
+
23
+ # The URL to the theme's homepage
24
+ attr_accessor :url
25
+
26
+ # Path to the directory containing all templates
27
+ attr_accessor :template_dir
28
+
29
+ # Path to the directory containing all template partials
30
+ attr_accessor :partial_dir
31
+
32
+ # Path to the theme's public directory (useful for CSS and Javascript files)
33
+ attr_accessor :public_dir
34
+
35
+ # Path to the directory containing all migrations for the theme
36
+ attr_accessor :migration_dir
37
+
38
+ ##
39
+ # Validates all attributes of this class.
40
+ #
41
+ # @author Yorick Peterse
42
+ # @since 0.2.5
43
+ #
44
+ def validate
45
+ validates_presence([:name, :author, :about, :template_dir])
46
+
47
+ # Validate all the directories
48
+ validates_filepath(:template_dir)
49
+
50
+ [:partial_dir, :public_dir, :migration_dir].each do |m|
51
+ if !send(m).nil?
52
+ validates_filepath(m)
53
+ end
54
+ end
55
+
56
+ # Check if the theme hasn't already been registered
57
+ if ::Zen::Theme::Registered.key?(name.to_sym)
58
+ raise(::Zen::ValidationError, "The theme #{name} has already been registered.")
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,149 @@
1
+ require __DIR__('error/validation_error')
2
+
3
+ #:nodoc:
4
+ module Zen
5
+ ##
6
+ # The Validation module is a very basic validation framework that's used by various
7
+ # internal modules/classes such as Zen::Plugin and Zen::Package.
8
+ #
9
+ # ## Usage
10
+ #
11
+ # Using the module is pretty simple. Include it, specify the validation rules in a
12
+ # method and call it. All official modules and classes use a method called "validate"
13
+ # but you're free to name it whatever you want. A basic example looks like the
14
+ # following:
15
+ #
16
+ # class Something
17
+ # include Zen::Validation
18
+ #
19
+ # attr_accessor :name
20
+ #
21
+ # def validate
22
+ # validates_presence(:name)
23
+ # end
24
+ # end
25
+ #
26
+ # @author Yorick Peterse
27
+ # @since 0.2.5
28
+ #
29
+ module Validation
30
+
31
+ ##
32
+ # Checks if the specified attributes exist and aren't set to nil.
33
+ #
34
+ # @example
35
+ # validates_presence(:name)
36
+ #
37
+ # @author Yorick Peterse
38
+ # @since 0.2.5
39
+ # @param [Array/Symbol/String] attributes Either a single or multiple attributes to
40
+ # validate.
41
+ # @raise [ValidationError] Raised whenever a attribute is missing or is set to nil.
42
+ #
43
+ def validates_presence(attributes)
44
+ if attributes.class != Array
45
+ attributes = [attributes]
46
+ end
47
+
48
+ attributes.each do |f|
49
+ if !respond_to?(f) or send(f).nil?
50
+ raise(ValidationError, "The attribute \"#{f}\" doesn't exist.")
51
+ end
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Checks if the length of a string matches the given length. You can specify a minimum
57
+ # length, a maximum one as well as both.
58
+ #
59
+ # @example
60
+ # validates_length(:foobar, :min => 5, :max => 10)
61
+ #
62
+ # @author Yorick Peterse
63
+ # @since 0.2.5
64
+ # @param [String/Symbol] attribute The attribute to validate.
65
+ # @param [Hash] options Hash containing the options to use for determining how long
66
+ # the attribute's value should be.
67
+ # @option options [Fixnum] :min The minimum length of the attribute's value.
68
+ # @option options [Fixnum] :max The maximum length of the value.
69
+ # @raise [ValidationError] Raised then the value of the attribute isn't long or short
70
+ # enough.
71
+ #
72
+ def validates_length(attribute, options)
73
+ value = send(attribute)
74
+
75
+ if !value.respond_to?(:length)
76
+ raise(
77
+ ValidationError,
78
+ "The length of \"#{attribute}\" can't be checked as the method \"length\" " +
79
+ "doesn't exist."
80
+ )
81
+ end
82
+
83
+ # Time to validate the length
84
+ length = value.length
85
+
86
+ if options.key?(:min) and length < options[:min]
87
+ raise(ValidationError, "The attribute \"#{attribute}\" is too short.")
88
+ end
89
+
90
+ if options.key?(:max) and length > options[:max]
91
+ raise(ValidationError, "The attribute \"#{attribute}\" is too long.")
92
+ end
93
+ end
94
+
95
+ ##
96
+ # Checks if the given attributes match the specified regular expressions.
97
+ # When a hash is specified the keys should be the names of the attributes to validate
98
+ # and the values the regular expressions to use.
99
+ #
100
+ # @example
101
+ # validates_format(:name, /[\w\-]+/)
102
+ # validates_format(:name => /[\w\-]+/, :age => /[0-9]+/)
103
+ #
104
+ # @author Yorick Peterse
105
+ # @since 0.2.5
106
+ # @param [Hash/Symbol] attribute The name of the attribute to validate or a hash
107
+ # containing all the attributes and their regular expressions.
108
+ # @param [Regexp] regexp The regular expression to use when validating a single
109
+ # attribute.
110
+ # @raise [ValidationError] Raised when one of the attributes doesn't matches the
111
+ # regular expression.
112
+ #
113
+ def validates_format(attribute, regexp = nil)
114
+ if attribute.class != Hash
115
+ attribute = {attribute => regexp}
116
+ end
117
+
118
+ # Try to match all attributes
119
+ attribute.each do |attr, regexp|
120
+ val = send(attr)
121
+ match = val =~ regexp
122
+
123
+ if !match
124
+ raise(ValidationError, "The attribute \"#{attr}\" doesn't match #{regexp}.")
125
+ end
126
+ end
127
+ end
128
+
129
+ ##
130
+ # Checks if the specified attribute contains a valid filepath.
131
+ #
132
+ # @example
133
+ # validates_filepath(:directory)
134
+ #
135
+ # @author Yorick Peterse
136
+ # @since 0.2.5
137
+ # @param [String/Symbol] attribute The attribute to validate.
138
+ # @raise [ValidationError] Raised when one of the paths didn't exist.
139
+ #
140
+ def validates_filepath(attribute)
141
+ path = send(attribute)
142
+
143
+ if !File.exist?(path)
144
+ raise(ValidationError, "The path #{path} in \"#{attribute}\" doesn't exist.")
145
+ end
146
+ end
147
+
148
+ end
149
+ end