Changeset 1257

Show
Ignore:
Timestamp:
2008-11-16 17:53:15 (2 months ago)
Author:
gaspard
Message:

commit 59dac1392647c1a509b7faabd8d55734db9c27d6
Author: Gaspard Bucher <gaspard@teti.ch>

Fixed bug where imported compressed xhtml templates would not parse zafu/css correctly. Added some tests to make sure these problems do not show up again.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/controllers/application.rb

    r1256 r1257  
    66  init_gettext 'zena' 
    77  helper_method :prefix, :zen_path, :zen_url, :data_path, :node_url, :notes, :error_messages_for, :render_errors, :processing_error 
    8   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 
     8  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, :find_node_by_pseudo 
    99  before_filter :set_lang 
    1010  before_filter :authorize 
     
    395395      end 
    396396       
    397       if opts[:parse_assets] 
     397      if opts[:parse_assets]   
    398398        current_folder = opts[:current_folder] || '' 
    399399        current_folder = current_folder[1..-1] if current_folder[0..0] == '/' 
    400        
    401400         
    402401        if src =~ /\A(.*)_(\w+)\Z/ 
     
    404403          src2, mode2 = $1, $2 
    405404        end 
    406          
     405 
    407406        if src[0..0] == '/' 
    408407          path1 = src[1..-1] 
     
    412411          path2 = current_folder + '/' + src2 if src2 
    413412        end 
    414          
     413 
    415414        # make sure path elements are url_names 
    416415        path1 = path1.split('/').map {|s| s.url_name!}.join('/') 
     
    428427        end 
    429428         
    430         return nil unless res = find_document_for_template(opts) 
     429        src2 = opts[:src].split('/').map {|s| s.url_name!}.join('/') 
     430         
     431        unless res = find_document_for_template(opts) 
     432          # '_...' did not mean mode but was an old name. 
     433          mode = nil 
     434          return nil unless res = find_document_for_template(opts.merge(:src => src2)) 
     435        end 
     436         
    431437        asset, url = *res 
    432438        @renamed_assets[url] = asset 
     
    486492      return document ? [document, (([skin_name] + url).join('/') + (mode ? "_#{mode}" : '') + (format ? ".#{format}" : ''))] : nil 
    487493    end 
    488    
     494     
     495    # Find a node's zip based on a query shortcut. Used by zazen to create a link for ""::art for example. 
     496    def find_node_by_pseudo(string, base_node = nil) 
     497      secure(Node) { Node.find_node_by_pseudo(string, base_node || @node) } 
     498    end 
     499 
    489500    # TODO: test 
    490501    def save_erb_to_url(template, template_url) 
  • trunk/app/controllers/nodes_controller.rb

    r1236 r1257  
    282282  def import 
    283283    @nodes = secure!(Node) { Node.create_nodes_from_folder(:klass => params[:node][:klass], :archive => params[:node][:archive], :parent => @node) }.values 
     284     
     285    # parse pseudo_ids 
     286    parse_assets(@nodes) 
    284287  end 
    285288   
     
    492495      @node.kind_of?(Document) && params[:format] == @node.c_ext 
    493496    end 
     497     
     498    # Transform pseudo id into absolute paths (used after import) 
     499    def parse_assets(nodes) 
     500      nodes.each do |n| 
     501        next unless n.errors.empty? 
     502 
     503        attrs = {} 
     504 
     505        n.parse_keys.each do |k| 
     506          orig  = n.send(k) 
     507          trans = n.parse_assets(orig, self, k) 
     508          if trans != orig 
     509            attrs[k] = trans 
     510          end 
     511        end 
     512 
     513        if attrs != {} 
     514          attrs['v_status'] = n.v_status 
     515          n.update_attributes(attrs) 
     516        end 
     517      end 
     518    end 
    494519end 
    495520 
  • trunk/app/controllers/versions_controller.rb

    r1217 r1257  
    6363        if @node.kind_of?(TextDocument) 
    6464          if params['parse_assets'] 
    65             @node.version.text = @node.parse_assets(@node.version.text, self
     65            @node.version.text = @node.parse_assets(@node.version.text, self, 'v_text'
    6666          elsif @node.kind_of?(TextDocument) && params['unparse_assets'] 
    67             @node.version.text = @node.unparse_assets(@node.version.text
     67            @node.version.text = @node.unparse_assets(@node.version.text, self, 'v_text'
    6868          end 
    6969        end 
  • trunk/app/helpers/application_helper.rb

    r1251 r1257  
    347347    HTMLDiff::diff(zazen(text1), zazen(text2)) 
    348348  end 
    349    
    350   # Find a node's zip based on a query shortcut. Used by zazen to create a link for ""::art for example. 
    351   def find_node_by_pseudo(string, base_node = nil) 
    352     secure(Node) { Node.find_node_by_pseudo(string, base_node || @node) } 
    353   end 
    354    
    355    
    356349 
    357350  # Parse the text in the given context (used by zazen) 
  • trunk/app/models/node.rb

    r1250 r1257  
    491491              # file 
    492492              insert_zafu_headings = false 
    493               if opts[:parent_class] == 'Skin' && attrs['c_ext'] == 'html' && attrs['name'] == 'index' 
     493              if opts[:parent_class] == 'Skin' && ['html','xhtml'].include?(attrs['c_ext']) && attrs['name'] == 'index' 
    494494                attrs['c_ext'] = 'zafu' 
    495495                attrs['name']  = 'Node' 
     
    531531        res[current_obj[:id].to_i] = current_obj 
    532532 
    533         res.merge!(create_nodes_from_folder(:folder => sub_folder, :parent_id => current_obj[:id], :defaults => defaults, :parent_class => opts[:klass], :is_sub => true)) if sub_folder && !current_obj.new_record? 
    534       end 
    535       unless opts[:is_sub] 
    536         res.each do |id,n| 
    537           next unless n.errors.empty? 
    538  
    539           # parse pseudo_ids 
    540           attrs = {} 
    541  
    542           n.export_keys[:zazen].each do |k| 
    543             orig  = n.send(k) 
    544             trans = n.parse_assets(orig, self) 
    545             if trans != orig 
    546               attrs[k] = trans 
    547             end 
    548           end 
    549  
    550           if attrs != {} 
    551             attrs['v_status'] = n.v_status 
    552             n.update_attributes(attrs) 
    553           end 
    554         end 
     533        res.merge!(create_nodes_from_folder(:folder => sub_folder, :parent_id => current_obj[:id], :defaults => defaults, :parent_class => opts[:klass])) if sub_folder && !current_obj.new_record? 
    555534      end 
    556535      res 
     
    729708          value = attributes[key] 
    730709          if value.kind_of?(String) 
     710            # FIXME: ignore if 'v_text' of a TextDocument... 
    731711            res[key] = ZazenParser.new(value,:helper=>self).render(:translate_ids=>:zip, :node=>base_node) 
    732712          else 
     
    875855   
    876856  # Parse text content and replace all relative urls ('../projects/art') by ids ('34') 
    877   def parse_assets(text, helper
     857  def parse_assets(text, helper, key
    878858    # helper is used in textdocuments 
    879859    ZazenParser.new(text,:helper=>helper).render(:translate_ids => :zip, :node=>self) 
     
    881861   
    882862  # Parse text and replace ids '!30!' by their pseudo path '!(img/bird)!' 
    883   def unparse_assets(text, helper
     863  def unparse_assets(text, helper, key
    884864    ZazenParser.new(text,:helper=>helper).render(:translate_ids => :relative_path, :node=>self) 
    885865  end 
     
    13641344    hash = {} 
    13651345    export_keys[:zazen].each do |k| 
    1366       hash[k] = unparse_assets(self.send(k), self
     1346      hash[k] = unparse_assets(self.send(k), self, k
    13671347    end 
    13681348     
     
    13751355  end 
    13761356   
     1357  # List of attribute keys to export in a zml file. 
    13771358  def export_keys 
    13781359    { 
     
    13801361      :dates => [], 
    13811362    } 
     1363  end 
     1364   
     1365  # List of attribute keys to transform (change references, etc). 
     1366  def parse_keys 
     1367    export_keys[:zazen] 
    13821368  end 
    13831369   
  • trunk/app/models/text_document.rb

    r1233 r1257  
    2828   
    2929  # Parse text content and replace all reference to relative urls ('img/footer.png') by their zen_path ('/en/image34.png') 
    30   def parse_assets(text, helper) 
    31     res = text.dup 
    32     ctype = version.content.content_type 
    33     case ctype 
    34     when 'text/css' 
     30  def parse_assets(text, helper, key) 
     31    if key == 'v_text' && version.content.content_type == 'text/css' 
     32      res = text.dup 
    3533      # use skin as root 
    3634      skin = section 
     
    6866    else 
    6967      # unknown type 
    70       errors.add('base', "Invalid content-type #{ctype.inspect} to parse assets.") 
     68      super 
    7169    end 
    7270    res 
     
    7472   
    7573  # Parse text and replace absolute urls ('/en/image30.jpg') by their relative value in the current skin ('img/bird.jpg') 
    76   def unparse_assets(text, helper) 
    77     res = text.dup 
    78     ctype = version.content.content_type 
    79     case ctype 
    80     when 'text/css' 
     74  def unparse_assets(text, helper, key) 
     75    if key == 'v_text' && version.content.content_type == 'text/css' 
     76      res = text.dup 
    8177      # use parent as relative root 
    8278      current_folder = parent.fullpath 
     
    105101        end 
    106102      end 
     103      res 
    107104    else 
    108       # unknown type 
    109       errors.add('base', "invalid content-type #{ctype.inspect} to unparse assets.") 
     105      super 
    110106    end 
    111     res 
    112107  end 
    113108   
     109  # List of keys to export in a zml file. "v_text" is ignored since it's exported in a separate file. 
    114110  def export_keys 
    115111    h = super 
    116112    h[:zazen] -= ['v_text'] 
    117113    h 
     114  end 
     115   
     116  # List of keys which need transformations 
     117  def parse_keys 
     118    (super + (version.content.content_type == 'text/css' ? ['v_text'] : [])).uniq 
    118119  end 
    119120   
  • trunk/lib/parser/lib/rules/zazen.rb

    r1252 r1257  
    158158        eat $& 
    159159        style, id, other_opts, mode, title_opts, title, link = $1, $2, $3, $4, $5, $6, $8 
    160         if node = @helper.find_node_by_pseudo(id, @context[:node]) 
     160        if node = @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    161161          if link && link =~ /^(#{PSEUDO_ID_REGEXP})(.*)$/ 
    162162            rest = $2 
    163             if link_node = @helper.find_node_by_pseudo($1, @context[:node]) 
     163            if link_node = @helper.send(:find_node_by_pseudo, $1, @context[:node]) 
    164164              link = link_node.pseudo_id(@context[:node], @translate_ids || :zip).to_s + rest 
    165165            end 
     
    192192        if link && link =~ /^(#{PSEUDO_ID_REGEXP})(.*)$/ 
    193193          rest = $2 
    194           if link_node = @helper.find_node_by_pseudo($1, @context[:node]) 
     194          if link_node = @helper.send(:find_node_by_pseudo, $1, @context[:node]) 
    195195            link = link_node[:zip].to_s + rest 
    196196          end 
     
    198198        if @translate_ids 
    199199          if @translate_ids != :zip 
    200             node = @helper.find_node_by_pseudo(id, @context[:node]) 
     200            node = @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    201201            id = node.pseudo_id(@context[:node], @translate_ids) if node 
    202202          end 
     
    220220          eat $& 
    221221          title, id = $1, $2 
    222           node = @helper.find_node_by_pseudo(id, @context[:node]) 
     222          node = @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    223223          id = node.pseudo_id(@context[:node], @translate_ids) if node 
    224224          store "\"#{title}\":#{id}" 
     
    237237        eat $& 
    238238        title, pseudo_id, mode_format, mode, format, dash = $1, $2, $3, $4, $5, $6 
    239         if node = @helper.find_node_by_pseudo(pseudo_id, @context[:node]) 
     239        if node = @helper.send(:find_node_by_pseudo, pseudo_id, @context[:node]) 
    240240          if @translate_ids 
    241241            id = "#{node.pseudo_id(@context[:node], @translate_ids)}#{mode_format}" 
     
    328328        if @translate_ids 
    329329          if @translate_ids != :zip 
    330             node = @helper.find_node_by_pseudo(id, @context[:node]) 
     330            node = @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    331331            id = node.pseudo_id(@context[:node], @translate_ids) if node 
    332332          end 
    333333          store "|#{style}#{id == '' ? '' : "#{id}."}#{attribute}#{title}|" 
    334334        else 
    335           node = id == '' ? @context[:node] : @helper.find_node_by_pseudo(id, @context[:node]) 
     335          node = id == '' ? @context[:node] : @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    336336          store @helper.make_table(:style=>style, :node=>node, :attribute=>attribute, :title=>title) 
    337337        end 
     
    343343        text = $& 
    344344        style, id, attribute, title_opts, title = $1, $2, $3, $4, $5 
    345         if node = @helper.find_node_by_pseudo(id, @context[:node]) 
     345        if node = @helper.send(:find_node_by_pseudo, id, @context[:node]) 
    346346          if @translate_ids 
    347347            # replace shortcut 
     
    448448      str.split(',').map do |id| 
    449449        if id.strip =~ /\A(\d+|#{PSEUDO_ID_REGEXP})/ 
    450           if node = @helper.find_node_by_pseudo($1, @context[:node]) 
     450          if node = @helper.send(:find_node_by_pseudo, $1, @context[:node]) 
    451451            # replace shortcut 
    452452            node.pseudo_id(@context[:node], meth) 
  • trunk/test/functional/nodes_controller_test.rb

    r1253 r1257  
    9595  end 
    9696   
     97  def test_import_xhtml 
     98    login(:tiger) 
     99    preserving_files('/test.host/data') do 
     100      post 'import', :id => nodes_zip(:skins), :node => {:klass => 'Skin', :archive => uploaded_archive('jet_30.zip')} 
     101      node_list = assigns(:nodes) 
     102      nodes = {} 
     103      node_list.each do |n| 
     104        nodes[n.name] = n 
     105      end 
     106      assert skin = nodes['jet30'] 
     107      assert_kind_of Skin, skin 
     108       
     109      assert zafu = nodes['Node'] 
     110      assert_kind_of Template, zafu 
     111      assert style = nodes['style'] 
     112      assert_kind_of TextDocument, style 
     113      assert navBar = nodes['navBar'] 
     114      assert_kind_of Image, navBar 
     115      assert xhtmlBgHover = nodes['xhtmlBgHover'] 
     116      assert_kind_of Image, xhtmlBgHover 
     117      assert topIcon = nodes['topIcon'] 
     118      assert_kind_of Image, topIcon 
     119      ['lftPic1', 'lftPic2', 'lftPic3'].each do |p| 
     120        assert nodes[p] 
     121        assert_kind_of Image, nodes[p] 
     122      end 
     123      assert_match %r{#header ul\{\s*background:url\('/oo/image#{navBar.zip}.gif'\)}m, style.v_text 
     124      assert_match %r{a\.xht:hover\{\s*background:url\('/oo/image#{xhtmlBgHover.zip}.gif'\)}, style.v_text 
     125       
     126      # use this template 
     127      status = secure(Node) { nodes(:status) } 
     128      assert status.update_attributes(:skin => 'jet30', :inherit => 0) 
     129      get 'show', 'prefix'=>'oo', 'path'=>['projects', 'cleanWater', "page#{nodes_zip(:status)}.html"] 
     130      assert_response :success 
     131      assert_match %r{posuere eleifend arcu</p>\s*<img [^>]*src\s*=\s*./oo/image#{topIcon.zip}.gif}, @response.body 
     132    end 
     133  end 
     134   
     135  def test_create_nodes_from_folder 
     136    login(:tiger) 
     137    preserving_files('/test.host/data') do 
     138      parent = secure!(Project) { Project.create(:name => 'import', :parent_id => nodes_id(:zena)) } 
     139      assert !parent.new_record?, "Not a new record" 
     140       
     141      nodes = secure!(Node) { Node.create_nodes_from_folder(:folder => File.join(RAILS_ROOT, 'test', 'fixtures', 'import'), :parent_id => parent[:id] )}.values 
     142      @controller.send(:parse_assets, nodes) 
     143      children = parent.find(:all, 'children') 
     144      assert_equal 2, children.size 
     145      assert_equal 4, nodes.size 
     146      bird, doc   = nil, nil 
     147      nodes.each do |n| 
     148        bird = n if n[:name] == 'bird' 
     149        doc  = n if n[:name] == 'document'     
     150      end 
     151      simple = secure!(Node) { Node.find_by_name_and_parent_id('simple', parent[:id]) } 
     152      photos = secure!(Node) { Node.find_by_name_and_parent_id('photos', parent[:id]) } 
     153     
     154      assert_equal 'bird', bird[:name] 
     155      assert_equal 'simple', simple[:name] 
     156      assert_equal 'The sky is blue', simple.v_title 
     157      assert_equal 'jpg', bird.c_ext 
     158      assert_equal 'Le septiÚme ciel', bird.v_title 
     159      versions = secure!(Node) { Node.find(bird[:id]) }.versions 
     160      assert_equal 2, versions.size 
     161      assert_equal 'fr', versions[0].lang 
     162      assert_equal 'en', versions[1].lang 
     163      assert_equal 'Le septiÚme ciel', versions[0].title 
     164      assert_equal 'Photos !', photos.v_title 
     165      assert_match %r{Here are some photos.*!\[\]!}m, photos.v_text 
     166      assert_match %r{!#{bird.zip}_med!}m,     photos.v_text 
     167      assert_match %r{"links":#{simple.zip}}m, photos.v_text 
     168      assert_equal "A simple \"test\":#{simple.zip}", photos.d_foo 
     169      in_photos = photos.find(:all, 'children') 
     170      assert_equal 2, in_photos.size 
     171     
     172      assert_equal bird[:id], in_photos[0][:id] 
     173      assert_equal doc[:id], in_photos[1][:id] 
     174      doc_versions = doc.versions.sort { |a,b| a[:lang] <=> b[:lang]} 
     175      assert_equal 2, doc_versions.size 
     176      assert_match %r{two}, doc_versions[0].text 
     177      assert_match %r{deux}, doc_versions[1].text 
     178    end 
     179  end 
    97180end 
    98181 
  • trunk/test/unit/node_test.rb

    r1250 r1257  
    873873    assert_equal 5,                attrs['five'] 
    874874    assert_equal 'I am done',      attrs['done'] 
    875   end 
    876    
    877   def test_create_nodes_from_folder 
    878     login(:tiger) 
    879     parent = secure!(Project) { Project.create(:name => 'import', :parent_id => nodes_id(:zena)) } 
    880     assert !parent.new_record?, "Not a new record" 
    881     nodes = secure!(Node) { Node.create_nodes_from_folder(:folder => File.join(RAILS_ROOT, 'test', 'fixtures', 'import'), :parent_id => parent[:id] )}.values 
    882     children = parent.find(:all, 'children') 
    883     assert_equal 2, children.size 
    884     assert_equal 4, nodes.size 
    885     bird, doc   = nil, nil 
    886     nodes.each do |n| 
    887       bird = n if n[:name] == 'bird' 
    888       doc  = n if n[:name] == 'document'     
    889     end 
    890     simple = secure!(Node) { Node.find_by_name_and_parent_id('simple', parent[:id]) } 
    891     photos = secure!(Node) { Node.find_by_name_and_parent_id('photos', parent[:id]) } 
    892      
    893     assert_equal 'bird', bird[:name] 
    894     assert_equal 'simple', simple[:name] 
    895     assert_equal 'The sky is blue', simple.v_title 
    896     assert_equal 'jpg', bird.c_ext 
    897     assert_equal 'Le septiÚme ciel', bird.v_title 
    898     versions = secure!(Node) { Node.find(bird[:id]) }.versions 
    899     assert_equal 2, versions.size 
    900     assert_equal 'fr', versions[0].lang 
    901     assert_equal 'en', versions[1].lang 
    902     assert_equal 'Le septiÚme ciel', versions[0].title 
    903     assert_equal 'Photos !', photos.v_title 
    904     assert_match %r{Here are some photos.*!\[\]!}m, photos.v_text 
    905     assert_match %r{!#{bird.zip}_med!}m,     photos.v_text 
    906     assert_match %r{"links":#{simple.zip}}m, photos.v_text 
    907     assert_equal "A simple \"test\":#{simple.zip}", photos.d_foo 
    908     in_photos = photos.find(:all, 'children') 
    909     assert_equal 2, in_photos.size 
    910      
    911     assert_equal bird[:id], in_photos[0][:id] 
    912     assert_equal doc[:id], in_photos[1][:id] 
    913     doc_versions = doc.versions.sort { |a,b| a[:lang] <=> b[:lang]} 
    914     assert_equal 2, doc_versions.size 
    915     assert_match %r{two}, doc_versions[0].text 
    916     assert_match %r{deux}, doc_versions[1].text 
    917875  end 
    918876   
     
    13811339    @node = secure!(Node) { nodes(:status) } 
    13821340    assert @node.update_attributes(:v_text => "Hello this is \"art\":#{nodes_zip(:art)}. !#{nodes_zip(:bird_jpg)}!") 
    1383     assert_equal "Hello this is \"art\":(../../../collections/art). !(../../wiki/bird)!", @node.unparse_assets(@node.v_text, self
     1341    assert_equal "Hello this is \"art\":(../../../collections/art). !(../../wiki/bird)!", @node.unparse_assets(@node.v_text, self, 'v_text'
    13841342  end 
    13851343   
     
    13881346    @node = secure!(Node) { nodes(:status) } 
    13891347    assert @node.update_attributes(:v_text => "Hello this is \"art\":(../../../collections/art).") 
    1390     assert_equal "Hello this is \"art\":#{nodes_zip(:art)}.", @node.parse_assets(@node.v_text, self
     1348    assert_equal "Hello this is \"art\":#{nodes_zip(:art)}.", @node.parse_assets(@node.v_text, self, 'v_text'
    13911349  end 
    13921350   
  • trunk/test/unit/text_document_test.rb

    r1231 r1257  
    6060    helper = ApplicationController.new 
    6161    helper.instance_variable_set(:@visitor, visitor) 
    62     text = node.parse_assets(start, helper
     62    text = node.parse_assets(start, helper, 'v_text'
    6363    assert node.errors.empty? 
    6464    res =<<-END_CSS 
     
    6868    END_CSS 
    6969    assert_equal res, text 
    70     text = node.parse_assets(text, helper
     70    text = node.parse_assets(text, helper, 'v_text'
    7171    assert_equal res, text 
    72     text = node.unparse_assets(text, helper
     72    text = node.unparse_assets(text, helper, 'v_text'
    7373    assert_equal start, text 
    74     text = node.unparse_assets(text, helper
     74    text = node.unparse_assets(text, helper, 'v_text'
    7575    assert_equal start, text 
    7676  end 
     
    9191    helper = ApplicationController.new 
    9292    helper.instance_variable_set(:@visitor, visitor) 
    93     text = node.parse_assets(start, helper
     93    text = node.parse_assets(start, helper, 'v_text'
    9494    assert node.errors.empty? 
    9595    res =<<-END_CSS