Class: Brut::FrontEnd::Components::TimeTag

Inherits:
Brut::FrontEnd::Component show all
Includes:
I18n::ForHTML
Defined in:
lib/brut/front_end/components/time_tag.rb

Overview

Renders a date or timestamp accessibly, using the <time> element. This will account for the current request's time zone. See Clock.

Instance Method Summary collapse

Methods included from I18n::ForHTML

#html_escape, #t

Methods included from I18n::BaseMethods

#l, #t, #t_direct, #this_field_value

Methods inherited from Brut::FrontEnd::Component

component_name, #component_name

Methods included from Brut::FrontEnd::Component::Helpers

#global_component, #inline_svg

Methods included from Brut::Framework::Errors

#abstract_method!, #bug!

Constructor Details

#initialize(timestamp: nil, date: nil, format: :full, skip_year_if_same: true, skip_dow_if_not_this_week: true, attribute_format: :iso_8601, clock: :from_request_context, **only_contains_class) { ... } ⇒ TimeTag

Creates the component will still render the datetime attribute, but not the inside. This is useful if you have a customized date or time display that you would like to be accessible. If omitted, the tag's contents will be the formated date or timestamp.

Parameters:

  • timestamp (Time) (defaults to: nil)

    the timestamp you wish to render. Mutually exclusive with date.

  • date (Date) (defaults to: nil)

    the date you wish to render. Mutually exclusive with timestamp.

  • format (Symbol) (defaults to: :full)

    the I18n format key fragment to use to locate the strftime format for formatting the timestamp. This is appended to "time.formats." to form the full string. If skip_year_if_same is true and the year of this timestamp is this year, "_no_year" is further appended. For example, if this value is :full and skip_year_if_same is false, the I18n key used will be "time.formats.full". If skip_year_if_same is true, the key would be "time.formats.full_no_year" only if this year is the year of the timestamp. Otherwise "time.formats.full" would be used.

  • skip_year_if_same (true|false) (defaults to: true)

    if true, and this year is the same year as the timestamp, "_no_year" is appened to the value of format to form the I18n key to use. This is applied before skip_dow_if_not_this_week's suffix is.

  • skip_dow_if_not_this_week (true|false) (defaults to: true)

    if true, and the date/timestamp is within 7 days of now, appends "no_dow" to the format string. If this matches a configured format, it's assumed that would be just like format but without the day of the week. This is applied after skip_year_if_same's suffix is.

  • attribute_format (Symbol) (defaults to: :iso_8601)

    the I18n format key fragment to use to locate the strftime format for formatting the datetime attribute of the HTML element that this component renders. Generally, you want to leave this as the default of :iso_8601, however if you need to change it, you can. This value is appeneded to "time.formats." to form the complete key. skip_year_if_same is not used for this value.

  • only_contains_class (Hash)

    exists because class is a reserved word

Options Hash (**only_contains_class):

  • :class (String)

    the value to use for the class attribute.

Yields:

  • No parameters given. This is expected to return markup to appear inside the <form> element. If provided, this component



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/brut/front_end/components/time_tag.rb', line 17

def initialize(
  timestamp: nil,
  date: nil,
  format: :full,
  skip_year_if_same: true,
  skip_dow_if_not_this_week: true,
  attribute_format: :iso_8601,
  clock: :from_request_context,
  **only_contains_class
)
  require_exactly_one!(timestamp:,date:)

  @date_only = timestamp.nil?
  @timestamp = timestamp || date
  @clock     = if clock == :from_request_context
                 Brut::FrontEnd::RequestContext.current[:clock]
               else
                 clock
               end

  formats = [ format ]
  use_no_year = skip_year_if_same && @timestamp.year == Time.now.year
  use_no_dow  = if skip_dow_if_not_this_week
                  $seven_days_ago = (Date.today - 7).to_time
                  $timestamp      = @timestamp.to_time
                  $timestamp < $seven_days_ago
                else
                  false
                end
  if use_no_year
    formats.unshift("#{format}_no_year")
  end

  if use_no_dow
    if use_no_year
      formats.unshift("#{format}_no_year_no_dow")
    else
      formats.unshift("#{format}_no_dow")
    end
  end

  assumed_key_base = if @date_only
                       "date.formats"
                     else
                       "time.formats"
                     end

  format_keys = formats.map { |f| "#{assumed_key_base}.#{f}" }

  found_format,_value = formats.zip( ::I18n.t(format_keys) ).detect { |(_key,value)|
    value !~ /^Translation missing/
  }

  if found_format.nil?
    raise ArgumentError,"format #{format} is not a known time format (checked #{format_keys})"
  end

  @format           = found_format.to_sym
  @attribute_format = attribute_format.to_sym
  @class_attribute  = only_contains_class[:class] || ""
end

Instance Method Details

#view_templateObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/brut/front_end/components/time_tag.rb', line 79

def view_template
  adjusted_value = if @date_only
                     @timestamp
                   else
                     @clock.in_time_zone(@timestamp)
                   end

  datetime_attribute = ::I18n.l(adjusted_value,format: @attribute_format)

  time(class: @class_attribute, datetime: datetime_attribute) do
    if block_given?
      yield
    else
      ::I18n.l(adjusted_value,format: @format)
    end
  end
end