rucola 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/ChangeLog +628 -0
  2. data/History.txt +4 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +106 -0
  5. data/README.txt +126 -0
  6. data/Rakefile +32 -0
  7. data/TODO +28 -0
  8. data/app_generators/rucola/USAGE +6 -0
  9. data/app_generators/rucola/rucola_generator.rb +112 -0
  10. data/app_generators/rucola/templates/Rakefile.erb +12 -0
  11. data/app_generators/rucola/templates/Rakefile.erb.old +156 -0
  12. data/app_generators/rucola/templates/app/controllers/application_controller.rb +22 -0
  13. data/app_generators/rucola/templates/config/Info.plist.erb +28 -0
  14. data/app_generators/rucola/templates/config/boot.rb +2 -0
  15. data/app_generators/rucola/templates/config/environment.rb +11 -0
  16. data/app_generators/rucola/templates/config/environments/debug.rb +3 -0
  17. data/app_generators/rucola/templates/config/environments/release.rb +3 -0
  18. data/app_generators/rucola/templates/config/environments/test.rb +3 -0
  19. data/app_generators/rucola/templates/config/ib_external_class_defs.yml +13 -0
  20. data/app_generators/rucola/templates/misc/English.lproj/InfoPlist.strings.erb +3 -0
  21. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/classes.nib +40 -0
  22. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/info.nib +18 -0
  23. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
  24. data/app_generators/rucola/templates/misc/main.m.erb +15 -0
  25. data/app_generators/rucola/templates/misc/rb_main.rb.erb +13 -0
  26. data/app_generators/rucola/templates/project.pbxproj.erb +299 -0
  27. data/app_generators/rucola/templates/script/plugin +84 -0
  28. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +10 -0
  29. data/app_generators/rucola/templates/test/test_helper.rb +10 -0
  30. data/bin/rucola +12 -0
  31. data/config/hoe.rb +71 -0
  32. data/config/requirements.rb +17 -0
  33. data/lib/rucola.rb +3 -0
  34. data/lib/rucola/info_plist.rb +37 -0
  35. data/lib/rucola/initializer.rb +313 -0
  36. data/lib/rucola/nib.rb +99 -0
  37. data/lib/rucola/rucola_support.rb +9 -0
  38. data/lib/rucola/rucola_support/controllers.rb +2 -0
  39. data/lib/rucola/rucola_support/controllers/rc_controller.rb +7 -0
  40. data/lib/rucola/rucola_support/controllers/rc_window_controller.rb +12 -0
  41. data/lib/rucola/rucola_support/core_ext.rb +2 -0
  42. data/lib/rucola/rucola_support/core_ext/objc.rb +4 -0
  43. data/lib/rucola/rucola_support/core_ext/objc/nsobject.rb +22 -0
  44. data/lib/rucola/rucola_support/core_ext/ruby.rb +4 -0
  45. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +21 -0
  46. data/lib/rucola/rucola_support/initialize_hooks.rb +21 -0
  47. data/lib/rucola/rucola_support/models.rb +1 -0
  48. data/lib/rucola/rucola_support/models/rc_document.rb +10 -0
  49. data/lib/rucola/rucola_support/notifications.rb +1 -0
  50. data/lib/rucola/rucola_support/notifications/notifications.rb +146 -0
  51. data/lib/rucola/rucola_support/rc_app.rb +101 -0
  52. data/lib/rucola/tasks/freeze.rake +44 -0
  53. data/lib/rucola/tasks/interface_builder.rake +80 -0
  54. data/lib/rucola/tasks/main.rake +29 -0
  55. data/lib/rucola/tasks/xcode.rake +43 -0
  56. data/lib/rucola/test_helper.rb +57 -0
  57. data/lib/rucola/version.rb +9 -0
  58. data/lib/rucola/xcode.rb +148 -0
  59. data/log/debug.log +0 -0
  60. data/rucola_generators/controller/USAGE +5 -0
  61. data/rucola_generators/controller/controller_generator.rb +84 -0
  62. data/rucola_generators/controller/templates/controller_template.rb.erb +5 -0
  63. data/rucola_generators/controller/templates/test_controller_template.rb.erb +10 -0
  64. data/rucola_generators/document_model/USAGE +5 -0
  65. data/rucola_generators/document_model/document_model_generator.rb +67 -0
  66. data/rucola_generators/document_model/templates/document_model_template.rb.erb +27 -0
  67. data/rucola_generators/document_model/templates/test_document_model_template.rb.erb +10 -0
  68. data/rucola_generators/window_controller/USAGE +6 -0
  69. data/rucola_generators/window_controller/templates/Window.nib/classes.nib.erb +35 -0
  70. data/rucola_generators/window_controller/templates/Window.nib/info.nib +16 -0
  71. data/rucola_generators/window_controller/templates/Window.nib/keyedobjects.nib +0 -0
  72. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +10 -0
  73. data/rucola_generators/window_controller/templates/window_controller_template.rb.erb +19 -0
  74. data/rucola_generators/window_controller/window_controller_generator.rb +74 -0
  75. data/script/destroy +14 -0
  76. data/script/generate +14 -0
  77. data/script/txt2html +74 -0
  78. data/setup.rb +1585 -0
  79. data/tasks/deployment.rake +27 -0
  80. data/tasks/environment.rake +7 -0
  81. data/tasks/website.rake +17 -0
  82. data/test/fixtures/Info.plist +28 -0
  83. data/test/fixtures/MainMenu.nib/classes.nib +32 -0
  84. data/test/fixtures/MainMenu.nib/info.nib +18 -0
  85. data/test/fixtures/MainMenu.nib/keyedobjects.nib +0 -0
  86. data/test/test_controller_generator.rb +75 -0
  87. data/test/test_core_ext.rb +15 -0
  88. data/test/test_document_model_generator.rb +64 -0
  89. data/test/test_generator_helper.rb +20 -0
  90. data/test/test_helper.rb +13 -0
  91. data/test/test_info_plist.rb +31 -0
  92. data/test/test_nib.rb +73 -0
  93. data/test/test_notifications.rb +75 -0
  94. data/test/test_objc_core_ext.rb +37 -0
  95. data/test/test_rc_app.rb +63 -0
  96. data/test/test_rc_document.rb +18 -0
  97. data/test/test_rc_window_controller.rb +13 -0
  98. data/test/test_rucola.rb +11 -0
  99. data/test/test_rucola_generator.rb +87 -0
  100. data/test/test_window_controller_generator.rb +50 -0
  101. data/test/test_xcode.rb +128 -0
  102. data/website/index.html +199 -0
  103. data/website/index.txt +126 -0
  104. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  105. data/website/stylesheets/screen.css +138 -0
  106. data/website/template.rhtml +48 -0
  107. metadata +189 -0
@@ -0,0 +1,99 @@
1
+ require 'osx/cocoa'
2
+ require 'fileutils'
3
+
4
+ module Rucola
5
+ module Nib
6
+
7
+ def self.backup(path)
8
+ nib = File.dirname(path)
9
+ nib_name = File.basename(nib)
10
+ backup = "/tmp/#{nib_name}.bak"
11
+ unless $TESTING
12
+ puts "\n========================================================================="
13
+ puts "Backing up #{nib} to #{backup}"
14
+ puts "Please retrieve that one if for some reason the nib was damaged!"
15
+ puts "=========================================================================\n\n"
16
+ end
17
+ FileUtils.rm_rf(backup) if File.exists?(backup)
18
+ FileUtils.cp_r(nib, backup)
19
+ end
20
+
21
+ class Classes
22
+ attr_reader :data
23
+
24
+ def self.open(classes_nib_path)
25
+ new(classes_nib_path)
26
+ end
27
+
28
+ def initialize(classes_nib_path)
29
+ @path = File.expand_path(classes_nib_path)
30
+ @data = OSX::NSDictionary.dictionaryWithContentsOfFile(@path)
31
+ end
32
+
33
+ def classes
34
+ @data['IBClasses']
35
+ end
36
+
37
+ def add_class(class_name)
38
+ classes.push({
39
+ 'CLASS' => class_name,
40
+ 'SUPERCLASS' => 'NSObject',
41
+ 'LANGUAGE' => 'ObjC'
42
+ })
43
+ end
44
+
45
+ def has_class?(class_name)
46
+ classes.any? { |klass| klass['CLASS'] == class_name }
47
+ end
48
+
49
+ def save
50
+ Rucola::Nib.backup(@path)
51
+ @data.writeToFile_atomically(@path, true)
52
+ end
53
+
54
+ end
55
+
56
+ class KeyedObjects
57
+ attr_reader :data
58
+
59
+ def self.open(path)
60
+ new(path)
61
+ end
62
+
63
+ def initialize(path)
64
+ @path = path
65
+ @data, format, error = OSX::NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription(
66
+ OSX::NSData.dataWithContentsOfFile(@path),
67
+ OSX::NSPropertyListMutableContainersAndLeaves
68
+ )
69
+ end
70
+
71
+ def files_owner_class
72
+ @data['$objects'][3]
73
+ end
74
+
75
+ # Changes the custom class of the File's Owner.
76
+ def change_files_owner_class(new_class)
77
+ # With a fresh nib the name of the custom class always appears as the 4th object
78
+ # in the $objects array. But this might not always be the case. At least for
79
+ # setting the initial custom class with a known nib, such as the one we use
80
+ # as a template, will work.
81
+ @data['$objects'][3] = new_class
82
+ end
83
+
84
+ # Save the keyedobjects.nib back to the original path.
85
+ # Or alternatively pass it a new path.
86
+ def save(new_path = nil)
87
+ new_data, new_error = OSX::NSPropertyListSerialization.dataFromPropertyList_format_errorDescription(@data, OSX::NSPropertyListBinaryFormat_v1_0)
88
+
89
+ Rucola::Nib.backup(@path)
90
+
91
+ path = (new_path.nil? ? @path : new_path)
92
+ dirname = File.dirname(path)
93
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
94
+
95
+ new_data.writeToFile_atomically(path, true)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,9 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rucola_support/rc_app'
5
+ require 'rucola_support/initialize_hooks'
6
+ require 'rucola_support/core_ext'
7
+ require 'rucola_support/controllers'
8
+ require 'rucola_support/models'
9
+ require 'rucola/rucola_support/notifications'
@@ -0,0 +1,2 @@
1
+ require 'rucola_support/controllers/rc_controller'
2
+ require 'rucola_support/controllers/rc_window_controller'
@@ -0,0 +1,7 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCController < OSX::NSObject
5
+ include Rucola::RCApp
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCWindowController < OSX::NSWindowController
5
+ # Loads the nib that corresponds to this subclass.
6
+ # So for instance a class PreferencesWindowController,
7
+ # will look for a nib in: app/views/Preferences.nib
8
+ def init
9
+ self if self.initWithWindowNibPath_owner(Rucola::RCApp.path_for_view(self), self)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ require 'rucola_support/core_ext/ruby'
2
+ require 'rucola_support/core_ext/objc'
@@ -0,0 +1,4 @@
1
+ Dir[File.dirname(__FILE__) + "/objc/*.rb"].sort.each do |path|
2
+ filename = File.basename(path)
3
+ require "rucola_support/core_ext/objc/#{filename}"
4
+ end
@@ -0,0 +1,22 @@
1
+ require 'osx/cocoa'
2
+
3
+ class OSX::NSObject
4
+ class << self
5
+ alias_method :_inherited_before_rucola, :inherited
6
+
7
+ def inherited(subclass)
8
+ # First let RubyCocoa do it's magic!
9
+ _inherited_before_rucola(subclass)
10
+
11
+ # We only want to mixin modules into subclasses of classes
12
+ # that start with 'Rucola::RC'.
13
+ class_prefix = subclass.superclass.name.to_s[0..9]
14
+ if class_prefix == 'Rucola::RC'
15
+ subclass.class_eval do
16
+ include Rucola::InitializeHooks
17
+ include Rucola::Notifications
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ Dir[File.dirname(__FILE__) + "/ruby/*.rb"].sort.each do |path|
2
+ filename = File.basename(path)
3
+ require "rucola_support/core_ext/ruby/#{filename}"
4
+ end
@@ -0,0 +1,21 @@
1
+ class String
2
+ # These 2 methods are taken blatently from the Merb string extensions.
3
+
4
+ # "FooBar".snake_case #=> "foo_bar"
5
+ def snake_case
6
+ gsub(/\B[A-Z]/, '_\&').downcase
7
+ end
8
+
9
+ # "foo_bar".camel_case #=> "FooBar"
10
+ def camel_case
11
+ if self.include? '_'
12
+ self.split('_').map{|e| e.capitalize}.join
13
+ else
14
+ unless self =~ (/^[A-Z]/)
15
+ self.capitalize
16
+ else
17
+ self
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Rucola
2
+ module InitializeHooks
3
+ module ClassMethods
4
+ # Adds the given proc to the initialize hooks queue,
5
+ # which will be ran after object initialization.
6
+ def _rucola_register_initialize_hook(hook)
7
+ (@_rucola_initialize_hooks ||= []).push hook
8
+ end
9
+ end
10
+
11
+ def initialize
12
+ # get the hooks, if they exist let them all do their after initialization work.
13
+ hooks = self.class.instance_variable_get(:@_rucola_initialize_hooks)
14
+ hooks.each { |hook| self.instance_eval(&hook) } unless hooks.nil?
15
+ end
16
+
17
+ def self.included(base) # :nodoc
18
+ base.extend(ClassMethods)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ require 'rucola_support/models/rc_document'
@@ -0,0 +1,10 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ class RCDocument < OSX::NSDocument
5
+ def makeWindowControllers
6
+ @@_window_controller ||= Object.const_get("#{self.class.name.to_s.camel_case}Controller")
7
+ addWindowController @@_window_controller.alloc.init
8
+ end
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ require 'rucola_support/notifications/notifications'
@@ -0,0 +1,146 @@
1
+ require 'osx/cocoa'
2
+
3
+ module Rucola
4
+ module Notifications
5
+ # This Notifications module will add a class method called +notify_on+, which registers
6
+ # your object for the given notification and executes the given block when the
7
+ # notification is posted to the OSX::NSNotificationCenter.defaultCenter.
8
+ #
9
+ # class FooController < OSX::NSObject
10
+ #
11
+ # notify_on OSX::NSApplicationDidFinishLaunchingNotification do |notification|
12
+ # puts "Application did finish launching."
13
+ # p notification
14
+ # end
15
+ #
16
+ # # code
17
+ #
18
+ # end
19
+ #
20
+ # In addition to notify_on, you also get a method called notify which allows you to specify methods
21
+ # to be invoked when a notification is posted.
22
+ #
23
+ # class FooController < OSX::NSObject
24
+ # notify :some_method, :when => :application_did_finish_launching
25
+ #
26
+ # def some_method(notification)
27
+ # puts "Application finished launching"
28
+ # end
29
+ # end
30
+
31
+
32
+ module ClassMethods
33
+ # Add prefix shortcuts as a hash.
34
+ #
35
+ # class FooController < OSX::NSObject
36
+ # acts_as_notifiable
37
+ #
38
+ # # This will make sure that :win_ is expanded to :window_ in the notifications that you register.
39
+ # notification_prefix :win => :window
40
+ #
41
+ # notify_on :win_did_become_key do |notification|
42
+ # # code
43
+ # end
44
+ # end
45
+ #
46
+ # By default the shortcut <tt>{ :app => :application }</tt> is registered.
47
+ def notification_prefix(prefixes)
48
+ (@_notification_prefixes ||= {}).merge! prefixes
49
+ end
50
+
51
+ # Registers the object for the given notification and executes the given block when the
52
+ # notification is posted to the OSX::NSNotificationCenter.defaultCenter.
53
+ #
54
+ # class FooController < OSX::NSObject
55
+ #
56
+ # notify_on OSX::NSApplicationDidFinishLaunchingNotification do |notification|
57
+ # puts "Application did finish launching."
58
+ # p notification
59
+ # end
60
+ #
61
+ # # code
62
+ #
63
+ # end
64
+ #
65
+ # You can also pass it a symbol as +notification+ in which case it will be exapnded.
66
+ # It will first check if the name + 'Notification' exists, if not it will prepend 'NS'.
67
+ # So :application_did_finish_launching becomes 'NSApplicationDidFinishLaunchingNotification'.
68
+ #
69
+ # You can even register shortcut prefixes. See +notification_prefix+.
70
+ def notify_on(notification, &block)
71
+ notification_name = notification
72
+
73
+ if notification_name.is_a? Symbol
74
+ notification_name = notification_name.to_s
75
+
76
+ # first check if this notification_name uses a shortcut prefix
77
+ splitted_notification_name = notification_name.split('_')
78
+ prefix = splitted_notification_name.first.to_sym
79
+ if @_notification_prefixes and @_notification_prefixes.has_key? prefix
80
+ notification_name = @_notification_prefixes[prefix].to_s << '_' << splitted_notification_name[1..-1].join('_')
81
+ end
82
+
83
+ begin
84
+ # try with only Notification appended
85
+ notification_name = notification_name.camel_case << 'Notification'
86
+ OSX.const_get(notification_name)
87
+ rescue NameError
88
+ begin
89
+ # then try with NS prepended
90
+ notification_name = 'NS' << notification_name
91
+ OSX.const_get(notification_name)
92
+ rescue NameError
93
+ raise NameError, "Unable to find the notification corresponding to :#{notification}"
94
+ end
95
+ end
96
+ end
97
+
98
+ method_name = "_handle_#{notification_name.snake_case}".to_sym
99
+
100
+ # define the handle method
101
+ class_eval do
102
+ define_method(method_name, &block)
103
+ end
104
+
105
+ @_registered_notifications ||= {}
106
+ @_registered_notifications[notification_name.to_s] = method_name
107
+ end
108
+
109
+ # Register a callback when a notification is posted.
110
+ #
111
+ # class FooController < OSX::NSObject
112
+ # notify :some_method, :when => :application_did_finish_launching
113
+ #
114
+ # def some_method(notification)
115
+ # puts "Application finished launching"
116
+ # end
117
+ # end
118
+ #
119
+ def notify(method_to_notify, options = {})
120
+ @_registered_notifications ||= {}
121
+ @_registered_notifications[options[:when]] = method_to_notify
122
+ end
123
+
124
+ end
125
+
126
+ def self.included(base) # :nodoc
127
+ base.extend(ClassMethods)
128
+
129
+ # register the initialize hook which actually registers the notifications for the instance.
130
+ base._rucola_register_initialize_hook lambda { self._register_notifications }
131
+
132
+ # register default shortcut
133
+ base.notification_prefix :app => :application
134
+ end
135
+
136
+ # this instance method is called after object initialization by the initialize hook
137
+ def _register_notifications # :nodoc:
138
+ notifications = self.class.instance_variable_get(:@_registered_notifications)
139
+ return if notifications.nil?
140
+ center = OSX::NSNotificationCenter.defaultCenter
141
+ notifications.each do |notification_name, notification_handler|
142
+ center.addObserver_selector_name_object(self, notification_handler, notification_name, nil)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,101 @@
1
+ module Rucola
2
+ module RCApp
3
+ # Returns the path to the current source root of the application.
4
+ #
5
+ # So in debug & test mode this will point to your development source root.
6
+ #
7
+ # In release however this will point to the equivalent of:
8
+ # <tt>NSBundle.mainBundle.resourcePath</tt>
9
+ def root_path
10
+ RUBYCOCOA_ROOT.to_s
11
+ end
12
+ module_function :root_path
13
+
14
+ # Returns the path to the current used app/controllers dir.
15
+ #
16
+ # So in debug & test mode this will point to your development
17
+ # source_root/app/controllers.
18
+ #
19
+ # In release however this will point to the equivalent of:
20
+ # NSBundle.mainBundle.resourcePath + 'app/controllers'
21
+ def controllers_path
22
+ (RUBYCOCOA_ROOT + 'app/controllers').to_s
23
+ end
24
+ module_function :controllers_path
25
+
26
+ # Returns the path to the current used app/models dir.
27
+ #
28
+ # So in debug & test mode this will point to your development
29
+ # source_root/app/models.
30
+ #
31
+ # In release however this will point to the equivalent of:
32
+ # NSBundle.mainBundle.resourcePath + 'app/models'
33
+ def models_path
34
+ (RUBYCOCOA_ROOT + 'app/models').to_s
35
+ end
36
+ module_function :models_path
37
+
38
+ # Returns the path to the current used app/assets dir.
39
+ #
40
+ # So in debug & test mode this will point to your development
41
+ # source_root/app/assets.
42
+ #
43
+ # In release however this will point to the equivalent of:
44
+ # NSBundle.mainBundle.resourcePath + 'app/assets'
45
+ def assets_path
46
+ (RUBYCOCOA_ROOT + 'app/assets').to_s
47
+ end
48
+ module_function :assets_path
49
+
50
+ # Returns the path to the current used app/views dir.
51
+ #
52
+ # So in debug & test mode this will point to your development
53
+ # source_root/app/views.
54
+ #
55
+ # In release however this will point to the equivalent of:
56
+ # NSBundle.mainBundle.resourcePath + 'app/views'
57
+ def views_path
58
+ (RUBYCOCOA_ROOT + 'app/views').to_s
59
+ end
60
+ module_function :views_path
61
+
62
+ # Returns the path to a +controller+ file.
63
+ #
64
+ # Rucola::RCApp.path_for_controller(ApplicationController) #=> 'root/app/controllers/application_controller.rb'
65
+ def path_for_controller(controller)
66
+ "#{controllers_path}/#{controller.name.to_s.snake_case}.rb"
67
+ end
68
+ module_function :path_for_controller
69
+
70
+ # Returns the path to a +model+ file.
71
+ #
72
+ # Rucola::RCApp.path_for_model(Person) #=> 'root/app/models/person.rb'
73
+ def path_for_model(model)
74
+ "#{models_path}/#{model.name.to_s.snake_case}.rb"
75
+ end
76
+ module_function :path_for_model
77
+
78
+ # Returns the path to a +view+ file.
79
+ #
80
+ # Rucola::RCApp.path_for_controller('preferences') #=> 'root/app/views/Preferences.nib'
81
+ # Rucola::RCApp.path_for_controller('Preferences') #=> 'root/app/views/Preferences.nib'
82
+ #
83
+ # Rucola::RCApp.path_for_controller(PreferencesController) #=> 'root/app/views/Preferences.nib'
84
+ # Rucola::RCApp.path_for_controller(PreferencesController.alloc.init) #=> 'root/app/views/Preferences.nib'
85
+ def path_for_view(view)
86
+ view = view.class unless view.is_a?(String) or view.is_a?(Class)
87
+ view = view.name.to_s.sub(/Controller$/, '') if view.is_a? Class
88
+ "#{views_path}/#{view.camel_case}.nib"
89
+ end
90
+ module_function :path_for_view
91
+
92
+ # Returns the path to an +asset+ file.
93
+ #
94
+ # Rucola::RCApp.path_for_asset('somefile.png') #=> 'root/app/assets/somefile.png'
95
+ def path_for_asset(asset)
96
+ "#{assets_path}/#{asset}"
97
+ end
98
+ module_function :path_for_asset
99
+
100
+ end
101
+ end