Class: Hanami::Assets::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/hanami/assets/configuration.rb

Overview

Framework configuration

Since:

  • 0.1.0

Constant Summary collapse

DEFAULT_SCHEME =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'http'.freeze
DEFAULT_HOST =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'localhost'.freeze
DEFAULT_PORT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'2300'.freeze
DEFAULT_PUBLIC_DIRECTORY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'public'.freeze
DEFAULT_MANIFEST =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'assets.json'.freeze
DEFAULT_PREFIX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'/assets'.freeze
URL_SEPARATOR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'/'.freeze
HTTP_SCHEME =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'http'.freeze
HTTP_PORT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'80'.freeze
HTTPS_SCHEME =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'https'.freeze
HTTPS_PORT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0

'443'.freeze
DEFAULT_SUBRESOURCE_INTEGRITY_ALGORITHM =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.3.0

:sha256
SUBRESOURCE_INTEGRITY_SEPARATOR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Since:

  • 0.3.0

' '.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&blk) ⇒ Hanami::Assets::Configuration

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new instance

Since:

  • 0.1.0



99
100
101
102
# File 'lib/hanami/assets/configuration.rb', line 99

def initialize(&blk)
  reset!
  instance_eval(&blk) if block_given?
end

Instance Attribute Details

#cdn(value = nil) ⇒ Object

CDN mode

Determine if the helpers should always generate absolute URL. This is useful in production mode.

Since:

  • 0.1.0



154
155
156
157
158
159
160
# File 'lib/hanami/assets/configuration.rb', line 154

def cdn(value = nil)
  if value.nil?
    @cdn
  else
    @cdn = !!value # rubocop:disable Style/DoubleNegation
  end
end

#compile(value = nil) ⇒ Object

Compile mode

Determine if compile assets from sources to destination. Usually this is turned off in production mode.

Since:

  • 0.1.0



110
111
112
113
114
115
116
# File 'lib/hanami/assets/configuration.rb', line 110

def compile(value = nil)
  if value.nil?
    @compile
  else
    @compile = value
  end
end

#host(value = nil) ⇒ Object

URL host for the application

This is used to generate absolute URL from helpers.

Since:

  • 0.1.0



278
279
280
281
282
283
284
# File 'lib/hanami/assets/configuration.rb', line 278

def host(value = nil)
  if value.nil?
    @host
  else
    @host = value
  end
end

#javascript_compressor(value = nil) ⇒ Object

JavaScript compressor

Determine which compressor to use for JavaScript files during deploy.

By default it’s nil, that means it doesn’t compress JavaScripts at deploy time.

It accepts a Symbol or an object that respond to #compress(file).

The following symbols are accepted:

* <tt>:builtin</tt> - Ruby based implementation of jsmin. It doesn't require any external gem.
* <tt>:yui</tt> - YUI Compressor, it depends on <tt>yui-compressor</tt> gem and it requires Java 1.4+
* <tt>:uglifier</tt> - UglifyJS, it depends on <tt>uglifier</tt> gem and it requires Node.js
* <tt>:closure</tt> - Google Closure Compiler, it depends on <tt>closure-compiler</tt> gem and it requires Java

Examples:

YUI Compressor

require 'hanami/assets'

Hanami::Assets.configure do
  # ...
  javascript_compressor :yui
end.load!

Custom Compressor

require 'hanami/assets'

Hanami::Assets.configure do
  # ...
  javascript_compressor MyCustomJavascriptCompressor.new
end.load!

Parameters:

  • value (Symbol, #compress) (defaults to: nil)

    the compressor

See Also:

Since:

  • 0.1.0



205
206
207
208
209
210
211
# File 'lib/hanami/assets/configuration.rb', line 205

def javascript_compressor(value = nil)
  if value.nil?
    @javascript_compressor
  else
    @javascript_compressor = value
  end
end

#manifest(value = nil) ⇒ Object

Manifest path from public directory

Since:

  • 0.1.0



348
349
350
351
352
353
354
# File 'lib/hanami/assets/configuration.rb', line 348

def manifest(value = nil)
  if value.nil?
    @manifest
  else
    @manifest = value.to_s
  end
end

#port(value = nil) ⇒ Object

URL port for the application

This is used to generate absolute URL from helpers.

Since:

  • 0.1.0



291
292
293
294
295
296
297
# File 'lib/hanami/assets/configuration.rb', line 291

def port(value = nil)
  if value.nil?
    @port
  else
    @port = value.to_s
  end
end

#prefix(value = nil) ⇒ Object

URL port for the application

This is used to generate absolute or relative URL from helpers.

Since:

  • 0.1.0



304
305
306
307
308
309
310
# File 'lib/hanami/assets/configuration.rb', line 304

def prefix(value = nil)
  if value.nil?
    @prefix
  else
    @prefix = Utils::PathPrefix.new(value)
  end
end

#public_directory(value = nil) ⇒ Object

Application public directory

Since:

  • 0.1.0



327
328
329
330
331
332
333
# File 'lib/hanami/assets/configuration.rb', line 327

def public_directory(value = nil)
  if value.nil?
    @public_directory
  else
    @public_directory = Pathname.new(::File.expand_path(value))
  end
end

#public_manifestObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.4.0



91
92
93
# File 'lib/hanami/assets/configuration.rb', line 91

def public_manifest
  @public_manifest
end

#root(value = nil) ⇒ Object

Sources root

Since:

  • 0.1.0



315
316
317
318
319
320
321
322
# File 'lib/hanami/assets/configuration.rb', line 315

def root(value = nil)
  if value.nil?
    @root
  else
    @root = Pathname.new(value).realpath
    sources.root = @root
  end
end

#scheme(value = nil) ⇒ Object

URL scheme for the application

This is used to generate absolute URL from helpers.

Since:

  • 0.1.0



265
266
267
268
269
270
271
# File 'lib/hanami/assets/configuration.rb', line 265

def scheme(value = nil)
  if value.nil?
    @scheme
  else
    @scheme = value
  end
end

#sourcesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Application’s assets sources

Since:

  • 0.1.0



368
369
370
# File 'lib/hanami/assets/configuration.rb', line 368

def sources
  @sources ||= Hanami::Assets::Config::Sources.new(root)
end

#stylesheet_compressor(value = nil) ⇒ Object

Stylesheet compressor

Determine which compressor to use for Stylesheet files during deploy.

By default it’s nil, that means it doesn’t compress Stylesheets at deploy time.

It accepts a Symbol or an object that respond to #compress(file).

The following symbols are accepted:

* <tt>:builtin</tt> - Ruby based compressor. It doesn't require any external gem. It's fast, but not an efficient compressor.
* <tt>:yui</tt> - YUI-Compressor, it depends on <tt>yui-compressor</tt> gem and requires Java 1.4+
* <tt>:sass</tt> - Sass, it depends on <tt>sass</tt> gem

Examples:

YUI Compressor

require 'hanami/assets'

Hanami::Assets.configure do
  # ...
  stylesheet_compressor :yui
end.load!

Custom Compressor

require 'hanami/assets'

Hanami::Assets.configure do
  # ...
  stylesheet_compressor MyCustomStylesheetCompressor.new
end.load!

Parameters:

  • value (Symbol, #compress) (defaults to: nil)

    the compressor

See Also:

Since:

  • 0.1.0



252
253
254
255
256
257
258
# File 'lib/hanami/assets/configuration.rb', line 252

def stylesheet_compressor(value = nil)
  if value.nil?
    @stylesheet_compressor
  else
    @stylesheet_compressor = value
  end
end

#subresource_integrity(*values) ⇒ Object

Subresource integrity mode

Determine if the helpers should generate the integrity attribute for an asset. Usually this is turned on in production mode.

Since:

  • 0.3.0



138
139
140
141
142
143
144
145
146
# File 'lib/hanami/assets/configuration.rb', line 138

def subresource_integrity(*values)
  if values.empty?
    @subresource_integrity
  elsif values.length == 1
    @subresource_integrity = values.first
  else
    @subresource_integrity = values
  end
end

Class Method Details

.for(base) ⇒ Hanami::Assets::Configuration

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a copy of the configuration of the framework instance associated with the given class.

When multiple instances of Hanami::Assets are used in the same application, we want to make sure that a controller or an action will receive the expected configuration.

Parameters:

  • base (Class, Module)

    a controller or an action

Returns:

Since:

  • 0.1.0



82
83
84
85
86
87
# File 'lib/hanami/assets/configuration.rb', line 82

def self.for(base)
  # TODO: this implementation is similar to Hanami::Controller::Configuration consider to extract it into Hanami::Utils
  namespace = Utils::String.new(base).namespace
  framework = Utils::Class.load_from_pattern!("(#{namespace}|Hanami)::Assets")
  framework.configuration
end

Instance Method Details

#asset_path(source) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Relative URL

Since:

  • 0.1.0



399
400
401
402
403
404
405
# File 'lib/hanami/assets/configuration.rb', line 399

def asset_path(source)
  if cdn
    asset_url(source)
  else
    compile_path(source)
  end
end

#asset_url(source) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Absolute URL

Since:

  • 0.1.0



411
412
413
# File 'lib/hanami/assets/configuration.rb', line 411

def asset_url(source)
  "#{@base_url}#{compile_path(source)}"
end

#css_compressorHanami::Assets::Compressors::Stylesheet

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Load Stylesheet compressor

Returns:

Raises:

See Also:

Since:

  • 0.1.0



470
471
472
473
# File 'lib/hanami/assets/configuration.rb', line 470

def css_compressor
  require 'hanami/assets/compressors/stylesheet'
  Hanami::Assets::Compressors::Stylesheet.for(stylesheet_compressor)
end

#destination_directoryObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Destination directory

It’s the combination of public_directory and prefix.

Since:

  • 0.1.0



341
342
343
# File 'lib/hanami/assets/configuration.rb', line 341

def destination_directory
  @destination_directory ||= public_directory.join(*prefix.split(URL_SEPARATOR))
end

#duplicateObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0



477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/hanami/assets/configuration.rb', line 477

def duplicate # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  Configuration.new.tap do |c|
    c.root                  = root
    c.scheme                = scheme
    c.host                  = host
    c.port                  = port
    c.prefix                = prefix
    c.subresource_integrity = subresource_integrity
    c.cdn                   = cdn
    c.compile               = compile
    c.public_directory      = public_directory
    c.manifest              = manifest
    c.sources               = sources.dup
    c.javascript_compressor = javascript_compressor
    c.stylesheet_compressor = stylesheet_compressor
  end
end

#filesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Application’s assets

Since:

  • 0.1.0



376
377
378
# File 'lib/hanami/assets/configuration.rb', line 376

def files
  sources.files
end

#find(file) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find a file from sources

Since:

  • 0.1.0



391
392
393
# File 'lib/hanami/assets/configuration.rb', line 391

def find(file)
  @sources.find(file)
end

#fingerprint(value = nil) ⇒ Object

Fingerprint mode

Determine if the helpers should generate the fingerprinted path for an asset. Usually this is turned on in production mode.

Since:

  • 0.1.0



124
125
126
127
128
129
130
# File 'lib/hanami/assets/configuration.rb', line 124

def fingerprint(value = nil)
  if value.nil?
    @fingerprint
  else
    @fingerprint = value
  end
end

#js_compressorHanami::Assets::Compressors::Javascript

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Load Javascript compressor

Returns:

Raises:

See Also:

Since:

  • 0.1.0



453
454
455
456
# File 'lib/hanami/assets/configuration.rb', line 453

def js_compressor
  require 'hanami/assets/compressors/javascript'
  Hanami::Assets::Compressors::Javascript.for(javascript_compressor)
end

#load!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Load the configuration

This MUST be executed before to accept the first HTTP request

Since:

  • 0.1.0



525
526
527
528
529
530
531
532
533
534
# File 'lib/hanami/assets/configuration.rb', line 525

def load!
  if (fingerprint || subresource_integrity) && manifest_path.exist?
    @public_manifest = Config::Manifest.new(
      JSON.parse(manifest_path.read),
      manifest_path
    )
  end

  @base_url = URI::Generic.build(scheme: scheme, host: host, port: url_port).to_s
end

#manifest_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Absolute manifest path

Since:

  • 0.1.0



360
361
362
# File 'lib/hanami/assets/configuration.rb', line 360

def manifest_path
  public_directory.join(manifest)
end

#reset!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.1.0



497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/hanami/assets/configuration.rb', line 497

def reset! # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  @scheme                = DEFAULT_SCHEME
  @host                  = DEFAULT_HOST
  @port                  = DEFAULT_PORT

  @prefix                = Utils::PathPrefix.new(DEFAULT_PREFIX)
  @subresource_integrity = false
  @cdn                   = false
  @fingerprint           = false
  @compile               = false
  @base_url              = nil
  @destination_directory = nil
  @public_manifest       = Config::NullManifest.new(self)

  @javascript_compressor = nil
  @stylesheet_compressor = nil

  root             Dir.pwd
  public_directory root.join(DEFAULT_PUBLIC_DIRECTORY)
  manifest         DEFAULT_MANIFEST
end

#source(file) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 0.3.0



382
383
384
385
# File 'lib/hanami/assets/configuration.rb', line 382

def source(file)
  pathname = Pathname.new(file)
  pathname.absolute? ? pathname : find(file)
end

#subresource_integrity_algorithmsObject

An array of crypographically secure hashing algorithms to use for generating asset subresource integrity checks

Since:

  • 0.3.0



419
420
421
422
423
424
425
426
427
# File 'lib/hanami/assets/configuration.rb', line 419

def subresource_integrity_algorithms
  if @subresource_integrity == true
    [DEFAULT_SUBRESOURCE_INTEGRITY_ALGORITHM]
  else
    # Using Array() allows us to accept Array or Symbol, and '|| nil' lets
    # us return an empty array when @subresource_integrity is `false`
    Array(@subresource_integrity || nil)
  end
end

#subresource_integrity_value(source) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Subresource integrity attribute

Since:

  • 0.3.0



433
434
435
436
437
438
439
# File 'lib/hanami/assets/configuration.rb', line 433

def subresource_integrity_value(source)
  return unless subresource_integrity

  public_manifest.subresource_integrity_values(
    prefix.join(source)
  ).join(SUBRESOURCE_INTEGRITY_SEPARATOR)
end