Skip to content

philcowans/action_embedding

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ActionEmbedding

An experimental Rails plugin to investigate ways to embed pagelets into standard ActionView templates. The term pagelet is taken from Facebook’s description of their BigPipe infrastructure [1].

WARNING: I’ve never actually used this in a production project, so it may be horribly broken in ways I haven’t figured out yet. If you can provide any evidence it actually works then let me know.

This was built against Rails 2.2.x - 2.3.x is in theory supported but uses a different entry point into ActionController::Base. No idea whether it’s at all usable against any of the 3.0.0 betas.

What does it do?

This is a bit of an experiment to look at different ways of composing larger pages from distinct ‘pagelets’ (or modules, or components, or cells). The key design principles are:

  • Pagelets share little or no state with each other or with the containing page. This makes them easier to reconfigure, if necessary using a language other than Ruby, and encourages good programming.

  • Pagelets have externally meaningful URLs. Again, this makes it possible to refer to them outside of a Rails application.

  • Switching between embedding methods should be a configuration rather than coding change.

Installation

Install the plugin, then include the helper module in your app:

module ApplicationHelper
  include ActionEmbedding::Helpers
end

Embed pagelets into your views using something like

<%=embed_pagelet('/pagelets/two', :method => :inline, :send_xhr_header => true) %>

Where /pagelets/two is a valid route to the content being embedded (i.e. you can access this path externally). The send_xhr_header option causes the embedded pagelet’s request to include an X-Requested-With: XMLHttpRequest header, which can be used to make it behave consistently with AJAX loaded content (e.g. by returning a fragment rather than a full HTML document).

How can pagelets be embedded?

There are currently four values for the method option:

  • :inline - the pagelet is rendered in the containing Rails process, halting execution of the containing page while it happens. This is the defaul method.

  • :proxy - the pagelet request is proxid to a separate backend HTTP server. Use :proxy_host to specify the hostname, and the optional :proxy_prefix to specify a prefix to apply to the path before sending to the backend.

  • :esi - include an <esi:include... > pseudo-tag at the insertion point so that substitution can be performed in a caching layer supporting Edge Side Includes (e.g. Varnish web accelerator, Akamai edge caching).

  • :xhr - include a div with class xhr-replace and an additional xhr-href parameter. Substitution of the correct content can be performed on page load with a small piece of JavaScript, e.g. using jQuery:

    <script> 
      $(document).ready(function() {
        $('.xhr-replace').each(function(idx) {
          $(this).load($(this).attr('xhr-href'));
        });
      });
    </script>

In theory the following are possible, but not yet implemented:

  • Multiple pagelets rendered in parallel, blocking at each insertion point until the relevant render job has completed. (Not sure how easy this will be in Rails.)

  • BigPipe style parallel rendering. (See [1]. Again, Rails may be a constraint here both through limits in its ability to handle multiple threads and the difficulty of flushing the output stream before the request has completed.)

1

www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919

About

(For now) experimental Rails plugin for embedding pagelets.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages