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

Load the configuration

This MUST be executed before to accept the first HTTP request

Since:

  • 0.1.0



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

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