No release in over a year
Ruby on Rails helpers for capturing view content into bundles.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 6.1.4, >= 6.1.4.1
 Project Readme

ContentPackRails

Gem Version Tests

A thin wrapper around ActionView::Helpers::CaptureHelper#content_for. Useful when you need to collect multiple content entries during page rendering, for example <script type="text/template"> templates, without woring about possible duplications and name clashes.

Installation

Add this line to your application's Gemfile:

gem 'content_pack_rails'

And then execute:

$ bundle install

Usage

Include ContentPackRails into your ApplicationHelper:

module ApplicationHelper
    include ContentPackRails
end

By default, this will add three view helpers content_pack, provide_content_pack and content_pack_get. To avoid collisions with a helper of the same name you might already have in your app, provide a different name:

module ApplicationHelper
    # This will add custom_named_pack and provide_custom_named_pack helpers respectively.
    include ContentPackRails.init(pack_name: 'custom_named_pack')
end

Helper content_pack declares the same parameters as the standard rails content_for and can be used similarly to capture content like this:

<% content_pack 'content-id' do |id| %>
   <!--
     Your content goes here.
     Additionally, the content name is passed as the first parameter.
     So you may use it further, for example, to set it as the id attribute for an element.
       <div id=<%= id %>></div>
   -->
<% end %>

or pass content as the second argument:

<% content_pack 'content-id', 'Your content' %>

Unlike content_for, by default, content_pack will not concatenate content with the same name. Multiple calls to content_pack with the same content name will result in only the first content being added to the pack. If you would like to add additional content on a given name, you should pass the append: true option like so:

<% content_pack 'content-id', 'first content' %>
<!-- following will be concatenated with the first one -->
<% content_pack 'content-id', 'second content', append: true %>

In case you want to override content on a given name, provide the flush: true option:

<% content_pack 'content-id', 'first content' %>
<!-- following will override the first one -->
<% content_pack 'content-id', 'second content', flush: true %>

Every content passed to the content_pack is aggregated into one "pack," which you can access through the correspondent provide_content_pack helper. So later on, you can render the whole pack somewhere in your view, like this:

<%= provide_content_pack %>

To access a single content entry from the pack, use content_pack_get:

<%= content_pack_get('content-id') %>

Should you want to have multiple packs, for example, to group content, you can set up those by including this module as many times as needed with different names:

module ApplicationHelper
    include ContentPackRails.init(pack_name: 'content_pack2')
    include ContentPackRails.init(pack_name: 'content_pack3')
    # etc.
end

Common use-case example

You may have javascript components that render HTML using templates in the form of <script type="text/template">. Those templates are usually included as a part of rendered HTML, and if you have enough of them, it is hard to track what has already been included.

Given that the same component may be a part of other components templates and so on, you may end up with multiple copies of the same template included in the final response. ContentPackRails helpers tandem allow you to organize JS templates provisioning in a way somewhat similar to how it is done with javascript files.

For example, you can keep such templates as regular rails view partials in separate files somewhere under app/views directory:

# ...
app/views/comments/_collection_template.html.erb
app/views/comments/_item_template.html.erb
# ...

Both those templates can be exported using content_pack helper like this:

<!-- app/views/comments/_item_template.html.erb -->
<%= content_pack 'comments-item-template' do |id| %>
   <script type="text/template" id=<%= id %>>
      // item component template goes here
   </script>
<% end %>
<!-- app/views/comments/_collection_template.html.erb -->

<% render 'item_template' %>

<%= content_pack 'comments-collection-template' do |id| %>
   <script type="text/template" id=<%= id %>>
      // somewhere here you will likely loop through comments using <comments-item-component> with some properties
   </script>
<% end %>

Note that in app/views/comments/_collection_template.html.erb we called render for item_template because the collection template depends on it. Calling render here may be thought of as import for the template, which in its turn tirgers content_pack (aka export) to include the template into a bundle. Each template contains all the imports it depends on, so you can just grab any template and be sure its dependencies also end up in a final pack, like in the following example.

<!-- app/views/comments/index.html.erb -->

<% render 'collection_template' %> <!-- this will include collection and item templates -->

<!-- rest of the index.html -->

Resulting bundle of templates we can include in our app/views/layouts/application.html.rb like so:

<html>
  <head></head>
  <body>
    <%= yield %>
  </body>
  <%= provide_content_pack %>
</html>

License

The gem is available as open source under the terms of the MIT License.