merb-assets 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 YOUR NAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,4 @@
1
+ merb-assets
2
+ ===========
3
+
4
+ A plugin for the Merb framework that provides ...
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ PLUGIN = "merb-assets"
5
+ NAME = "merb-assets"
6
+ VERSION = "0.9.2"
7
+ AUTHOR = "Ezra Zygmuntowicz"
8
+ EMAIL = "ez@engineyard.com"
9
+ HOMEPAGE = "http://merb-plugins.rubyforge.org/merb-assets/"
10
+ SUMMARY = "Merb plugin that provides the helpers for assets and asset bundling"
11
+
12
+ spec = Gem::Specification.new do |s|
13
+ s.name = NAME
14
+ s.version = VERSION
15
+ s.platform = Gem::Platform::RUBY
16
+ s.has_rdoc = true
17
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
18
+ s.summary = SUMMARY
19
+ s.description = s.summary
20
+ s.author = AUTHOR
21
+ s.email = EMAIL
22
+ s.homepage = HOMEPAGE
23
+ s.add_dependency('merb-core', '>= 0.9.2')
24
+ s.require_path = 'lib'
25
+ s.autorequire = PLUGIN
26
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
27
+ end
28
+
29
+ Rake::GemPackageTask.new(spec) do |pkg|
30
+ pkg.gem_spec = spec
31
+ end
32
+
33
+ task :install => [:package] do
34
+ sh %{sudo gem install pkg/#{NAME}-#{VERSION} --no-update-sources --no-update-sources}
35
+ end
36
+
37
+ namespace :jruby do
38
+
39
+ desc "Run :package and install the resulting .gem with jruby"
40
+ task :install => :package do
41
+ sh %{#{SUDO} jruby -S gem install pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
42
+ end
43
+
44
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/merb-haml.rb
5
+ Add your Merb rake tasks to lib/merb-haml/merbtasks.rb
@@ -0,0 +1,14 @@
1
+ require 'merb-assets/assets'
2
+ require 'merb-assets/assets_mixin'
3
+
4
+ Merb::BootLoader.before_app_loads do
5
+ Merb::Controller.send(:include, Merb::AssetsMixin)
6
+ end
7
+
8
+
9
+ Merb::Plugins.config[:asset_helpers] = {
10
+ :max_hosts => 4,
11
+ :asset_domain => "assets%s",
12
+ :domain => "my-awesome-domain.com",
13
+ :use_ssl => false
14
+ } if Merb::Plugins.config[:asset_helpers].nil?
@@ -0,0 +1,198 @@
1
+ module Merb
2
+ module Assets
3
+
4
+ # Check whether the assets should be bundled.
5
+ #
6
+ # ==== Returns
7
+ # Boolean::
8
+ # True if the assets should be bundled (e.g., production mode or
9
+ # :bundle_assets is explicitly enabled).
10
+ def self.bundle?
11
+ (Merb.environment == 'production') ||
12
+ (!!Merb::Config[:bundle_assets])
13
+ end
14
+
15
+ # Helpers for handling asset files.
16
+ module AssetHelpers
17
+ # :nodoc:
18
+ ASSET_FILE_EXTENSIONS = {
19
+ :javascript => ".js",
20
+ :stylesheet => ".css"
21
+ }
22
+
23
+ # Returns the URI path to a particular asset file. If +local_path+ is
24
+ # true, returns the path relative to the Merb.root, not the public
25
+ # directory. Uses the path_prefix, if any is configured.
26
+ #
27
+ # ==== Parameters
28
+ # asset_type<Symbol>:: Type of the asset (e.g. :javascript).
29
+ # filename<~to_s>:: The path to the file.
30
+ # local_path<Boolean>::
31
+ # If true, the returned path will be relative to the Merb.root,
32
+ # otherwise it will be the public URI path. Defaults to false.
33
+ #
34
+ # ==== Returns
35
+ # String:: The path to the asset.
36
+ #
37
+ # ==== Examples
38
+ # asset_path(:javascript, :dingo)
39
+ # # => "/javascripts/dingo.js"
40
+ #
41
+ # asset_path(:javascript, :dingo, true)
42
+ # # => "public/javascripts/dingo.js"
43
+ def asset_path(asset_type, filename, local_path = false)
44
+ filename = filename.to_s
45
+ if filename !~ /#{'\\' + ASSET_FILE_EXTENSIONS[asset_type]}\Z/
46
+ filename << ASSET_FILE_EXTENSIONS[asset_type]
47
+ end
48
+ filename = "/#{asset_type}s/#{filename}"
49
+ if local_path
50
+ return "public#{filename}"
51
+ else
52
+ return "#{Merb::Config[:path_prefix]}#{filename}"
53
+ end
54
+ end
55
+ end
56
+
57
+ # Helper for creating unique paths to a file name
58
+ # Can increase speend for browsers that are limited to a certain number of connections per host
59
+ # for downloading static files (css, js, images...)
60
+ class UniqueAssetPath
61
+ class << self
62
+ @@config = Merb::Plugins.config[:asset_helpers]
63
+
64
+ # Builds the path to the file based on the name
65
+ #
66
+ # ==== Parameters
67
+ # filename<String>:: Name of file to generate path for
68
+ #
69
+ # ==== Returns
70
+ # String:: The path to the asset.
71
+ #
72
+ # ==== Examples
73
+ # build("/javascripts/my_fancy_script.js")
74
+ # # => "https://assets5.my-awesome-domain.com/javascripts/my_fancy_script.js"
75
+ #
76
+ def build(filename)
77
+ #%{#{(USE_SSL ? 'https' : 'http')}://#{sprintf(@@config[:asset_domain],self.calculate_host_id(file))}.#{@@config[:domain]}/#{filename}}
78
+ path = @@config[:use_ssl] ? 'https://' : 'http://'
79
+ path << sprintf(@@config[:asset_domain],self.calculate_host_id(filename)) << ".#{@@config[:domain]}"
80
+ path << "/" if filename.index('/') != 0
81
+ path << filename
82
+ end
83
+
84
+ protected
85
+
86
+ # Calculates the id for the host
87
+ def calculate_host_id(filename)
88
+ ascii_total = 0
89
+ filename.each_byte {|byte|
90
+ ascii_total += byte
91
+ }
92
+ (ascii_total % @@config[:max_hosts] + 1)
93
+ end
94
+ end
95
+ end
96
+
97
+ # An abstract class for bundling text assets into single files.
98
+ class AbstractAssetBundler
99
+ class << self
100
+
101
+ # ==== Parameters
102
+ # &block:: A block to add as a post-bundle callback.
103
+ #
104
+ # ==== Examples
105
+ # add_callback { |filename| `yuicompressor #{filename}` }
106
+ def add_callback(&block)
107
+ callbacks << block
108
+ end
109
+ alias_method :after_bundling, :add_callback
110
+
111
+ # Retrieve existing callbacks.
112
+ #
113
+ # ==== Returns
114
+ # Array[Proc]:: An array of existing callbacks.
115
+ def callbacks
116
+ @callbacks ||= []
117
+ return @callbacks
118
+ end
119
+
120
+ # The type of asset for which the bundler is responsible. Override
121
+ # this method in your bundler code.
122
+ #
123
+ # ==== Raises
124
+ # NotImplementedError:: This method is implemented by the bundler.
125
+ #
126
+ # ==== Returns
127
+ # Symbol:: The type of the asset
128
+ def asset_type
129
+ raise NotImplementedError, "should return a symbol for the first argument to be passed to asset_path"
130
+ end
131
+ end
132
+
133
+ # ==== Parameters
134
+ # name<~to_s>::
135
+ # Name of the bundle. If name is true, it will be converted to :all.
136
+ # *files<String>:: Names of the files to bundle.
137
+ def initialize(name, *files)
138
+ @bundle_name = name == true ? :all : name
139
+ @bundle_filename = asset_path(self.class.asset_type, @bundle_name, true)
140
+ @files = files.map { |f| asset_path(self.class.asset_type, f, true) }
141
+ end
142
+
143
+ # Creates the new bundled file, executing all the callbacks.
144
+ #
145
+ # ==== Returns
146
+ # Symbol:: Name of the bundle.
147
+ def bundle!
148
+ # TODO: Move this file check out into an in-memory cache. Also, push it out to the helper level so we don't have to create the helper object.
149
+ unless File.exist?(@bundle_filename)
150
+ bundle_files(@bundle_filename, *@files)
151
+ self.class.callbacks.each { |c| c.call(@bundle_filename) }
152
+ end
153
+ return @bundle_name
154
+ end
155
+
156
+ protected
157
+
158
+ include Merb::Assets::AssetHelpers # for asset_path
159
+
160
+ # Bundle all the files into one.
161
+ #
162
+ # ==== Parameters
163
+ # filename<String>:: Name of the bundle file.
164
+ # *files<String>:: Filenames to be bundled.
165
+ def bundle_files(filename, *files)
166
+ File.open(filename, "w") do |f|
167
+ files.each { |file| f.puts(File.read(file)) }
168
+ end
169
+ end
170
+
171
+ end
172
+
173
+ # Bundles javascripts into a single file:
174
+ #
175
+ # javascripts/#{name}.js
176
+ class JavascriptAssetBundler < AbstractAssetBundler
177
+
178
+ # ==== Returns
179
+ # Symbol:: The asset type, i.e. :javascript.
180
+ def self.asset_type
181
+ :javascript
182
+ end
183
+ end
184
+
185
+ # Bundles stylesheets into a single file:
186
+ #
187
+ # stylesheets/#{name}.css
188
+ class StylesheetAssetBundler < AbstractAssetBundler
189
+
190
+ # ==== Returns
191
+ # Symbol:: The asset type, i.e. :stylesheet.
192
+ def self.asset_type
193
+ :stylesheet
194
+ end
195
+ end
196
+
197
+ end
198
+ end
@@ -0,0 +1,562 @@
1
+ module Merb
2
+ # The AssetsMixin module provides a number of helper methods to views for
3
+ # linking to assets and other pages, dealing with JavaScript and CSS.
4
+ module AssetsMixin
5
+ include Merb::Assets::AssetHelpers
6
+ # :section: Accessing Assets
7
+ # Merb provides views with convenience methods for links images and other
8
+ # assets.
9
+
10
+ # ==== Parameters
11
+ # name<~to_s>:: The text of the link.
12
+ # url<~to_s>:: The URL to link to. Defaults to an empty string.
13
+ # opts<Hash>:: Additional HTML options for the link.
14
+ #
15
+ # ==== Examples
16
+ # link_to("The Merb home page", "http://www.merbivore.com/")
17
+ # # => <a href="http://www.merbivore.com/">The Merb home page</a>
18
+ #
19
+ # link_to("The Ruby home page", "http://www.ruby-lang.org", {'class' => 'special', 'target' => 'blank'})
20
+ # # => <a href="http://www.ruby-lang.org" class="special" target="blank">The Ruby home page</a>
21
+ #
22
+ # link_to p.title, "/blog/show/#{p.id}"
23
+ # # => <a href="blog/show/13">The Entry Title</a>
24
+ #
25
+ def link_to(name, url='', opts={})
26
+ opts[:href] ||= url
27
+ %{<a #{ opts.to_xml_attributes }>#{name}</a>}
28
+ end
29
+
30
+ # ==== Parameters
31
+ # img<~to_s>:: The image path.
32
+ # opts<Hash>:: Additional options for the image tag (see below).
33
+ #
34
+ # ==== Options (opts)
35
+ # :path<String>::
36
+ # Sets the path prefix for the image. Defaults to "/images/" or whatever
37
+ # is specified in Merb::Config. This is ignored if img is an absolute
38
+ # path or full URL.
39
+ #
40
+ # All other options set HTML attributes on the tag.
41
+ #
42
+ # ==== Examples
43
+ # image_tag('foo.gif')
44
+ # # => <img src='/images/foo.gif' />
45
+ #
46
+ # image_tag('foo.gif', :class => 'bar')
47
+ # # => <img src='/images/foo.gif' class='bar' />
48
+ #
49
+ # image_tag('foo.gif', :path => '/files/')
50
+ # # => <img src='/files/foo.gif' />
51
+ #
52
+ # image_tag('http://test.com/foo.gif')
53
+ # # => <img src="http://test.com/foo.gif">
54
+ #
55
+ # image_tag('charts', :path => '/dynamic/')
56
+ # or
57
+ # image_tag('/dynamic/charts')
58
+ # # => <img src="/dynamic/charts">
59
+ def image_tag(img, opts={})
60
+ if img[0].chr == '/'
61
+ opts[:src] = img
62
+ else
63
+ opts[:path] ||=
64
+ if img =~ %r{^https?://}
65
+ ''
66
+ else
67
+ if Merb::Config[:path_prefix]
68
+ Merb::Config[:path_prefix] + '/images/'
69
+ else
70
+ '/images/'
71
+ end
72
+ end
73
+ opts[:src] ||= opts.delete(:path) + img
74
+ end
75
+ %{<img #{ opts.to_xml_attributes } />}
76
+ end
77
+
78
+ # :section: JavaScript related functions
79
+ #
80
+
81
+ # ==== Parameters
82
+ # javascript<String>:: Text to escape for use in JavaScript.
83
+ #
84
+ # ==== Examples
85
+ # escape_js("'Lorem ipsum!' -- Some guy")
86
+ # # => "\\'Lorem ipsum!\\' -- Some guy"
87
+ #
88
+ # escape_js("Please keep text\nlines as skinny\nas possible.")
89
+ # # => "Please keep text\\nlines as skinny\\nas possible."
90
+ def escape_js(javascript)
91
+ (javascript || '').gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
92
+ end
93
+
94
+ # ==== Parameters
95
+ # name<~to_s>:: The text in the link.
96
+ # function<~to_s>:: The onClick event in JavaScript.
97
+ #
98
+ # ==== Examples
99
+ # link_to_function('Click me', "alert('hi!')")
100
+ # # => <a href="#" onclick="alert('hi!'); return false;">Click me</a>
101
+ #
102
+ # link_to_function('Add to cart', "item_total += 1; alert('Item added!');")
103
+ # # => <a href="#" onclick="item_total += 1; alert('Item added!'); return false;">Add to cart</a>
104
+ def link_to_function(name, function)
105
+ %{<a href="#" onclick="#{function}; return false;">#{name}</a>}
106
+ end
107
+
108
+ # ==== Parameters
109
+ # data<Object>::
110
+ # Object to translate into JSON. If the object does not respond to
111
+ # :to_json, then data.inspect.to_json is returned instead.
112
+ #
113
+ # ==== Examples
114
+ # js({'user' => 'Lewis', 'page' => 'home'})
115
+ # # => "{\"user\":\"Lewis\",\"page\":\"home\"}"
116
+ #
117
+ # js([ 1, 2, {"a"=>3.141}, false, true, nil, 4..10 ])
118
+ # # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
119
+ def js(data)
120
+ if data.respond_to? :to_json
121
+ data.to_json
122
+ else
123
+ data.inspect.to_json
124
+ end
125
+ end
126
+
127
+ # :section: External JavaScript and Stylesheets
128
+ #
129
+ # You can use require_js(:prototype) or require_css(:shinystyles)
130
+ # from any view or layout, and the scripts will only be included once
131
+ # in the head of the final page. To get this effect, the head of your
132
+ # layout you will need to include a call to include_required_js and
133
+ # include_required_css.
134
+ #
135
+ # ==== Examples
136
+ # # File: app/views/layouts/application.html.erb
137
+ #
138
+ # <html>
139
+ # <head>
140
+ # <%= include_required_js %>
141
+ # <%= include_required_css %>
142
+ # </head>
143
+ # <body>
144
+ # <%= catch_content :layout %>
145
+ # </body>
146
+ # </html>
147
+ #
148
+ # # File: app/views/whatever/_part1.herb
149
+ #
150
+ # <% require_js 'this' -%>
151
+ # <% require_css 'that', 'another_one' -%>
152
+ #
153
+ # # File: app/views/whatever/_part2.herb
154
+ #
155
+ # <% require_js 'this', 'something_else' -%>
156
+ # <% require_css 'that' -%>
157
+ #
158
+ # # File: app/views/whatever/index.herb
159
+ #
160
+ # <%= partial(:part1) %>
161
+ # <%= partial(:part2) %>
162
+ #
163
+ # # Will generate the following in the final page...
164
+ # <html>
165
+ # <head>
166
+ # <script src="/javascripts/this.js" type="text/javascript"></script>
167
+ # <script src="/javascripts/something_else.js" type="text/javascript"></script>
168
+ # <link href="/stylesheets/that.css" media="all" rel="Stylesheet" type="text/css"/>
169
+ # <link href="/stylesheets/another_one.css" media="all" rel="Stylesheet" type="text/css"/>
170
+ # </head>
171
+ # .
172
+ # .
173
+ # .
174
+ # </html>
175
+ #
176
+ # See each method's documentation for more information.
177
+
178
+ # :section: Bundling Asset Files
179
+ #
180
+ # The key to making a fast web application is to reduce both the amount of
181
+ # data transfered and the number of client-server interactions. While having
182
+ # many small, module Javascript or stylesheet files aids in the development
183
+ # process, your web application will benefit from bundling those assets in
184
+ # the production environment.
185
+ #
186
+ # An asset bundle is a set of asset files which are combined into a single
187
+ # file. This reduces the number of requests required to render a page, and
188
+ # can reduce the amount of data transfer required if you're using gzip
189
+ # encoding.
190
+ #
191
+ # Asset bundling is always enabled in production mode, and can be optionally
192
+ # enabled in all environments by setting the <tt>:bundle_assets</tt> value
193
+ # in <tt>config/merb.yml</tt> to +true+.
194
+ #
195
+ # ==== Examples
196
+ #
197
+ # In the development environment, this:
198
+ #
199
+ # js_include_tag :prototype, :lowpro, :bundle => true
200
+ #
201
+ # will produce two <script> elements. In the production mode, however, the
202
+ # two files will be concatenated in the order given into a single file,
203
+ # <tt>all.js</tt>, in the <tt>public/javascripts</tt> directory.
204
+ #
205
+ # To specify a different bundle name:
206
+ #
207
+ # css_include_tag :typography, :whitespace, :bundle => :base
208
+ # css_include_tag :header, :footer, :bundle => "content"
209
+ # css_include_tag :lightbox, :images, :bundle => "lb.css"
210
+ #
211
+ # (<tt>base.css</tt>, <tt>content.css</tt>, and <tt>lb.css</tt> will all be
212
+ # created in the <tt>public/stylesheets</tt> directory.)
213
+ #
214
+ # == Callbacks
215
+ #
216
+ # To use a Javascript or CSS compressor, like JSMin or YUI Compressor:
217
+ #
218
+ # Merb::Assets::JavascriptAssetBundler.add_callback do |filename|
219
+ # system("/usr/local/bin/yui-compress #{filename}")
220
+ # end
221
+ #
222
+ # Merb::Assets::StylesheetAssetBundler.add_callback do |filename|
223
+ # system("/usr/local/bin/css-min #{filename}")
224
+ # end
225
+ #
226
+ # These blocks will be run after a bundle is created.
227
+ #
228
+ # == Bundling Required Assets
229
+ #
230
+ # Combining the +require_css+ and +require_js+ helpers with bundling can be
231
+ # problematic. You may want to separate out the common assets for your
232
+ # application -- Javascript frameworks, common CSS, etc. -- and bundle those
233
+ # in a "base" bundle. Then, for each section of your site, bundle the
234
+ # required assets into a section-specific bundle.
235
+ #
236
+ # <b>N.B.: If you bundle an inconsistent set of assets with the same name,
237
+ # you will have inconsistent results. Be thorough and test often.</b>
238
+ #
239
+ # ==== Example
240
+ #
241
+ # In your application layout:
242
+ #
243
+ # js_include_tag :prototype, :lowpro, :bundle => :base
244
+ #
245
+ # In your controller layout:
246
+ #
247
+ # require_js :bundle => :posts
248
+
249
+ # The require_js method can be used to require any JavaScript file anywhere
250
+ # in your templates. Regardless of how many times a single script is
251
+ # included with require_js, Merb will only include it once in the header.
252
+ #
253
+ # ==== Parameters
254
+ # *js<~to_s>:: JavaScript files to include.
255
+ #
256
+ # ==== Examples
257
+ # <% require_js 'jquery' %>
258
+ # # A subsequent call to include_required_js will render...
259
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
260
+ #
261
+ # <% require_js 'jquery', 'effects' %>
262
+ # # A subsequent call to include_required_js will render...
263
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
264
+ # # <script src="/javascripts/effects.js" type="text/javascript"></script>
265
+ #
266
+ def require_js(*js)
267
+ @required_js ||= []
268
+ @required_js |= js
269
+ end
270
+
271
+ # The require_css method can be used to require any CSS file anywhere in
272
+ # your templates. Regardless of how many times a single stylesheet is
273
+ # included with require_css, Merb will only include it once in the header.
274
+ #
275
+ # ==== Parameters
276
+ # *css<~to_s>:: CSS files to include.
277
+ #
278
+ # ==== Examples
279
+ # <% require_css('style') %>
280
+ # # A subsequent call to include_required_css will render...
281
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
282
+ #
283
+ # <% require_css('style', 'ie-specific') %>
284
+ # # A subsequent call to include_required_css will render...
285
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
286
+ # # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
287
+ #
288
+ def require_css(*css)
289
+ @required_css ||= []
290
+ @required_css |= css
291
+ end
292
+
293
+ # A method used in the layout of an application to create +<script>+ tags
294
+ # to include JavaScripts required in in templates and subtemplates using
295
+ # require_js.
296
+ #
297
+ # ==== Parameters
298
+ # options<Hash>:: Options to pass to js_include_tag.
299
+ #
300
+ # ==== Returns
301
+ # String:: The JavaScript tag.
302
+ #
303
+ # ==== Examples
304
+ # # my_action.herb has a call to require_js 'jquery'
305
+ # # File: layout/application.html.erb
306
+ # include_required_js
307
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
308
+ #
309
+ # # my_action.herb has a call to require_js 'jquery', 'effects', 'validation'
310
+ # # File: layout/application.html.erb
311
+ # include_required_js
312
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
313
+ # # <script src="/javascripts/effects.js" type="text/javascript"></script>
314
+ # # <script src="/javascripts/validation.js" type="text/javascript"></script>
315
+ #
316
+ def include_required_js(options = {})
317
+ return '' if @required_js.nil?
318
+ js_include_tag(*(@required_js + [options]))
319
+ end
320
+
321
+ # A method used in the layout of an application to create +<link>+ tags for
322
+ # CSS stylesheets required in in templates and subtemplates using
323
+ # require_css.
324
+ #
325
+ # ==== Parameters
326
+ # options<Hash>:: Options to pass to css_include_tag.
327
+ #
328
+ # ==== Returns
329
+ # String:: The CSS tag.
330
+ #
331
+ # ==== Examples
332
+ # # my_action.herb has a call to require_css 'style'
333
+ # # File: layout/application.html.erb
334
+ # include_required_css
335
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
336
+ #
337
+ # # my_action.herb has a call to require_js 'style', 'ie-specific'
338
+ # # File: layout/application.html.erb
339
+ # include_required_css
340
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
341
+ # # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
342
+ #
343
+ def include_required_css(options = {})
344
+ return '' if @required_css.nil?
345
+ css_include_tag(*(@required_css + [options]))
346
+ end
347
+
348
+ # ==== Parameters
349
+ # *scripts::
350
+ # The scripts to include. If the last element is a Hash, it will be used
351
+ # as options (see below). If ".js" is left out from the script names, it
352
+ # will be added to them.
353
+ #
354
+ # ==== Options
355
+ # :bundle<~to_s>::
356
+ # The name of the bundle the scripts should be combined into.
357
+ #
358
+ # ==== Returns
359
+ # String:: The JavaScript include tag(s).
360
+ #
361
+ # ==== Examples
362
+ # js_include_tag 'jquery'
363
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
364
+ #
365
+ # js_include_tag 'moofx.js', 'upload'
366
+ # # => <script src="/javascripts/moofx.js" type="text/javascript"></script>
367
+ # # <script src="/javascripts/upload.js" type="text/javascript"></script>
368
+ #
369
+ # js_include_tag :effects
370
+ # # => <script src="/javascripts/effects.js" type="text/javascript"></script>
371
+ #
372
+ # js_include_tag :jquery, :validation
373
+ # # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
374
+ # # <script src="/javascripts/validation.js" type="text/javascript"></script>
375
+ #
376
+ def js_include_tag(*scripts)
377
+ options = scripts.last.is_a?(Hash) ? scripts.pop : {}
378
+ return nil if scripts.empty?
379
+
380
+ if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && scripts.size > 1
381
+ bundler = Merb::Assets::JavascriptAssetBundler.new(bundle_name, *scripts)
382
+ bundled_asset = bundler.bundle!
383
+ return js_include_tag(bundled_asset)
384
+ end
385
+
386
+ tags = ""
387
+
388
+ for script in scripts
389
+ attrs = {
390
+ :src => asset_path(:javascript, script),
391
+ :type => "text/javascript"
392
+ }
393
+ tags << %Q{<script #{attrs.to_xml_attributes}></script>}
394
+ end
395
+
396
+ return tags
397
+ end
398
+
399
+ # ==== Parameters
400
+ # *stylesheets::
401
+ # The stylesheets to include. If the last element is a Hash, it will be
402
+ # used as options (see below). If ".css" is left out from the stylesheet
403
+ # names, it will be added to them.
404
+ #
405
+ # ==== Options
406
+ # :bundle<~to_s>::
407
+ # The name of the bundle the stylesheets should be combined into.
408
+ # :media<~to_s>::
409
+ # The media attribute for the generated link element. Defaults to :all.
410
+ #
411
+ # ==== Returns
412
+ # String:: The CSS include tag(s).
413
+ #
414
+ # ==== Examples
415
+ # css_include_tag 'style'
416
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
417
+ #
418
+ # css_include_tag 'style.css', 'layout'
419
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
420
+ # # <link href="/stylesheets/layout.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
421
+ #
422
+ # css_include_tag :menu
423
+ # # => <link href="/stylesheets/menu.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
424
+ #
425
+ # css_include_tag :style, :screen
426
+ # # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
427
+ # # <link href="/stylesheets/screen.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
428
+ #
429
+ # css_include_tag :style, :media => :print
430
+ # # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="utf-8" />
431
+ #
432
+ # css_include_tag :style, :charset => 'iso-8859-1'
433
+ # # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="iso-8859-1" />
434
+ def css_include_tag(*stylesheets)
435
+ options = stylesheets.last.is_a?(Hash) ? stylesheets.pop : {}
436
+ return nil if stylesheets.empty?
437
+
438
+ if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && stylesheets.size > 1
439
+ bundler = Merb::Assets::StylesheetAssetBundler.new(bundle_name, *stylesheets)
440
+ bundled_asset = bundler.bundle!
441
+ return css_include_tag(bundled_asset)
442
+ end
443
+
444
+ tags = ""
445
+
446
+ for stylesheet in stylesheets
447
+ attrs = {
448
+ :href => asset_path(:stylesheet, stylesheet),
449
+ :type => "text/css",
450
+ :rel => "Stylesheet",
451
+ :charset => options[:charset] || 'utf-8',
452
+ :media => options[:media] || :all
453
+ }
454
+ tags << %Q{<link #{attrs.to_xml_attributes} />}
455
+ end
456
+
457
+ return tags
458
+ end
459
+
460
+ # ==== Parameters
461
+ # *assets::
462
+ # The assets to include. These should be the full paths to any static served file
463
+ #
464
+ # ==== Returns
465
+ # Array:: Full unique paths to assets OR
466
+ # String:: if only a single path is requested
467
+ # ==== Examples
468
+ # uniq_path("/javascripts/my.js","/javascripts/my.css")
469
+ # #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets2.my-awesome-domain.com/javascripts/my.css"]
470
+ #
471
+ # uniq_path(["/javascripts/my.js","/stylesheets/my.css"])
472
+ # #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"]
473
+ #
474
+ # uniq_path(%w(/javascripts/my.js /stylesheets/my.css))
475
+ # #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"]
476
+ #
477
+ # uniq_path('/stylesheets/somearbitrary.css')
478
+ # #=> "http://assets3.my-awesome-domain.com/stylesheets/somearbitrary.css"
479
+ #
480
+ # uniq_path('/images/hostsexypicture.jpg')
481
+ # #=>"http://assets1.my-awesome-domain.com/images/hostsexypicture.jpg"
482
+ def uniq_path(*assets)
483
+ paths = []
484
+ assets.collect.flatten.each do |filename|
485
+ paths.push(UniqueAssetPath.build(filename))
486
+ end
487
+ paths.length > 1 ? paths : paths.first
488
+ end
489
+
490
+ # ==== Parameters
491
+ # *assets::
492
+ # Creates unique paths for javascript files (prepends "/javascripts" and appends ".js")
493
+ #
494
+ # ==== Returns
495
+ # Array:: Full unique paths to assets OR
496
+ # String:: if only a single path is requested
497
+ # ==== Examples
498
+ # uniq_js_path("my")
499
+ # #=> "http://assets2.my-awesome-domain.com/javascripts/my.js"
500
+ #
501
+ # uniq_js_path(["admin/secrets","home/signup"])
502
+ # #=> ["http://assets2.my-awesome-domain.com/javascripts/admin/secrets.js",
503
+ # "http://assets1.my-awesome-domain.com/javascripts/home/signup.js"]
504
+ def uniq_js_path(*assets)
505
+ paths = []
506
+ assets.collect.flatten.each do |filename|
507
+ paths.push(UniqueAssetPath.build(asset_path(:javascript,filename,true)))
508
+ end
509
+ paths.length > 1 ? paths : paths.first
510
+ end
511
+
512
+ # ==== Parameters
513
+ # *assets::
514
+ # Creates unique paths for stylesheet files (prepends "/stylesheets" and appends ".css")
515
+ #
516
+ # ==== Returns
517
+ # Array:: Full unique paths to assets OR
518
+ # String:: if only a single path is requested
519
+ # ==== Examples
520
+ # uniq_css_path("my")
521
+ # #=> "http://assets2.my-awesome-domain.com/stylesheets/my.css"
522
+ #
523
+ # uniq_css_path(["admin/secrets","home/signup"])
524
+ # #=> ["http://assets2.my-awesome-domain.com/stylesheets/admin/secrets.css",
525
+ # "http://assets1.my-awesome-domain.com/stylesheets/home/signup.css"]
526
+ def uniq_css_path(*assets)
527
+ paths = []
528
+ assets.collect.flatten.each do |filename|
529
+ paths.push(UniqueAssetPath.build(asset_path(:stylesheet,filename,true)))
530
+ end
531
+ paths.length > 1 ? paths : paths.first
532
+ end
533
+
534
+ # ==== Parameters
535
+ # *assets::
536
+ # As js_include_tag but has unique path
537
+ #
538
+ # ==== Returns
539
+ # Array:: Full unique paths to assets OR
540
+ # String:: if only a single path is requested
541
+ # ==== Examples
542
+ # uniq_js_tag("my")
543
+ # #=> <script type="text/javascript" src="http://assets2.my-awesome-domain.com/javascripts/my.js"></script>
544
+ def uniq_js_tag(*assets)
545
+ js_include_tag(uniq_js_path(assets))
546
+ end
547
+
548
+ # ==== Parameters
549
+ # *assets::
550
+ # As uniq_css_tag but has unique path
551
+ #
552
+ # ==== Returns
553
+ # Array:: Full unique paths to assets OR
554
+ # String:: if only a single path is requested
555
+ # ==== Examples
556
+ # uniq_css_tag("my")
557
+ # #=> <link href="http://assets2.my-awesome-domain.com/stylesheets/my.css" type="text/css" />
558
+ def uniq_css_tag(*assets)
559
+ css_include_tag(uniq_css_path(assets))
560
+ end
561
+ end
562
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb-assets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.2
5
+ platform: ruby
6
+ authors:
7
+ - Ezra Zygmuntowicz
8
+ autorequire: merb-assets
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-24 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb-core
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.2
23
+ version:
24
+ description: Merb plugin that provides the helpers for assets and asset bundling
25
+ email: ez@engineyard.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README
32
+ - LICENSE
33
+ - TODO
34
+ files:
35
+ - LICENSE
36
+ - README
37
+ - Rakefile
38
+ - TODO
39
+ - lib/merb-assets
40
+ - lib/merb-assets/assets.rb
41
+ - lib/merb-assets/assets_mixin.rb
42
+ - lib/merb-assets.rb
43
+ has_rdoc: true
44
+ homepage: http://merb-plugins.rubyforge.org/merb-assets/
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.0.1
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: Merb plugin that provides the helpers for assets and asset bundling
69
+ test_files: []
70
+