require 'hpricot' module Webby module Filters # The BasePath filter is used to rewrite URI paths in HTML documents. This # is useful when the server location of the website is not located at the # root of the webserver (e.g. http://my.site.com/foo/bar). # # The BasePath filter will adjust the URI paths in a given HTML document by # prepending a base path to the URI. This only works for URIs that start # with a leading slash "/". Any other character will exclude the URI from # being modified. # # Assume the user specifies a new URI base in the Webby.site.base # property: # # Webby.site.base = '/foo/bar' # # Here is a snippet from some HTML document. # # Page # a fractal # # When run through the BasePath filter, the resulting snippet would look # like this. # # Page # a fractal # # The +href+ attribute of the anchor tag is modified because it started # with a leading slash. The +src+ attribute of the image tag is not # modified because it lacks the leading slash. # class BasePath # call-seq: # BasePath.new( html, mode ) # # Creates a new BasePath 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 ) @str = str @mode = mode.downcase.to_sym 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: # # Page # # and the user has requested for the base path to be some other directory # on the webserver -- /some/other/directory. The result of the # BasePath filter would be: # # Page # def filter doc = @mode == :xml ? Hpricot.XML(@str) : Hpricot(@str) base_path = ::Webby.site.base attr_rgxp = %r/\[@(\w+)\]$/o sub_rgxp = %r/\A(?=\/)/o ::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) element.set_attribute(@attr_name, a) if a.sub!(sub_rgxp, base_path) end end doc.to_html end end # class BasePath # Rewrite base URIs in the input HTML text. # register :basepath do |input, cursor| if ::Webby.site.base then BasePath.new(input, cursor.page.extension).filter else input end end end # module Filters end # module Webby # EOF