bullet_train-themes 1.0.20 → 1.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/theme_helper.rb +48 -72
- data/app/views/themes/base/attributes/_text.html.erb +2 -1
- data/app/views/themes/base/fields/_emoji_field.html.erb +30 -0
- data/app/views/themes/base/fields/_super_select.html.erb +3 -2
- data/lib/bullet_train/themes/version.rb +1 -1
- data/lib/bullet_train/themes.rb +30 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6ec7ac778169e393502c1149e3ef264ff92c8bd142ec3348a2fb986ea38b98b
|
4
|
+
data.tar.gz: 7c11f42d705cd7a20efd93c0a1b59ce739319aea04770a1cd733fdb27589006c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1c5e71cb2161fedd8764c51926620c0ba0b156385e75901e00cba9db7a8aa63724e6ac3b1b815e70684dfcbe4206553b4e497c34926f8393fedcd7c17afa19f
|
7
|
+
data.tar.gz: 9f731798611e2fcd61c206741fc7e881f3045c7ad6ce47ade05a8a2435fbeb071372fbc1cff178474443d552430edebd5b97b7ce1a51eb8a973035e9e188ea6a
|
data/app/helpers/theme_helper.rb
CHANGED
@@ -1,81 +1,57 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
6
19
|
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
29
|
+
|
30
|
+
resolver.find(name, prefixes, partial, details, details_key, keys)
|
31
|
+
end
|
32
|
+
alias_method :find_template, :find
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
10
36
|
|
37
|
+
module ThemeHelper
|
11
38
|
def current_theme_object
|
12
39
|
@current_theme_object ||= "BulletTrain::Themes::#{current_theme.to_s.classify}::Theme".constantize.new
|
13
40
|
end
|
14
41
|
|
15
42
|
def render(options = {}, locals = {}, &block)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
76
|
-
|
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
|
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
|
+
|
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] ||=
|
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]
|
29
|
+
html_options[:data] ||= {}
|
30
|
+
html_options[:data].merge!("#{stimulus_controller}-target": 'select')
|
30
31
|
|
31
32
|
%>
|
32
33
|
|
data/lib/bullet_train/themes.rb
CHANGED
@@ -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.
|
4
|
+
version: 1.0.23
|
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-
|
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
|
@@ -101,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
102
|
- !ruby/object:Gem::Version
|
102
103
|
version: '0'
|
103
104
|
requirements: []
|
104
|
-
rubygems_version: 3.
|
105
|
+
rubygems_version: 3.3.7
|
105
106
|
signing_key:
|
106
107
|
specification_version: 4
|
107
108
|
summary: Bullet Train Themes
|