Skip to content
DAddYE edited this page Sep 12, 2010 · 22 revisions

Localization with Rails I18n

  • Emails and activations are translated with rails locale. [done]
  • Javascripts works with the integrated localization of rails. [done]
  • Defined method missing in ActiveRecord to intercept calls to non-localized methods (eg. name instead of name_cz) [done]

Short example:


# /config/locale/backend/en.yml

en:
  lipsiadmin:
    javascripts:
      buttons:
        add: "Add"
        edit: "Edit"
        remove: "Delete"

So in a javascript you can use:


alert(Backend.locale.buttons.add);

If we have this columns in a table:


m.col :string, :name_it, :name_en, :name_cz
m.col :text, :description_it, :description_en, :description_cz

# we can call

puts myinstance.name
# or
puts myinstance.description

Lipsiadmin look this columns for your current locale.

Javascripts features

  • Now the main js app is called Backend. [done]
  • Two fully tested templated (see app/views/backend/base/index). [done]
  • In this new version there is a better organization of backend.js now is more clean and more more fast. [done]
  • Now we have two beautiful templates, standard and slate. [done]
  • Now we have one top side menu (like toolbar). [done]
  • Now there is a beautifull helper for load html or load and execute js [done]
  • Cookie status of columns/grids, now you can personalize columns width, position etc. [done]
  • No more proxy memory for manage search and pagination, now are server side. [done]
  • Better generation of standard grids, editable grids, tree see this example. [done]
  • Caching and History support for columns and next-back buttons. [done]
  • Now you can reuse everywhere your forms in any page. [done]

Examples:


// some examples
Backend.app.load('/my_grid.js')
Backend.app.load('/my_page')
Backend.app.backTo = '/backend/mygrid'
Backend.app.back

Grid Generations:


# in app/controllers/events_controller.rb
  def index
    params[:limit] ||= 50

    @column_store = column_store_for Event do |cm|
      cm.add :name,             "Name",      :sortable => true
      cm.add "procedure.name",  "Procedures", :sortable => true
      cm.add :position,         "Position", :sortable => true, :width => 30, :align => :center
      cm.add :default,          "Default",   :sortable => true, :width => 20, :renderer => :boolean
      cm.add :description,      "Expire At",  :sortable => false
      cm.add :created_at,       "Created At", :sortable => true, :renderer => :datetime, :align => :right
    end

    respond_to do |format|
      format.js 
      format.json do
        render :json => @column_store.store_data(params, :include => :procedure)
      end
    end
  end

# in app/views/events/index.rjs

page.grid do |grid|
  grid.id "grid-events"
  grid.title "List Procedures"
  grid.base_path "/backend/events"
  grid.forgery_protection_token request_forgery_protection_token
  grid.authenticity_token form_authenticity_token
  grid.tbar  :default
  grid.store do |store|
    store.url "/backend/events.json"
    store.fields @column_store.store_fields
    store.groupField "procedures.name"
    store.sortInfo   :field => "events.position", :direction => "ASC"
  end
  grid.columns do |columns|
    columns.fields @column_store.column_fields
  end
  grid.bbar  :store => grid.get_store, :pageSize => params[:limit]
end

Lipsiadmin mapping for you external columns for do a correct search:


var store = new Ext.data.GroupingStore({
    remoteSort: true,
    sortInfo: {"field": "events.position", "direction": "ASC"},
    proxy: new Ext.data.HttpProxy({
        url: "/backend/events.json"
    }),
    baseParams: {"_method": "GET"},
    groupField: "procedures.name",
    reader: new Ext.data.JsonReader({
        root: "results",
        totalProperty: "count",
        fields: [{
            name: "events.name",
            mapping: "events_name"
      },{
            name: "procedures.name",
            mapping: "procedures_name"
      },{
            name: "events.position",
            mapping: "events_position"
      },{
            name: "events.default",
            mapping: "events_default"
      },{
            name: "events.description",
            mapping: "events_description"
      },{
            type: "date",
            name: "events.created_at",
            mapping: "events_created_at",
            dateFormat: "c"
      }],
        id: "id"
    })
  });

Example of reusing accounts form in another form:


# in app/views/dossiers/_form.html.haml

-tab "Accounts", :style => "padding:10px" do
  %table
    %tr
      %td{:style=>"width:100px"} 
        %b Customer:
      %td
        %span{:id => :account_name}=@dossier.account ? @dossier.account.full_name : "None"
        =hidden_field :dossier, :account_id
        =open_window "/backend/accounts.js", :id, :name, :dossier_account_id, :account_name

Helpers

  • Helpers for generate Ext Tabs [done]
  • Helpers for generate Ext BoxComponent [done]
  • Helpers for show errors with the Ext MessageBox [done]
  • Helpers for automatize sorting of image or files
  • Helpers for automatize file_field etc…

Attachments

  • In the next version we use a new integrated system for storing images and files (like paperclip). [done]

In any model you can do:


  has_many_attachments              :attachments, :dependent => :destroy
  has_one_attachment                   :image
  attachment_styles_for                 :attachments, :normal, "128x128!"
  validates_attachment_presence_for     :attachments
  validates_attachment_size_for         :attachments, :greater_than => 10.megabytes
  validates_attachment_content_type_for :attachments, "image/png"
  ...

And in your view simply:


  =fields_for "dossier[attachments_attributes][]", @dossier.attachments.build do |attachment|
    Attach your file:
    =attachment.file_field :file

Pdf generation

  • Now we use pd4ml for build pdf. [done]
  • Pdf are generated from standard html/haml. [done]
  • Pd4ml have a free fully functional version (included). [done]

Examples:


$ script/generate pdf invoice

# in any of your controllers copy this:

def generate_pdf_invoice
    render_pdf :invoice, 'invoice_file.pdf'
end

# edit /app/views/pdf/invoice.html.haml

# go to /backend/yourview/invoice

we prefer to use a commercial version for few dollars than spent a lot of hours for build pdf templates

Authentication

  • New builtin authentication with modules and roles, multiaccount. [done]
  • Auth don’t need to restart the web server. [done]
  • SubMenu creations. [done]
  • Better backend and frontend managment. [done]

See this example:


  1. in app/models/account_access.rb
    class AccountAccess < Lipsiadmin::AccessControl::Base
roles_for :administrator do |role|
  1. Shared Permission
    role.allow_all_actions “/backend/base”
    role.allow_all_actions “/backend/event_logs”
    role.deny “/backend/base/onlyforcustomers”
role.project_module “My Administration Menu” do |project| project.menu :test, “/backend/dossiers/14/edit” do |submenu| submenu.add :sub_test_1 do |subsubmenu| subsubmenu.add :sub_sub_test_1, “/backend/dossier/test” subsubmenu.add :sub_sub_test_2, “/backend/dossier/test” end submenu.add :sub_test_2, “/backend/dossiers/14/edit” end …

Exception Notifier

  • Mail handler for production errors [done]
  • Templating of errors (like merb) with haml/erb pages and frontend/backend layout [done]
  • Compatibility with redmine mail handler [done]

 # in config/initializers/exception_notifier.rb

Lipsiadmin::Mailer::ExceptionNotifier.sender_address       = %("Exception Notifier" <exceptions@lipsiasoft.com>)
Lipsiadmin::Mailer::ExceptionNotifier.recipients_addresses = %(helpdesk@lipsiasoft.com)
Lipsiadmin::Mailer::ExceptionNotifier.email_prefix         = "[Project Name]"

# Uncomment this if this mail is for redmine handler
# Lipsiadmin::Mailer::ExceptionNotifier.extra_options        = { :project => "lipsiabug", :tracker => "Bug", :priority => "Immediata" }
Clone this wiki locally