Module: PublicActivity::Renderable

Included in:
ORM::ActiveRecord::Activity, ORM::MongoMapper::Activity, ORM::Mongoid::Activity
Defined in:
lib/public_activity/renderable.rb

Overview

Provides logic for rendering activities. Handles both i18n strings support and smart partials rendering (different templates per activity key).

Instance Method Summary collapse

Instance Method Details

#layout_path(path = nil, root = nil) ⇒ Object


151
152
153
154
155
# File 'lib/public_activity/renderable.rb', line 151

def layout_path(path = nil, root = nil)
  path.nil? and return
  root ||= 'layouts'
  select_path path, root
end

#partial_path(path = nil, root = nil) ⇒ Object


145
146
147
148
149
# File 'lib/public_activity/renderable.rb', line 145

def partial_path(path = nil, root = nil)
  root ||= 'public_activity'
  path ||= self.key.to_s.gsub('.', '/')
  select_path path, root
end

#prepare_locals(params) ⇒ Object


157
158
159
160
161
162
163
164
165
166
167
# File 'lib/public_activity/renderable.rb', line 157

def prepare_locals(params)
  locals = params.delete(:locals) || Hash.new

  controller          = PublicActivity.get_controller
  prepared_parameters = prepare_parameters(params)
  locals.merge\
    activity:     self,
    controller:   controller,
    current_user: controller.respond_to?(:current_user) ? controller.current_user : nil,
    parameters:   prepared_parameters
end

#prepare_parameters(params) ⇒ Object


169
170
171
# File 'lib/public_activity/renderable.rb', line 169

def prepare_parameters(params)
  @prepared_params ||= self.parameters.with_indifferent_access.merge(params)
end

#render(context, params = {}) ⇒ nil

Renders activity from views.

Renders activity to the given ActionView context with included AV::Helpers::RenderingHelper (most commonly just ActionView::Base)

The preferred way of rendering activities is to provide a template specifying how the rendering should be happening. However, one may choose using I18n based approach when developing an application that supports plenty of languages.

If partial view exists that matches the key attribute renders that partial with local variables set to contain both Activity and activity_parameters (hash with indifferent access).

If the partial view does not exist and you wish to fallback to rendering through the I18n translation, you can do so by passing in a :fallback parameter whose value equals :text.

If you do not want to define a partial view, and instead want to have all missing views fallback to a default, you can define the :fallback value equal to the partial you wish to use when the partial defined by the activity key does not exist.

Layouts

You can supply a layout that will be used for activity partials with :layout param. Keep in mind that layouts for partials are also partials.

Custom Layout Location

You can customize the layout directory by supplying :layout_root or by using an absolute path.

Creating a template

To use templates for formatting how the activity should render, create a template based on activity key, for example:

Given a key activity.article.create, create directory tree app/views/public_activity/article/ and create the create partial there

Note that if a key consists of more than three parts splitted by commas, your directory structure will have to be deeper, for example: activity.article.comments.destroy => app/views/public_activity/articles/comments/_destroy.html.erb

Custom Directory

You can override the default public_directory template root with the :root parameter

Variables in templates

From within a template there are two variables at your disposal:

  • activity (aliased as a for a shortcut)
  • parameters (aliased as p) [converted into a HashWithIndifferentAccess]

Examples:

Render a list of all activities from a view (erb)

<ul>
  <% for activity in PublicActivity::Activity.all %>
   <li><%= render_activity(activity) %></li>
  <% end %>
</ul>

Fallback to the I18n text translation if the view is missing

<ul>
  <% for activity in PublicActivity::Activity.all %>
   <li><%= render_activity(activity, fallback: :text) %></li>
  <% end %>
</ul>

Fallback to a default view if the view for the current activity key is missing. The string is the partial name you wish to use.

<ul>
  <% for activity in PublicActivity::Activity.all %>
   <li><%= render_activity(activity, fallback: 'default') %></li>
  <% end %>
</ul>

Supply a layout

# in views:
#   All examples look for a layout in app/views/layouts/_activity.erb
 render_activity @activity, :layout => "activity"
 render_activity @activity, :layout => "layouts/activity"
 render_activity @activity, :layout => :activity

# app/views/layouts/_activity.erb
<p><%= a.created_at %></p>
<%= yield %>

Declare custom layout location


# Both examples look for a layout in "app/views/custom/_layout.erb"

 render_activity @activity, :layout_root => "custom"
 render_activity @activity, :layout      => "/custom/layout"

Custom template root

# look for templates inside of /app/views/custom instead of /app/views/public_directory
render_activity @activity, :root => "custom"

Template for key: activity.article.create (erb)

<p>
  Article <strong><%= p[:name] %></strong>
  was written by <em><%= p["author"] %></em>
  <%= distance_of_time_in_words_to_now(a.created_at) %>
</p>

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/public_activity/renderable.rb', line 124

def render(context, params = {})
  params[:i18n] and return context.render :text => self.text(params)

  partial = partial_path(*params.values_at(:partial, :partial_root))
  layout  = layout_path(*params.values_at(:layout, :layout_root))
  locals  = prepare_locals(params)

  begin 
    context.render params.merge(partial: partial, layout: layout, locals: locals)
  rescue ActionView::MissingTemplate => e
    if params[:fallback] == :text
      context.render :text => self.text(params)
    elsif params[:fallback].present?
      partial = partial_path(*params.values_at(:fallback, :partial_root))
      context.render params.merge(partial: partial, layout: layout, locals: locals)
    else
      raise e
    end
  end
end

#text(params = {}) ⇒ Object

Virtual attribute returning text description of the activity using the activity's key to translate using i18n.


7
8
9
10
11
12
13
14
# File 'lib/public_activity/renderable.rb', line 7

def text(params = {})
  # TODO: some helper for key transformation for two supported formats
  k = key.split('.')
  k.unshift('activity') if k.first != 'activity'
  k = k.join('.')

  I18n.t(k, parameters.merge(params) || {})
end