darthapo (owner)

Revisions

gist: 10318 Download_button fork
public
Description:
A webby filter for turning absolute paths (paths that start with a slash "/") into relative paths ("../").
Public Clone URL: git://gist.github.com/10318.git
Embed All Files: show embed
relative_paths.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# A webby filter for turning absolute paths (paths that start with a slash "/")
# into relative paths ("../").
#
# Should be used as a filter for Layouts.
#
# Created by: M@ McCray (http://mattmccray.com)
 
require 'hpricot'
 
 
# Patch Webby's Renderer class so we can have access to the target page
# (so filtering on layouts will work right...)
class Webby::Renderer
  attr_accessor :page
end
 
class Webby::Resources::Page
  def url
    return @url unless @url.nil?
    @url = super
 
    # Uncomment this to return to default behavior of
    # only referencing the parent folder for index pages...
    #@url = File.dirname(@url) if filename == 'index'
 
    @url
  end
end
 
# Used Webby::Filters::BasePath as an example...
class RelativePaths
 
  # call-seq:
  # RelativePaths.new( html, mode, page )
  #
  # Creates a new RelativePaths filter that will operate on the given _html_
  # string. The _mode_ is either 'xml' or 'html' and determines how Hpricot
  # will handle the parsing of the input string.
  #
  def initialize( str, mode, page )
    @str = str
    @mode = (mode || 'html').downcase.to_sym
    @page = page
  end
 
  # call-seq:
  # filter => html
  #
  # Process the original html document passed to the filter when it was
  # created. The document will be scanned and the basepath for certain
  # elements will be modified.
  #
  # For example, if a document contains the following line:
  #
  # <a href="/link/to/another/page.html">Page</a>
  #
  # And the document is located at /my/other/dir/file.txt, the result of
  # the filter would be:
  #
  # <a href="../../../link/to/another/page.html">Page</a>
  #
  def filter
    doc = @mode == :xml ? Hpricot.XML(@str) : Hpricot(@str)
    attr_rgxp = %r/\[@(\w+)\]$/o
path_to_root = ""
path_parts = @page.destination.split('/') - SITE.output_dir.split('/')
(path_parts.length - 1).times { path_to_root += "../" }
Webby.site.xpaths.each do |xpath|
@attr_name = nil
doc.search(xpath).each do |element|
@attr_name ||= attr_rgxp.match(xpath)[1]
a = element.get_attribute(@attr_name)
if a[0..0] == '/' # Only 'fix' absolute URIs
          new_uri = path_to_root + a[1..-1]
         # puts "Updating URI: #{a}"
         # puts " to: #{new_uri}"
          element.set_attribute(@attr_name, new_uri)
        end
      end
    end
 
    doc.to_html
  end
 
end # class RelativePaths
 
 
# Rewrite base URIs in the input HTML text.
#
Webby::Filters.register :relativepaths do |input, cursor|
  page = cursor.page.is_a?(Webby::Resources::Page) ? cursor.page : cursor.renderer.page
  RelativePaths.new(input, cursor.page.extension, page).filter
end
 
# EOF