bullet_train-themes 1.0.17 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ca353e53e2aac869ee3d8eb03a91600543f3e34f837640fdef3e4addc9bd905
4
- data.tar.gz: 8585a3b07952827006f23534baa00e742a9dc41bc4b9bfd825e65e8546da212f
3
+ metadata.gz: 685b92afad2e422cdc06cca2443590eaa4d845b865199afca11889494680230f
4
+ data.tar.gz: 10a9416768d934e69ed1105dcf1d5ce3170a1e60d71612a5901766510f92976d
5
5
  SHA512:
6
- metadata.gz: c71b2e02e85a63498db7edde0aeb78075d6f01c5735286e08984336fa4c097c26c25616b1cbeae73c36ea6cce992ff1403e13d866591df6fffc9a4e892417ebf
7
- data.tar.gz: b03ae206f6f8fcaa2a20d7ea166f15667c2d40fd6c3157f3a6e3befb32f08a47d5309f3f41f907d6c88996490699762cc8ebe1bed8ac7830e99e0ab497f5edcc
6
+ metadata.gz: 5500669ce576dcd48a105791dd4a98719cc311a80b2586f46e959f44533bf63abf76cee9fb4b53ee6f1f6f190e26a3441d0464a95550ce6ccefe68df43d39108
7
+ data.tar.gz: 8fde38b8386af1698559268a4766361d834bc781013b2653bdc29cd14da0f1f0d3154480e2cef64425ae69e9a6d64b90f4f108b78005b63639960712c334a89a
@@ -1,81 +1,57 @@
1
- module ThemeHelper
2
- # TODO Do we want this to be configurable by downstream applications?
3
- INVOCATION_PATTERNS = [
4
- # This path is included for legacy purposes, but you shouldn't reference partials like this in new code.
5
- /^account\/shared\//,
6
-
7
- # ✅ This is the correct path to generically reference theme component partials with.
8
- /^shared\//,
9
- ]
10
-
11
- def current_theme_object
12
- @current_theme_object ||= "BulletTrain::Themes::#{current_theme.to_s.classify}::Theme".constantize.new
13
- end
1
+ # Our custom devise views are housed in `bullet_train-base`, but they're overwritten
2
+ # by devise's standard views if the devise gem is declared after `bullet_train`.
3
+ # To ensure we use our custom views, we temporarily unregister the original devise
4
+ # views path from the FileSystemResolver, add our custom path, and find the views that way.
5
+ module ActionView
6
+ class LookupContext
7
+ module ViewPaths
8
+ def find(name, prefixes = [], partial = false, keys = [], options = {})
9
+ name, prefixes = normalize_name(name, prefixes)
10
+ details, details_key = detail_args_for(options)
11
+
12
+ devise_view = false
13
+ prefixes.each do |prefix|
14
+ if prefix.match?(/devise/)
15
+ devise_view = true
16
+ break
17
+ end
18
+ end
14
19
 
15
- def render(options = {}, locals = {}, &block)
16
- # The theme engine only supports `<%= render 'shared/box' ... %>` style calls to `render`.
17
- if options.is_a?(String)
18
- # Initialize a global variable that will cache all resolutions of a given path for the entire life of the server.
19
- $resolved_theme_partial_paths ||= {}
20
+ resolver = if name == "devise" || devise_view
21
+ original_devise_view_path = BulletTrain::Themes::Light.original_devise_path
22
+ bullet_train_resolver = @view_paths.paths.reject do |resolver|
23
+ resolver.path.match?(original_devise_view_path)
24
+ end
25
+ PathSet.new(bullet_train_resolver)
26
+ else
27
+ @view_paths
28
+ end
20
29
 
21
- # Check whether we've already resolved this partial to render from another path before.
22
- # If we've already resolved this partial from a different path before, then let's just skip to that.
23
- # TODO This should be disabled in development so new templates are taken into account without restarting the server.
24
- if $resolved_theme_partial_paths[options]
25
- # Override the value in place. This will be respected when we call `super` below.
26
- options = $resolved_theme_partial_paths[options]
30
+ resolver.find(name, prefixes, partial, details, details_key, keys)
27
31
  end
32
+ alias_method :find_template, :find
28
33
  end
34
+ end
35
+ end
29
36
 
30
- begin
31
- # This is where we try to just lean on Rails default behavior. If someone renders `shared/box` and also has a
32
- # `app/views/shared/_box.html.erb`, then no error will be thrown and we will have never interfered in the normal
33
- # Rails behavior.
34
- #
35
- # We also don't do anything special if someone renders `shared/box` and we've already previously resolved that
36
- # partial to be served from `themes/light/box`. In that case, we've already replaced `shared/box` with the
37
- # actual path of the partial, and Rails will do the right thing from this point.
38
- #
39
- # However, if one of those two situations isn't true, then this call here will throw an exception and we can
40
- # perform the appropriate magic to figure out where amongst the themes the partial should be rendering from.
41
- super
42
- rescue ActionView::MissingTemplate => exception
43
- # The theme engine only supports `<%= render 'shared/box' ... %>` style calls to `render`.
44
- if options.is_a?(String)
45
-
46
- # Does the requested partial path match one of the invocation regexes?
47
- if (invocation_pattern = INVOCATION_PATTERNS.detect { |regex| options.match?(regex) })
48
- # Keep track of the original options.
49
- original_options = options
50
-
51
- # Trim out the base part of the requested partial.
52
- requested_partial = options.gsub(invocation_pattern, "")
53
-
54
- # TODO We're hard-coding this for now, but this should probably come from the `Current` model.
55
- current_theme_object.directory_order.each do |theme_path|
56
- # Update our options from something like `shared/box` to `themes/light/box`.
57
- options = "themes/#{theme_path}/#{requested_partial}"
58
-
59
- # Try rendering the partial again with the updated options.
60
- body = super
61
-
62
- # 🏆 If we get this far, then we've found the actual path of the theme partial. We should cache it!
63
- $resolved_theme_partial_paths[original_options] = options
64
-
65
- # We also need to return whatever the rendered body was.
66
- return body
67
-
68
- # If calling `render` with the updated options is still resulting in a missing template, we need to
69
- # keep iterating over `directory_order` to work our way up the theme stack and see if we can find the
70
- # partial there, e.g. going from `light` to `tailwind` to `base`.
71
- rescue ActionView::MissingTemplate => _
72
- next
73
- end
74
- end
75
- end
37
+ module ThemeHelper
38
+ def current_theme_object
39
+ BulletTrain::Themes.themes[current_theme]
40
+ end
76
41
 
77
- # If we weren't able to find the partial in some theme-based place, then just let the original error bubble up.
78
- raise exception
79
- end
42
+ def render(options = {}, locals = {}, &block)
43
+ options = current_theme_object.resolved_partial_path_for(@lookup_context, options, locals) || options
44
+
45
+ # This is where we try to just lean on Rails default behavior. If someone renders `shared/box` and also has a
46
+ # `app/views/shared/_box.html.erb`, then no error will be thrown and we will have never interfered in the normal
47
+ # Rails behavior.
48
+ #
49
+ # We also don't do anything special if someone renders `shared/box` and we've already previously resolved that
50
+ # partial to be served from `themes/light/box`. In that case, we've already replaced `shared/box` with the
51
+ # actual path of the partial, and Rails will do the right thing from this point.
52
+ #
53
+ # However, if one of those two situations isn't true, then this call here will throw an exception and we can
54
+ # perform the appropriate magic to figure out where amongst the themes the partial should be rendering from.
55
+ super
80
56
  end
81
57
  end
@@ -1,9 +1,10 @@
1
1
  <% object ||= current_attributes_object %>
2
2
  <% strategy ||= current_attributes_strategy || :none %>
3
3
  <% url ||= nil %>
4
+ <% options ||= {} %>
4
5
 
5
6
  <% if object.send(attribute).present? %>
6
7
  <%= render 'shared/attributes/attribute', object: object, attribute: attribute, strategy: strategy, url: url do %>
7
- <%= object.send(attribute) %>
8
+ <%= options[:password] ? "●" * object.send(attribute).length : object.send(attribute) %>
8
9
  <% end %>
9
10
  <% end %>
@@ -0,0 +1,30 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ stimulus_controller = 'fields--emoji-picker'
5
+
6
+ form ||= current_fields_form
7
+ options ||= {}
8
+ other_options ||= {}
9
+ value = form.object.send(method)
10
+ %>
11
+
12
+ <%= render 'shared/fields/field', form: form, method: method, options: options, other_options: other_options do %>
13
+ <% content_for :field do %>
14
+ <div data-controller="<%= stimulus_controller %>">
15
+ <%= tag.button data: {action: "#{stimulus_controller}#toggle", target: "#{stimulus_controller}.button"}, class: "button-alternative" do %>
16
+ <span data-target="<%= stimulus_controller %>.display">
17
+ <% if value.present? %>
18
+ <%= value %>
19
+ <% else %>
20
+ <i class="ti ti-face-smile"></i>
21
+ <% end %>
22
+ </span>
23
+ &nbsp;
24
+ Choose an Emoji
25
+ <% end %>
26
+ <%= form.hidden_field method, data: {"#{stimulus_controller}-target": "input"} %>
27
+ </div>
28
+
29
+ <% end %>
30
+ <% end %>
@@ -7,7 +7,7 @@ form ||= current_fields_form
7
7
  options ||= {}
8
8
  other_options ||= {}
9
9
  html_options ||= {}
10
- html_options[:id] ||= id_for(form, method)
10
+ html_options[:id] ||= form.field_id(method)
11
11
  html_options[:class] = "form-control select2 #{html_options[:class]}".strip
12
12
  choices_url ||= nil
13
13
  if choices_url.nil?
@@ -26,7 +26,8 @@ wrapper_options = { data: { controller: stimulus_controller }}
26
26
  wrapper_options[:data]["#{stimulus_controller}-enable-search-value"] = true if other_options[:search]
27
27
  wrapper_options[:data]["#{stimulus_controller}-accepts-new-value"] = true if other_options[:accepts_new]
28
28
  wrapper_options[:data]["#{stimulus_controller}-search-url-value"] = choices_url if choices_url.present?
29
- html_options[:data] = { "#{stimulus_controller}-target": 'select' }
29
+ html_options[:data] ||= {}
30
+ html_options[:data].merge!("#{stimulus_controller}-target": 'select')
30
31
 
31
32
  %>
32
33
 
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module Themes
3
- VERSION = "1.0.17"
3
+ VERSION = "1.0.22"
4
4
  end
5
5
  end
@@ -7,11 +7,41 @@ module BulletTrain
7
7
  mattr_accessor :themes, default: {}
8
8
  mattr_accessor :logo_height, default: 54
9
9
 
10
+ mattr_reader :partial_paths, default: {}
11
+
12
+ # TODO Do we want this to be configurable by downstream applications?
13
+ INVOCATION_PATTERNS = [
14
+ # ❌ This path is included for legacy purposes, but you shouldn't reference partials like this in new code.
15
+ /^account\/shared\//,
16
+
17
+ # ✅ This is the correct path to generically reference theme component partials with.
18
+ /^shared\//,
19
+ ]
20
+
21
+ def self.theme_invocation_path_for(path)
22
+ # Themes only support `<%= render 'shared/box' ... %>` style calls to `render`, so check `path` is a string first.
23
+ if path.is_a?(String) && (pattern = INVOCATION_PATTERNS.find { _1.match? path })
24
+ path.remove(pattern)
25
+ end
26
+ end
27
+
10
28
  module Base
11
29
  class Theme
12
30
  def directory_order
13
31
  ["base"]
14
32
  end
33
+
34
+ def resolved_partial_path_for(lookup_context, path, locals)
35
+ # TODO This caching should be disabled in development so new templates are taken into account without restarting the server.
36
+ BulletTrain::Themes.partial_paths.fetch(path) do
37
+ if (theme_path = BulletTrain::Themes.theme_invocation_path_for(path))
38
+ # TODO directory_order should probably come from the `Current` model.
39
+ if (partial = lookup_context.find_all(theme_path, directory_order.map { "themes/#{_1}" }, true, locals.keys).first)
40
+ BulletTrain::Themes.partial_paths[path] = partial.virtual_path.gsub("/_", "/")
41
+ end
42
+ end
43
+ end
44
+ end
15
45
  end
16
46
  end
17
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-themes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.17
4
+ version: 1.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-03 00:00:00.000000000 Z
11
+ date: 2022-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: standard
@@ -69,6 +69,7 @@ files:
69
69
  - app/views/themes/base/attributes/_text.html.erb
70
70
  - app/views/themes/base/fields/_ckeditor.html.erb
71
71
  - app/views/themes/base/fields/_email_field.html.erb
72
+ - app/views/themes/base/fields/_emoji_field.html.erb
72
73
  - app/views/themes/base/fields/_password_field.html.erb
73
74
  - app/views/themes/base/fields/_phone_field.html.erb
74
75
  - app/views/themes/base/fields/_super_select.html.erb