Skip to content

Commit

Permalink
MAJOR REFACTORING
Browse files Browse the repository at this point in the history
Split out the resource object into layout, page, static and put them in the new
resources folder

Added a partial resource type

Better handling / checking of rendering loops
  • Loading branch information
TwP committed Feb 24, 2008
1 parent 8ad4bd5 commit 6b99a1f
Show file tree
Hide file tree
Showing 19 changed files with 665 additions and 361 deletions.
5 changes: 3 additions & 2 deletions History.txt
@@ -1,9 +1,10 @@
== 0.8.0 / 2008-

* 1 major enhancement
* 2 major enhancements
- Refactored the coderay and graphviz filters into helper methods
accessible from ERB
* 1 minor enhancement
- Added support for partials
* 2 minor enhancements
- Added a template file for creating Atom feeds
- The SITE configuration is available in pages and layouts as
the @config variable
Expand Down
10 changes: 5 additions & 5 deletions lib/webby.rb
Expand Up @@ -96,7 +96,7 @@ def self.exclude
# modification time of the file is important.
#
def self.cairn
@cairn ||= File.join(site.output_dir, '.cairn')
@cairn ||= ::File.join(site.output_dir, '.cairn')
end

# Returns the library path for Webby. If any arguments are given,
Expand Down Expand Up @@ -124,9 +124,9 @@ def self.path( *args )
# the _filename_ does not have to be equivalent to the directory.
#
def self.require_all_libs_relative_to( fname, dir = nil )
dir ||= File.basename(fname, '.*')
search_me = File.expand_path(
File.join(File.dirname(fname), dir, '**', '*.rb'))
dir ||= ::File.basename(fname, '.*')
search_me = ::File.expand_path(
::File.join(::File.dirname(fname), dir, '*.rb'))

Dir.glob(search_me).sort.each {|rb| require rb}
end
Expand All @@ -147,7 +147,7 @@ def try_require( lib )
false
end

Webby.require_all_libs_relative_to __FILE__
Webby.require_all_libs_relative_to(__FILE__)

end # unless defined?

Expand Down
2 changes: 1 addition & 1 deletion lib/webby/auto_builder.rb
Expand Up @@ -56,7 +56,7 @@ def update( *events )
@log.debug "changed #{evt.path}"
next unless test ?f, evt.path
next if evt.path =~ ::Webby.exclude
Resource.new evt.path
Resources.new evt.path
end

@builder.run :load_files => false
Expand Down
8 changes: 4 additions & 4 deletions lib/webby/builder.rb
Expand Up @@ -90,7 +90,7 @@ def run( opts = {} )
load_files if opts[:load_files]
loop_check

Resource.pages.each do |page|
Resources.pages.each do |page|
next unless page.dirty? or opts[:rebuild]

@log.info "creating #{page.destination}"
Expand All @@ -99,7 +99,7 @@ def run( opts = {} )
FileUtils.mkdir_p ::File.dirname(page.destination)

# copy the resource to the output directory if it is static
if page.is_static?
if page.instance_of? Resources::Static
FileUtils.cp page.path, page.destination
FileUtils.chmod 0644, page.destination

Expand All @@ -124,7 +124,7 @@ def load_files
::Find.find(layout_dir, content_dir) do |path|
next unless test ?f, path
next if path =~ ::Webby.exclude
Resource.new path
Resources.new path
end
end

Expand All @@ -133,7 +133,7 @@ def load_files
# error if one is detected.
#
def loop_check
layouts = Resource.layouts
layouts = Resources.layouts

layouts.each do |lyt|
stack = []
Expand Down
2 changes: 2 additions & 0 deletions lib/webby/filters.rb
Expand Up @@ -90,4 +90,6 @@ def handle(filter, handler, *args)
end # module Filters
end # module Webby

Webby.require_all_libs_relative_to(__FILE__)

# EOF
2 changes: 2 additions & 0 deletions lib/webby/helpers.rb
Expand Up @@ -27,4 +27,6 @@ def self.register( helper )
end # module Helper
end # module Webby

Webby.require_all_libs_relative_to(__FILE__)

# EOF
10 changes: 5 additions & 5 deletions lib/webby/helpers/url_helper.rb
Expand Up @@ -39,7 +39,7 @@ def url_for( *args )
anchor = opts.delete(:anchor)
escape = opts.has_key?(:escape) ? opts.delte(:escape) : true

url = Webby::Resource === obj ? obj.url : obj.to_s
url = Webby::Resources::Resource === obj ? obj.url : obj.to_s
url = escape_once(url) if escape
url << "#" << anchor if anchor

Expand All @@ -54,8 +54,8 @@ def url_for( *args )
# method for final URL creation; see the url_for method for
# documentation on those options.
#
# The PagesDB#find method is used to locate the page; see the find method
# for the available options.
# The Resources::DB#find method is used to locate the page; see the find
# method for the available options.
#
# ==== Examples
#
Expand Down Expand Up @@ -96,7 +96,7 @@ def link_to( name, *args )
attrs = opts.delete(:attrs)

url = case url
when String, Webby::Resource
when String, Webby::Resources::Resource
self.url_for(url, opts)
when :back
'javascript:history.back()'
Expand Down Expand Up @@ -210,7 +210,7 @@ def _find_page( args )
link_opts = opts.delete(:url) || {}
link_opts[:attrs] = opts.delete(:attrs)

if Webby::Resource === name
if Webby::Resources::Resource === name
p, name = name, nil
elsif opts.empty? && name
p = @pages.find(Webby.site.find_by.to_sym => name)
Expand Down
84 changes: 70 additions & 14 deletions lib/webby/renderer.rb
Expand Up @@ -5,10 +5,6 @@
unless defined? ::Webby::Renderer

require 'erb'
try_require 'bluecloth'
try_require 'redcloth'
try_require 'haml'
try_require 'sass'

module Webby

Expand All @@ -27,7 +23,10 @@ module Webby
class Renderer
include ERB::Util

class Error < StandardError; end # :nodoc:
# :stopdoc:
class Error < StandardError; end
@@stack = []
# :startdoc:

# call-seq:
# Renderer.write( page )
Expand All @@ -43,7 +42,7 @@ def self.write( page )
::File.open(page.destination, 'w') do |fd|
fd.write renderer.layout_page
end
break unless renderer.__send__(:next_page)
break unless renderer.__send__(:_next_page)
}
end

Expand All @@ -55,13 +54,13 @@ def self.write( page )
# render the filtered page into the desired layout.
#
def initialize( page )
unless page.is_page?
unless page.instance_of? Resources::Page
raise ArgumentError,
"only page resources can be rendered '#{page.path}'"
end

@page = page
@pages = Resource.pages
@pages = Resources.pages
@content = nil
@config = ::Webby.site

Expand All @@ -77,19 +76,25 @@ def initialize( page )
# page's meta-data.
#
def layout_page
layouts = Resource.layouts
layouts = Resources.layouts
obj = @page
str = @page.render(self)

@@stack << @page.path
loop do
lyt = layouts.find :filename => obj.layout
break if lyt.nil?

@content, str = str, ::Webby::File.read(lyt.path)
str = Filters.process(self, lyt, str)
@content, str = str, ::Webby::Resources::File.read(lyt.path)
str = _track_rendering(lyt.path) {
Filters.process(self, lyt, str)
}
@content, obj = nil, lyt
end

@@stack.pop if @page.path == @@stack.last
raise Error, "rendering stack corrupted" unless @@stack.empty?

str
rescue => err
@log.error "while rendering page '#{@page.path}'"
Expand All @@ -103,7 +108,28 @@ def layout_page
# determined from the page's meta-data.
#
def render_page
Filters.process(self, @page, ::Webby::File.read(@page.path))
_track_rendering(@page.path) {
Filters.process(self, @page, ::Webby::Resources::File.read(@page.path))
}
end

# call-seq:
# partial( name ) => string
#
# Finds the partial identified by _name_ and returns the contents after
# rendering. Rendering if performed by filtering the contents of the
# partial using the filters identified in the meta-data of the partial.
#
def partial( name, opts = {} )
fn = '_' + name
part = Resources.partials.find(
:filename => fn, :in_directory => @page.dir ) rescue nil
part ||= Resources.partials.find(:filename => fn)
raise Error, "could not find partial '#{name}'" if part.nil?

_track_rendering(part.path) {
Filters.process(self, part, ::Webby::Resources::File.read(part.path))
}
end

# call-seq:
Expand Down Expand Up @@ -141,13 +167,13 @@ def get_binding
private

# call-seq:
# next_page => true or false
# _next_page => true or false
#
# Returns +true+ if there is a next page to render. Returns +false+ if
# there is no next page or if pagination has not been configured for the
# current page.
#
def next_page
def _next_page
return false unless defined? @pager and @pager

# go to the next page; break out if there is no next page
Expand All @@ -161,9 +187,39 @@ def next_page
true
end

# call-seq:
# _track_rendering( path ) {block}
#
# Keep track of the page rendering for the given _path_. The _block_ is
# where the the page will be rendered.
#
# This method keeps a stack of the current pages being rendeered. It looks
# for duplicates in the stack -- an indication of a rendering loop. When a
# rendering loop is detected, an error is raised.
#
# This method returns whatever is returned from the _block_.
#
def _track_rendering( path )
loop_error = @@stack.include? path
@@stack << path

if loop_error
msg = "rendering loop detected for '#{path}'\n"
msg << " current rendering stack\n\t"
msg << @@stack.join("\n\t")
raise Error, msg
end

yield
ensure
@@stack.pop if path == @@stack.last
end

end # class Renderer
end # module Webby

Webby.require_all_libs_relative_to(__FILE__, 'stelan')

end # unless defined?

# EOF

0 comments on commit 6b99a1f

Please sign in to comment.