#2373: Create FilePresenter classes to make better file type display for UploadedFiles

Type: FeatureItem Feature: FilePresenter, Infrastructure, UserInterface Tags:  
ScheduledFor: 0.45.0 Assigned to: AurelioAHeckert Sites: RIPE
Priority: 0 Status: Done  

Currently, if we want different view for a file-type (image, PDF, video,...), we must use an "if" and render explicitly an other view.

A class for every file-type (instead only the UploadedFile) is a nice idea because:

  • the view can be automatically selected from the @page class;
  • specific file-type methods can be organized on it's own place.
but, that is a bad idea because:
  • we must to migrate all UploadedFiles;
  • we will must to migrate every time when we create a new file-type class;
  • we will suffer in pain if we want to remove an specific file-type class handler;
  • by the pain we may be afraid to make plugins of file-type class.

The solution is to make a presenter class for each file-type, and that will be a kind of decorator. A presenter object will incorporate the original UploadedFile, but will call a specific view, may add some methods for it's specific view, and may (only "may") change some original file methods to act like an exhibit.

An abstract class FilePresenter will be implemented by specific file-types or for a sort of file-types. The concrete file presenter classes will response if it can present some UploadedFile and its priority to the class selection chain.

class FilePresenter

  # Will return a encapsulated UploadedFile or the same object if no
  # one accepts it. That behave allow to give any model to this class,
  # like a Article and have no trouble with that.
  def self.for(f)
    klass = subclasses.sort_by { |c| c.accepts?(f) || 0 }.last
    klass.accepts?(f) ? klass.new(f) : f

  def initialize(f)
    @file = f

  # This method must be overridden in subclasses.
  # If the class accepts the file, return a number that represents the
  # priority the class should be given to handle that file. Higher numbers
  # mean higher priority.
  # If the class does not accept the file, return false.
  def self.accepts?(f)

  def method_missing(m, *args)
    file.send(m, *args)

class Playable < FilePresenter
  def self.accepts?(f)
    type = f.content_type[0..5]
    ( type == 'video/' || type == 'audio/' ) ? 5 : nil

class Video < FilePresenter
  def self.accepts?(f)
    ( f.content_type[0..5] == 'video/' ) ? 10 : nil

  def web_versions

class Image < FilePresenter
  def self.accepts?(f)
    ( f.image? ) ? 10 : nil

On view_page method on content_viewer_controller.rb, after @page.hit, we may add
"@page = FilePresenter.for(@page)".

-- AurelioAHeckert - 29 Jun 2012

I'm working on this feature on this branch.

That adds this features:

  • Allows specific methods to the file types.
  • Gives specific views to identified file types.
  • Set file type related icon on CMS and folder listing.
  • Provide a basic HTML5 Video plugin to exemplify the custom FilePresenter creation
  • Gives a generic info page to unhandled files types.

-- AurelioAHeckert - 09 May 2013

Merge Request: https://gitorious.org/noosfero/noosfero/merge_requests/316

-- AurelioAHeckert - 16 May 2013

Add comment
You need to login to be able to comment.

ActionItemForm edit

Title Create FilePresenter classes to make better file type display for UploadedFiles
ActionItemType? FeatureItem
Priority 0
Feature FilePresenter, Infrastructure, UserInterface
Sites RIPE
ResponsibleDevelopers AurelioAHeckert
ScheduledFor? 0.45.0
Status Done
Ticket SAC:
who cares AurelioAHeckert?
Topic revision: r12 - 14 Aug 2014 - 21:08:45 - AurelioAHeckert

irc Talk with Devs Now!

Translations: English
Search on Docs:
ActionItem Search:

Copyright © 2007-2015 by the Noosfero contributors
Colivre - Cooperativa de Tecnologias Livres