merb-assets 0.9.2

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.
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
+