Changeset 23

Show
Ignore:
Timestamp:
11/04/2006 11:09:53 PM (2 years ago)
Author:
matthew
Message:

A bunch of things I should've committed separately as I did them... :)

* Added configuration option 'url_prefix', to override the default

'/admin' prefix in the automatic routes

* Added model method paginate_every(n): set default rows per page on

list view

* Added model method human_name(s): override the string used to refer to

the model in the interface

* Changed searching to use ILIKE instead of LIKE
* Added :link option to admin_child_table, to specify which (if any)

columns should have their value linked to the row's object

* Added Django table definition method delete_button(): adds a

JavaScript? 'delete' button to each row

* Changed static_text() presentation of boolean values; Django theme now

defaults to using icons

* Changed static_text() to use to_label instead of to_s

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/auto-admin/init.rb

    r9 r23  
    88  def draw_with_admin 
    99    draw_without_admin do |map| 
    10       map.connect 'admin', :controller => 'auto_admin', :action => 'index' 
    11       map.connect 'admin/-/:action/:id', :controller => 'auto_admin', :action => 'index', 
     10      prefix = AutoAdmin::AutoAdminConfiguration.url_prefix rescue 'admin' 
     11      map.connect "#{prefix}", :controller => 'auto_admin', :action => 'index' 
     12      map.connect "#{prefix}/-/:action/:id", :controller => 'auto_admin', :action => 'index', 
    1213        :requirements => { :model => nil } 
    13       map.connect 'admin/asset/*path', :controller => 'auto_admin', :action => 'asset' 
     14      map.connect "#{prefix}/asset/*path", :controller => 'auto_admin', :action => 'asset' 
    1415 
    15       map.connect 'admin/:model/:action', :controller => 'auto_admin', :action => 'list',  
     16      map.connect "#{prefix}/:model/:action", :controller => 'auto_admin', :action => 'list',  
    1617        :requirements => { :action => /[^0-9].*/, :id => nil } 
    17       map.connect 'admin/:model/:id/:action', :controller => 'auto_admin', :action => 'edit',  
     18      map.connect "#{prefix}/:model/:id/:action", :controller => 'auto_admin', :action => 'edit',  
    1819        :requirements => { :id => /\d+/ } 
    1920      yield map 
  • trunk/auto-admin/lib/auto_admin_configuration.rb

    r20 r23  
    3030  def self.controller_super_class; @@controller_super_class ||= ActionController::Base; end 
    3131  def self.controller_super_class=(klass); @@controller_super_class = klass; end 
     32  def self.url_prefix; @@url_prefix ||= 'admin'; end 
     33  def self.url_prefix= new_value; @@url_prefix = new_value; end 
    3234  def self.model name 
    3335    Object.const_get( name.to_s.camelcase ) 
     
    5254EVAL 
    5355    end 
     56    def human_name(v=nil); @human_name = v if v; @human_name ||= name.titleize; end 
     57 
    5458    def self.array_accessor *names 
    5559      names.each {|name| defaulted_accessor name, '[]' } 
     
    157161    def sort_reverse; defined?( @sort_column ) ? @sort_reverse : (default_sort_info[:reverse] rescue nil); end 
    158162 
     163    def paginate_every(n=nil); @paginate = n if n; @paginate || 20; end 
     164 
    159165    array_accessor :admin_fieldsets 
    160166    def default_admin_fieldsets 
     
    242248          1.upto blank_records do |n| 
    243249            idx += 1 
    244             build_object(builder, children.build, idx, 
    245               "#{row.class.name.underscore.humanize.downcase} ##{n}") 
     250            o = children.build 
     251            build_object(builder, o, idx, 
     252              "#{o.class.human_name} ##{n}") 
    246253          end 
    247254        end 
     
    259266 
    260267      def build_object(builder, obj, idx, caption) 
    261         builder.with_object(obj) do 
     268        name = field.to_s.dup 
     269        name << '[' << idx.to_s << ']' if idx 
     270        builder.with_object(obj, name) do 
    262271          builder.fieldset( :fields, caption ) do 
    263272            yield builder if block_given? 
     
    270279        builder.fieldset( :table, name ) do 
    271280          model = object.reflect_on_association( field ).klass 
    272           builder.table_fields_for( field, nil, :model => model ) do |inner| 
     281          opts = options.merge( :model => model ) 
     282          builder.table_fields_for( field, nil, opts ) do |inner| 
    273283            inner.outer do 
    274284              inner.prologue do 
     
    289299          conditions = options[:conditions] || [] 
    290300          conditions = [conditions] unless conditions.is_a? Array 
    291           new_condition = '(' + columns_for_search.map { |col| "#{col} LIKE ?" }.join( ' OR ' ) + ')' 
     301          new_condition = '(' + columns_for_search.map { |col| "#{col} ILIKE ?" }.join( ' OR ' ) + ')' 
    292302          if conditions.size > 0 
    293303            conditions[0] = "(#{conditions[0]}) AND (#{new_condition})" 
  • trunk/auto-admin/lib/auto_admin_controller.rb

    r21 r23  
    117117      model.append_search_condition! params[:search], options 
    118118    end 
    119     options.update( :per_page => (params[:per_page] || 20).to_i, :singular_name => params[:model] ) 
     119    options.update( :per_page => (params[:per_page] || model.paginate_every).to_i, :singular_name => params[:model] ) 
    120120    @pages, @objects = paginate(params[:model], options) 
    121121    session[:admin_list_params] ||= {} 
     
    135135 
    136136      # Save attributes on the primary object 
    137       unless @object.update_attributes( params[params[:model]] ) && @object.valid? 
     137      flash[:notice] = @object.inspect 
     138      @object.attributes = params[params[:model]] 
     139      unless @object.save 
     140        flash[:warning] = "Failed to update the #{human_model.downcase} \"#{@object.to_label}\". " 
    138141        render :action => 'edit' and return 
    139142      end 
    140143 
    141       # Save child objects 
    142       # FIXME: This is currently quite entirely broken. At least it 
    143       # isn't preventing the main object from being saved, so it should 
    144       # be okay for read-only lists. 
     144      # Save child objects... seems to work at the moment (for tables, 
     145      # at least) 
    145146      model.admin_fieldsets.each do |set| 
    146147        case set.fieldset_type 
    147148        when :tabular, :child_input 
     149          next if set.options[:read_only] 
     150 
     151          is_blank = lambda do |info| 
     152            if set.options[:blank] 
     153              case set.options[:blank] 
     154              when Hash 
     155                set.options[:blank].all? do |k,v| 
     156                  !info.include?(k) || 
     157                    (Proc === v ? v.call(info[k]) : info[k] === v) 
     158                end 
     159              when Proc 
     160                set.options[:blank].call(info) 
     161              end 
     162            else 
     163              info.values.all? {|v| v.blank? } 
     164            end 
     165          end 
     166 
    148167          children = @object.send( set.field ) 
    149168          child_class = children.build.class 
    150           child_params = params["#{params[:model]}_#{set.field}"
     169          child_params = params[set.field.to_s
    151170          child_params.each do |child_index, child_info| 
     171            child_info = child_info.dup 
    152172            next unless Hash === child_info 
    153             o = child_info[:id] ? child_class.find( child_info[:id] ) : children.build 
    154 #            child_info.delete :id 
     173            child_id = child_info.delete :id 
     174            if child_info.delete(:delete) == 'DELETE' || is_blank.call(child_info) 
     175              child_class.find( child_id ).destroy if child_id 
     176              next 
     177            end 
     178 
     179            o = child_id ? child_class.find( child_id ) : children.build 
    155180            unless o.update_attributes child_info 
     181              flash[:warning] = "Failed to #{o.new_record? ? 'add' : 'change'} the #{o.class.name.titleize.downcase} \"#{o.to_label}\" (#{set.label || 'Child list'}). " 
    156182              render :action => 'edit' and return 
    157183            end 
  • trunk/auto-admin/lib/auto_admin_django_theme.rb

    r19 r23  
    7878      end 
    7979    end 
     80    def static_text_without_theme(field, options = {}) 
     81      v = @object.send(field) 
     82      if v == true || v == false 
     83        v = v ? 'Yes' : 'No' 
     84        helpers.send(:image_tag, helpers.send(:url_for, :escape => false, :action => :asset, :path => "images/auto_admin/icon-#{v.downcase}.gif" ), :alt => v, :title => v) 
     85      else 
     86        super 
     87      end 
     88    end 
    8089  end 
    8190  class TableBuilder < AutoAdmin::TableBuilder(FormBuilder) 
     
    97106    def outer; %(<table cellspacing="0">); end 
    98107    def fieldset(style, title=nil) 
    99       @first = true 
     108      @column_num = 0 
    100109      super 
     110    end 
     111    def delete_button options={} 
     112      wrap_field :delete_button, nil, options do |*a| 
     113        <<-foo 
     114        <a href="#" onclick="this.getElementsByTagName('input')[0].value = 'DELETE'; this.parentNode.parentNode.style.display = 'none'; return false;"> 
     115          <input type="hidden" value="" name="#{@object_name}[delete]" /> 
     116          #{helpers.send(:image_tag, helpers.send(:url_for, :escape => false, :action => :asset, :path => "images/auto_admin/icon_deletelink.gif" ), :alt => ' [X]', :title => 'Delete')} 
     117        </a> 
     118        foo 
     119      end 
    101120    end 
    102121    def table_cell(field_type, field_name, options) 
     
    110129              '' 
    111130 
    112       was_first, @first = @first, false 
    113       if was_first 
     131      @column_num += 1 
     132      do_link =  
     133        case opt = option(:link) 
     134        when Array 
     135          opt.any? {|el| (el === @column_num rescue false) || (el === field_name rescue false) } 
     136        when Proc 
     137          opt[@column_num, field_name, options] 
     138        when true, false, nil 
     139          opt 
     140        else 
     141          opt === @column_num 
     142        end 
     143 
     144      if do_link 
    114145        link = link_to( yield, :action => 'edit', :model => model_name, :id => @object.id ) 
    115146        %(<th class="#{klass}">#{link}</th>) 
  • trunk/auto-admin/lib/auto_admin_helper.rb

    r14 r23  
    2121  end 
    2222  def human_model name=nil, pluralize=false 
    23     s = model(name).name 
     23    s = model(name).human_name 
    2424    s = s.pluralize if pluralize && pluralize != 1 
    25     s.titleize 
     25    s 
    2626  end 
    2727 
  • trunk/auto-admin/lib/auto_admin_simple_theme.rb

    r22 r23  
    118118  module PrivateFormHelpers 
    119119    private 
    120     DEFAULT_OPTIONS = { :sort_key => :sort }.freeze 
     120    DEFAULT_OPTIONS = { :sort_key => :sort, :link => 1 }.freeze 
    121121    def option(opt_name) 
    122       DEFAULT_OPTIONS.include?( opt_name ) ? DEFAULT_OPTIONS[opt_name] : @options[opt_name] 
     122      (@options && @options.include?( opt_name )) ? @options[opt_name] : DEFAULT_OPTIONS[opt_name] 
    123123    end 
    124124    def model 
     
    239239      end 
    240240    end 
    241     def with_object(object
     241    def with_object(object, object_name=@object_name
    242242      previous_object, @object = @object, object 
     243      previous_object_name, @object_name = @object_name, object_name 
    243244      yield 
    244       @object = previous_object 
     245      @object, @object_name = previous_object, previous_object_name 
     246      @object 
    245247    end 
    246248 
     
    325327    end 
    326328    def static_text(field, options = {}) 
    327       h( @object.send field ) 
     329      v = @object.send(field) 
     330      h( v.nil? ? v : v.to_label ) 
    328331    end 
    329332    def calculated_text(options = {}) # :yields: object 
    330       h( yield @object ) 
     333      v = yield @object 
     334      h( v.nil? ? v : v.to_label ) 
    331335    end 
    332336    def static_html(field, options = {}) 
     
    391395      yield self.class.new( inner_object, name, extra_options[:model], @controller, table_params, options ) if table_params 
    392396    end 
    393     def with_object(object
     397    def with_object(object, object_name=@object_name
    394398      previous_object, @object = @object, object 
     399      previous_object_name, @object_name = @object_name, object_name 
    395400      yield 
    396       @object = previous_object 
     401      @object, @object_name = previous_object, previous_object_name 
     402      @object 
    397403    end 
    398404 
     
    484490        def #{helper}(options={}, *args, &proc) 
    485491          wrap_field #{helper.to_sym.inspect}, nil, options do |*a| 
    486             a.empty? ? super(options, *args, &proc) : super(*a) 
     492            a.empty? ? #{helper}_without_theme(options, *args, &proc) : #{helper}_without_theme(*a) 
    487493          end 
    488494        end 
     
    494500        def #{helper}(field, options={}, *args, &proc) 
    495501          wrap_field #{helper.to_sym.inspect}, field, options do |*a| 
    496             a.empty? ? super(field, options, *args, &proc) : super(*a) 
     502            a.empty? ? #{helper}_without_theme(field, options, *args, &proc) : #{helper}_without_theme(*a) 
    497503          end 
    498504        end 
  • trunk/auto-admin/themes/django/views/edit.rhtml

    r7 r23  
    22@body_class = 'change-form' 
    33@content_class = 'colM' 
    4 @title = @object.new_record? ? "Add #{params[:model].humanize.downcase}" : "Change #{params[:model].humanize.downcase}" 
     4@title = @object.new_record? ? "Add #{human_model.downcase}" : "Change #{human_model.downcase}" 
    55@tools = [] 
    66@tools << link_to( "History", { :model => params[:model], :action => 'history', :id => params[:id] } ) if has_history? 
  • trunk/auto-admin/themes/django/views/index.rhtml

    r1 r23  
    1212  o = obj.name.underscore 
    1313  %> 
    14     <tr><th><%= link_to o.humanize, list_page_for(o) %></th> 
     14    <tr><th><%= link_to obj.human_name, list_page_for(o) %></th> 
    1515      <td><%= link_to 'Add', { :model => o, :action => 'edit' }, { :class => 'addlink' } %></td> 
    1616      <td><%= link_to 'Change', list_page_for( o ), { :class => 'changelink' } %></td></tr> 
  • trunk/auto-admin/themes/django/views/layout.rhtml

    r5 r23  
    3535        crumbs = [link_to( 'Home', :controller => 'auto_admin')] 
    3636        if params[:action] == 'list' 
    37           crumbs << h( params[:model].pluralize.humanize
     37          crumbs << h( human_model(nil, true)
    3838        else 
    39           crumbs << link_to( h( params[:model].pluralize.humanize ), { :controller => 'auto_admin', :model => params[:model], :action => 'list', :id => nil } ) 
    40           crumbs << h( (defined?( @object ) && @object.respond_to?( :to_label )) ? @object.to_label : @title ) 
     39          crumbs << link_to( h( human_model(nil, true) ), { :controller => 'auto_admin', :model => params[:model], :action => 'list', :id => nil } ) 
     40          crumbs << h( (defined?( @object ) && !@object.new_record? && @object.respond_to?( :to_label )) ? @object.to_label : @title ) 
    4141        end 
    4242      else