zen 0.2.4.1 → 0.2.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 (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