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.



58
59
60
61
# File 'lib/docter/template.rb', line 58

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

Instance Attribute Details

#optionsObject (readonly)

Options passed when creating the template.



56
57
58
# File 'lib/docter/template.rb', line 56

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.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/docter/template.rb', line 136

def copy_resources(to_dir)
  mkpath to_dir
  @sources.each do |file|
    if File.directory?(file)
      base = File.dirname(file) + "/"
      FileList[File.join(file, "**/*")].each do |file|
        target = File.join(to_dir, file.sub(base, ""))
        mkpath File.dirname(target)
        cp file, target
      end
    else
      cp file, 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.



157
158
159
160
# File 'lib/docter/template.rb', line 157

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.



105
106
107
108
# File 'lib/docter/template.rb', line 105

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"


120
121
122
123
124
125
126
127
128
129
130
# File 'lib/docter/template.rb', line 120

def find(path)
  @sources.inject(nil) do |found, file|
    break found if found
    if File.directory?(file)
      base = File.dirname(file) + "/"
      FileList["#{file}/**/*"].find { |file| file.sub(base, "") == path }
    else
      file if File.basename(file) == 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.



94
95
96
97
# File 'lib/docter/template.rb', line 94

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.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/docter/template.rb', line 74

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