coprl 3.0.0.beta.2 → 3.0.0.beta.3

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +31 -0
  5. data/app/demo/components/nav/menu.pom +0 -1
  6. data/app/demo/plugins/cacheable.pom +64 -0
  7. data/app/demo/plugins/google_maps.pom +24 -0
  8. data/app/demo/plugins/image_crop.pom +1 -1
  9. data/app/demo/plugins/nav/drawer.pom +1 -1
  10. data/app/demo/plugins/script.pom +17 -0
  11. data/app/demo/plugins/scroll_to.pom +22 -0
  12. data/app/demo/shared/context_list.pom +1 -1
  13. data/config.ru +15 -1
  14. data/lib/coprl/presenters/cli.rb +10 -0
  15. data/lib/coprl/presenters/dsl/components/event.rb +6 -1
  16. data/lib/coprl/presenters/generators/plugin.rb +20 -6
  17. data/lib/coprl/presenters/generators/templates/plugin/.github/workflows/semantic-release.yml +41 -0
  18. data/lib/coprl/presenters/generators/templates/plugin/.releaserc +15 -0
  19. data/lib/coprl/presenters/generators/templates/plugin/.ruby-version +1 -0
  20. data/lib/coprl/presenters/generators/templates/plugin/README.md.tt +34 -0
  21. data/lib/coprl/presenters/generators/templates/plugin/demo/plugin.pom.tt +15 -0
  22. data/lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/components/actions/dsl.rb.tt +1 -1
  23. data/lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/version.rb.tt +3 -0
  24. data/lib/coprl/presenters/generators/templates/plugin/presenter_plugin.gemspec.tt +8 -7
  25. data/lib/coprl/presenters/generators/templates/plugin/views/components/application/component.erb.tt +1 -1
  26. data/lib/coprl/presenters/settings.rb +1 -1
  27. data/lib/coprl/presenters/version.rb +1 -1
  28. data/rails-engine/app/controllers/coprl_controller.rb +18 -1
  29. data/rails-engine/config/initializers/session.rb +8 -0
  30. data/views/mdc/components/unordered_list/_list_item.erb +3 -3
  31. metadata +13 -7
  32. data/app/demo/components/google_maps.pom +0 -22
  33. data/lib/coprl/presenters/generators/templates/plugin/README.md +0 -253
  34. data/lib/coprl/presenters/plugins/google_maps.rb +0 -24
  35. data/lib/coprl/presenters/plugins/google_maps/google_map.erb +0 -10
  36. data/lib/coprl/presenters/plugins/google_maps/google_map.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e11f41de6e5ebd00304df4a4cfe917123cf26cce95f02f8d9ead207f55204101
4
- data.tar.gz: 0c65b1a3211123c2a2ed171fc811816e1646f5d9c5997b375d1bde5d2e979db2
3
+ metadata.gz: 7d7518e53fa8334d12c57f9221559528d01368548e0806077042e232c47cf6d4
4
+ data.tar.gz: c7cbe113161ae098b0a789827edc1233d1a59299d6bdbc618a077c66b8cb85a0
5
5
  SHA512:
6
- metadata.gz: efb2027ca9f8ec7863dbb946cf6cfab079b747300e3afb3af9d6c176e50a195950dcf3677db68834d7a601ffd9efda6a859abcc5d3471df615b295829c0ea11b
7
- data.tar.gz: 9abeedcb34dcb334c6438f14ffe0cb2e78cd1d47ad39eea111b0ae368cd52dc36eba87697237cbf4bb603746e530e7036b699bd45d6d78998509d709ab4c613f
6
+ metadata.gz: f1b6b99fc482af03d45152745a7969cc190cf9948f116d8026a7623d8c4a11cd4fcfef7a66894b262e8110aa960f15bdec72c91913a4dc3ba0473ee4b640147e
7
+ data.tar.gz: a3d7dd1e766e3fc1e8f619f8abc658cf8dd0a887eee46068f9e147540768e6927e50cdb129346d79bc14402f960064d3df00608e15af8e3633e90d3347bb9ec4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [3.0.0-beta.3](https://github.com/rx/presenters/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2021-06-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added cli --version ([4c5b10e](https://github.com/rx/presenters/commit/4c5b10e0707bcdeecfb29908eb3284b692cbcd41))
7
+ * added missing prepare context callbacks to Rails Engine ([bafa36d](https://github.com/rx/presenters/commit/bafa36d6e95ad9863eb93cb44cc894163c147c4f))
8
+ * added prepare context for Rails native views engine that sets the request and session automatically ([a09f3c6](https://github.com/rx/presenters/commit/a09f3c637102e640fe0b91894ae89b5a07288846))
9
+ * Added version.rb to plugin generator ([f1f2092](https://github.com/rx/presenters/commit/f1f20925dfd326fb5a47910952e21b34b762c31d))
10
+ * Added version.rb to plugin generator ([35187bf](https://github.com/rx/presenters/commit/35187bf188957e2ca93e2bf07963e958452f27fe))
11
+ * expanded plugin generator to include github semantic release, demo pom and sample README ([06de7a2](https://github.com/rx/presenters/commit/06de7a237f8a417a11776d1994915c32253a981d))
12
+ * fixed unordered list partial rendering error ([014f1d1](https://github.com/rx/presenters/commit/014f1d19926d7e9d39618fbe68c8068db316ac4b))
13
+ * generator not compatible with COPRL 3 Rails templating naming conventions ([f6d80f0](https://github.com/rx/presenters/commit/f6d80f0a44f6305b9339bc2bd6db8487eefc68cc))
14
+ * removed google_map built in plugin to its own plugin ([a34290d](https://github.com/rx/presenters/commit/a34290de890e2fdf7e6c2c7b1714854d454c82a4))
15
+
16
+
17
+ ### Features
18
+
19
+ * Added singular alias for common actions: load, replace, post, create, and delete ([b57c305](https://github.com/rx/presenters/commit/b57c305bd4dbf95b8a9662ad747020683bf74c8d))
20
+
1
21
  # [3.0.0-beta.2](https://github.com/rx/presenters/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2021-06-03)
2
22
 
3
23
 
data/Gemfile CHANGED
@@ -24,7 +24,12 @@ end
24
24
  gem 'foo_presenter_plugin', github: 'coprl/foo_presenter_plugin', require: false
25
25
  gem 'image_crop_presenter_plugin', github: 'coprl/image_crop_presenter_plugin', require: false
26
26
  gem 'chart_presenter_plugin', github: 'coprl/chart_presenter_plugin', require: false
27
+ gem 'google_maps_presenter_plugin', github: 'coprl/google_maps_presenter_plugin', branch: :main, require: false
28
+ gem 'cacheable_presenter_plugin', github: 'coprl/cacheable_presenter_plugin', require: false
29
+ gem 'script_presenter_plugin', github: 'coprl/script_presenter_plugin', require: false
30
+ gem 'scroll_to_presenter_plugin', github: 'coprl/scroll_to_presenter_plugin', require: false
27
31
 
28
32
  gem 'rack-cors'
29
33
  gem 'honeybadger' if ENV.fetch('HONEYBADGER_API_KEY'){false}
30
34
  gem 'puma'
35
+ gem 'dotenv'
data/Gemfile.lock CHANGED
@@ -1,3 +1,9 @@
1
+ GIT
2
+ remote: https://github.com/coprl/cacheable_presenter_plugin.git
3
+ revision: 262ac076d70d94b111b9ccb692dfc9225c7cc6c6
4
+ specs:
5
+ cacheable_presenter_plugin (0.0.3)
6
+
1
7
  GIT
2
8
  remote: https://github.com/coprl/chart_presenter_plugin.git
3
9
  revision: ae9a8bb805570dbf2c1156e3c81f07e3a24807e2
@@ -10,12 +16,31 @@ GIT
10
16
  specs:
11
17
  foo_presenter_plugin (0.0.2)
12
18
 
19
+ GIT
20
+ remote: https://github.com/coprl/google_maps_presenter_plugin.git
21
+ revision: 237d956ce36b6c9945080088e4d9e5a2f042ee5b
22
+ branch: main
23
+ specs:
24
+ google_maps_presenter_plugin (0.1.0)
25
+
13
26
  GIT
14
27
  remote: https://github.com/coprl/image_crop_presenter_plugin.git
15
28
  revision: 33452c5d3b232e93a942280f8429be2707c992ab
16
29
  specs:
17
30
  image_crop_presenter_plugin (0.1.0)
18
31
 
32
+ GIT
33
+ remote: https://github.com/coprl/script_presenter_plugin.git
34
+ revision: c7cea03e73f4752a3df99e4b3ab0d4030f141f4d
35
+ specs:
36
+ script_presenter_plugin (0.0.2)
37
+
38
+ GIT
39
+ remote: https://github.com/coprl/scroll_to_presenter_plugin.git
40
+ revision: e1dd957723561117ee45743ac9e27a4fd91a4a97
41
+ specs:
42
+ scroll_to_presenter_plugin (0.0.2)
43
+
19
44
  PATH
20
45
  remote: .
21
46
  specs:
@@ -40,6 +65,7 @@ GEM
40
65
  concurrent-ruby (1.1.8)
41
66
  diff-lcs (1.3)
42
67
  docile (1.3.1)
68
+ dotenv (2.7.6)
43
69
  dry-configurable (0.12.1)
44
70
  concurrent-ruby (~> 1.0)
45
71
  dry-core (~> 0.5, >= 0.5.0)
@@ -143,10 +169,13 @@ PLATFORMS
143
169
 
144
170
  DEPENDENCIES
145
171
  bundler (>= 1.13)
172
+ cacheable_presenter_plugin!
146
173
  chart_presenter_plugin!
147
174
  coprl!
175
+ dotenv
148
176
  foo_presenter_plugin!
149
177
  gem-release (~> 2.0)
178
+ google_maps_presenter_plugin!
150
179
  image_crop_presenter_plugin!
151
180
  pry
152
181
  pry-byebug
@@ -158,6 +187,8 @@ DEPENDENCIES
158
187
  rspec
159
188
  rspec-html-matchers
160
189
  rspec_junit_formatter
190
+ script_presenter_plugin!
191
+ scroll_to_presenter_plugin!
161
192
  shotgun (~> 0.9)
162
193
  simplecov
163
194
  thor (~> 1.1.0)
@@ -25,7 +25,6 @@ Coprl::Presenters.define('component_menu') do
25
25
  layouts
26
26
  lists
27
27
  number_fields
28
- maps
29
28
  menus
30
29
  multi_selects
31
30
  progress
@@ -0,0 +1,64 @@
1
+ require 'ostruct'
2
+
3
+ Coprl::Presenters.define(:cacheable, namespace: :plugins) do
4
+ helpers Demo::Helpers::IndentedGrid
5
+ attach :top_nav
6
+ attach :plugin_drawer
7
+ plugin :cacheable
8
+
9
+ page_title 'Cacheable'
10
+
11
+ helpers do
12
+ def cache_object
13
+ OpenStruct.new(cache_key: 'wild')
14
+ end
15
+
16
+ def cache_objects
17
+ [
18
+ OpenStruct.new(cache_key: 'abc'),
19
+ OpenStruct.new(cache_key: '123'),
20
+ ]
21
+ end
22
+ end
23
+
24
+ indented_grid do
25
+ body <<~DOC
26
+ The caching plugin provides russian doll caching support.
27
+ Declare the plugin in your pom, `plugin :cacheable`, or configure it globally:
28
+
29
+ ```
30
+ Coprl::Presenters::Settings.configure do |config|
31
+ config.presenters.plugins.push(:cacheable)
32
+ end
33
+ ```
34
+
35
+ For Rails it automatically uses the Rails::Cache. For other Rack apps you need to configure it with a block:
36
+
37
+ ```
38
+ Coprl::Presenters::Plugins::Cacheable::Settings.configure do |config|
39
+ # A cache needs to respond to fetch(key, &block) and exist?(key) or has_key?(key)
40
+ config.cache=cache_store
41
+ end
42
+ ```
43
+ Simply wrap your POM with the cache directive.
44
+ Complex keys are supported. If an object responds to `cache_key` then that will be used for it.
45
+ An object that responds to `map` will be expanded. As a last resort `to_s` is used.
46
+
47
+ Examples (refresh your browser to observe cached values):
48
+ DOC
49
+ title "Not cached at #{DateTime.now}"
50
+ cache :remember_me do
51
+ title "Simple Cache Key - cached at #{DateTime.now}"
52
+ end
53
+
54
+ cache [:title, cache_object, cache_objects] do
55
+ title "Complex Cache Key - cached at #{DateTime.now}"
56
+ end
57
+ blank
58
+ body <<~DOC
59
+ Note: Confusion alert ... if you are using shotgun for the demo, it **will not cache**, since the demo uses an in memory cache and shotgun reloads its entire process with each refresh.
60
+ DOC
61
+
62
+ end
63
+ attach :code, file: __FILE__
64
+ end
@@ -0,0 +1,24 @@
1
+ Coprl::Presenters.define(:google_maps, namespace: :plugins) do
2
+ helpers Demo::Helpers::IndentedGrid
3
+ attach :top_nav
4
+ attach :plugin_drawer
5
+ plugin :google_maps
6
+ page_title 'Maps'
7
+
8
+ indented_grid do
9
+ unless ENV['GOOGLE_API_KEY']
10
+ headline 'You must define the ENV variable GOOGLE_API_KEY for this to render a map'
11
+ subtitle 'Dev hint: Create an .env file with a `GOOGLE_API_KEY=yourkey` and restart. Goto [Google Using API Keys](https://developers.google.com/maps/documentation/javascript/get-api-key) to create a key.'
12
+ end
13
+ subheading 'Static Maps'
14
+ address = '125 Park Street, Traverse City, MI'
15
+ google_map address: address, height: "300px", width: "400px" do
16
+ event :click do
17
+ loads "https://www.google.com/maps/place/#{address}"
18
+ end
19
+ end
20
+
21
+ attach :code, file: __FILE__
22
+ end
23
+
24
+ end
@@ -20,7 +20,7 @@ Coprl::Presenters.define(:image_crop, namespace: :plugins) do
20
20
  grid do
21
21
  column 12 do
22
22
  card do
23
- text 'Drop it here'
23
+ text 'Drop an image or click'
24
24
  button icon: :cloud_upload
25
25
  end
26
26
  end
@@ -7,7 +7,7 @@ Coprl::Presenters.define(:plugin_drawer, namespace: :plugins) do
7
7
  loads :index
8
8
  end
9
9
  end
10
- %i(image_crop chart).sort.each do |comp|
10
+ %i(image_crop chart google_maps cacheable script scroll_to).sort.each do |comp|
11
11
  item titleize(comp) do
12
12
  event :click do
13
13
  loads comp
@@ -0,0 +1,17 @@
1
+ Coprl::Presenters.define(:script, namespace: :plugins) do
2
+ helpers Demo::Helpers::IndentedGrid
3
+ attach :top_nav
4
+ attach :plugin_drawer
5
+ plugin :script
6
+ page_title 'Script'
7
+
8
+ script inline: <<~JAVASCRIPT
9
+ alert( 'Hello, world!' );
10
+ JAVASCRIPT
11
+ indented_grid do
12
+ subheading 'You can write arbitrary javascript using the script component. For example, the alert you just dismissed.'
13
+
14
+ attach :code, file: __FILE__
15
+ end
16
+
17
+ end
@@ -0,0 +1,22 @@
1
+ Coprl::Presenters.define(:scroll_to, namespace: :plugins) do
2
+ helpers Demo::Helpers::IndentedGrid
3
+ attach :top_nav
4
+ attach :plugin_drawer
5
+ plugin :scroll_to
6
+ page_title 'Scroll to'
7
+
8
+ indented_grid do
9
+ subheading 'Sometimes you need to scroll to find content after some action. This is what the scroll to plugin is for.'
10
+ button :scroll do
11
+ event :click do
12
+ scroll_to :scroll_target #, smooth: true, offset: 100
13
+ end
14
+ end
15
+ (1..100).each do
16
+ body '.'
17
+ end
18
+ title 'Thanks for scrolling here', id: :scroll_target
19
+
20
+ attach :code, file: __FILE__
21
+ end
22
+ end
@@ -9,7 +9,7 @@ Coprl::Presenters.define(:context_list) do
9
9
  end
10
10
 
11
11
  def scrubbed_context
12
- scrubbed_keys = context.fetch(:exclude) {%w{title file hide_time _presenter_ _namespace1_ session}}
12
+ scrubbed_keys = context.fetch(:exclude) {%w{title file hide_time _presenter_ _namespace1_ session request controller action presenter}}
13
13
  context.select {|k, _| !scrubbed_keys.include?(k.to_s)}
14
14
  end
15
15
  end
data/config.ru CHANGED
@@ -9,7 +9,7 @@ if ENV['VOOM_ENV'] == 'integration_testing'
9
9
  end
10
10
 
11
11
  ENV['VOOM_ROOT'] = File.expand_path(__dir__)
12
- ENV['GOOGLE_API_KEY'] = 'AIzaSyDhSgj9XSBLY5E9Rx5pP2ILQ7IXnD4uX2Q'
12
+ require 'dotenv/load'
13
13
  require 'coprl'
14
14
 
15
15
  require 'rack/cors'
@@ -27,6 +27,20 @@ Coprl::Presenters::Settings.configure do |config|
27
27
  }
28
28
  end
29
29
 
30
+ require 'pry'
31
+ require 'coprl/presenters/plugins/cacheable'
32
+ cache_store = Concurrent::Hash.new
33
+ # Quick and dirty demo always growing memory cache -- DONT DO THIS IN PRODUCTION!
34
+ def cache_store.fetch(key, options=nil, &block)
35
+ result = super(key, &block)
36
+ store(key, result) unless has_key?(key)
37
+ result
38
+ end
39
+
40
+ Coprl::Presenters::Plugins::Cacheable::Settings.configure do |config|
41
+ config.cache=cache_store
42
+ end
43
+
30
44
  use Coprl::Presenters::Demo::Search
31
45
  use Coprl::Presenters::Demo::Echo
32
46
  use Coprl::Presenters::Demo::Slow
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require_relative 'generators/plugin'
3
+ require_relative 'version'
3
4
 
4
5
  module Coprl
5
6
  module Presenters
@@ -20,6 +21,15 @@ module Coprl
20
21
  end
21
22
  end
22
23
  class Cli < Thor
24
+ def self.exit_on_failure?
25
+ true
26
+ end
27
+ map %w[--version -v] => :__print_version
28
+
29
+ desc "--version, -v", "print the version"
30
+ def __print_version
31
+ puts Coprl::Presenters::Version::VERSION
32
+ end
23
33
  desc "generate", "generate a plugin"
24
34
  subcommand "generate", Generate
25
35
  end
@@ -27,6 +27,7 @@ module Coprl
27
27
  wait_for_download: wait_for_download,
28
28
  params: params, &block)
29
29
  end
30
+ alias load loads
30
31
 
31
32
  def replaces(target, presenter, input_tag: nil, ignore_input_values: [], **params, &block)
32
33
  self << Actions::Replaces.new(parent: self,
@@ -36,6 +37,7 @@ module Coprl
36
37
  ignore_input_values: Array(ignore_input_values),
37
38
  params: params, &block)
38
39
  end
40
+ alias replace replaces
39
41
 
40
42
  # Method can be one of :post, :put, :delete or :patch
41
43
  def posts(path, input_tag: nil, headers: nil, **params, &block)
@@ -45,8 +47,10 @@ module Coprl
45
47
  headers: headers,
46
48
  params: params, &block)
47
49
  end
48
-
50
+ alias post posts
49
51
  alias creates posts
52
+ alias create posts
53
+
50
54
 
51
55
  def updates(path, input_tag: nil, headers: nil, **params, &block)
52
56
  self << Actions::Updates.new(parent: self,
@@ -63,6 +67,7 @@ module Coprl
63
67
  headers: headers,
64
68
  params: params, &block)
65
69
  end
70
+ alias delete deletes
66
71
 
67
72
  def dialog(dialog_id, **params, &block)
68
73
  self << Actions::Dialog.new(parent: self,
@@ -32,13 +32,13 @@ module Coprl
32
32
 
33
33
  def template_file(template, target_filename=template, source_path=nil, target_path=source_path)
34
34
  source = join_path(TEMPLATES_ROOT, source_path, "#{template}.tt")
35
- destination = join_path(plusin_name, target_path, target_filename)
35
+ destination = join_path(plugin_name, target_path, target_filename)
36
36
  template source, destination
37
37
  end
38
38
 
39
39
  def file(file, target_filename=file, source_path=nil, target_path=nil)
40
40
  source = join_path(TEMPLATES_ROOT, source_path, file)
41
- destination = join_path(plusin_name, target_path, target_filename)
41
+ destination = join_path(plugin_name, target_path, target_filename)
42
42
 
43
43
  copy_file source, destination
44
44
  end
@@ -59,17 +59,27 @@ module Coprl
59
59
  underscore(name)
60
60
  end
61
61
 
62
- def plusin_name
62
+ def plugin_name
63
63
  "#{underscored_name}_presenter_plugin"
64
64
  end
65
65
  end
66
66
 
67
+ def create_version
68
+ template_file('version.rb', "version.rb", LIB_ROOT, "lib/#{underscored_name}_presenter_plugin")
69
+ end
70
+
67
71
  def create_root_files
68
72
  file('.gitignore')
69
73
  template_file('Gemfile')
70
74
  template_file('LICENSE.txt')
71
75
  template_file('presenter_plugin.gemspec', "#{underscored_name}_presenter_plugin.gemspec")
72
- file 'README.md'
76
+ template_file 'README.md'
77
+ end
78
+
79
+ def create_semantic_release_github_action
80
+ file('.releaserc')
81
+ file('.ruby-version')
82
+ file('semantic-release.yml', 'semantic-release.yml', dir('.github', 'workflows'))
73
83
  end
74
84
 
75
85
  def create_plugin
@@ -90,9 +100,9 @@ module Coprl
90
100
  dir('views', 'assets', 'css', 'components'))
91
101
  template_file('component.js', "#{underscored_name}.js",
92
102
  dir('views', 'assets', 'js', 'components'))
93
- template_file('component.erb', "#{underscored_name}.erb",
103
+ template_file('component.erb', "_#{underscored_name}.erb",
94
104
  dir('views', 'components', 'application'))
95
- template_file('component_header.erb', "#{underscored_name}_header.erb",
105
+ template_file('component_header.erb', "_#{underscored_name}_header.erb",
96
106
  dir('views', 'components', 'application'))
97
107
  end
98
108
 
@@ -115,6 +125,10 @@ module Coprl
115
125
  lib_dir('helpers'),
116
126
  named_dir('helpers'))
117
127
  end
128
+
129
+ def create_demo_pom
130
+ template_file('plugin.pom', "#{underscored_name}.pom", dir('demo'))
131
+ end
118
132
  end
119
133
  end
120
134
  end
@@ -0,0 +1,41 @@
1
+ name: CI
2
+
3
+ # Controls when the action will run.
4
+ on:
5
+ # Triggers the workflow on push or pull request events but only for the master branch
6
+ push:
7
+ branches: [ master ]
8
+ pull_request:
9
+ branches: [ master ]
10
+
11
+ # Allows you to run this workflow manually from the Actions tab
12
+ workflow_dispatch:
13
+
14
+ # A workflow run is made up of one or more jobs that can run sequentially or in parallel
15
+ jobs:
16
+ # This workflow contains a single job called "build"
17
+ build:
18
+ # The type of runner that the job will run on
19
+ runs-on: ubuntu-latest
20
+
21
+ # Steps represent a sequence of tasks that will be executed as part of the job
22
+ steps:
23
+ - name: Checkout
24
+ uses: actions/checkout@v2
25
+ - name: Setup Ruby
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
29
+ - name: Semantic Release
30
+ uses: cycjimmy/semantic-release-action@v2
31
+ with:
32
+ extra_plugins: |
33
+ @semantic-release/git
34
+ @semantic-release/changelog
35
+ @semantic-release/github
36
+ semantic-release-rubygem
37
+ dry_run: false
38
+ env:
39
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40
+ GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
41
+
@@ -0,0 +1,15 @@
1
+ {
2
+ "branches": ['+([0-9])?(.{+([0-9]),x}).x', 'master', 'next', 'next-major', {name: 'beta', prerelease: true}, {name: 'alpha', prerelease: true}],
3
+ "plugins": [
4
+ "@semantic-release/commit-analyzer",
5
+ "@semantic-release/release-notes-generator",
6
+ "@semantic-release/changelog",
7
+ "@semantic-release/github",
8
+ ["semantic-release-rubygem",
9
+ {
10
+ "gemPublish": false
11
+ }
12
+ ],
13
+ "@semantic-release/git"
14
+ ]
15
+ }
@@ -0,0 +1,34 @@
1
+ # <%= humanize(name) %> Presenter Plugin
2
+
3
+ A [COPRL](http://github.com/coprl/coprl) presenter plugin that <%= name %>
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem '<%= name %>_presenter_plugin', git: 'https://github.com/coprl/<%= name %>_presenter_plugin', require: false
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+
18
+ ## Usage in POMs
19
+
20
+ Declare the plugin in your pom, `plugin :<%= name %>`.
21
+
22
+ TODO: Add an example POM and describe your plugin here
23
+
24
+ ## Contributing
25
+
26
+ Bug reports and pull requests are welcome on GitHub at https://github.com/coprl/<%= name %>_presenter_plugin.
27
+
28
+ ## License
29
+
30
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
31
+
32
+ ## Code of Conduct
33
+
34
+ Everyone interacting in the COPRL project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/coprl/coprl/blob/master/CODE-OF-CONDUCT.md).
@@ -0,0 +1,15 @@
1
+ Coprl::Presenters.define(:<%= name %>, namespace: :plugins) do
2
+ helpers Demo::Helpers::IndentedGrid
3
+ attach :top_nav
4
+ attach :plugin_drawer
5
+ plugin :<%= name %>
6
+ page_title '<%= humanize(name) %>'
7
+
8
+ <%= name %> # TODO Add your demo code here
9
+
10
+ indented_grid do
11
+ subheading 'TODO describe how to use your plugin'
12
+
13
+ attach :code, file: __FILE__
14
+ end
15
+ end
@@ -1,4 +1,4 @@
1
- require_relative '<%= classify(name) %>_action'
1
+ require_relative '<%= underscore(name) %>_action'
2
2
 
3
3
  module Coprl
4
4
  module Presenters
@@ -0,0 +1,3 @@
1
+ module <%= classify(name) %>PresenterPlugin
2
+ VERSION = "0.0.1"
3
+ end
@@ -1,21 +1,22 @@
1
1
  lib = File.expand_path("../lib", __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require '<%= name %>_presenter_plugin/version'
3
4
 
4
5
  Gem::Specification.new do |spec|
5
- spec.name = "<%= name %>_presenter_plugin"
6
- spec.version = '0.0.1'
6
+ spec.name = '<%= name %>_presenter_plugin'
7
+ spec.version = <%= classify(name) %>PresenterPlugin::VERSION
7
8
  spec.authors = ["<%= `git config user.name`.strip %>"]
8
9
  spec.email = ["<%= `git config user.email`.strip %>"]
9
10
 
10
- spec.summary = %q{<%= name %> presenter plugin.}
11
+ spec.summary = %q{A COPRL presenter plugin for <%= name %>}
11
12
  spec.homepage = 'http://github.com/<%= `git config user.name`.strip %>/<%= name %>_presenters_plugin'
12
- spec.license = "MIT"
13
+ spec.license = 'MIT'
13
14
 
14
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
16
  f.match(%r{^(test|spec|features)/})
16
17
  end
17
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
18
19
 
19
- spec.add_development_dependency "bundler", "~> 1.16"
20
- spec.add_development_dependency "rake", "~> 10.0"
20
+ spec.add_development_dependency 'bundler', "~> 2.0"
21
+ spec.add_development_dependency 'rake', "~> 10.0"
21
22
  end
@@ -11,4 +11,4 @@ Any additional data you want to pass to your component javascript should be setu
11
11
  -->
12
12
  <iframe id="random_fact" class='v-plugin v-input' data-plugin-callback='RandomFacts'
13
13
  src="<%%= comp.random_fact %>" height=512
14
- <%%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>></iframe>
14
+ <%%= partial "components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>></iframe>
@@ -32,7 +32,7 @@ unless defined?(Coprl::Presenters::Settings)
32
32
  setting :custom_css, '../public/presenters'
33
33
  setting :protect_from_forgery, false
34
34
  end
35
- setting :plugins, [:google_maps]
35
+ setting :plugins, []
36
36
  setting :components do
37
37
  setting :defaults do
38
38
  setting :datetime do
@@ -1,7 +1,7 @@
1
1
  module Coprl
2
2
  module Presenters
3
3
  module Version
4
- VERSION = '3.0.0.beta.2'
4
+ VERSION = '3.0.0.beta.3'
5
5
  end
6
6
  end
7
7
  end
@@ -12,7 +12,7 @@ class CoprlController < ApplicationController
12
12
  fq_presenter_name = [presenter_name, 'index'].compact.join(':')
13
13
  presenter_name = fq_presenter_name if Coprl::Presenters::App.registered?(fq_presenter_name)
14
14
  presenter = Coprl::Presenters::App[presenter_name].call
15
- context = params.dup.to_unsafe_hash
15
+ context = prepare_context(params)
16
16
  router = Coprl::Presenters::WebClient::Router.new(base_url: request.base_url)
17
17
  @pom = presenter.expand(router: router, context: context)
18
18
  end
@@ -23,4 +23,21 @@ class CoprlController < ApplicationController
23
23
  prepend_view_path path
24
24
  end
25
25
  end
26
+
27
+ def prepare_context(base_params = params)
28
+ prepare_context = Coprl::Presenters::Settings.config.presenters.web_client.prepare_context.dup
29
+ prepare_context.push(method(:scrub_context))
30
+ context = base_params.dup.to_unsafe_hash
31
+ prepare_context.reduce(context) do |params, context_proc|
32
+ context = context_proc.call(params, session, request.env)
33
+ end
34
+ context
35
+ end
36
+
37
+ def scrub_context(params, _session, _env)
38
+ %i(grid_nesting input_tag).each do |key|
39
+ params.delete(key) {params.delete(key.to_s)}
40
+ end
41
+ params
42
+ end
26
43
  end
@@ -0,0 +1,8 @@
1
+ Rails.application.config.to_prepare do
2
+ Coprl::Presenters::Settings.configure do |config|
3
+ config.presenters.web_client.prepare_context.prepend ->(context, session, _env) {
4
+ context.merge(request: Rack::Request.new(_env),
5
+ session: session)
6
+ }
7
+ end
8
+ end
@@ -1,7 +1,7 @@
1
1
  <li class="<%= 'icon-li' if list_item.icon %>">
2
- <%= erb :"components/unordered_list/icon", :locals => {:list_item => list_item} %>
2
+ <%= partial "components/unordered_list/icon", :locals => {:list_item => list_item} %>
3
3
  <%= expand_text(list_item.text&.text) %>
4
4
  <% if list_item.unordered_list %>
5
- <%= erb :"components/unordered_list", :locals => {:comp => list_item.unordered_list} %>
5
+ <%= partial "components/unordered_list", :locals => {:comp => list_item.unordered_list} %>
6
6
  <% end %>
7
- </li>
7
+ </li>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coprl
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.2
4
+ version: 3.0.0.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Russell Edens
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-03 00:00:00.000000000 Z
11
+ date: 2021-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ice_nine
@@ -340,7 +340,6 @@ files:
340
340
  - app/demo/components/fabs.pom
341
341
  - app/demo/components/file_inputs.pom
342
342
  - app/demo/components/footers.pom
343
- - app/demo/components/google_maps.pom
344
343
  - app/demo/components/headers.pom
345
344
  - app/demo/components/hidden_fields.pom
346
345
  - app/demo/components/icons.pom
@@ -405,10 +404,14 @@ files:
405
404
  - app/demo/patterns/drag_drop.pom
406
405
  - app/demo/patterns/floating_card.pom
407
406
  - app/demo/patterns/search_select.pom
407
+ - app/demo/plugins/cacheable.pom
408
408
  - app/demo/plugins/chart.pom
409
+ - app/demo/plugins/google_maps.pom
409
410
  - app/demo/plugins/image_crop.pom
410
411
  - app/demo/plugins/index.pom
411
412
  - app/demo/plugins/nav/drawer.pom
413
+ - app/demo/plugins/script.pom
414
+ - app/demo/plugins/scroll_to.pom
412
415
  - app/demo/shared/code.pom
413
416
  - app/demo/shared/context_list.pom
414
417
  - app/demo/shared/debug.pom
@@ -558,16 +561,21 @@ files:
558
561
  - lib/coprl/presenters/errors/unprocessable.rb
559
562
  - lib/coprl/presenters/generators/inflectors.rb
560
563
  - lib/coprl/presenters/generators/plugin.rb
564
+ - lib/coprl/presenters/generators/templates/plugin/.github/workflows/semantic-release.yml
561
565
  - lib/coprl/presenters/generators/templates/plugin/.gitignore
566
+ - lib/coprl/presenters/generators/templates/plugin/.releaserc
567
+ - lib/coprl/presenters/generators/templates/plugin/.ruby-version
562
568
  - lib/coprl/presenters/generators/templates/plugin/Gemfile.tt
563
569
  - lib/coprl/presenters/generators/templates/plugin/LICENSE.txt.tt
564
- - lib/coprl/presenters/generators/templates/plugin/README.md
570
+ - lib/coprl/presenters/generators/templates/plugin/README.md.tt
571
+ - lib/coprl/presenters/generators/templates/plugin/demo/plugin.pom.tt
565
572
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/components/actions/action.rb.tt
566
573
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/components/actions/dsl.rb.tt
567
574
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/components/component.rb.tt
568
575
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/components/dsl.rb.tt
569
576
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/helpers/helper.rb.tt
570
577
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/plugin.rb.tt
578
+ - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/version.rb.tt
571
579
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/web_client/components/actions/data.rb.tt
572
580
  - lib/coprl/presenters/generators/templates/plugin/lib/coprl/presenters/plugins/web_client/components/render.rb.tt
573
581
  - lib/coprl/presenters/generators/templates/plugin/presenter_plugin.gemspec.tt
@@ -589,9 +597,6 @@ files:
589
597
  - lib/coprl/presenters/namespace.rb
590
598
  - lib/coprl/presenters/pluggable.rb
591
599
  - lib/coprl/presenters/plugins.rb
592
- - lib/coprl/presenters/plugins/google_maps.rb
593
- - lib/coprl/presenters/plugins/google_maps/google_map.erb
594
- - lib/coprl/presenters/plugins/google_maps/google_map.rb
595
600
  - lib/coprl/presenters/rails/engine.rb
596
601
  - lib/coprl/presenters/rails/railtie.rb
597
602
  - lib/coprl/presenters/registry.rb
@@ -672,6 +677,7 @@ files:
672
677
  - rails-engine/app/views/layouts/coprl.html.erb
673
678
  - rails-engine/config.ru
674
679
  - rails-engine/config/initializers/presenters.rb
680
+ - rails-engine/config/initializers/session.rb
675
681
  - rails-engine/config/routes.rb
676
682
  - scripts/build.sh
677
683
  - views/mdc/.babelrc
@@ -1,22 +0,0 @@
1
- require_relative '../helpers/indented_grid'
2
-
3
- Coprl::Presenters.define(:maps) do
4
- helpers Demo::Helpers::IndentedGrid
5
- attach :top_nav
6
- attach :component_drawer
7
- page_title 'Maps'
8
-
9
- indented_grid do
10
- subheading 'Static Maps'
11
-
12
- address = '125 Park Street, Traverse City, MI'
13
- google_map address: address, height: 300, width: 400 do
14
- event :click do
15
- loads "https://www.google.com/maps/place/#{address}"
16
- end
17
- end
18
-
19
- attach :code, file: __FILE__
20
- end
21
-
22
- end
@@ -1,253 +0,0 @@
1
- # Presenter Plugins
2
-
3
- Presenter plugins allows extension and modification of the DSL and WebClient.
4
- It is powerfully designed for adding additional components to the system, or to change the behavior/look feel/capabilities of existing components.
5
-
6
- ## Global Plugins
7
-
8
- Presenters have global plugins that are configured in the system. They are declared as a setting like so:
9
-
10
- Coprl::Presenters::Settings.configure do |config|
11
- config.presenters.plugins.push(:foo)
12
- end
13
-
14
- A global plugin is available to all presenters.
15
-
16
- ## Local Plugins
17
-
18
- A presenters can define that it uses a plugin like so:
19
-
20
- Coprl::Presenters.define(:index, namespace: :plugins) do
21
- plugin :foo
22
- end
23
-
24
- A local plugin is available only to the presenter that it is defined in.
25
-
26
-
27
- ## Creating Plugins
28
-
29
- The skeleton for a plugin starts with an empty module in a file stored in `coprl/presenters/plugins` somewhere in ruby's load path
30
- (typically in a gemfile or in the lib directory of an framework app, like Rails):
31
-
32
- module Coprl
33
- module Presenters
34
- module Plugins
35
- module Foo
36
- end
37
- end
38
- end
39
- end
40
-
41
- ## Extending the presenter DSL and POM
42
-
43
- ### Components
44
- If you want to add additional components to the presenters DSL, provide a `DSLComponents` module under the plugin module:
45
-
46
- module DSLComponents
47
- def foo(random_fact, **attributes, &block)
48
- self << Foo::Component.new(random_fact, parent: self, **attributes, &block)
49
- end
50
- end
51
-
52
- The above example will extend the dsl by adding the foo method that will add the Foo component to the
53
- presenter object model tree.
54
-
55
- A presenter component derives from `DSL::Components::Base` or if it needs to handle events `DSL::Components::EventBase`
56
-
57
- require 'coprl/presenters/dsl/components/base'
58
-
59
- module Coprl
60
- module Presenters
61
- module Plugins
62
- module Foo
63
- class Component < DSL::Components::Base
64
- def initialize(**attribs_, &block)
65
- super(type: :foo, **attribs_, &block)
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
72
-
73
- ### Helpers
74
-
75
- To add helpers to the POM define the module `DSLHelpers`
76
-
77
- module DSLHelpers
78
- def random_fact
79
- "http://en.wikipedia.org/wiki/Special:Randompage"
80
- end
81
- end
82
-
83
- ### Event Actions
84
- A plugin can extend the set of event actions that are available.
85
- When an event fires in the client, like mouse click, a set of actions are executed. A plugin can provide custom
86
- actions. This examnple adds a actionJs actionJs that can be bound to an event.
87
-
88
- module DSLEventActions
89
- def actionJs(text, **attributes, &block)
90
- self << Foo::Action.new(text: text, parent: self, **attributes, &block)
91
- end
92
- end
93
-
94
- Example actionJs class:
95
-
96
- require 'coprl/presenters/dsl/components/actions/base'
97
-
98
- module Coprl
99
- module Presenters
100
- module Plugins
101
- module Foo
102
- class Action < DSL::Components::Actions::Base
103
- def initialize(**attribs_, &block)
104
- super(type: :actionJs, **attribs_, &block)
105
- end
106
- end
107
- end
108
- end
109
- end
110
- end
111
-
112
-
113
- ## Adding a WebClient implementation
114
-
115
- A plugin that extends the DSL will give you a new custom POM (Presenter Object Model), but that alone won't get you very far.
116
- The POM describes the user interface, a client must implement each of the components.
117
- For the WebClient this means adding a template with HTML, CSS and Javascript.
118
-
119
- ### Component Templates
120
-
121
- To render your component you need to add the following to your plugin:
122
-
123
- module WebClientComponents
124
- def render_foo(comp,
125
- render:,
126
- components:,
127
- index:)
128
- view_dir = File.join(__dir__, 'foo')
129
- render.call :erb, :foo, views: view_dir,
130
- locals: {comp: comp,
131
- components: components, index: index}
132
- end
133
- end
134
-
135
- From you ERB you can call any of the other built in WebClient erb's. You can even replace built in component templates.
136
- The render object supports all the template types supported by Tilt/Sinatra (http://sinatrarb.com/intro.html)
137
-
138
- Example template:
139
-
140
- <iframe id="random_fact" src="<%= comp.random_fact %>" height=512 <%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>></iframe>
141
-
142
-
143
- ### Event Action Data
144
-
145
- An actionJs from the Presenter Object Model (POM) is sent to a ruby method during template expansion.
146
- You are able to then setup any data that you want passed to your actionJs javascript method.
147
- It expects you will return an array with a type that matches your event actionJs presenter type. The rest is up to you.
148
-
149
-
150
- module WebClientActions
151
- def action_data_bar(actionJs, _parent_id, *)
152
- # Type, URL, Options, Params (passed into javascript event/actionJs classes)
153
- [actionJs.type, actionJs.url, actionJs.options.to_h, actionJs.attributes.to_h]
154
- end
155
- end
156
-
157
- Example Javascript method (typically rendered by a template triggered by the render_foo method above):
158
-
159
- <script>
160
- function actionJs(_options, params, _event) {
161
- // Reload iFrame: https://stackoverflow.com/questions/86428/what-s-the-best-way-to-reload-refresh-an-iframe
162
- document.getElementById('random_fact').src += '';
163
- return {actionJs: 'actionJs', content: {data: params.text}, statusCode: 200};
164
- }
165
- </script>
166
-
167
- Event actionJs WebClient methods must return a Javascript Object with the properties `actionJs`, `content` and `statusCode`.
168
-
169
-
170
- ## WebClient Javascript Interface
171
-
172
- When developing a plugin for the WebClient you may want to have your data submitted as part of another component container.
173
- The most familiar example is a Form. This requires that you bind your component to the DOM with a few methods.
174
- Not all plugins need to do this.
175
- It is only needed in the case of those components that add their data to an http post.
176
-
177
- The following components are Containers that will collect data from nested DOM elements using this lifecycle protocol.
178
- cards.js
179
- content.js
180
- dialogs.js
181
- file-inputs.js
182
- forms.js
183
- grid.js
184
- steppers.js
185
-
186
- Lifecycle Protocol:
187
-
188
- We call it it a protocol, because it defines a small number of DOM relationships to participate as an integrated component.
189
- Many frameworks require a common base class, this approach is very light by design.
190
-
191
- Container data in the WebClient is collected and submitted using the following sequence:
192
-
193
- In your element markup include the `v-input` class on an DOM element.
194
-
195
- You can see the container calling code here:
196
- https://github.com/rx/presenters/blob/master/views/mdc/assets/js/components/base-container.js
197
-
198
- If you add the v-plugin class to the DOM element along with a data-plugin-callback dataset that contains a string
199
- with the class name to proxy the plugin events to.
200
-
201
-
202
- Sample callback class:
203
-
204
- // Optional Javascript callback class. You typically need to define this when you have data to submit, or special
205
- // event handling to bind to.
206
- // To hook this up you need to provide the `v-plugin` class and
207
- // data-plugin-callback='RandomFacts' on the element.
208
- class RandomFacts {
209
- // passed the DOM element that has the .v-plugin class on it.
210
- constructor(element) {
211
- }
212
-
213
- // optional.
214
- // Called before the component is submitted via post/put. Allows the component to add its key/value pairs to the
215
- // submitted data.
216
- // If you provide this you need to add the v-input class to your DOM element to get called.
217
- // Containers iterate their elements that have the v-input class defined on them and invoke the prepareSubmit
218
- // function for each.
219
- prepareSubmit(params) {
220
- // params is a key,value pair. Add name/value like so:
221
- // params.push(['some_name', 'some_value']);
222
- }
223
-
224
- // optional.
225
- // Called whenever a container is about to be submitted, before prepareSubmit.
226
- // returns true on success
227
- // returns on failure return an error object that can be processed by VErrors:
228
- // { email: ["email must be filled", "email must be from your domain"] }
229
- // { page: ["must be filled"] }
230
- // Returning an error stops the submission.
231
- validate(formData) {
232
- return true;
233
- }
234
-
235
- // optional.
236
- // Clear's the control
237
- clear() {
238
- }
239
-
240
- // called to add an event listener to the component
241
- // this only needs to be defined if you need the event handler to be bound to the component
242
- // in a different manner. Here is the default implementation you get if you don't define this method:
243
- initEventListener(eventName, eventHandler) {
244
- if (typeof this.eventsHandler === 'undefined') {
245
- this.eventsHandler = {};
246
- }
247
- if (!this.eventsHandler[eventName]) {
248
- // Delegate to the component if possible
249
- this.eventsHandler[eventName] = eventHandler;
250
- this.element.addEventListener(eventName, eventHandler);
251
- }
252
- }
253
- }
@@ -1,24 +0,0 @@
1
- module Coprl
2
- module Presenters
3
- module Plugins
4
- module GoogleMaps
5
- module DSLComponents
6
- def google_map(**attributes, &block)
7
- self << GoogleMap.new(parent: self, **attributes, &block)
8
- end
9
- end
10
- module WebClientComponents
11
- def render_google_map(comp,
12
- render:,
13
- components:,
14
- index:)
15
- view_dir = File.join(__dir__, 'google_maps')
16
- render.call :erb, :google_map, views: view_dir,
17
- locals: {comp: comp,
18
- components: components, index: index}
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,10 +0,0 @@
1
- <% if comp %>
2
- <img id="<%= comp.id %>"
3
- class="v-image v-google-map-image <%= comp.events ? 'v-actionable' : nil%>"
4
- src="<%= comp.url %>"
5
- border="0"
6
- height="<%= comp.height %>"
7
- width="<%= comp.width %>"
8
- alt=""
9
- <%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>>
10
- <% end %>
@@ -1,41 +0,0 @@
1
- require 'uri'
2
-
3
- module Coprl
4
- module Presenters
5
- module Plugins
6
- module GoogleMaps
7
- class GoogleMap < DSL::Components::EventBase
8
-
9
- attr_reader :url, :google_api_key, :height, :width
10
-
11
- def initialize(**attribs_, &block)
12
- super(type: :google_map, **attribs_, &block)
13
- @address = attribs.delete(:address)
14
- @latitude = attribs.delete(:latitude)
15
- @longitude = attribs.delete(:longitude)
16
- @width = attribs.delete(:width) { 640 }
17
- @height = attribs.delete(:height) { 640 }
18
- @zoom = attribs.delete(:zoom) { 14 }
19
- @scale = attribs.delete(:scale) { 1 }
20
- @google_api_key = attribs.delete(:google_api_key) { ENV['GOOGLE_API_KEY'] }
21
- @url = build_static_map_image_url
22
- expand!
23
- end
24
-
25
- private
26
-
27
- def build_static_map_image_url
28
- return @img_url if locked?
29
- @img_url = "https://maps.googleapis.com/maps/api/staticmap?center=#{query_string}&zoom=#{@zoom}&scale=#{@scale}&size=#{@width}x#{@height}&markers=|#{query_string}&key=#{@google_api_key}"
30
- end
31
-
32
- def query_string
33
- return "#{@latitude},#{@longitude}" if @latitude && @longitude
34
- URI.escape(@address)
35
- end
36
-
37
- end
38
- end
39
- end
40
- end
41
- end