rbexy 0.1.5 → 0.3.0

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: f2c4fd57eed2a80ab3e953e5ea7ca577723dad29e5af7d2fb1bc231171c359e6
4
- data.tar.gz: 3f578fae5f23cab09d4b25744a933adcab8a119c72d3a937496298db9b235583
3
+ metadata.gz: deef1d8ce0aa71474ace3e813e28df01736d209b043734b7d83f7bb214a8eb5a
4
+ data.tar.gz: 31c8f2258bd54bab4a5f31cebcaf510f965b812fb7aca526098bb18878a41ce3
5
5
  SHA512:
6
- metadata.gz: 7330738b406e5944b8b4c9d379f1527ec78745026e2505902149d32164ed8b074cbe8f485a2dcbdeae8e75e11339142e94d804bf1b0470d840313082fc73ce53
7
- data.tar.gz: a900f8c4991796ef6719d4ed29bc6e7e60a7d04fdbee3fd29cc3ee38e50baa04597030dcac33c7e4c30f2af6b228e3e7cc863d348780732c77e0a4d80a5b9ba4
6
+ metadata.gz: b11967dff6d336fc3360b731ec6178b255b43e5c502580185541361c7ca3b9df41b5cf1f5c408c7cb1b2719722ff237f687d3bcf0f472b07edbb6137317655ec
7
+ data.tar.gz: 4f5238c70548687dc966d4a440a424176619f2255fb00f0a0508a21cf6642f888c7070016efba63e0c18f54c47bfe4873612f843b1058560cfc6bb951d378aff
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
- spec/dummy/log/
1
+ spec/dummy/log/*
2
2
  pkg/
3
+ spec/dummy/tmp/*
4
+ spec/dummy/db/*
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbexy (0.1.5)
4
+ rbexy (0.3.0)
5
5
  actionview (>= 5.0, < 7.0)
6
6
  activesupport (>= 5.0, < 7.0)
7
7
  railties (>= 5.0, < 7.0)
data/README.md CHANGED
@@ -375,6 +375,16 @@ Rbexy.configure do |config|
375
375
  end
376
376
  ```
377
377
 
378
+ Or in Rails you can customize the component provider just for a controller:
379
+
380
+ ```ruby
381
+ class ThingsController < ApplicationController
382
+ def rbexy_component_provider
383
+ MyComponentProvider.new
384
+ end
385
+ end
386
+ ```
387
+
378
388
  See `lib/rbexy/component_providers/` for example implementations.
379
389
 
380
390
  ## Usage outside of Rails
@@ -6,6 +6,7 @@ volumes:
6
6
  services:
7
7
  rbexy:
8
8
  build: .
9
+ image: rbexy
9
10
  volumes:
10
11
  - .:/app
11
12
  - bundle:/usr/local/bundle
@@ -13,3 +14,14 @@ services:
13
14
  - $HOME/.gitconfig:/root/.gitconfig:ro
14
15
  - $HOME/.gem/credentials:/root/.gem/credentials
15
16
  working_dir: /app
17
+ dummy:
18
+ image: rbexy
19
+ volumes:
20
+ - .:/app
21
+ - bundle:/usr/local/bundle
22
+ working_dir: /app/spec/dummy/
23
+ command: ./start.sh
24
+ ports:
25
+ - 3000:3000
26
+ environment:
27
+ - RAILS_LOG_STDOUT=1
@@ -1,22 +1,20 @@
1
1
  require "action_view"
2
+ require "active_support/core_ext/class/attribute"
2
3
 
3
4
  module Rbexy
4
5
  class Component < ActionView::Base
5
- class LookupContext < ActionView::LookupContext
6
- def self.details_hash(context)
7
- context.registered_details.each_with_object({}) do |key, details_hash|
8
- value = key == :locale ? [context.locale] : context.send(key)
9
- details_hash[key] = value
10
- end
6
+ class TemplatePath < String
7
+ def to_s
8
+ self
11
9
  end
10
+ end
12
11
 
13
- # We override any calls to args_for_lookup and set partial=false so that
14
- # the lookup context doesn't automatically add a `_` prefix to the
15
- # template path, since we're using the Rails partial-rendering
16
- # functionality but don't want our templates prefixed with a `_`
17
- def args_for_lookup(name, prefixes, partial, keys, details_options)
18
- super(name, prefixes, false, keys, details_options)
19
- end
12
+ def self.component_name
13
+ name.underscore
14
+ end
15
+
16
+ def component_name
17
+ self.class.component_name
20
18
  end
21
19
 
22
20
  def initialize(view_context, **props)
@@ -37,20 +35,18 @@ module Rbexy
37
35
  def setup(**props); end
38
36
 
39
37
  def render(&block)
40
- @content = nil
41
38
  @content_block = block_given? ? block : nil
42
39
  call
43
40
  end
44
41
 
45
42
  def call
46
- replace_lookup_context
47
- view_renderer.render(self, partial: component_name, &nil)
48
- ensure
49
- restore_lookup_context
43
+ path = TemplatePath.new(component_name)
44
+ template = view_context.lookup_context.find(path)
45
+ template.render(self, {})
50
46
  end
51
47
 
52
48
  def content
53
- @content ||= content_block ? view_context.capture(self, &content_block) : ""
49
+ content_block ? view_context.capture(self, &content_block) : ""
54
50
  end
55
51
 
56
52
  def create_context(name, value)
@@ -64,37 +60,13 @@ module Rbexy
64
60
  raise(ContextNotFound, "no parent context `#{name}`")
65
61
  end
66
62
 
67
- def view_renderer
68
- view_context.view_renderer
69
- end
70
-
71
- def component_name
72
- self.class.name.underscore
63
+ def compiled_method_container
64
+ Rbexy::Component
73
65
  end
74
66
 
75
67
  private
76
68
 
77
- attr_reader :view_context, :content_block, :old_lookup_context
78
-
79
- def replace_lookup_context
80
- return if view_renderer.lookup_context.is_a? Rbexy::Component::LookupContext
81
- @old_lookup_context = view_renderer.lookup_context
82
- view_renderer.lookup_context = build_lookup_context(old_lookup_context)
83
- end
84
-
85
- def restore_lookup_context
86
- return unless old_lookup_context
87
- view_renderer.lookup_context = old_lookup_context
88
- @old_lookup_context = nil
89
- end
90
-
91
- def build_lookup_context(existing_context)
92
- paths = existing_context.view_paths.dup.unshift(
93
- *Rbexy.configuration.template_paths.map { |p| ActionView::OptimizedFileSystemResolver.new(p) }
94
- )
95
-
96
- LookupContext.new(paths, LookupContext.details_hash(existing_context))
97
- end
69
+ attr_reader :view_context, :content_block
98
70
 
99
71
  def method_missing(meth, *args, &block)
100
72
  if view_context.respond_to?(meth)
@@ -0,0 +1,20 @@
1
+ module Rbexy
2
+ module ComponentProviders
3
+ class NamespacedRbexyProvider < Rbexy::ComponentProviders::RbexyProvider
4
+ attr_reader :namespaces
5
+
6
+ def initialize(*namespaces)
7
+ @namespaces = namespaces
8
+ end
9
+
10
+ def find(name)
11
+ namespaces.each do |namespace|
12
+ result = super("#{namespace}::#{name}")
13
+ return result if result != nil
14
+ end
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
@@ -10,8 +10,6 @@ module Rbexy
10
10
  find(name).new(context, **props).render(&block)
11
11
  end
12
12
 
13
- private
14
-
15
13
  def find(name)
16
14
  ActiveSupport::Inflector.constantize("#{name}Component")
17
15
  rescue NameError => e
@@ -10,8 +10,6 @@ module Rbexy
10
10
  find(name).new(**props).render_in(context, &block)
11
11
  end
12
12
 
13
- private
14
-
15
13
  def find(name)
16
14
  ActiveSupport::Inflector.constantize("#{name}Component")
17
15
  rescue NameError => e
@@ -2,6 +2,7 @@ module Rbexy
2
2
  class Configuration
3
3
  attr_accessor :component_provider
4
4
  attr_accessor :template_paths
5
+ attr_accessor :enable_context
5
6
 
6
7
  def template_paths
7
8
  @template_paths ||= []
@@ -85,11 +85,14 @@ module Rbexy
85
85
  base_tag
86
86
  end
87
87
 
88
+ context_open = Rbexy.configuration.enable_context ? "rbexy_context.push({});" : nil
89
+ context_close = Rbexy.configuration.enable_context ? "rbexy_context.pop;" : nil
90
+
88
91
  [
89
92
  "Rbexy::OutputBuffer.new.tap { |output|",
90
- "rbexy_context.push({}) if defined?(Rbexy::Component) && self.is_a?(Rbexy::Component);",
91
- "output << (#{tag});",
92
- "rbexy_context.pop if defined?(Rbexy::Component) && self.is_a?(Rbexy::Component);",
93
+ context_open,
94
+ "output << (#{tag}).html_safe;",
95
+ context_close,
93
96
  "}.html_safe"
94
97
  ].join(" ")
95
98
  end
@@ -1,7 +1,9 @@
1
+ require "active_support/core_ext/string/output_safety"
2
+
1
3
  module Rbexy
2
- class OutputBuffer < String
4
+ class OutputBuffer < ActiveSupport::SafeBuffer
3
5
  def <<(content)
4
- value = content.is_a?(Array) ? content.join : content
6
+ value = content.is_a?(Array) ? content.join.html_safe : content
5
7
  super([nil, false].include?(value) ? "" : value.to_s)
6
8
  end
7
9
  end
@@ -2,7 +2,8 @@ module Rbexy
2
2
  autoload :Component, "rbexy/component"
3
3
 
4
4
  module Rails
5
- autoload :TemplateHandler, "rbexy/rails/template_handler"
6
5
  autoload :Engine, "rbexy/rails/engine"
6
+ autoload :ControllerHelper, "rbexy/rails/controller_helper"
7
+ autoload :ComponentTemplateResolver, "rbexy/rails/component_template_resolver"
7
8
  end
8
9
  end
@@ -0,0 +1,35 @@
1
+ require "action_view"
2
+
3
+ module Rbexy
4
+ module Rails
5
+ class ComponentTemplateResolver < ActionView::FileSystemResolver
6
+ # Rails 6 requires us to override `_find_all` in order to hook
7
+ def _find_all(name, prefix, partial, details, key, locals)
8
+ find_templates(name, prefix, partial, details, locals)
9
+ end
10
+
11
+ # Rails 5 only requires `find_templates` (which tbh is the proper way
12
+ # to implement subclasses of ActionView::Resolver)
13
+ def find_templates(name, prefix, partial, details, locals = [])
14
+ return [] unless name.is_a? Rbexy::Component::TemplatePath
15
+
16
+ templates_path = File.join(@path, prefix, name)
17
+ extensions = details[:handlers].join(",")
18
+
19
+ Dir["#{templates_path}.*{#{extensions}}"].map do |template_path|
20
+ source = File.binread(template_path)
21
+ handler = ActionView::Template.handler_for_extension(File.extname(template_path)[1..-1])
22
+ virtual_path = ["rbexy_component", prefix, name].join("/")
23
+
24
+ ActionView::Template.new(
25
+ source,
26
+ template_path,
27
+ handler,
28
+ locals: [],
29
+ virtual_path: virtual_path
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require "active_support/concern"
2
+
3
+ module Rbexy
4
+ module Rails
5
+ module ControllerHelper
6
+ extend ActiveSupport::Concern
7
+
8
+ def rbexy_component_provider; end
9
+
10
+ class_methods do
11
+ def inherited(klass)
12
+ super
13
+ Rbexy.configuration.template_paths.each do |path|
14
+ prepend_view_path(Rbexy::Rails::ComponentTemplateResolver.new(path))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -12,6 +12,8 @@ module Rbexy
12
12
 
13
13
  ActiveSupport.on_load :action_controller_base do
14
14
  helper Rbexy::ViewContextHelper
15
+ helper_method :rbexy_component_provider
16
+ include ControllerHelper
15
17
  end
16
18
 
17
19
  if defined?(ViewComponent)
@@ -22,6 +24,7 @@ module Rbexy
22
24
  require "rbexy/component_providers/rbexy_provider"
23
25
  config.component_provider = Rbexy::ComponentProviders::RbexyProvider.new
24
26
  config.template_paths << ::Rails.root.join("app", "components")
27
+ config.enable_context = true
25
28
  end
26
29
  end
27
30
  end
@@ -11,7 +11,11 @@ module Rbexy
11
11
 
12
12
  DefaultTagBuilder = ActionView::Helpers::TagHelper::TagBuilder
13
13
 
14
- def self.create_tag_builder(context, provider = Rbexy.configuration.component_provider)
14
+ def self.create_tag_builder(context, provider = nil)
15
+ provider = provider ||
16
+ provider_from_context(context) ||
17
+ Rbexy.configuration.component_provider
18
+
15
19
  if provider
16
20
  ComponentTagBuilder.new(context, provider)
17
21
  else
@@ -19,6 +23,12 @@ module Rbexy
19
23
  end
20
24
  end
21
25
 
26
+ def self.provider_from_context(context)
27
+ if context.respond_to?(:rbexy_component_provider)
28
+ context.rbexy_component_provider
29
+ end
30
+ end
31
+
22
32
  def initialize(component_provider = nil)
23
33
  @rbexy_tag = self.class.create_tag_builder(self, component_provider)
24
34
  end
@@ -1,3 +1,3 @@
1
1
  module Rbexy
2
- VERSION = "0.1.5"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbexy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Giancola
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-13 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -224,6 +224,7 @@ files:
224
224
  - example.rb
225
225
  - lib/rbexy.rb
226
226
  - lib/rbexy/component.rb
227
+ - lib/rbexy/component_providers/namespaced_rbexy_provider.rb
227
228
  - lib/rbexy/component_providers/rbexy_provider.rb
228
229
  - lib/rbexy/component_providers/view_component_provider.rb
229
230
  - lib/rbexy/component_tag_builder.rb
@@ -234,6 +235,8 @@ files:
234
235
  - lib/rbexy/output_buffer.rb
235
236
  - lib/rbexy/parser.rb
236
237
  - lib/rbexy/rails.rb
238
+ - lib/rbexy/rails/component_template_resolver.rb
239
+ - lib/rbexy/rails/controller_helper.rb
237
240
  - lib/rbexy/rails/engine.rb
238
241
  - lib/rbexy/runtime.rb
239
242
  - lib/rbexy/version.rb