rbexy 0.1.5 → 0.3.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
  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