├── Rakefile
├── Gemfile
├── lib
├── ljax_rails
│ ├── action_dispatch_monkey.rb
│ ├── action_controller_monkey.rb
│ └── action_view_monkey.rb
└── ljax_rails.rb
├── .gitignore
├── app
└── assets
│ └── javascripts
│ └── ljax_rails.js.coffee
├── ljax_rails.gemspec
├── README.md
└── MIT_LICENSE
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/gem_tasks"
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Specify your gem's dependencies in ljax_rails.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/lib/ljax_rails/action_dispatch_monkey.rb:
--------------------------------------------------------------------------------
1 | ActionDispatch::Request.class_eval do
2 | def ljax?
3 | xhr? && headers['X-LJAX']
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | .bundle
4 | .config
5 | .yardoc
6 | Gemfile.lock
7 | InstalledFiles
8 | _yardoc
9 | coverage
10 | doc/
11 | lib/bundler/man
12 | pkg
13 | rdoc
14 | spec/reports
15 | test/tmp
16 | test/version_tmp
17 | tmp
18 | log
19 |
--------------------------------------------------------------------------------
/lib/ljax_rails/action_controller_monkey.rb:
--------------------------------------------------------------------------------
1 | module LjaxRails::LjaxActionProcessor
2 | def default_render(*)
3 | if request.ljax?
4 | partial = LjaxRails.encryptor.decrypt_and_verify request.headers['X-LJAX-Partial']
5 | render partial: partial
6 | else
7 | super
8 | end
9 | end
10 | end
11 |
12 | ActionController::Base.send :prepend, LjaxRails::LjaxActionProcessor
13 |
--------------------------------------------------------------------------------
/app/assets/javascripts/ljax_rails.js.coffee:
--------------------------------------------------------------------------------
1 | $ ->
2 | $('.ljax-container').each (index, container) =>
3 | $.ajax
4 | type: 'GET'
5 | dataType: 'html'
6 | url: $(container).data('remote-url')
7 | cache: false
8 | headers: {'X-LJAX': 'true', 'X-LJAX-Container': container.id, 'X-LJAX-Partial': $(container).data('ljax-partial')}
9 | success: (data) ->
10 | $(container).replaceWith(data).trigger('ljax:success')
11 | error: ->
12 | $(container).trigger('ljax:error')
13 | complete: ->
14 | $(container).trigger('ljax:complete')
15 |
--------------------------------------------------------------------------------
/lib/ljax_rails/action_view_monkey.rb:
--------------------------------------------------------------------------------
1 | require 'securerandom'
2 |
3 | module LjaxRails
4 | module LjaxRenderer
5 | def render_partial(context, options, &block)
6 | if options[:locals] && options[:locals].delete(:remote)
7 | partial = options.delete :partial
8 | encrypted_partial = LjaxRails.encryptor.encrypt_and_sign partial
9 |
10 | url = options[:locals].delete :remote_url
11 | id = "ljax-#{SecureRandom.uuid}"
12 | loading = block.call if block
13 |
14 | %Q!
#{loading}
!.html_safe
15 | else
16 | super
17 | end
18 | end
19 | end
20 | end
21 |
22 | ActionView::Renderer.send :prepend, LjaxRails::LjaxRenderer
23 |
--------------------------------------------------------------------------------
/lib/ljax_rails.rb:
--------------------------------------------------------------------------------
1 | module LjaxRails
2 | VERSION = Gem.loaded_specs['ljax_rails'].version.to_s
3 |
4 | class Engine < ::Rails::Engine
5 | initializer 'ljax_rails.add_controller' do
6 | ActiveSupport.on_load :action_controller do
7 | require_relative 'ljax_rails/action_dispatch_monkey'
8 | require_relative 'ljax_rails/action_view_monkey'
9 | require_relative 'ljax_rails/action_controller_monkey'
10 | end
11 | end
12 | end
13 |
14 | def self.encryptor
15 | @encryptor ||= begin
16 | key = if Rails.application.config.respond_to? :secret_key_base
17 | Rails.application.config.secret_key_base || Rails.application.config.secret_token
18 | else
19 | Rails.application.config.secret_token
20 | end
21 | ActiveSupport::MessageEncryptor.new key
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/ljax_rails.gemspec:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | lib = File.expand_path('../lib', __FILE__)
3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4 |
5 | Gem::Specification.new do |spec|
6 | spec.name = "ljax_rails"
7 | spec.version = '0.0.1'
8 | spec.authors = ["Akira Matsuda"]
9 | spec.email = ["ronnie@dio.jp"]
10 | spec.description = '"LJAX" (= Lazy load Ajax) on Rails'
11 | spec.summary = '"LJAX" (= Lazy load Ajax) on Rails'
12 | spec.homepage = 'https://github.com/amatsuda/ljax_rails'
13 | spec.license = "MIT"
14 |
15 | spec.files = `git ls-files`.split($/)
16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18 | spec.require_paths = ["lib"]
19 |
20 | spec.add_development_dependency "rake"
21 | end
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LJAX
2 |
3 | Lazy-load AJAX on Rails
4 |
5 | ## Installation
6 |
7 | Bundle `ljax_rails` gem:
8 |
9 | gem 'ljax_rails'
10 |
11 | Then add this to your app/assets/javascripts/application.js (or whatever bundle you use):
12 |
13 | //=require ljax_rails
14 |
15 | ## Usage
16 |
17 | ### Views
18 |
19 | Add `remote: true` option to your `render :partial` call, then the partial will be lazily rendered in a separate HTTP request.
20 |
21 | ```erb
22 | <%= render 'users', remote: true %>
23 | ```
24 |
25 | Also, you can give `remote_url` option for specifying request target URL.
26 |
27 | ```erb
28 | <%= render 'sidebar', remote: true, remote_url: '/shared/sidebar' %>
29 | ```
30 |
31 | ### Controllers
32 |
33 | `request.ljax?` tells you whether the request was sent via LJAX or not.
34 |
35 | ```ruby
36 | def index
37 | if request.ljax?
38 | @users = User.all
39 | end
40 | end
41 | ```
42 |
43 | ## TODO
44 |
45 | * JS error handling
46 | * JS event hook
47 | * spinner?
48 | * tests
49 | * documentation
50 | * tutorial
51 |
52 | ## Contributing
53 |
54 | Send me your PRs!
55 |
--------------------------------------------------------------------------------
/MIT_LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Akira Matsuda
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------