hanami 2.1.0.rc1 → 2.1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/hanami.gemspec +2 -2
  4. data/lib/hanami/app.rb +0 -5
  5. data/lib/hanami/config/actions.rb +3 -4
  6. data/lib/hanami/config/assets.rb +1 -1
  7. data/lib/hanami/config/views.rb +10 -2
  8. data/lib/hanami/config.rb +21 -16
  9. data/lib/hanami/extensions/view/context.rb +122 -10
  10. data/lib/hanami/extensions/view/part.rb +14 -2
  11. data/lib/hanami/extensions/view/scope.rb +7 -0
  12. data/lib/hanami/extensions/view/slice_configured_context.rb +12 -8
  13. data/lib/hanami/extensions/view/slice_configured_helpers.rb +12 -1
  14. data/lib/hanami/extensions/view/slice_configured_part.rb +4 -5
  15. data/lib/hanami/extensions/view/slice_configured_view.rb +12 -4
  16. data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
  17. data/lib/hanami/extensions/view.rb +5 -3
  18. data/lib/hanami/helpers/assets_helper.rb +71 -70
  19. data/lib/hanami/helpers/form_helper/form_builder.rb +54 -54
  20. data/lib/hanami/helpers/form_helper/values.rb +8 -8
  21. data/lib/hanami/helpers/form_helper.rb +9 -9
  22. data/lib/hanami/providers/assets.rb +4 -1
  23. data/lib/hanami/rake_tasks.rb +1 -9
  24. data/lib/hanami/slice.rb +10 -0
  25. data/lib/hanami/version.rb +1 -1
  26. data/spec/integration/assets/assets_spec.rb +67 -24
  27. data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +130 -0
  28. data/spec/integration/view/context/assets_spec.rb +57 -31
  29. data/spec/support/app_integration.rb +12 -6
  30. data/spec/unit/hanami/config/render_detailed_errors_spec.rb +1 -1
  31. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +11 -0
  32. data/spec/unit/hanami/version_spec.rb +1 -1
  33. metadata +13 -11
@@ -7,13 +7,13 @@ module Hanami
7
7
  module Extensions
8
8
  # Integrated behavior for `Hanami::View` classes within Hanami apps.
9
9
  #
10
- # This is NOT RELEASED as of 2.0.0.
11
- #
12
10
  # @see Hanami::View
13
11
  #
14
- # @api private
12
+ # @api public
13
+ # @since 2.1.0
15
14
  module View
16
15
  # @api private
16
+ # @since 2.1.0
17
17
  def self.included(view_class)
18
18
  super
19
19
 
@@ -22,8 +22,10 @@ module Hanami
22
22
  end
23
23
 
24
24
  # @api private
25
+ # @since 2.1.0
25
26
  module ClassMethods
26
27
  # @api private
28
+ # @since 2.1.0
27
29
  def configure_for_slice(slice)
28
30
  extend SliceConfiguredView.new(slice)
29
31
  end
@@ -11,47 +11,47 @@ module Hanami
11
11
  #
12
12
  # Inject these helpers in a view
13
13
  #
14
- # @since 0.1.0
14
+ # @since 2.1.0
15
15
  #
16
16
  # @see http://www.rubydoc.info/gems/hanami-helpers/Hanami/Helpers/HtmlHelper
17
17
  module AssetsHelper
18
- # @since 0.1.0
18
+ # @since 2.1.0
19
19
  # @api private
20
20
  NEW_LINE_SEPARATOR = "\n"
21
21
 
22
- # @since 0.1.0
22
+ # @since 2.1.0
23
23
  # @api private
24
24
  WILDCARD_EXT = ".*"
25
25
 
26
- # @since 0.1.0
26
+ # @since 2.1.0
27
27
  # @api private
28
28
  JAVASCRIPT_EXT = ".js"
29
29
 
30
- # @since 0.1.0
30
+ # @since 2.1.0
31
31
  # @api private
32
32
  STYLESHEET_EXT = ".css"
33
33
 
34
- # @since 0.1.0
34
+ # @since 2.1.0
35
35
  # @api private
36
36
  JAVASCRIPT_MIME_TYPE = "text/javascript"
37
37
 
38
- # @since 0.1.0
38
+ # @since 2.1.0
39
39
  # @api private
40
40
  STYLESHEET_MIME_TYPE = "text/css"
41
41
 
42
- # @since 0.1.0
42
+ # @since 2.1.0
43
43
  # @api private
44
44
  FAVICON_MIME_TYPE = "image/x-icon"
45
45
 
46
- # @since 0.1.0
46
+ # @since 2.1.0
47
47
  # @api private
48
48
  STYLESHEET_REL = "stylesheet"
49
49
 
50
- # @since 0.1.0
50
+ # @since 2.1.0
51
51
  # @api private
52
52
  FAVICON_REL = "shortcut icon"
53
53
 
54
- # @since 0.1.0
54
+ # @since 2.1.0
55
55
  # @api private
56
56
  DEFAULT_FAVICON = "favicon.ico"
57
57
 
@@ -85,7 +85,7 @@ module Hanami
85
85
  # name of the algorithm, then a hyphen, then the hash value of the file.
86
86
  # If more than one algorithm is used, they"ll be separated by a space.
87
87
  #
88
- # @param sources [Array<String>] one or more assets by name or absolute URL
88
+ # @param source_paths [Array<String, #url>] one or more assets by name or absolute URL
89
89
  #
90
90
  # @return [Hanami::View::HTML::SafeString] the markup
91
91
  #
@@ -93,64 +93,64 @@ module Hanami
93
93
  # `subresource_integrity` modes are on and the javascript file is missing
94
94
  # from the manifest
95
95
  #
96
- # @since 0.1.0
96
+ # @since 2.1.0
97
97
  #
98
98
  # @see Hanami::Assets::Helpers#path
99
99
  #
100
100
  # @example Single Asset
101
101
  #
102
- # <%= js "application" %>
102
+ # <%= javascript_tag "application" %>
103
103
  #
104
104
  # # <script src="/assets/application.js" type="text/javascript"></script>
105
105
  #
106
106
  # @example Multiple Assets
107
107
  #
108
- # <%= js "application", "dashboard" %>
108
+ # <%= javascript_tag "application", "dashboard" %>
109
109
  #
110
110
  # # <script src="/assets/application.js" type="text/javascript"></script>
111
111
  # # <script src="/assets/dashboard.js" type="text/javascript"></script>
112
112
  #
113
113
  # @example Asynchronous Execution
114
114
  #
115
- # <%= js "application", async: true %>
115
+ # <%= javascript_tag "application", async: true %>
116
116
  #
117
117
  # # <script src="/assets/application.js" type="text/javascript" async="async"></script>
118
118
  #
119
119
  # @example Subresource Integrity
120
120
  #
121
- # <%= js "application" %>
121
+ # <%= javascript_tag "application" %>
122
122
  #
123
123
  # # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
124
124
  # # type="text/javascript" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
125
125
  #
126
126
  # @example Subresource Integrity for 3rd Party Scripts
127
127
  #
128
- # <%= js "https://example.com/assets/example.js", integrity: "sha384-oqVu...Y8wC" %>
128
+ # <%= javascript_tag "https://example.com/assets/example.js", integrity: "sha384-oqVu...Y8wC" %>
129
129
  #
130
130
  # # <script src="https://example.com/assets/example.js" type="text/javascript"
131
131
  # # integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
132
132
  #
133
133
  # @example Deferred Execution
134
134
  #
135
- # <%= js "application", defer: true %>
135
+ # <%= javascript_tag "application", defer: true %>
136
136
  #
137
137
  # # <script src="/assets/application.js" type="text/javascript" defer="defer"></script>
138
138
  #
139
139
  # @example Absolute URL
140
140
  #
141
- # <%= js "https://code.jquery.com/jquery-2.1.4.min.js" %>
141
+ # <%= javascript_tag "https://code.jquery.com/jquery-2.1.4.min.js" %>
142
142
  #
143
143
  # # <script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
144
144
  #
145
145
  # @example Fingerprint Mode
146
146
  #
147
- # <%= js "application" %>
147
+ # <%= javascript_tag "application" %>
148
148
  #
149
149
  # # <script src="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js" type="text/javascript"></script>
150
150
  #
151
151
  # @example CDN Mode
152
152
  #
153
- # <%= js "application" %>
153
+ # <%= javascript_tag "application" %>
154
154
  #
155
155
  # # <script src="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
156
156
  # # type="text/javascript"></script>
@@ -189,7 +189,7 @@ module Hanami
189
189
  # name of the algorithm, then a hyphen, then the hashed value of the file.
190
190
  # If more than one algorithm is used, they"ll be separated by a space.
191
191
  #
192
- # @param sources [Array<String>] one or more assets by name or absolute URL
192
+ # @param source_paths [Array<String, #url>] one or more assets by name or absolute URL
193
193
  #
194
194
  # @return [Hanami::View::HTML::SafeString] the markup
195
195
  #
@@ -197,53 +197,53 @@ module Hanami
197
197
  # `subresource_integrity` modes are on and the stylesheet file is missing
198
198
  # from the manifest
199
199
  #
200
- # @since 0.1.0
200
+ # @since 2.1.0
201
201
  #
202
202
  # @see Hanami::Assets::Helpers#path
203
203
  #
204
204
  # @example Single Asset
205
205
  #
206
- # <%= css "application" %>
206
+ # <%= stylesheet_tag "application" %>
207
207
  #
208
208
  # # <link href="/assets/application.css" type="text/css" rel="stylesheet">
209
209
  #
210
210
  # @example Multiple Assets
211
211
  #
212
- # <%= css "application", "dashboard" %>
212
+ # <%= stylesheet_tag "application", "dashboard" %>
213
213
  #
214
214
  # # <link href="/assets/application.css" type="text/css" rel="stylesheet">
215
215
  # # <link href="/assets/dashboard.css" type="text/css" rel="stylesheet">
216
216
  #
217
217
  # @example Subresource Integrity
218
218
  #
219
- # <%= css "application" %>
219
+ # <%= stylesheet_tag "application" %>
220
220
  #
221
221
  # # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
222
222
  # # type="text/css" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
223
223
  #
224
224
  # @example Subresource Integrity for 3rd Party Assets
225
225
  #
226
- # <%= css "https://example.com/assets/example.css", integrity: "sha384-oqVu...Y8wC" %>
226
+ # <%= stylesheet_tag "https://example.com/assets/example.css", integrity: "sha384-oqVu...Y8wC" %>
227
227
  #
228
228
  # # <link href="https://example.com/assets/example.css"
229
229
  # # type="text/css" rel="stylesheet" integrity="sha384-oqVu...Y8wC" crossorigin="anonymous"></script>
230
230
  #
231
231
  # @example Absolute URL
232
232
  #
233
- # <%= css "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" %>
233
+ # <%= stylesheet_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" %>
234
234
  #
235
235
  # # <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
236
236
  # # type="text/css" rel="stylesheet">
237
237
  #
238
238
  # @example Fingerprint Mode
239
239
  #
240
- # <%= css "application" %>
240
+ # <%= stylesheet_tag "application" %>
241
241
  #
242
242
  # # <link href="/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css" type="text/css" rel="stylesheet">
243
243
  #
244
244
  # @example CDN Mode
245
245
  #
246
- # <%= css "application" %>
246
+ # <%= stylesheet_tag "application" %>
247
247
  #
248
248
  # # <link href="https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.css"
249
249
  # # type="text/css" rel="stylesheet">
@@ -282,7 +282,7 @@ module Hanami
282
282
  # If the "CDN mode" is on, the `src` is an absolute URL of the
283
283
  # application CDN.
284
284
  #
285
- # @param source [String] asset name or absolute URL
285
+ # @param source [String, #url] asset name, absolute URL, or asset object
286
286
  # @param options [Hash] HTML 5 attributes
287
287
  #
288
288
  # @return [Hanami::View::HTML::SafeString] the markup
@@ -291,43 +291,43 @@ module Hanami
291
291
  # `subresource_integrity` modes are on and the image file is missing
292
292
  # from the manifest
293
293
  #
294
- # @since 0.1.0
294
+ # @since 2.1.0
295
295
  #
296
296
  # @see Hanami::Assets::Helpers#path
297
297
  #
298
298
  # @example Basic Usage
299
299
  #
300
- # <%= image "logo.png" %>
300
+ # <%= image_tag "logo.png" %>
301
301
  #
302
302
  # # <img src="/assets/logo.png" alt="Logo">
303
303
  #
304
304
  # @example Custom alt Attribute
305
305
  #
306
- # <%= image "logo.png", alt: "Application Logo" %>
306
+ # <%= image_tag "logo.png", alt: "Application Logo" %>
307
307
  #
308
308
  # # <img src="/assets/logo.png" alt="Application Logo">
309
309
  #
310
310
  # @example Custom HTML Attributes
311
311
  #
312
- # <%= image "logo.png", id: "logo", class: "image" %>
312
+ # <%= image_tag "logo.png", id: "logo", class: "image" %>
313
313
  #
314
314
  # # <img src="/assets/logo.png" alt="Logo" id="logo" class="image">
315
315
  #
316
316
  # @example Absolute URL
317
317
  #
318
- # <%= image "https://example-cdn.com/images/logo.png" %>
318
+ # <%= image_tag "https://example-cdn.com/images/logo.png" %>
319
319
  #
320
320
  # # <img src="https://example-cdn.com/images/logo.png" alt="Logo">
321
321
  #
322
322
  # @example Fingerprint Mode
323
323
  #
324
- # <%= image "logo.png" %>
324
+ # <%= image_tag "logo.png" %>
325
325
  #
326
326
  # # <img src="/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
327
327
  #
328
328
  # @example CDN Mode
329
329
  #
330
- # <%= image "logo.png" %>
330
+ # <%= image_tag "logo.png" %>
331
331
  #
332
332
  # # <img src="https://assets.bookshelf.org/assets/logo-28a6b886de2372ee3922fcaf3f78f2d8.png" alt="Logo">
333
333
  def image_tag(source, options = {})
@@ -353,7 +353,7 @@ module Hanami
353
353
  # If the "CDN mode" is on, the `href` is an absolute URL of the
354
354
  # application CDN.
355
355
  #
356
- # @param source [String] asset name
356
+ # @param source [String, #url] asset name or asset object
357
357
  # @param options [Hash] HTML 5 attributes
358
358
  #
359
359
  # @return [Hanami::View::HTML::SafeString] the markup
@@ -362,37 +362,37 @@ module Hanami
362
362
  # `subresource_integrity` modes are on and the favicon is file missing
363
363
  # from the manifest
364
364
  #
365
- # @since 0.1.0
365
+ # @since 2.1.0
366
366
  #
367
367
  # @see Hanami::Assets::Helpers#path
368
368
  #
369
369
  # @example Basic Usage
370
370
  #
371
- # <%= favicon %>
371
+ # <%= favicon_tag %>
372
372
  #
373
373
  # # <link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
374
374
  #
375
375
  # @example Custom Path
376
376
  #
377
- # <%= favicon "fav.ico" %>
377
+ # <%= favicon_tag "fav.ico" %>
378
378
  #
379
379
  # # <link href="/assets/fav.ico" rel="shortcut icon" type="image/x-icon">
380
380
  #
381
381
  # @example Custom HTML Attributes
382
382
  #
383
- # <%= favicon "favicon.ico", id: "fav" %>
383
+ # <%= favicon_tag "favicon.ico", id: "fav" %>
384
384
  #
385
385
  # # <link id: "fav" href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">
386
386
  #
387
387
  # @example Fingerprint Mode
388
388
  #
389
- # <%= favicon %>
389
+ # <%= favicon_tag %>
390
390
  #
391
391
  # # <link href="/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico" rel="shortcut icon" type="image/x-icon">
392
392
  #
393
393
  # @example CDN Mode
394
394
  #
395
- # <%= favicon %>
395
+ # <%= favicon_tag %>
396
396
  #
397
397
  # # <link href="https://assets.bookshelf.org/assets/favicon-28a6b886de2372ee3922fcaf3f78f2d8.ico"
398
398
  # rel="shortcut icon" type="image/x-icon">
@@ -424,7 +424,7 @@ module Hanami
424
424
  # If the "CDN mode" is on, the `src` is an absolute URL of the
425
425
  # application CDN.
426
426
  #
427
- # @param source [String] asset name or absolute URL
427
+ # @param source [String, #url] asset name, absolute URL or asset object
428
428
  # @param options [Hash] HTML 5 attributes
429
429
  #
430
430
  # @return [Hanami::View::HTML::SafeString] the markup
@@ -436,25 +436,25 @@ module Hanami
436
436
  # @raise [ArgumentError] if source isn"t specified both as argument or
437
437
  # tag inside the given block
438
438
  #
439
- # @since 0.1.0
439
+ # @since 2.1.0
440
440
  #
441
441
  # @see Hanami::Assets::Helpers#path
442
442
  #
443
443
  # @example Basic Usage
444
444
  #
445
- # <%= video "movie.mp4" %>
445
+ # <%= video_tag "movie.mp4" %>
446
446
  #
447
447
  # # <video src="/assets/movie.mp4"></video>
448
448
  #
449
449
  # @example Absolute URL
450
450
  #
451
- # <%= video "https://example-cdn.com/assets/movie.mp4" %>
451
+ # <%= video_tag "https://example-cdn.com/assets/movie.mp4" %>
452
452
  #
453
453
  # # <video src="https://example-cdn.com/assets/movie.mp4"></video>
454
454
  #
455
455
  # @example Custom HTML Attributes
456
456
  #
457
- # <%= video("movie.mp4", autoplay: true, controls: true) %>
457
+ # <%= video_tag("movie.mp4", autoplay: true, controls: true) %>
458
458
  #
459
459
  # # <video src="/assets/movie.mp4" autoplay="autoplay" controls="controls"></video>
460
460
  #
@@ -485,25 +485,25 @@ module Hanami
485
485
  #
486
486
  # @example Without Any Argument
487
487
  #
488
- # <%= video %>
488
+ # <%= video_tag %>
489
489
  #
490
490
  # # ArgumentError
491
491
  #
492
492
  # @example Without src And Without Block
493
493
  #
494
- # <%= video(content: true) %>
494
+ # <%= video_tag(content: true) %>
495
495
  #
496
496
  # # ArgumentError
497
497
  #
498
498
  # @example Fingerprint Mode
499
499
  #
500
- # <%= video "movie.mp4" %>
500
+ # <%= video_tag "movie.mp4" %>
501
501
  #
502
502
  # # <video src="/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
503
503
  #
504
504
  # @example CDN Mode
505
505
  #
506
- # <%= video "movie.mp4" %>
506
+ # <%= video_tag "movie.mp4" %>
507
507
  #
508
508
  # # <video src="https://assets.bookshelf.org/assets/movie-28a6b886de2372ee3922fcaf3f78f2d8.mp4"></video>
509
509
  def video_tag(source = nil, options = {}, &blk)
@@ -526,7 +526,7 @@ module Hanami
526
526
  # If the "CDN mode" is on, the `src` is an absolute URL of the
527
527
  # application CDN.
528
528
  #
529
- # @param source [String] asset name or absolute URL
529
+ # @param source [String, #url] asset name, absolute URL or asset object
530
530
  # @param options [Hash] HTML 5 attributes
531
531
  #
532
532
  # @return [Hanami::View::HTML::SafeString] the markup
@@ -538,25 +538,25 @@ module Hanami
538
538
  # @raise [ArgumentError] if source isn"t specified both as argument or
539
539
  # tag inside the given block
540
540
  #
541
- # @since 0.1.0
541
+ # @since 2.1.0
542
542
  #
543
543
  # @see Hanami::Assets::Helpers#path
544
544
  #
545
545
  # @example Basic Usage
546
546
  #
547
- # <%= audio "song.ogg" %>
547
+ # <%= audio_tag "song.ogg" %>
548
548
  #
549
549
  # # <audio src="/assets/song.ogg"></audio>
550
550
  #
551
551
  # @example Absolute URL
552
552
  #
553
- # <%= audio "https://example-cdn.com/assets/song.ogg" %>
553
+ # <%= audio_tag "https://example-cdn.com/assets/song.ogg" %>
554
554
  #
555
555
  # # <audio src="https://example-cdn.com/assets/song.ogg"></audio>
556
556
  #
557
557
  # @example Custom HTML Attributes
558
558
  #
559
- # <%= audio("song.ogg", autoplay: true, controls: true) %>
559
+ # <%= audio_tag("song.ogg", autoplay: true, controls: true) %>
560
560
  #
561
561
  # # <audio src="/assets/song.ogg" autoplay="autoplay" controls="controls"></audio>
562
562
  #
@@ -587,25 +587,25 @@ module Hanami
587
587
  #
588
588
  # @example Without Any Argument
589
589
  #
590
- # <%= audio %>
590
+ # <%= audio_tag %>
591
591
  #
592
592
  # # ArgumentError
593
593
  #
594
594
  # @example Without src And Without Block
595
595
  #
596
- # <%= audio(controls: true) %>
596
+ # <%= audio_tag(controls: true) %>
597
597
  #
598
598
  # # ArgumentError
599
599
  #
600
600
  # @example Fingerprint Mode
601
601
  #
602
- # <%= audio "song.ogg" %>
602
+ # <%= audio_tag "song.ogg" %>
603
603
  #
604
604
  # # <audio src="/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
605
605
  #
606
606
  # @example CDN Mode
607
607
  #
608
- # <%= audio "song.ogg" %>
608
+ # <%= audio_tag "song.ogg" %>
609
609
  #
610
610
  # # <audio src="https://assets.bookshelf.org/assets/song-28a6b886de2372ee3922fcaf3f78f2d8.ogg"></audio>
611
611
  def audio_tag(source = nil, options = {}, &blk)
@@ -626,7 +626,7 @@ module Hanami
626
626
  #
627
627
  # If CDN mode is on, it returns the absolute URL of the asset.
628
628
  #
629
- # @param source [String] the asset name
629
+ # @param source_path [String, #url] the asset name or asset object
630
630
  #
631
631
  # @return [String] the asset path
632
632
  #
@@ -634,7 +634,7 @@ module Hanami
634
634
  # `subresource_integrity` modes are on and the asset is missing
635
635
  # from the manifest
636
636
  #
637
- # @since 0.1.0
637
+ # @since 2.1.0
638
638
  #
639
639
  # @example Basic Usage
640
640
  #
@@ -666,6 +666,7 @@ module Hanami
666
666
  #
667
667
  # # "https://assets.bookshelf.org/assets/application-28a6b886de2372ee3922fcaf3f78f2d8.js"
668
668
  def asset_url(source_path)
669
+ return source_path.url if source_path.respond_to?(:url)
669
670
  return source_path if _absolute_url?(source_path)
670
671
 
671
672
  _context.assets[source_path].url
@@ -673,7 +674,7 @@ module Hanami
673
674
 
674
675
  private
675
676
 
676
- # @since 0.1.0
677
+ # @since 2.1.0
677
678
  # @api private
678
679
  def _safe_tags(*source_paths, &blk)
679
680
  ::Hanami::View::HTML::SafeString.new(
@@ -684,7 +685,7 @@ module Hanami
684
685
  # @since 2.1.0
685
686
  # @api private
686
687
  def _typed_path(source, ext)
687
- source = "#{source}#{ext}" if _append_extension?(source, ext)
688
+ source = "#{source}#{ext}" if source.is_a?(String) && _append_extension?(source, ext)
688
689
  asset_url(source)
689
690
  end
690
691
 
@@ -696,7 +697,7 @@ module Hanami
696
697
  _context.assets[source_path].sri
697
698
  end
698
699
 
699
- # @since 0.1.0
700
+ # @since 2.1.0
700
701
  # @api private
701
702
  def _absolute_url?(source)
702
703
  ABSOLUTE_URL_MATCHER.match(source)
@@ -710,7 +711,7 @@ module Hanami
710
711
  _context.assets.crossorigin?(source)
711
712
  end
712
713
 
713
- # @since 0.1.0
714
+ # @since 2.1.0
714
715
  # @api private
715
716
  def _source_options(src, options, &blk)
716
717
  options ||= {}