Class: Docter::Template

Inherits:
Resource::Base show all
Defined in:
lib/docter/template.rb

Overview

A template for formatting pages. The template is parsed once and processed using each Page to produce an HTML document. Processing can rely on various attributes of the Scope.

A template will require additional files like CSS stylesheets, images, JavaScript, etc. You can associate additional resources with the template using #include and #exclude. These resources are copied to the destination directory when generating output, and served from the integrated Web server.

Defined Under Namespace

Modules: ContextMethods

Instance Attribute Summary collapse

Attributes included from Resource::Reloadable

#filename

Instance Method Summary collapse

Methods included from Resource::Reloadable

#modified, #modified?, #reload, #to_s

Methods included from HTML

inner_text_from, regexp_attribute, regexp_element

Constructor Details

#initialize(*args) ⇒ Template

Returns a new instance of Template.



80
81
82
83
# File 'lib/docter/template.rb', line 80

def initialize(*args)
  super
  @sources = FileList[]
end

Instance Attribute Details

#optionsObject (readonly)

Options passed when creating the template.



78
79
80
# File 'lib/docter/template.rb', line 78

def options
  @options
end

Instance Method Details

#copy_resources(to_dir) ⇒ Object

:call-seq:

copy_resources(to_dir)

Copy resource files to the destination directory.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/docter/template.rb', line 158

def copy_resources(to_dir)
  mkpath to_dir
  @sources.each do |src|
    if File.directory?(src)
      target = File.join(to_dir, File.basename(src))
      mkpath target
      FileList["#{src}/**/*"].reject { |path| File.directory?(path) }.each do |path|
        mkpath File.dirname(path).gsub(/^#{src}/, target)
        cp path, path.gsub(/^#{src}/, target)
      end
    else
      cp src, to_dir
    end
  end
  touch to_dir # For Rake dependency management.
end

#dependenciesObject

:call-seq:

Returns a list of dependencies (resource files, the template file, etc). Useful when creating a Rake task based on this template.



179
180
181
182
# File 'lib/docter/template.rb', line 179

def dependencies
  @sources.map { |path| File.directory?(path) ? FileList[path, File.join(path, '**/*')] : path }.flatten +
    [@filename].compact
end

#exclude(*paths) ⇒ Object

:call-seq:

exclude(*paths) => self

Excludes files or directories from the generated output.



127
128
129
130
# File 'lib/docter/template.rb', line 127

def exclude(*paths)
  @sources.exclude *paths.flatten
  self
end

#find(path) ⇒ Object

:call-seq:

find(path) => file

Returns the location of a file on disk based on the request path.

For example:

template.include('html/index.html', 'images', 'css/*')
map.find('index.html') => 'html/index.html'
map.find('images/logo.png') => 'images/logo.png'
map.find('fancy.css') => 'css/fancy.css'


142
143
144
145
146
147
148
149
150
151
152
# File 'lib/docter/template.rb', line 142

def find(path)
  @sources.inject(nil) do |found, source|
    break found if found
    if File.directory?(source)
      base = File.join(File.dirname(source), '')
      Dir.glob(File.join(source, "/**/*")).find { |file| file.sub(base, '') == path }
    else
      source if File.basename(source) == path
    end 
  end
end

#include(*paths) ⇒ Object Also known as: add

:call-seq:

include(*paths) => self

Adds files and directories included in the generated output.



116
117
118
119
# File 'lib/docter/template.rb', line 116

def include(*paths)
  @sources.include *paths.flatten
  self
end

#render(context) ⇒ Object

:call-seq:

render(context) => html

Renders this template. The template is processed using a context that provides the template with access to various methods and variables, e.g. the page being rendered, or the ToC.

There are two ways to supply a context:

  • Hash – Each key becomes a method you can call on the hash to obtain it’s value. The hash will include a method called template that returns the template itself.

  • Object – Creates a context object that delegates all method calls to this object, and adds the method template that returns the template itself.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/docter/template.rb', line 96

def render(context)
  load
  if Hash === context
    hash = context.merge(:template=>self)
    struct = Struct.new(*hash.keys).new(*hash.values)
    struct.class.send :include, ContextMethods
    @process.call struct
  else
    delegate = Class.new
    context.class.instance_methods.each { |method| delegate.send :define_method, method, &context.method(method) }
    context.class.send :include, ContextMethods
    delegate.send(:define_method, :template) { self }
    @process.call delegate.new
  end
end