Changeset 1236

Show
Ignore:
Timestamp:
2008-10-23 23:38:32 (3 months ago)
Author:
gaspard
Message:

commit 7706f023fb7ebc928de8819d11af4d6d3c115789
Author: Gaspard Bucher <gaspard@teti.ch>

Finished implementing a simple table entry. Refs state:resolved.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/CREDITS

    r905 r1236  
    44    http://dynarch.com 
    55    adapted to Rails by Gaspard Bucher 
     6 
     7tablekit table editor 
     8--------------------- 
     9    Andrew Tetlaw & Millstream Web Software 
     10    http://www.millstream.com.au/view/code/tablekit/ 
     11    add/remove columns and drag&drop support added by Gaspard Bucher 
    612     
    713soft icons 
     
    1218xspf mp3 player 
    1319--------------- 
    14        Fabricio Zuardi 
    15        http://musicplayer.sourceforge.net/ 
     20    Fabricio Zuardi 
     21    http://musicplayer.sourceforge.net/ 
    1622         
    1723upload progress bar (sample application demo) 
  • trunk/app/controllers/application.rb

    r1231 r1236  
    55  init_gettext 'zena' 
    66  helper_method :prefix, :zen_path, :zen_url, :data_path, :node_url, :notes, :error_messages_for, :render_errors, :processing_error 
    7   helper_method :get_template_text, :template_url_for_asset, :save_erb_to_url, :lang, :visitor, :fullpath_from_template_url, :eval_parameters_from_template_url, :format_date 
     7  helper_method :get_template_text, :template_url_for_asset, :save_erb_to_url, :lang, :visitor, :fullpath_from_template_url, :eval_parameters_from_template_url, :format_date, :get_table_from_json 
    88  before_filter :set_lang 
    99  before_filter :authorize 
     
    871871      res 
    872872    end 
     873     
     874    # Build a tabular content from a node's attribute 
     875    def get_table_from_json(node, attribute) 
     876      text = Node.zafu_attribute(node, attribute) 
     877      if text.blank? 
     878        table = [{"type"=>"table"},[["title"],["value"]]] 
     879      else 
     880        table = JSON.parse(text) 
     881      end 
     882      raise JSON::ParserError unless table.kind_of?(Array) && table.size == 2 && table[0].kind_of?(Hash) && table[0]['type'] == 'table' && table[1].kind_of?(Array) 
     883      table 
     884    end 
    873885end 
    874886 
  • trunk/app/controllers/nodes_controller.rb

    r1231 r1236  
    7070      format.js { render :action => 'show' } 
    7171    end 
     72  end 
     73   
     74  # Get cell text 
     75  def cell_edit 
     76    # get table 
     77    table = get_table_from_json(@node, params[:attr]) 
     78    # get row/cell 
     79    table_data = table[1] 
     80     
     81    if row = table_data[params[:row].to_i] 
     82      if cell = row[params[:cell].to_i] 
     83        render :text => cell 
     84      else 
     85        ' ' 
     86      end 
     87    else   
     88      ' ' 
     89    end 
     90  end 
     91   
     92  # Ajax table editor 
     93  def cell_update 
     94    # get table 
     95    table = get_table_from_json(@node, params[:attr]) 
     96    # get row/cell 
     97    table_data = table[1] 
     98     
     99    if row = table_data[params[:row].to_i] 
     100      if cell = row[params[:cell].to_i] 
     101        if cell != params[:value] 
     102          row[params[:cell].to_i] = params[:value] 
     103          @node.update_attributes(params[:attr] => table.to_json) 
     104        end 
     105      else 
     106        @node.errors.add(params[:attr], 'Cell outside of table range.') 
     107      end 
     108    else   
     109      @node.errors.add(params[:attr], 'Row outside of table range.') 
     110    end 
     111     
     112    respond_to do |format| 
     113      format.html { render :inline => @node.errors.empty? ? "<%= zazen(params[:value], :no_p => true) %>" : error_messages_for(@node) } 
     114    end 
     115  rescue JSON::ParserError 
     116    render :inline => _('could not save value (bad attribute)') 
     117  end 
     118   
     119  # Ajax table add row/column 
     120  def table_update 
     121    # get table 
     122    @table = get_table_from_json(@node, params[:attr]) 
     123    # get row/cell 
     124    table_data = @table[1] 
     125 
     126    if params[:add] == 'row' 
     127      table_data << table_data[0].map { ' ' } 
     128    elsif params[:add] == 'column' 
     129      table_data.each do |row| 
     130        row << ' ' 
     131      end 
     132    elsif params[:remove] == 'row' && table_data.size > 2 
     133      table_data.pop 
     134    elsif params[:remove] == 'column' && table_data[0].size > 1 
     135      table_data.each do |row| 
     136        row.pop 
     137      end 
     138    else 
     139      # reorder ... 
     140    end 
     141 
     142    @node.update_attributes(params[:attr] => @table.to_json) 
     143     
     144  rescue JSON::ParserError 
     145    render :inline => _('could not save value (bad attribute)') 
    72146  end 
    73147   
  • trunk/app/helpers/application_helper.rb

    r1232 r1236  
    11require 'digest/sha1' 
    22require 'tempfile' 
     3require 'json' 
    34 
    45# Methods added to this helper will be available to all templates in the application. 
     
    317318    return '' unless text 
    318319    opt = {:images=>true, :pretty_code=>true, :output=>'html'}.merge(opt) 
     320    no_p = opt.delete(:no_p) 
    319321    img = opt[:images] 
    320322    if opt[:limit] 
     
    326328    end 
    327329    opt[:node] ||= @node 
    328     ZazenParser.new(text,:helper=>self).render(opt) 
     330    res = ZazenParser.new(text,:helper=>self).render(opt) 
     331    if no_p && !text.include?("\n") 
     332      res.gsub(%r{\A<p>|</p>\Z},'') 
     333    else 
     334      res 
     335    end 
    329336  end 
    330337   
     
    545552    render_to_string( :partial=>'nodes/gallery', :locals=>{:gallery=>images} ) 
    546553  end 
     554   
     555  # Create a table from an attribute 
     556  def make_table(opts) 
     557    style, node, attribute, title, table = opts[:style], opts[:node], opts[:attribute], opts[:title], opts[:table] 
     558    attribute = "d_#{attribute}" unless ['v_', 'd_'].include?(attribute[0..1]) 
     559    case (style || '').sub('.', '') 
     560    when ">" 
     561      prefix = "<div class='img_right'>" 
     562      suffix = "</div>" 
     563    when "<" 
     564      prefix = "<div class='img_left'>" 
     565      suffix = "</div>" 
     566    when "=" 
     567      prefix = "<div class='img_center'>" 
     568      suffix = "</div>" 
     569    else 
     570      prefix = '' 
     571      suffix = '' 
     572    end 
     573     
     574    if node.can_write? 
     575      prefix << "<div class='table_add'>" 
     576      prefix << link_to_remote("<img src='/images/column_add.png' alt='#{_('add column')}'/>",  
     577                                :url => "/nodes/#{node.zip}/table_update?add=column&attr=#{attribute}") 
     578      prefix << link_to_remote("<img src='/images/column_delete.png' alt='#{_('add column')}'/>",  
     579                                :url => "/nodes/#{node.zip}/table_update?remove=column&attr=#{attribute}") 
     580      prefix << link_to_remote("<img src='/images/row_add.png' alt='#{_('add column')}'/>",  
     581                                :url => "/nodes/#{node.zip}/table_update?add=row&attr=#{attribute}") 
     582      prefix << link_to_remote("<img src='/images/row_delete.png' alt='#{_('add column')}'/>",  
     583                                :url => "/nodes/#{node.zip}/table_update?remove=row&attr=#{attribute}") 
     584      prefix << "</div>" 
     585    end 
     586     
     587    table ||= get_table_from_json(node, attribute) 
     588     
     589    prefix + render_to_string( :partial=>'nodes/table', :locals=>{:table=>table, :node=>node, :attribute=>attribute}) + suffix 
     590  rescue JSON::ParserError 
     591    "<span class='unknownLink'>could not build table from text</span>" 
     592  end 
    547593 
    548594  def list_nodes(ids=[], opts={}) 
  • trunk/config/deploy.rb

    r1235 r1236  
    3636set :apache2_reload_cmd, "/etc/init.d/apache2 reload" 
    3737set :debian_host,           true 
    38  
    39 role :web,         "root@#{server_ip}" 
    40 role :app,         "root@#{server_ip}" 
    41 role :db,          "root@#{server_ip}", :primary => true 
     38set :ssh_user,              "root" 
    4239 
    4340load File.join(File.dirname(__FILE__), 'deploy_config') 
     41 
     42role :web,         "#{ssh_user}@#{server_ip}" 
     43role :app,         "#{ssh_user}@#{server_ip}" 
     44role :db,          "#{ssh_user}@#{server_ip}", :primary => true 
    4445 
    4546#================= END ADVANCED SETTINGS ==========# 
     
    272273  ports = (mongrel_port.to_i...(mongrel_port.to_i + mongrel_count.to_i)).to_a 
    273274  httpd_conf = render("config/httpd.rhtml", :balancer => db_name, :ports => ports) 
    274   put(httpd_conf, "/etc/apache2/conf.d/#{db_name}") 
     275  if debian_host 
     276    put(httpd_conf, "/etc/apache2/conf.d/#{db_name}") 
     277  else 
     278    put(httpd_conf, "/etc/apache2/conf.d/#{db_name}") 
     279  end 
    275280   
    276281  run "test -e /etc/apache2/sites-enabled/000-default && a2dissite default || echo 'default already disabled'" 
  • trunk/config/routes.rb

    r1231 r1236  
    2020    :member =>     { :import => :post, :export => :get, :save_text => :put, 
    2121                     :order => :any, :clear_order => :any, 
    22                      :zafu => :get, :drop => :put, :attribute => :get } do |nodes| 
     22                     :zafu => :get, :drop => :put, :attribute => :get, 
     23                     :cell_update => :post, :table_update => :post, :cell_edit => :get } do |nodes| 
    2324    nodes.resources :versions,  
    2425                    :name_prefix => nil, 
  • trunk/db/init/base/skins/default/style.css

    r1055 r1236  
    33a.wiki { color:inherit; border-bottom:1px dotted blue;} 
    44.zazen a:hover, #footer a:hover { border-bottom:1px solid blue;} 
     5.table_add a:hover { border:0;} 
    56input { padding:3px 4px;} 
    67 
     
    3031.summary { font-style:italic;} 
    3132.zazen h1, .zazen h2, .zazen h3, .zazen h4, .zazen p, .zazen ol, .zazen ul { margin:21px 0;} 
     33.zazen table p, .zazen table ol, .zazen table ul { margin-top:0; margin-bottom:0;} 
    3234h1, h2, h3 { color:black;} 
    3335h1 { font-size:28px; line-height:42px; font-weight:bold; color:black;} 
  • trunk/lib/parser/lib/rules/zazen.rb

    r1232 r1236  
    6666    def scan 
    6767      #puts "SCAN:[#{@text}]" 
    68       if @text =~ /\A([^!"<\n\[]*)/m 
     68      if @text =~ /\A([^\|!"<\n\[]*)/m 
    6969        flush $& 
    7070        if @text[0..0] == '!' 
     
    7474        elsif @text[0..0] == '[' 
    7575          scan_bracket 
     76        elsif @text[0..0] == '|' 
     77          scan_pipe 
    7678        elsif @text[0..4] == '<code' 
    7779          # FIXME: implement <code..> and @@ instead of "extract" 
     
    315317    end 
    316318     
     319    def scan_pipe 
     320      #puts "PIPE:[#{@text}]" 
     321      if @text =~ /\A\|([<=>]\.|)([0-9]+\.|)([a-zA-Z_]+)(\/([^\|]*)|)\|/m 
     322        # table |<.34.shopping_list/blah blah| 
     323        # table |shopping_list| 
     324        #puts "TABLE:#{$~.to_a.inspect}" 
     325        eat $& 
     326        style, id, attribute, title_opts, title = $1, $2, $3, $4, $5 
     327        id = id[0..-2] if id != '' 
     328        if @translate_ids 
     329          if @translate_ids != :zip 
     330            node = @helper.find_node_by_pseudo(id, @context[:node]) 
     331            id = node.pseudo_id(@context[:node], @translate_ids) if node 
     332          end 
     333          store "|#{style}#{id == '' ? '' : "#{id}."}#{attribute}#{title}|" 
     334        else 
     335          node = id == '' ? @context[:node] : @helper.find_node_by_pseudo(id, @context[:node]) 
     336          store @helper.make_table(:style=>style, :node=>node, :attribute=>attribute, :title=>title) 
     337        end 
     338      elsif @text =~ /\A\|([<=>]\.|)(#{PSEUDO_ID_REGEXP})\.([a-zA-Z_]+)(\/([^\|]*)|)\|/m 
     339        # table |<.:art++.shopping_list/blah blah| 
     340        # table |shopping_list| 
     341        #puts "TABLE SHORTCUT:#{$~.to_a.inspect}" 
     342        eat $& 
     343        text = $& 
     344        style, id, attribute, title_opts, title = $1, $2, $3, $4, $5 
     345        if node = @helper.find_node_by_pseudo(id, @context[:node]) 
     346          if @translate_ids 
     347            # replace shortcut 
     348            store "|#{style}#{node.pseudo_id(@context[:node], @translate_ids || :zip)}.#{attribute}#{title}|" 
     349          else 
     350            # write table 
     351            store @helper.make_table(:style=>style, :node=>node, :attribute=>attribute, :title=>title) 
     352          end 
     353        elsif @translate_ids 
     354          # node not found, ignore 
     355          store text 
     356        else 
     357          # node not found 
     358          store "[#{id} not found]" 
     359        end 
     360      else 
     361        #puts "EAT:[#{$&}]" 
     362        # eat marker and continue scan 
     363        flush @text[0..0] 
     364      end 
     365    end 
    317366     
    318367    def extract_code(fulltext) 
  • trunk/lib/parser/lib/rules/zena.rb

    r1218 r1236  
    16531653    def r_javascripts 
    16541654      if @params[:list] == 'all' || @params[:list].nil? 
    1655         list = %w{ prototype effects zena } 
     1655        list = %w{ prototype effects tablekit zena } 
    16561656      else 
    16571657        list = @params[:list].split(',').map{|e| e.strip} 
  • trunk/lib/parser/test/parser/zazen.yml

    r1219 r1236  
    117117  src: "!http://www.example.org/images/test.jpg!" 
    118118  res: "<p><img src=\"http://www.example.org/images/test.jpg\" alt=\"\" /></p>" 
     119   
     120table: 
     121  src: "|shopping_list|" 
     122  res: "<p>[make_table attribute:|shopping_list| style:||]</p>" 
     123   
     124table_title: 
     125  src: "|shopping_list/A list of frequent problems|" 
     126  res: "<p>[make_table attribute:|shopping_list| style:|| title:|A list of frequent problems|]</p>" 
     127   
     128table_id: 
     129  src: "|34.shopping_list|" 
     130  res: "<p>[make_table attribute:|shopping_list| node:|34| style:||]</p>" 
     131   
     132table_pseudo_id: 
     133  src: "|:art+.shopping_list|" 
     134  res: "<p>[make_table attribute:|shopping_list| node:|:art+| style:||]</p>" 
     135   
     136table_pseudo_path: 
     137  src: "|(../some/path).shopping_list|" 
     138  res: "<p>[make_table attribute:|shopping_list| node:|(../some/path)| style:||]</p>" 
    119139 
    120140link_with_title: 
  • trunk/lib/parser/test/parser_test.rb

    r1232 r1236  
    1616class ParserModule::DummyHelper 
    1717  def find_node_by_pseudo(*args) 
    18     nil 
     18    args[0] 
    1919  end 
    2020end 
     
    7272      self.inspect 
    7373    end 
     74  end 
     75end 
     76 
     77class String 
     78  def pseudo_id(*args) 
     79    self 
    7480  end 
    7581end 
  • trunk/public/stylesheets/zena.css

    r1170 r1236  
    6464#dev li table { display:none;} 
    6565#dev:hover table { display:block;} 
     66 
     67/* table js */ 
     68.zazen .table_add a { visibility:hidden; padding:0 5px; text-decoration:none;} 
     69.zazen .table_add img { border:0;} 
     70.zazen .table_add:hover a { visibility:visible;} 
  • trunk/test/helpers/zazen_test.rb

    r1232 r1236  
    176176           zazen('This "is":(collections/art) "a":(/projects/wiki) !(/projects/wiki/bird)! "link":(people/lion).', :translate_ids => :zip, :node => zena) 
    177177  end 
     178   
     179  def test_table_asset 
     180    login(:tiger) 
     181    @node = secure!(Node) { nodes(:status) } 
     182    assert_match %r{<table.*<tr.*<th>title</th.*<tr.*value}m, zazen("This is a table test:\n\n|shopping_list|") 
     183    assert_match %r{<table.*<th>problem</th>.*<th>solution</th>.*<th>cost</th>.*<tr>.*<td>dead hard drive</td>}m, zazen("This is a table test:\n\n|problems|") 
     184  end 
    178185 
    179186end 
  • trunk/test/sites/zena/dyn_attributes.yml

    r1121 r1236  
    2727  value:           gaspard 
    2828 
    29 cleanWater_en_d_tz: 
     29cleanWater_en_tz: 
    3030  owner:           cleanWater_en 
    3131  key:             tz 
    3232  value:           Asia/Jakarta 
     33 
     34status_en_problems: 
     35  owner:           status_en 
     36  key:             problems 
     37  value: | 
     38    [{"type":"table"}, 
     39     [["problem","solution","cost"], 
     40      ["dead hard drive", "buy a new one", 150.00], 
     41      ["hurting hands", "take a rest", 0.0], 
     42      ["buggy display", "wait for a bug fix", 0.0] 
     43     ]]