hanami-helpers 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00c50648c23a0d34befe080287206beb9e46aa34
4
- data.tar.gz: 2be73f77dead23bc48142b567b0a2595d9ba6a00
3
+ metadata.gz: e90f277e6ff4d461bd7ebcc45e48de6c03f91e70
4
+ data.tar.gz: 8d97b52cf45b16454acf597a6fe198b3a549148a
5
5
  SHA512:
6
- metadata.gz: ce6e712b2a0e0aaf38e79a682112a51929ec62fb77cc2f2af17c0645fddc28d56654e0c0b8dd4acf4c707c502ea7cc6dc19870e1ed7ca027304755d90dde9826
7
- data.tar.gz: 75c87873818c331507ce01574fbd5652a9be6f8e782805e4f731377f37e81429578384cc9dde5b7a1f521d6c0473ab4e6f4057ff9593fcee49bf68bdd9f6d419
6
+ metadata.gz: 21d4b2160f0d6af94d099ec8f765bbcce309b22623aff0ce3190f50b7fb2fec228fde3b6f330a47242455ab7989144e8c04b5a146170399d74f914ba0facc79f
7
+ data.tar.gz: f898b3a411eb8d77e776a398ef2873bc6b6e8ef39fffd59602f8d0b7cd53a5662ea767665a95e7da228271bb3f16cf635f3df12d28feceed507177b2e621134c
@@ -1,6 +1,20 @@
1
1
  # Hanami::Helpers
2
2
  View helpers for Ruby web applications
3
3
 
4
+ ## v0.4.0 - 2016-07-22
5
+ ### Added
6
+ - [Luca Guidi] Allow `link_to` to be concat with other helpers. Eg `link_to(...) + link_to(...)`, `span(...) + link_to(...)`.
7
+ - [Anton Davydov] Support blank `<option>` tag for `select` form helper. Eg. `select :store, [...], options: { prompt: '' }`
8
+ - [Sebastjan Hribar] Support selected `<option>` for `select` form helper. Eg. `select :store, [...], options: { selected: 'it' }`
9
+ - [Cang Ta] Added `datalist` form helper
10
+
11
+ ### Changed
12
+ – [Luca Guidi] Drop support for Ruby 2.0 and 2.1. Official support for JRuby 9.0.5.0+.
13
+ - [Luca Guidi] Inverted options (label, value) for `select` form helper. Now the syntax is `select :store, { 'Italy' => 'it', 'United States' => 'us' }`
14
+
15
+ ### Fixed
16
+ – [Nikolay Shebanov] Explicitly require some `hanami-utils` dependencies
17
+
4
18
  ## v0.3.0 - 2016-01-22
5
19
  ### Changed
6
20
  - [Luca Guidi] Renamed the project
@@ -8,20 +8,21 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Hanami::Helpers::VERSION
9
9
  spec.authors = ['Luca Guidi', 'Trung Lê', 'Alfonso Uceda']
10
10
  spec.email = ['me@lucaguidi.com', 'trung.le@ruby-journal.com', 'uceda73@gmail.com']
11
- spec.summary = %q{Hanami helpers}
12
- spec.description = %q{View helpers for Ruby applications}
11
+ spec.summary = 'Hanami helpers'
12
+ spec.description = 'View helpers for Ruby applications'
13
13
  spec.homepage = 'http://hanamirb.org'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-helpers.gemspec`.split($/)
16
+ spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-helpers.gemspec`.split($/) # rubocop:disable Style/SpecialGlobalVars
17
+
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
20
  spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.0.0'
21
+ spec.required_ruby_version = '>= 2.2.0'
21
22
 
22
- spec.add_dependency 'hanami-utils', '~> 0.7'
23
+ spec.add_dependency 'hanami-utils', '~> 0.8'
23
24
 
24
25
  spec.add_development_dependency 'bundler', '~> 1.6'
25
- spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rake', '~> 11'
26
27
  spec.add_development_dependency 'minitest', '~> 5.5'
27
28
  end
@@ -1 +1 @@
1
- require 'hanami/helpers'
1
+ require 'hanami/helpers' # rubocop:disable Style/FileName
@@ -4,7 +4,7 @@ module Hanami
4
4
  module Helpers
5
5
  # Escape helpers
6
6
  #
7
- # You can include this module inside your view and
7
+ # You can include this module inside your view and
8
8
  # the view will have access all methods.
9
9
  #
10
10
  # By including <tt>Hanami::Helpers::EscapeHelper</tt> it will inject private
@@ -13,6 +13,7 @@ module Hanami
13
13
  # @since 0.1.0
14
14
  module EscapeHelper
15
15
  private
16
+
16
17
  # Escape the given HTML tag content.
17
18
  #
18
19
  # This should be used only for untrusted contents: user input.
@@ -75,7 +76,7 @@ module Hanami
75
76
  end
76
77
 
77
78
  # @since 0.1.0
78
- alias_method :h, :escape_html
79
+ alias h escape_html
79
80
 
80
81
  # Escape the given HTML tag attribute.
81
82
  #
@@ -147,7 +148,7 @@ module Hanami
147
148
  end
148
149
 
149
150
  # @since 0.1.0
150
- alias_method :ha, :escape_html_attribute
151
+ alias ha escape_html_attribute
151
152
 
152
153
  # Escape an URL to be used in HTML attributes
153
154
  #
@@ -225,7 +226,7 @@ module Hanami
225
226
  end
226
227
 
227
228
  # @since 0.1.0
228
- alias_method :hu, :escape_url
229
+ alias hu escape_url
229
230
 
230
231
  # Bypass escape.
231
232
  #
@@ -28,22 +28,24 @@ module Hanami
28
28
  #
29
29
  # Supported tags and inputs:
30
30
  #
31
+ # * <tt>check_box</tt>
31
32
  # * <tt>color_field</tt>
32
33
  # * <tt>date_field</tt>
33
34
  # * <tt>datetime_field</tt>
34
35
  # * <tt>datetime_local_field</tt>
35
36
  # * <tt>email_field</tt>
36
- # * <tt>hidden_field</tt>
37
- # * <tt>file_field</tt>
38
37
  # * <tt>fields_for</tt>
38
+ # * <tt>file_field</tt>
39
39
  # * <tt>form_for</tt>
40
+ # * <tt>hidden_field</tt>
40
41
  # * <tt>label</tt>
41
- # * <tt>text_area</tt>
42
- # * <tt>text_field</tt>
42
+ # * <tt>number_field</tt>
43
43
  # * <tt>password_field</tt>
44
44
  # * <tt>radio_button</tt>
45
45
  # * <tt>select</tt>
46
46
  # * <tt>submit</tt>
47
+ # * <tt>text_area</tt>
48
+ # * <tt>text_field</tt>
47
49
  #
48
50
  # @since 0.2.0
49
51
  #
@@ -395,13 +397,13 @@ module Hanami
395
397
  # # </form>
396
398
  def form_for(name, url, options = {}, &blk)
397
399
  form = if name.is_a?(Form)
398
- options = url
399
- name
400
- else
401
- Form.new(name, url, options.delete(:values))
402
- end
400
+ options = url
401
+ name
402
+ else
403
+ Form.new(name, url, options.delete(:values))
404
+ end
403
405
 
404
- attributes = { action: form.url, method: form.verb, :'accept-charset' => DEFAULT_CHARSET, id: "#{ form.name }-form" }.merge(options)
406
+ attributes = { action: form.url, method: form.verb, :'accept-charset' => DEFAULT_CHARSET, id: "#{form.name}-form" }.merge(options)
405
407
  FormBuilder.new(form, attributes, self, &blk)
406
408
  end
407
409
 
@@ -11,18 +11,18 @@ module Hanami
11
11
  # @since 0.2.0
12
12
  #
13
13
  # @see Hanami::Helpers::HtmlHelper::HtmlBuilder
14
- class FormBuilder < ::Hanami::Helpers::HtmlHelper::HtmlBuilder
14
+ class FormBuilder < ::Hanami::Helpers::HtmlHelper::HtmlBuilder # rubocop:disable Metrics/ClassLength
15
15
  # Set of HTTP methods that are understood by web browsers
16
16
  #
17
17
  # @since 0.2.0
18
18
  # @api private
19
- BROWSER_METHODS = ['GET', 'POST'].freeze
19
+ BROWSER_METHODS = %w(GET POST).freeze
20
20
 
21
21
  # Set of HTTP methods that should NOT generate CSRF token
22
22
  #
23
23
  # @since 0.2.0
24
24
  # @api private
25
- EXCLUDED_CSRF_METHODS = ['GET'].freeze
25
+ EXCLUDED_CSRF_METHODS = %w(GET).freeze
26
26
 
27
27
  # Checked attribute value
28
28
  #
@@ -104,11 +104,13 @@ module Hanami
104
104
  #
105
105
  # @since 0.2.0
106
106
  # @api private
107
- def initialize(form, attributes, context = nil, &blk)
107
+ def initialize(form, attributes, context = nil, &blk) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
108
108
  super()
109
109
 
110
- @context = context
111
- @blk = blk
110
+ @context = context
111
+ @blk = blk
112
+ @verb = nil
113
+ @csrf_token = nil
112
114
 
113
115
  # Nested form
114
116
  if @context.nil? && attributes.is_a?(Values)
@@ -361,7 +363,7 @@ module Hanami
361
363
  # # <input type="checkbox" name="book[languages][]" value="italian" checked="checked">
362
364
  # # <input type="checkbox" name="book[languages][]" value="english">
363
365
  def check_box(name, attributes = {})
364
- _hidden_field_for_check_box( name, attributes)
366
+ _hidden_field_for_check_box(name, attributes)
365
367
  input _attributes_for_check_box(name, attributes)
366
368
  end
367
369
 
@@ -486,6 +488,7 @@ module Hanami
486
488
  # @param name [Symbol] the input name
487
489
  # @param attributes [Hash] HTML attributes to pass to the input tag
488
490
  # @option attributes [String,Array] :accept Optional set of accepted MIME Types
491
+ # @option attributes [TrueClass,FalseClass] :multiple Optional, allow multiple file upload
489
492
  #
490
493
  # @since 0.2.0
491
494
  #
@@ -515,6 +518,15 @@ module Hanami
515
518
  #
516
519
  # # Output:
517
520
  # # <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
521
+ #
522
+ # @example Accepted multiple file upload (as array)
523
+ # <%=
524
+ # # ...
525
+ # file_field :resume, multiple: true
526
+ # %>
527
+ #
528
+ # # Output:
529
+ # # <input type="file" name="user[resume]" id="user-resume" multiple="multiple">
518
530
  def file_field(name, attributes = {})
519
531
  attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept)
520
532
  attributes = { type: :file, name: _input_name(name), id: _input_id(name) }.merge(attributes)
@@ -609,7 +621,7 @@ module Hanami
609
621
  content = nil
610
622
  end
611
623
 
612
- attributes = {name: _input_name(name), id: _input_id(name)}.merge(attributes)
624
+ attributes = { name: _input_name(name), id: _input_id(name) }.merge(attributes)
613
625
  textarea(content || _value(name), attributes)
614
626
  end
615
627
 
@@ -631,7 +643,7 @@ module Hanami
631
643
  def text_field(name, attributes = {})
632
644
  input _attributes(:text, name, attributes)
633
645
  end
634
- alias_method :input_text, :text_field
646
+ alias input_text text_field
635
647
 
636
648
  # Radio input
637
649
  #
@@ -701,7 +713,7 @@ module Hanami
701
713
  #
702
714
  # @param name [Symbol] the input name
703
715
  # @param values [Hash] a Hash to generate <tt><option></tt> tags.
704
- # Keys correspond to <tt>value</tt> and values correspond to the content.
716
+ # Values correspond to <tt>value</tt> and keys correspond to the content.
705
717
  # @param attributes [Hash] HTML attributes to pass to the input tag
706
718
  #
707
719
  # If request params have a value that corresponds to one of the given values,
@@ -713,7 +725,7 @@ module Hanami
713
725
  # @example Basic usage
714
726
  # <%=
715
727
  # # ...
716
- # values = Hash['it' => 'Italy', 'us' => 'United States']
728
+ # values = Hash['Italy' => 'it', 'United States' => 'us']
717
729
  # select :stores, values
718
730
  # %>
719
731
  #
@@ -741,21 +753,132 @@ module Hanami
741
753
  # # <option value="it" selected="selected">Italy</option>
742
754
  # # <option value="us">United States</option>
743
755
  # # </select>
744
- def select(name, values, attributes = {})
745
- options = attributes.delete(:options) || {}
756
+ #
757
+ # @example Prompt option
758
+ # <%=
759
+ # # ...
760
+ # values = Hash['it' => 'Italy', 'us' => 'United States']
761
+ # select :stores, values, options: {prompt: 'Select a store'}
762
+ # %>
763
+ #
764
+ # # Output:
765
+ # # <select name="book[store]" id="book-store">
766
+ # # <option>Select a store</option>
767
+ # # <option value="it">Italy</option>
768
+ # # <option value="us">United States</option>
769
+ # # </select>
770
+ #
771
+ # @example Selected option
772
+ # <%=
773
+ # # ...
774
+ # values = Hash['it' => 'Italy', 'us' => 'United States']
775
+ # select :stores, values, options: {selected: book.store}
776
+ # %>
777
+ #
778
+ # # Output:
779
+ # # <select name="book[store]" id="book-store">
780
+ # # <option value="it" selected="selected">Italy</option>
781
+ # # <option value="us">United States</option>
782
+ # # </select>
783
+ def select(name, values, attributes = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
784
+ options = attributes.delete(:options) { {} }
746
785
  attributes = { name: _input_name(name), id: _input_id(name) }.merge(attributes)
786
+ prompt = options.delete(:prompt)
787
+ selected = options.delete(:selected)
747
788
 
748
789
  super(attributes) do
749
- values.each do |value, content|
750
- if _value(name) == value
751
- option(content, {value: value, selected: SELECTED}.merge(options))
790
+ option(prompt) unless prompt.nil?
791
+
792
+ values.each do |content, value|
793
+ if selected == value || _value(name) == value
794
+ option(content, { value: value, selected: SELECTED }.merge(options))
752
795
  else
753
- option(content, {value: value}.merge(options))
796
+ option(content, { value: value }.merge(options))
754
797
  end
755
798
  end
756
799
  end
757
800
  end
758
801
 
802
+ # Datalist input
803
+ #
804
+ # @param name [Symbol] the input name
805
+ # @param values [Array,Hash] a collection that is transformed into <tt><option></tt> tags.
806
+ # @param list [String] the name of list for the text input, it's also the id of datalist
807
+ # @param attributes [Hash] HTML attributes to pass to the input tag
808
+ #
809
+ # @since 0.4.0
810
+ #
811
+ # @example Basic Usage
812
+ # <%=
813
+ # # ...
814
+ # values = ['Italy', 'United States']
815
+ # datalist :stores, values, 'books'
816
+ # %>
817
+ #
818
+ # # Output:
819
+ # # <input type="text" name="book[store]" id="book-store" value="" list="books">
820
+ # # <datalist id="books">
821
+ # # <option value="Italy"></option>
822
+ # # <option value="United States"></option>
823
+ # # </datalist>
824
+ #
825
+ # @example Options As Hash
826
+ # <%=
827
+ # # ...
828
+ # values = Hash['Italy' => 'it', 'United States' => 'us']
829
+ # datalist :stores, values, 'books'
830
+ # %>
831
+ #
832
+ # # Output:
833
+ # # <input type="text" name="book[store]" id="book-store" value="" list="books">
834
+ # # <datalist id="books">
835
+ # # <option value="Italy">it</option>
836
+ # # <option value="United States">us</option>
837
+ # # </datalist>
838
+ #
839
+ # @example Specify Custom Attributes For Datalist Input
840
+ # <%=
841
+ # # ...
842
+ # values = ['Italy', 'United States']
843
+ # datalist :stores, values, 'books', datalist: { class: 'form-control' }
844
+ # %>
845
+ #
846
+ # # Output:
847
+ # # <input type="text" name="book[store]" id="book-store" value="" list="books">
848
+ # # <datalist id="books" class="form-control">
849
+ # # <option value="Italy"></option>
850
+ # # <option value="United States"></option>
851
+ # # </datalist>
852
+ #
853
+ # @example Specify Custom Attributes For Options List
854
+ # <%=
855
+ # # ...
856
+ # values = ['Italy', 'United States']
857
+ # datalist :stores, values, 'books', options: { class: 'form-control' }
858
+ # %>
859
+ #
860
+ # # Output:
861
+ # # <input type="text" name="book[store]" id="book-store" value="" list="books">
862
+ # # <datalist id="books">
863
+ # # <option value="Italy" class="form-control"></option>
864
+ # # <option value="United States" class="form-control"></option>
865
+ # # </datalist>
866
+ def datalist(name, values, list, attributes = {}) # rubocop:disable Metrics/MethodLength
867
+ attrs = attributes.dup
868
+ options = attrs.delete(:options) || {}
869
+ datalist = attrs.delete(:datalist) || {}
870
+
871
+ attrs[:list] = list
872
+ datalist[:id] = list
873
+
874
+ text_field(name, attrs)
875
+ super(datalist) do
876
+ values.each do |value, content|
877
+ option(content, { value: value }.merge(options))
878
+ end
879
+ end
880
+ end
881
+
759
882
  # Submit button
760
883
  #
761
884
  # @param content [String] The content
@@ -777,6 +900,7 @@ module Hanami
777
900
  end
778
901
 
779
902
  protected
903
+
780
904
  # A set of options to pass to the sub form helpers.
781
905
  #
782
906
  # @api private
@@ -786,6 +910,7 @@ module Hanami
786
910
  end
787
911
 
788
912
  private
913
+
789
914
  # Check the current builder is top-level
790
915
  #
791
916
  # @api private
@@ -835,7 +960,7 @@ module Hanami
835
960
  # @api private
836
961
  # @since 0.2.0
837
962
  def _input_name(name)
838
- "#{ @name }[#{ name }]"
963
+ "#{@name}[#{name}]"
839
964
  end
840
965
 
841
966
  # Input <tt>id</tt> HTML attribute
@@ -877,11 +1002,11 @@ module Hanami
877
1002
  # @see Hanami::Helpers::FormHelper::FormBuilder#check_box
878
1003
  def _hidden_field_for_check_box(name, attributes)
879
1004
  if attributes[:value].nil? || !attributes[:unchecked_value].nil?
880
- input({
1005
+ input(
881
1006
  type: :hidden,
882
1007
  name: attributes[:name] || _input_name(name),
883
1008
  value: attributes.delete(:unchecked_value) || DEFAULT_UNCHECKED_VALUE
884
- })
1009
+ )
885
1010
  end
886
1011
  end
887
1012
 
@@ -900,8 +1025,8 @@ module Hanami
900
1025
  }.merge(attributes)
901
1026
 
902
1027
  value = _value(name)
903
- attributes[:checked] = CHECKED if value &&
904
- ( value == attributes[:value] || value.include?(attributes[:value]) )
1028
+ attributes[:checked] = CHECKED if !value.nil? &&
1029
+ (value == attributes[:value] || value.include?(attributes[:value]))
905
1030
 
906
1031
  attributes
907
1032
  end
@@ -34,6 +34,7 @@ module Hanami
34
34
  end
35
35
 
36
36
  private
37
+
37
38
  # Resolve the (nested) content
38
39
  #
39
40
  # @return [String] the content
@@ -68,9 +69,9 @@ module Hanami
68
69
  def _csrf_protection!
69
70
  return if @csrf_token.nil?
70
71
 
71
- _csrf_token = @csrf_token
72
+ csrf_token = @csrf_token
72
73
  @builder.resolve do
73
- input(type: :hidden, name: FormHelper::CSRF_TOKEN, value: _csrf_token)
74
+ input(type: :hidden, name: FormHelper::CSRF_TOKEN, value: csrf_token)
74
75
  end
75
76
  end
76
77
  end
@@ -3,19 +3,37 @@ require 'hanami/utils/hash'
3
3
  module Hanami
4
4
  module Helpers
5
5
  module FormHelper
6
+ # Values from params and form helpers.
7
+ #
8
+ # It's responsible to populate input values with data coming from params
9
+ # and inline values specified via form helpers like `text_field`.
10
+ #
11
+ # @since 0.2.0
12
+ # @api private
6
13
  class Values
14
+ # @since 0.2.0
15
+ # @api private
7
16
  GET_SEPARATOR = '.'.freeze
8
17
 
18
+ # @since 0.2.0
19
+ # @api private
9
20
  def initialize(values, params)
10
21
  @values = Utils::Hash.new(values).stringify!
11
22
  @params = params
12
23
  end
13
24
 
25
+ # Returns the value for the given key, if present
26
+ #
27
+ # @since 0.2.0
28
+ # @api private
14
29
  def get(key)
15
30
  @params.get(key) || _get_from_values(key)
16
31
  end
17
32
 
18
33
  private
34
+
35
+ # @since 0.2.0
36
+ # @api private
19
37
  def _get_from_values(key)
20
38
  initial_key, *keys = key.to_s.split(GET_SEPARATOR)
21
39
  result = @values[initial_key]
@@ -23,11 +41,9 @@ module Hanami
23
41
  Array(keys).each do |k|
24
42
  break if result.nil?
25
43
 
26
- result = if result.respond_to?(k)
27
- result.public_send(k)
28
- else
29
- nil
30
- end
44
+ result = if result.respond_to?(k) # rubocop:disable Style/IfUnlessModifier
45
+ result.public_send(k)
46
+ end
31
47
  end
32
48
 
33
49
  result
@@ -185,6 +185,7 @@ module Hanami
185
185
  # # </div>
186
186
  module HtmlHelper
187
187
  private
188
+
188
189
  # Instantiate an HTML builder
189
190
  #
190
191
  # @param blk [Proc,Hanami::Helpers::HtmlHelper::HtmlBuilder,NilClass] the optional content block
@@ -12,15 +12,54 @@ module Hanami
12
12
  # @api private
13
13
  #
14
14
  # @see http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attribute
15
- BOOLEAN_ATTRIBUTES = %w{allowfullscreen async autobuffer autofocus
16
- autoplay checked compact controls declare default defaultchecked
17
- defaultmuted defaultselected defer disabled draggable enabled
18
- formnovalidate hidden indeterminate inert ismap itemscope loop
19
- multiple muted nohref noresize noshade novalidate nowrap open
20
- pauseonexit pubdate readonly required reversed scoped seamless
21
- selected sortable spellcheck translate truespeed typemustmatch
15
+ BOOLEAN_ATTRIBUTES = %w(
16
+ allowfullscreen
17
+ async
18
+ autobuffer
19
+ autofocus
20
+ autoplay
21
+ checked
22
+ compact
23
+ controls
24
+ declare
25
+ default
26
+ defaultchecked
27
+ defaultmuted
28
+ defaultselected
29
+ defer
30
+ disabled
31
+ draggable
32
+ enabled
33
+ formnovalidate
34
+ hidden
35
+ indeterminate
36
+ inert
37
+ ismap
38
+ itemscope
39
+ loop
40
+ multiple
41
+ muted
42
+ nohref
43
+ noresize
44
+ noshade
45
+ novalidate
46
+ nowrap
47
+ open
48
+ pauseonexit
49
+ pubdate
50
+ readonly
51
+ required
52
+ reversed
53
+ scoped
54
+ seamless
55
+ selected
56
+ sortable
57
+ spellcheck
58
+ translate
59
+ truespeed
60
+ typemustmatch
22
61
  visible
23
- }.freeze
62
+ ).freeze
24
63
 
25
64
  # Attributes separator
26
65
  #
@@ -49,10 +88,11 @@ module Hanami
49
88
  # @since 0.1.0
50
89
  # @api private
51
90
  def to_s
52
- %(<#{ @name }#{attributes}>)
91
+ %(<#{@name}#{attributes}>)
53
92
  end
54
93
 
55
94
  private
95
+
56
96
  # Resolve the attributes
57
97
  #
58
98
  # @return [String,NilClass] the tag attributes
@@ -60,7 +100,7 @@ module Hanami
60
100
  # @since 0.1.0
61
101
  # @api private
62
102
  def attributes
63
- return if @attributes.nil?
103
+ return unless defined?(@attributes) && !@attributes.nil?
64
104
  result = ''
65
105
 
66
106
  @attributes.each do |attribute_name, value|
@@ -79,12 +119,12 @@ module Hanami
79
119
  end
80
120
 
81
121
  # Do not render boolean attributes when their value is _false_.
82
- def boolean_attribute(attribute_name, value)
83
- %(#{ATTRIBUTES_SEPARATOR}#{ attribute_name }="#{ attribute_name }")
122
+ def boolean_attribute(attribute_name, _value)
123
+ %(#{ATTRIBUTES_SEPARATOR}#{attribute_name}="#{attribute_name}")
84
124
  end
85
125
 
86
126
  def attribute(attribute_name, value)
87
- %(#{ATTRIBUTES_SEPARATOR}#{ attribute_name }="#{ value }")
127
+ %(#{ATTRIBUTES_SEPARATOR}#{attribute_name}="#{value}")
88
128
  end
89
129
  end
90
130
  end
@@ -12,7 +12,7 @@ module Hanami
12
12
  # HTML Builder
13
13
  #
14
14
  # @since 0.1.0
15
- class HtmlBuilder
15
+ class HtmlBuilder # rubocop:disable Metrics/ClassLength
16
16
  # HTML5 content tags
17
17
  #
18
18
  # @since 0.1.0
@@ -20,103 +20,103 @@ module Hanami
20
20
  #
21
21
  # @see Hanami::Helpers::HtmlHelper::HtmlNode
22
22
  # @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element
23
- CONTENT_TAGS = [
24
- 'a',
25
- 'abbr',
26
- 'address',
27
- 'article',
28
- 'aside',
29
- 'audio',
30
- 'b',
31
- 'bdi',
32
- 'bdo',
33
- 'blockquote',
34
- 'body',
35
- 'button',
36
- 'canvas',
37
- 'caption',
38
- 'cite',
39
- 'code',
40
- 'colgroup',
41
- 'data',
42
- 'datalist',
43
- 'del',
44
- 'details',
45
- 'dfn',
46
- 'div',
47
- 'dl',
48
- 'dt',
49
- 'dd',
50
- 'em',
51
- 'fieldset',
52
- 'figcaption',
53
- 'figure',
54
- 'footer',
55
- 'form',
56
- 'h1',
57
- 'h2',
58
- 'h3',
59
- 'h4',
60
- 'h5',
61
- 'h6',
62
- 'head',
63
- 'header',
64
- 'i',
65
- 'iframe',
66
- 'ins',
67
- 'kbd',
68
- 'label',
69
- 'legend',
70
- 'li',
71
- 'link',
72
- 'main',
73
- 'map',
74
- 'mark',
75
- 'math',
76
- 'menu',
77
- 'meter',
78
- 'nav',
79
- 'noscript',
80
- 'object',
81
- 'ol',
82
- 'optgroup',
83
- 'option',
84
- 'output',
85
- 'p',
86
- 'pre',
87
- 'progress',
88
- 'q',
89
- 'rp',
90
- 'rt',
91
- 'ruby',
92
- 's',
93
- 'samp',
94
- 'script',
95
- 'section',
96
- 'select',
97
- 'small',
98
- 'span',
99
- 'strong',
100
- 'style',
101
- 'sub',
102
- 'summary',
103
- 'sup',
104
- 'svg',
105
- 'table',
106
- 'tbody',
107
- 'td',
108
- 'template',
109
- 'textarea',
110
- 'tfoot',
111
- 'th',
112
- 'thead',
113
- 'time',
114
- 'title',
115
- 'tr',
116
- 'u',
117
- 'ul',
118
- 'video',
119
- ].freeze
23
+ CONTENT_TAGS = %w(
24
+ a
25
+ abbr
26
+ address
27
+ article
28
+ aside
29
+ audio
30
+ b
31
+ bdi
32
+ bdo
33
+ blockquote
34
+ body
35
+ button
36
+ canvas
37
+ caption
38
+ cite
39
+ code
40
+ colgroup
41
+ data
42
+ datalist
43
+ del
44
+ details
45
+ dfn
46
+ div
47
+ dl
48
+ dt
49
+ dd
50
+ em
51
+ fieldset
52
+ figcaption
53
+ figure
54
+ footer
55
+ form
56
+ h1
57
+ h2
58
+ h3
59
+ h4
60
+ h5
61
+ h6
62
+ head
63
+ header
64
+ i
65
+ iframe
66
+ ins
67
+ kbd
68
+ label
69
+ legend
70
+ li
71
+ link
72
+ main
73
+ map
74
+ mark
75
+ math
76
+ menu
77
+ meter
78
+ nav
79
+ noscript
80
+ object
81
+ ol
82
+ optgroup
83
+ option
84
+ output
85
+ p
86
+ pre
87
+ progress
88
+ q
89
+ rp
90
+ rt
91
+ ruby
92
+ s
93
+ samp
94
+ script
95
+ section
96
+ select
97
+ small
98
+ span
99
+ strong
100
+ style
101
+ sub
102
+ summary
103
+ sup
104
+ svg
105
+ table
106
+ tbody
107
+ td
108
+ template
109
+ textarea
110
+ tfoot
111
+ th
112
+ thead
113
+ time
114
+ title
115
+ tr
116
+ u
117
+ ul
118
+ video
119
+ ).freeze
120
120
 
121
121
  # HTML5 empty tags
122
122
  #
@@ -125,24 +125,24 @@ module Hanami
125
125
  #
126
126
  # @see Hanami::Helpers::HtmlHelper::EmptyHtmlNode
127
127
  # @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element
128
- EMPTY_TAGS = [
129
- 'area',
130
- 'base',
131
- 'br',
132
- 'col',
133
- 'embed',
134
- 'hr',
135
- 'img',
136
- 'input',
137
- 'keygen',
138
- 'link',
139
- 'menuitem',
140
- 'meta',
141
- 'param',
142
- 'source',
143
- 'track',
144
- 'wbr',
145
- ].freeze
128
+ EMPTY_TAGS = %w(
129
+ area
130
+ base
131
+ br
132
+ col
133
+ embed
134
+ hr
135
+ img
136
+ input
137
+ keygen
138
+ link
139
+ menuitem
140
+ meta
141
+ param
142
+ source
143
+ track
144
+ wbr
145
+ ).freeze
146
146
 
147
147
  # New line separator
148
148
  #
@@ -152,8 +152,8 @@ module Hanami
152
152
 
153
153
  CONTENT_TAGS.each do |tag|
154
154
  class_eval %{
155
- def #{ tag }(content = nil, attributes = nil, &blk)
156
- @nodes << self.class.html_node.new(:#{ tag }, blk || content, attributes || content, options)
155
+ def #{tag}(content = nil, attributes = nil, &blk)
156
+ @nodes << self.class.html_node.new(:#{tag}, blk || content, attributes || content, options)
157
157
  self
158
158
  end
159
159
  }
@@ -161,8 +161,8 @@ module Hanami
161
161
 
162
162
  EMPTY_TAGS.each do |tag|
163
163
  class_eval %{
164
- def #{ tag }(attributes = nil)
165
- @nodes << EmptyHtmlNode.new(:#{ tag }, attributes)
164
+ def #{tag}(attributes = nil)
165
+ @nodes << EmptyHtmlNode.new(:#{tag}, attributes)
166
166
  self
167
167
  end
168
168
  }
@@ -310,7 +310,7 @@ module Hanami
310
310
 
311
311
  # @since 0.2.5
312
312
  # @api private
313
- alias_method :+, :text
313
+ alias + text
314
314
 
315
315
  # Resolves all the nodes and generates the markup
316
316
  #
@@ -1,3 +1,5 @@
1
+ require 'hanami/utils/escape'
2
+
1
3
  module Hanami
2
4
  module Helpers
3
5
  module HtmlHelper
@@ -36,7 +38,7 @@ module Hanami
36
38
  if @builder.nested?
37
39
  @builder.to_s
38
40
  else
39
- "#{ Utils::Escape.html(result) }"
41
+ Utils::Escape.html(result)
40
42
  end
41
43
  end
42
44
  end
@@ -1,4 +1,5 @@
1
1
  require 'hanami/helpers/html_helper/empty_html_node'
2
+ require 'hanami/utils/escape'
2
3
 
3
4
  module Hanami
4
5
  module Helpers
@@ -15,10 +16,10 @@ module Hanami
15
16
  # @param name [Symbol,String] the name of the tag
16
17
  # @param content [String,Proc,Hanami::Helpers::HtmlHelper::HtmlBuilder,NilClass] the optional content
17
18
  # @param attributes [Hash,NilClass] the optional tag attributes
18
- # @param options [Hash] a optional set of data
19
+ # @param _options [Hash] a optional set of data
19
20
  #
20
21
  # @return [Hanami::Helpers::HtmlHelper::HtmlNode]
21
- def initialize(name, content, attributes, options = {})
22
+ def initialize(name, content, attributes, _options = {})
22
23
  @builder = HtmlBuilder.new
23
24
  @name = name
24
25
  @content = case content
@@ -40,25 +41,26 @@ module Hanami
40
41
  #
41
42
  # @see Hanami::Helpers::HtmlHelper::EmptyHtmlNode#to_s
42
43
  def to_s
43
- %(#{ super }#{ content }</#{ @name }>)
44
+ %(#{super}#{content}</#{@name}>)
44
45
  end
45
46
 
46
47
  private
48
+
47
49
  # Resolve the (nested) content
48
50
  #
49
51
  # @return [String] the content
50
52
  #
51
53
  # @since 0.1.0
52
54
  # @api private
53
- def content
55
+ def content # rubocop:disable Metrics/MethodLength
54
56
  case @content
55
57
  when Proc
56
58
  result = @builder.resolve(&@content)
57
59
 
58
60
  if @builder.nested?
59
- "\n#{ @builder }\n"
61
+ "\n#{@builder}\n"
60
62
  else
61
- "\n#{ Utils::Escape.html(result) }\n"
63
+ "\n#{Utils::Escape.html(result)}\n"
62
64
  end
63
65
  else
64
66
  Utils::Escape.html(@content)
@@ -1,3 +1,5 @@
1
+ require 'hanami/utils/escape'
2
+
1
3
  module Hanami
2
4
  module Helpers
3
5
  module HtmlHelper
@@ -115,7 +115,7 @@ module Hanami
115
115
  # @example With only content
116
116
  # <%= link_to 'Home' %>
117
117
  # # => ArgumentError
118
- def link_to(content, url = nil, options = {}, &blk)
118
+ def link_to(content, url = nil, options = {}, &blk) # rubocop:disable Metrics/MethodLength
119
119
  if block_given?
120
120
  options = url || {}
121
121
  url = content
@@ -128,7 +128,7 @@ module Hanami
128
128
  raise ArgumentError
129
129
  end
130
130
 
131
- html.a(blk || content, options).to_s
131
+ html.a(blk || content, options)
132
132
  end
133
133
  end
134
134
  end
@@ -1,3 +1,5 @@
1
+ require 'hanami/utils/kernel'
2
+
1
3
  module Hanami
2
4
  module Helpers
3
5
  # Number formatter
@@ -11,6 +13,7 @@ module Hanami
11
13
  # @since 0.2.0
12
14
  module NumberFormattingHelper
13
15
  private
16
+
14
17
  # Format the given number, according to the options
15
18
  #
16
19
  # It accepts a number (<tt>Numeric</tt>) or a string representation.
@@ -1,3 +1,5 @@
1
+ require 'hanami/utils/string'
2
+
1
3
  module Hanami
2
4
  module Helpers
3
5
  # Routing helper for full stack Hanami web applications.
@@ -39,11 +41,11 @@ module Hanami
39
41
  # # <%= link_to_home %>
40
42
  module RoutingHelper
41
43
  def self.included(base)
42
- factory = "#{ Utils::String.new(base).namespace }::Routes"
44
+ factory = "#{Utils::String.new(base).namespace}::Routes"
43
45
 
44
46
  base.class_eval <<-END_EVAL, __FILE__, __LINE__
45
47
  def routes
46
- #{ factory }
48
+ #{factory}
47
49
  end
48
50
  END_EVAL
49
51
  end
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Define version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.3.0'.freeze
6
+ VERSION = '0.4.0'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-01-22 00:00:00.000000000 Z
13
+ date: 2016-07-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hanami-utils
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '0.7'
21
+ version: '0.8'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '0.7'
28
+ version: '0.8'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: bundler
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -46,14 +46,14 @@ dependencies:
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '10.0'
49
+ version: '11'
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: '10.0'
56
+ version: '11'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: minitest
59
59
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 2.0.0
113
+ version: 2.2.0
114
114
  required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - ">="
@@ -118,9 +118,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  version: '0'
119
119
  requirements: []
120
120
  rubyforge_project:
121
- rubygems_version: 2.5.1
121
+ rubygems_version: 2.6.4
122
122
  signing_key:
123
123
  specification_version: 4
124
124
  summary: Hanami helpers
125
125
  test_files: []
126
- has_rdoc: