pagelet_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +402 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/pagelet_rails_manifest.js +0 -0
  6. data/app/assets/javascripts/pagelet_rails/jquery.ajaxprogress.js +76 -0
  7. data/app/assets/javascripts/pagelet_rails.js +185 -0
  8. data/app/assets/javascripts/views/modal_dialog.jst.ejs +13 -0
  9. data/app/assets/javascripts/views/modal_dialog_iframe.jst.ejs +7 -0
  10. data/app/assets/javascripts/views/pagelet_load_failed.jst.ejs +7 -0
  11. data/app/assets/javascripts/views/pagelet_loading_overlay.jst.ejs +15 -0
  12. data/app/controllers/pagelet_controller.rb +4 -0
  13. data/app/controllers/pagelet_proxy_controller.rb +20 -0
  14. data/app/helpers/pagelets_helper.rb +82 -0
  15. data/app/views/layouts/pagelet_rails/container.html.slim +24 -0
  16. data/app/views/layouts/pagelet_rails/inner.slim +1 -0
  17. data/app/views/layouts/pagelet_rails/loading_placeholder.slim +14 -0
  18. data/config/routes.rb +7 -0
  19. data/lib/action_controller/action_caching.rb +16 -0
  20. data/lib/action_controller/caching/actions.rb +210 -0
  21. data/lib/pagelet_rails/concerns/cache.rb +65 -0
  22. data/lib/pagelet_rails/concerns/controller.rb +73 -0
  23. data/lib/pagelet_rails/concerns/options.rb +76 -0
  24. data/lib/pagelet_rails/concerns/placeholder.rb +35 -0
  25. data/lib/pagelet_rails/concerns/response_wrapper.rb +33 -0
  26. data/lib/pagelet_rails/concerns/routes.rb +83 -0
  27. data/lib/pagelet_rails/encryptor.rb +49 -0
  28. data/lib/pagelet_rails/engine.rb +4 -0
  29. data/lib/pagelet_rails/router.rb +23 -0
  30. data/lib/pagelet_rails/version.rb +3 -0
  31. data/lib/pagelet_rails.rb +28 -0
  32. data/lib/tasks/pagelet_rails_tasks.rake +4 -0
  33. metadata +104 -0
@@ -0,0 +1,185 @@
1
+ //= require_tree ./views
2
+ //= require pagelet_rails/jquery.ajaxprogress
3
+
4
+ (function (w) {
5
+
6
+ var root = w['PageletRails'] || {};
7
+ w['PageletRails'] = root;
8
+
9
+ root.addParamsToUrl = function( url, data ) {
10
+ if ( ! $.isEmptyObject(data) ) {
11
+ url += ( url.indexOf('?') >= 0 ? '&' : '?' ) + $.param(data);
12
+ }
13
+ return url;
14
+ };
15
+
16
+ root.appendScriptTag = function (text) {
17
+ var script = document.createElement( "script" );
18
+ script.type = "text/javascript";
19
+ script.text = text;
20
+ $("body").append(script);
21
+ };
22
+
23
+ root.loadDirectly = function(data) {
24
+ $.ajax({
25
+ url: data.url,
26
+ dataType: 'script',
27
+ headers: {
28
+ 'X-Pagelet': 'pagelet'
29
+ }
30
+ }).done(function(_) {
31
+ }).fail(function(){
32
+ var html = JST['views/pagelet_load_failed']({
33
+ pagelet_url: data.url,
34
+ reload_function: "PageletRails.loadPagelets('#" + data.id + "');"
35
+ });
36
+ data.elem.html(html)
37
+ });
38
+ };
39
+
40
+ root.loadThroughBatchProxy = function(urls) {
41
+ if (urls.length == 0) { return; }
42
+
43
+ var prev_index = 0;
44
+
45
+ $.ajax({
46
+ url: '/pagelet_proxy',
47
+ data: {
48
+ urls: urls
49
+ },
50
+ dataType: 'text',
51
+ cache: false,
52
+ headers: {
53
+ 'X-Pagelet': 'pagelet'
54
+ },
55
+ progress: function(_, progressEvent) {
56
+ var text = progressEvent.target.responseText;
57
+ var end_index = -1;
58
+
59
+ do {
60
+ end_index = text.indexOf("\n\n//\n\n", prev_index);
61
+
62
+ if (end_index != -1) {
63
+ var new_text = text.substring(prev_index, end_index);
64
+
65
+ eval(new_text);
66
+
67
+ prev_index = end_index + 1;
68
+ // console.log('found');
69
+ // console.log(new_text);
70
+ }
71
+
72
+ } while (end_index != -1);
73
+ }
74
+ });
75
+ };
76
+
77
+ root.loadPagelets = function(selector) {
78
+ selector = selector || '[data-widget-url]';
79
+ var groups = {};
80
+
81
+ $(selector).each(function(index, elem) {
82
+ var $el = $(elem);
83
+ var path = $el.data('widget-url');
84
+ var group = $el.data('pagelet-group');
85
+ var id = $el.attr('id');
86
+
87
+ var url = root.addParamsToUrl(path, {
88
+ target_container: id,
89
+ original_pagelet_options: $el.data('pagelet-options')
90
+ });
91
+
92
+ groups[group] = groups[group] || [];
93
+ groups[group].push({
94
+ id: id,
95
+ elem: $el,
96
+ url: url,
97
+ group: group
98
+ });
99
+ });
100
+
101
+ for (var group_name in groups) {
102
+ if (groups.hasOwnProperty(group_name)) {
103
+ var group = groups[group_name];
104
+
105
+ if (group.length == 1) {
106
+ root.loadDirectly(group[0]);
107
+ } else {
108
+ var urls = group.map(function(e) { return e.url; });
109
+ root.loadThroughBatchProxy(urls);
110
+ }
111
+ }
112
+ }
113
+ };
114
+
115
+ root.pageletArrived = function(id, content) {
116
+ root.placeToContainer(id, content);
117
+ root.processDataRemoteTags();
118
+ $(document).trigger('pagelet-loaded');
119
+ };
120
+
121
+ root.placeToContainer = function(id, content) {
122
+ $('#' + id).html(content);
123
+ };
124
+
125
+ root.processDataRemoteTags = function() {
126
+ $('form[data-remote]').each(function(index, elem){
127
+ var $el = $(elem);
128
+ var container = $el.closest('[data-pagelet-container]');
129
+
130
+ if (!container) {
131
+ return;
132
+ }
133
+
134
+ var hidden_field = $el.find('input[name=target_container]')[0];
135
+ if (!hidden_field) {
136
+ $("<input/>", {
137
+ name: "target_container",
138
+ type: "hidden",
139
+ value: container.attr('id')
140
+ }).appendTo($el);
141
+ }
142
+
143
+ hidden_field = $el.find('input[name=original_pagelet_options]')[0];
144
+ if (!hidden_field) {
145
+ $("<input/>", {
146
+ name: "original_pagelet_options",
147
+ type: "hidden",
148
+ value: container.data('pagelet-options')
149
+ }).appendTo($el);
150
+ }
151
+ });
152
+
153
+ var selector = 'a[data-remote]:not([disabled]),button[data-remote]:not([disabled])';
154
+ $(selector).each(function(index, elem){
155
+ var $el = $(elem);
156
+ var container = $el.closest('[data-pagelet-container]');
157
+
158
+ if (!container) {
159
+ return;
160
+ }
161
+
162
+ var params = $el.data('params');
163
+ if (!params) {
164
+ var value = $.param({
165
+ target_container: container.attr('id'),
166
+ original_pagelet_options: container.data('pagelet-options')
167
+ });
168
+ $el.data('params', value);
169
+ }
170
+ });
171
+ };
172
+
173
+ function initialise() {
174
+ document.addEventListener("turbolinks:load", function(){
175
+ root.loadPagelets();
176
+ root.processDataRemoteTags();
177
+ });
178
+ }
179
+
180
+ initialise();
181
+ })(window);
182
+
183
+
184
+
185
+
@@ -0,0 +1,13 @@
1
+ <div class="modal-dialog">
2
+ <div class="modal-content">
3
+ <div class="modal-body">
4
+ <% if (state == 'loading') { %>
5
+ <p>Loading...</p>
6
+ <% } %>
7
+
8
+ <% if (state == 'error') { %>
9
+ <p>This page could not be loaded. Please try again later.</p>
10
+ <% } %>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -0,0 +1,7 @@
1
+ <div class="modal-dialog modal-lg">
2
+ <div class="modal-content">
3
+ <div class="modal-body">
4
+ <iframe src="<%= src %>" style="zoom:0.60" width="99.6%" height="0" frameborder="0"></iframe>
5
+ </div>
6
+ </div>
7
+ </div>
@@ -0,0 +1,7 @@
1
+ Error occurred during loading
2
+ <div class="debug">
3
+
4
+ <a href="<%= pagelet_url %>" target="_blank">Open in new tab</a>
5
+
6
+ <a href="javascript:<%= reload_function %>"> Reload </a>
7
+ </div>
@@ -0,0 +1,15 @@
1
+ <div class="pagelet-loading-overlay fade">
2
+ <div style="display: table; overflow: hidden; width: 100%; height:auto;">
3
+ <div style="display: table-cell; vertical-align: middle;">
4
+ <div class="pagelet-loading-overlay__content">
5
+ <span class="spinner spinner-three-bounce">
6
+ <div class="bounce1"></div>
7
+ <div class="bounce2"></div>
8
+ <div class="bounce3"></div>
9
+ </span>
10
+ <br>
11
+ <span>Loading...</span>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
@@ -0,0 +1,4 @@
1
+ class PageletController < ::ApplicationController
2
+ include PageletRails::Concerns::Controller
3
+
4
+ end
@@ -0,0 +1,20 @@
1
+ class PageletProxyController < ::ApplicationController
2
+ include ActionController::Live
3
+ include PageletsHelper
4
+
5
+ def show
6
+ @urls = params[:urls]
7
+
8
+ response.headers['Content-Type'] = 'text/javascript'
9
+
10
+ response.stream.write "\n"
11
+
12
+ @urls.each do |url|
13
+ response.stream.write pagelet(url)
14
+ response.stream.write "\n\n//\n\n"
15
+ end
16
+ ensure
17
+ response.stream.close
18
+ end
19
+
20
+ end
@@ -0,0 +1,82 @@
1
+ module PageletsHelper
2
+
3
+ def pagelet_stream
4
+ return nil if pagelet_stream_objects.empty?
5
+ pagelet_stream_objects.each do |key, block|
6
+ concat content_tag('script', raw("PageletRails.pageletArrived('#{key}', '#{j capture(&block)}');\n"), type: 'text/javascript')
7
+ end
8
+ nil
9
+ end
10
+
11
+ def pagelet_default_id
12
+ "pagelet_#{rand(2**60).to_s(36)}"
13
+ end
14
+
15
+ def add_pagelet_stream key, &block
16
+ objects = pagelet_stream_objects
17
+ raise "duplicate key: #{key}" if objects.has_key?(key)
18
+ objects[key] = block
19
+ request.instance_variable_set(:@pagelet_stream_objects, objects)
20
+ end
21
+
22
+ def pagelet_stream_objects
23
+ request.instance_variable_get(:@pagelet_stream_objects) || {}
24
+ end
25
+
26
+ def pagelet path, p_options = {}
27
+ puts "Rendering pagelet #{path}".blue
28
+
29
+ p_params = p_options.delete(:params) { {} }.with_indifferent_access
30
+
31
+ if path.is_a? Symbol
32
+ path = self.send("#{path}_path", p_params)
33
+ else
34
+ uri = URI(path)
35
+ p_params.merge! Rack::Utils.parse_nested_query(uri.query)
36
+ p_options.merge! remote: false
37
+ end
38
+
39
+ path_opts = Rails.application.routes.recognize_path(path)
40
+ p_params.reverse_merge!(path_opts)
41
+
42
+ controller_class = path_opts[:controller].camelize.concat('Controller').constantize
43
+ action = path_opts[:action]
44
+
45
+
46
+ if p_options[:remote] == :stream
47
+ html_id = p_options.dig(:html, :id) || pagelet_default_id
48
+ p_options.deep_merge! html: { id: html_id }
49
+
50
+ add_pagelet_stream html_id, &Proc.new {
51
+ pagelet path, p_options.merge(remote: false, skip_container: true)
52
+ }
53
+ end
54
+
55
+ p_options.deep_merge! parent_params: params.to_h
56
+
57
+ c = controller_class.new
58
+ c.pagelet_options p_options
59
+ c.pagelet_options original_options: p_options
60
+
61
+ env = Rack::MockRequest.env_for(path,
62
+ 'REMOTE_ADDR' => request.env['REMOTE_ADDR'],
63
+ 'HTTP_HOST' => request.env['HTTP_HOST'],
64
+ 'HTTP_TURBOLINKS_REFERRER' => request.env['HTTP_TURBOLINKS_REFERRER'],
65
+ 'HTTP_USER_AGENT' => request.env['HTTP_USER_AGENT'],
66
+ 'HTTP_X_CSRF_TOKEN' => request.env['HTTP_X_CSRF_TOKEN'],
67
+ 'HTTP_X_PAGELET' => request.env['HTTP_X_PAGELET'],
68
+ 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest",
69
+ )
70
+
71
+ p_request = ActionDispatch::Request.new(env)
72
+ p_request.parameters.clear
73
+ p_request.parameters.merge! p_params
74
+
75
+ p_response = controller_class.make_response! p_request
76
+ c.dispatch(action, p_request, p_response)
77
+
78
+ body = c.response.body
79
+ body.html_safe
80
+ end
81
+
82
+ end
@@ -0,0 +1,24 @@
1
+ - if pagelet_request? || pagelet_options.skip_container
2
+ = content_for?(:content) ? yield(:content) : yield
3
+
4
+ - else
5
+ ruby:
6
+ html_opts = pagelet_options.html || {}
7
+ classes = html_opts.fetch(:class, '').split(' ')
8
+ classes << "pagelet-#{controller_name}"
9
+ classes << "pagelet-#{controller_name}-#{action_name}"
10
+
11
+ html_opts[:id] ||= pagelet_default_id
12
+ html_opts[:class] = classes.join(' ')
13
+
14
+ html_opts['data-pagelet-container'] = true
15
+
16
+ encode_data = pagelet_options.original_options.to_h.except('remote')
17
+ html_opts['data-pagelet-options'] = PageletRails::Encryptor.encode(encode_data)
18
+
19
+ if pagelet_options.ajax_group
20
+ html_opts['data-pagelet-group'] = pagelet_options.ajax_group
21
+ end
22
+
23
+ div *html_opts
24
+ = content_for?(:content) ? yield(:content) : yield
@@ -0,0 +1 @@
1
+ = content_for?(:content) ? yield(:content) : yield
@@ -0,0 +1,14 @@
1
+ ruby:
2
+ height = pagelet_options.placeholder.try(:[], :height)
3
+ text = pagelet_options.placeholder.try(:[], :text) || 'Loading ...'
4
+ height = height.is_a?(Numeric) ? "#{height}px" : 'auto'
5
+
6
+ div style="display: table; height: #{height}; overflow: hidden; width: 100%;"
7
+ div style="display: table-cell; vertical-align: middle;"
8
+ div.text-center
9
+ span.spinner.spinner-three-bounce
10
+ .bounce1
11
+ .bounce2
12
+ .bounce3
13
+ br
14
+ span = text
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ Rails.application.routes.draw do
2
+
3
+ PageletRails::Router.load_routes!(self)
4
+
5
+ get 'pagelet_proxy' => 'pagelet_proxy#show'
6
+
7
+ end
@@ -0,0 +1,16 @@
1
+ # Cloned from https://github.com/rails/actionpack-action_caching
2
+ # as it does not support rails 5 yet
3
+
4
+ require 'action_controller/caching/actions'
5
+
6
+ module ActionController
7
+ module Caching
8
+ eager_autoload do
9
+ autoload :Actions
10
+ end
11
+
12
+ include Actions
13
+ end
14
+ end
15
+
16
+ ActionController::Base.send(:include, ActionController::Caching::Actions)
@@ -0,0 +1,210 @@
1
+ require 'set'
2
+
3
+ module ActionController
4
+ module Caching
5
+ # Action caching is similar to page caching by the fact that the entire
6
+ # output of the response is cached, but unlike page caching, every
7
+ # request still goes through Action Pack. The key benefit of this is
8
+ # that filters run before the cache is served, which allows for
9
+ # authentication and other restrictions on whether someone is allowed
10
+ # to execute such action.
11
+ #
12
+ # class ListsController < ApplicationController
13
+ # before_filter :authenticate, except: :public
14
+ #
15
+ # caches_page :public
16
+ # caches_action :index, :show
17
+ # end
18
+ #
19
+ # In this example, the +public+ action doesn't require authentication
20
+ # so it's possible to use the faster page caching. On the other hand
21
+ # +index+ and +show+ require authentication. They can still be cached,
22
+ # but we need action caching for them.
23
+ #
24
+ # Action caching uses fragment caching internally and an around
25
+ # filter to do the job. The fragment cache is named according to
26
+ # the host and path of the request. A page that is accessed at
27
+ # <tt>http://david.example.com/lists/show/1</tt> will result in a fragment named
28
+ # <tt>david.example.com/lists/show/1</tt>. This allows the cacher to
29
+ # differentiate between <tt>david.example.com/lists/</tt> and
30
+ # <tt>jamis.example.com/lists/</tt> -- which is a helpful way of assisting
31
+ # the subdomain-as-account-key pattern.
32
+ #
33
+ # Different representations of the same resource, e.g.
34
+ # <tt>http://david.example.com/lists</tt> and
35
+ # <tt>http://david.example.com/lists.xml</tt>
36
+ # are treated like separate requests and so are cached separately.
37
+ # Keep in mind when expiring an action cache that
38
+ # <tt>action: 'lists'</tt> is not the same as
39
+ # <tt>action: 'lists', format: :xml</tt>.
40
+ #
41
+ # You can modify the default action cache path by passing a
42
+ # <tt>:cache_path</tt> option. This will be passed directly to
43
+ # <tt>ActionCachePath.new</tt>. This is handy for actions with
44
+ # multiple possible routes that should be cached differently. If a
45
+ # block is given, it is called with the current controller instance.
46
+ # If an object that responds to <tt>call</tt> is given, it'll be called
47
+ # with the current controller instance.
48
+ #
49
+ # And you can also use <tt>:if</tt> (or <tt>:unless</tt>) to pass a
50
+ # proc that specifies when the action should be cached.
51
+ #
52
+ # As of Rails 3.0, you can also pass <tt>:expires_in</tt> with a time
53
+ # interval (in seconds) to schedule expiration of the cached item.
54
+ #
55
+ # The following example depicts some of the points made above:
56
+ #
57
+ # class CachePathCreator
58
+ # def initialize(name)
59
+ # @name = name
60
+ # end
61
+ #
62
+ # def call(controller)
63
+ # "cache-path-#{@name}"
64
+ # end
65
+ # end
66
+ #
67
+ #
68
+ # class ListsController < ApplicationController
69
+ # before_filter :authenticate, except: :public
70
+ #
71
+ # caches_page :public
72
+ #
73
+ # caches_action :index, if: Proc.new do
74
+ # !request.format.json? # cache if is not a JSON request
75
+ # end
76
+ #
77
+ # caches_action :show, cache_path: { project: 1 },
78
+ # expires_in: 1.hour
79
+ #
80
+ # caches_action :feed, cache_path: Proc.new do
81
+ # if params[:user_id]
82
+ # user_list_url(params[:user_id, params[:id])
83
+ # else
84
+ # list_url(params[:id])
85
+ # end
86
+ # end
87
+ #
88
+ # caches_action :posts, cache_path: CachePathCreator.new('posts')
89
+ # end
90
+ #
91
+ # If you pass <tt>layout: false</tt>, it will only cache your action
92
+ # content. That's useful when your layout has dynamic information.
93
+ #
94
+ # Warning: If the format of the request is determined by the Accept HTTP
95
+ # header the Content-Type of the cached response could be wrong because
96
+ # no information about the MIME type is stored in the cache key. So, if
97
+ # you first ask for MIME type M in the Accept header, a cache entry is
98
+ # created, and then perform a second request to the same resource asking
99
+ # for a different MIME type, you'd get the content cached for M.
100
+ #
101
+ # The <tt>:format</tt> parameter is taken into account though. The safest
102
+ # way to cache by MIME type is to pass the format in the route.
103
+ module Actions
104
+ extend ActiveSupport::Concern
105
+
106
+ module ClassMethods
107
+ # Declares that +actions+ should be cached.
108
+ # See ActionController::Caching::Actions for details.
109
+ def caches_action(*actions)
110
+ return unless cache_configured?
111
+ options = actions.extract_options!
112
+ options[:layout] = true unless options.key?(:layout)
113
+ filter_options = options.extract!(:if, :unless).merge(only: actions)
114
+ cache_options = options.extract!(:layout, :cache_path).merge(store_options: options)
115
+
116
+ around_filter ActionCacheFilter.new(cache_options), filter_options
117
+ end
118
+ end
119
+
120
+ def _save_fragment(name, options)
121
+ content = ''
122
+ response_body.each do |parts|
123
+ content << parts
124
+ end
125
+
126
+ if caching_allowed?
127
+ write_fragment(name, content, options)
128
+ else
129
+ content
130
+ end
131
+ end
132
+
133
+ def caching_allowed?
134
+ (request.get? || request.head?) && response.status == 200
135
+ end
136
+
137
+ protected
138
+ def expire_action(options = {})
139
+ return unless cache_configured?
140
+
141
+ if options.is_a?(Hash) && options[:action].is_a?(Array)
142
+ options[:action].each { |action| expire_action(options.merge(action: action)) }
143
+ else
144
+ expire_fragment(ActionCachePath.new(self, options, false).path)
145
+ end
146
+ end
147
+
148
+ class ActionCacheFilter # :nodoc:
149
+ def initialize(options, &block)
150
+ @cache_path, @store_options, @cache_layout =
151
+ options.values_at(:cache_path, :store_options, :layout)
152
+ end
153
+
154
+ def around(controller)
155
+ cache_layout = @cache_layout.respond_to?(:call) ? @cache_layout.call(controller) : @cache_layout
156
+
157
+ path_options = if @cache_path.is_a?(Proc)
158
+ controller.instance_exec(controller, &@cache_path)
159
+ elsif @cache_path.respond_to?(:call)
160
+ @cache_path.call(controller)
161
+ else
162
+ @cache_path
163
+ end
164
+
165
+ cache_path = ActionCachePath.new(controller, path_options || {})
166
+
167
+ body = controller.read_fragment(cache_path.path, @store_options)
168
+
169
+ unless body
170
+ controller.action_has_layout = false unless cache_layout
171
+ yield
172
+ controller.action_has_layout = true
173
+ body = controller._save_fragment(cache_path.path, @store_options)
174
+ end
175
+
176
+ body = controller.render_to_string(body: body, layout: true) unless cache_layout
177
+
178
+ controller.response_body = body
179
+ controller.content_type = Mime[cache_path.extension || :html]
180
+ end
181
+ end
182
+
183
+ class ActionCachePath
184
+ attr_reader :path, :extension
185
+
186
+ # If +infer_extension+ is +true+, the cache path extension is looked up from the request's
187
+ # path and format. This is desirable when reading and writing the cache, but not when
188
+ # expiring the cache - +expire_action+ should expire the same files regardless of the
189
+ # request format.
190
+ def initialize(controller, options = {}, infer_extension = true)
191
+ if infer_extension
192
+ @extension = controller.params[:format]
193
+ options.reverse_merge!(format: @extension) if options.is_a?(Hash)
194
+ end
195
+
196
+ path = controller.url_for(options).split('://', 2).last
197
+ @path = normalize!(path)
198
+ end
199
+
200
+ private
201
+ def normalize!(path)
202
+ ext = URI.parser.escape(extension) if extension
203
+ path << 'index' if path[-1] == ?/
204
+ path << ".#{ext}" if extension and !path.split('?', 2).first.ends_with?(".#{ext}")
205
+ URI.parser.unescape(path)
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,65 @@
1
+ module PageletRails::Concerns::Cache
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include ActionController::Caching::Actions
6
+
7
+ pagelet_options cache_defaults: {
8
+ expires_in: 5.seconds,
9
+ cache_path: {}
10
+ }
11
+
12
+ around_action :pagelet_cache
13
+ end
14
+
15
+ def pagelet_cache &block
16
+ # puts 'pagelet_cache'.blue
17
+ cache_enabled = pagelet_options.cache || pagelet_options.cache_path || pagelet_options.expires_in
18
+
19
+ if !cache_enabled
20
+ return yield
21
+ end
22
+
23
+ cache_defaults = (pagelet_options.cache_defaults || {}).to_h.symbolize_keys
24
+ store_options = cache_defaults.except(:cache_path)
25
+ store_options[:expires_in] = pagelet_options.expires_in if pagelet_options.expires_in
26
+
27
+ cache_path = pagelet_options.cache_path || cache_defaults[:cache_path]
28
+
29
+ cache_path = if cache_path.is_a?(Proc)
30
+ self.instance_exec(self, &cache_path)
31
+ elsif cache_path.respond_to?(:call)
32
+ cache_path.call(self)
33
+ elsif cache_path.is_a?(String)
34
+ {
35
+ custom: cache_path
36
+ }
37
+ else
38
+ cache_path
39
+ end
40
+ cache_path ||= {}
41
+ cache_path[:controller] = params[:controller]
42
+ cache_path[:action] = params[:action]
43
+
44
+ path_object = ActionController::Caching::Actions::ActionCachePath.new(self, cache_path)
45
+ has_cache = fragment_exist?(path_object.path, store_options)
46
+ pagelet_options has_cache: has_cache
47
+
48
+
49
+ if (pagelet_render_remotely? && has_cache) || !pagelet_render_remotely?
50
+ cache_options = {
51
+ layout: false,
52
+ store_options: store_options,
53
+ cache_path: cache_path
54
+ }
55
+
56
+ filter = ActionController::Caching::Actions::ActionCacheFilter.new(cache_options)
57
+
58
+ filter.around(self, &block)
59
+
60
+ else
61
+ yield
62
+ end
63
+ end
64
+
65
+ end