Class: Hyde::Page

Inherits:
Object
  • Object
show all
Defined in:
lib/hyde/page.rb

Direct Known Subclasses

Layout

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, project = Hyde.project) ⇒ Page

Returns a new instance of Page.

Raises:



41
42
43
44
45
# File 'lib/hyde/page.rb', line 41

def initialize(file, project=Hyde.project)
  @file = File.expand_path(file)  if file.is_a?(String)
  @project = project
  raise Error  if project.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &blk) ⇒ Object



203
204
205
206
# File 'lib/hyde/page.rb', line 203

def method_missing(meth, *args, &blk)
  super  unless meta.instance_variable_get(:@table).keys.include?(meth.to_sym)
  meta.send(meth)
end

Instance Attribute Details

#fileObject (readonly)

Returns the value of attribute file.



4
5
6
# File 'lib/hyde/page.rb', line 4

def file
  @file
end

#projectObject (readonly)

Returns the value of attribute project.



3
4
5
# File 'lib/hyde/page.rb', line 3

def project
  @project
end

Class Method Details

.[](id, project = Hyde.project) ⇒ Object



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
# File 'lib/hyde/page.rb', line 6

def self.[](id, project=Hyde.project)
  site_path = root_path(project)
  return nil  if site_path.nil?

  site = lambda { |*x| File.join site_path, *(x.compact) }
  try  = lambda { |_id| p = new(_id, project); p if p.exists? }

  # For paths like '/' or '/hello/'
  nonfile = File.basename(id).gsub('/','').empty?

  # Account for:
  #   ~/mysite/site/about/us.html.haml
  #   about/us.html.haml => ~/mysite/site/about/us.html.haml
  #   about/us.html      => ~/mysite/site/about/us.html.*
  #   about/us.html      => ~/mysite/site/about/us.*
  #   about/us           => ~/mysite/site/about/us/index.*
  #
  page   = try[id]
  page ||= try[site[id]]
  unless nonfile
    page ||= try[Dir[site["#{id}.*"]].first]
    page ||= try[Dir[site["#{id.to_s.sub(/\.[^\.]*/,'')}.*"]].first]
  end
  page ||= try[Dir[site[id, "index.*"]].first]

  # Subclass
  if page && page.tilt? && page.meta[:type]
    klass = Page.get_type(page.meta[:type])
    raise Error, "#{page.filepath}: Class for type '#{page.meta[:type]}' not found"  unless klass
    page = klass.new(id, project)
  end

  page
end

.get_type(type) ⇒ Object

Returns a page subtype.

Examples:

Page.get_type(‘post’) => Hyde::Page::Post



116
117
118
119
120
121
# File 'lib/hyde/page.rb', line 116

def self.get_type(type)
  type  = type.to_s
  klass = type[0..0].upcase + type[1..-1].downcase
  klass = klass.to_sym
  self.const_get(klass)  if self.const_defined?(klass)
end

Instance Method Details

#<=>(other) ⇒ Object



78
79
80
81
82
# File 'lib/hyde/page.rb', line 78

def <=>(other)
  result   = self.position <=> other.position
  result ||= self.position.to_s <=> other.position.to_s
  result
end

#==(other) ⇒ Object



267
268
269
# File 'lib/hyde/page.rb', line 267

def ==(other)
  self.path == other.path
end


240
241
242
# File 'lib/hyde/page.rb', line 240

def breadcrumbs
  Set.new(parent? ? (parent.breadcrumbs + [self]) : [self])
end

#childrenObject



220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/hyde/page.rb', line 220

def children
  files = if index?
    # about/index.html => about/*
    File.expand_path('../*', @file)
  else
    # products.html => products/*
    base = File.basename(@file, '.*')
    File.expand_path("../#{base}/*", @file)
  end

  Set.new Dir[files].reject { |f| f == @file }.map { |f| self.class[f, project] }.compact.sort
end

#content(locals = {}, tilt_options = {}, &blk) ⇒ Object



133
134
135
136
# File 'lib/hyde/page.rb', line 133

def content(locals={}, tilt_options={}, &blk)
  return markup  unless tilt?
  tilt(tilt_options).render(dup.extend(Helpers), locals, &blk)
end

#default_extObject



105
106
107
108
109
110
111
112
# File 'lib/hyde/page.rb', line 105

def default_ext
  case mime_type
  when 'text/html' then 'html'
  when 'text/css' then 'css'
  when 'text/xml' then 'xml'
  when 'application/javascript' then 'js'
  end
end

#depthObject



256
257
258
# File 'lib/hyde/page.rb', line 256

def depth
  breadcrumbs.size
end

#exists?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/hyde/page.rb', line 123

def exists?
  @file and File.file?(@file||'') and valid?
end

#filepathObject

Returns a short filepath relative to the project path



61
62
63
64
65
66
# File 'lib/hyde/page.rb', line 61

def filepath
  root = project.root
  fpath = file
  fpath = fpath[root.size..-1]  if fpath[0...root.size] == root
  fpath
end

#html?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/hyde/page.rb', line 84

def html?
  mime_type == 'text/html'
end

#index?Boolean

Returns:

  • (Boolean)


244
245
246
# File 'lib/hyde/page.rb', line 244

def index?
  File.basename(path, '.*') == 'index'
end

#inspectObject



271
272
273
# File 'lib/hyde/page.rb', line 271

def inspect
  "<##{self.class.name} #{path.inspect}>"
end

#layoutObject



144
145
146
147
148
# File 'lib/hyde/page.rb', line 144

def layout
  layout = meta.layout
  layout ||= default_layout  unless meta.layout == false
  Layout[layout, page]  if layout
end

#layout?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/hyde/page.rb', line 154

def layout?
  !! layout
end

#markupObject



199
200
201
# File 'lib/hyde/page.rb', line 199

def markup
  parts.last
end

#metaObject



158
159
160
# File 'lib/hyde/page.rb', line 158

def meta
  @meta ||= Meta.new(parts.first)
end

#mime_typeObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hyde/page.rb', line 88

def mime_type
  return nil  unless tilt?

  mime = nil
  mime = tilt_engine.default_mime_type  if tilt_engine.respond_to?(:default_mime_type)

  mime ||= case tilt_engine.name
    when 'Tilt::SassTemplate' then 'text/css'
    when 'Tilt::ScssTemplate' then 'text/css'
    when 'Tilt::LessTemplate' then 'text/css'
    when 'Tilt::CoffeeScriptTemplate' then 'application/javascript'
    when 'Tilt::NokogiriTemplate' then 'text/xml'
    when 'Tilt::BuilderTemplate' then 'text/xml'
    else 'text/html'
  end
end

#nextObject



260
261
262
263
264
265
# File 'lib/hyde/page.rb', line 260

def next
  page = self
  while true do
    page.siblings.index(self)
  end
end

#pageObject



150
151
152
# File 'lib/hyde/page.rb', line 150

def page
  self
end

#parentObject



208
209
210
211
212
213
214
215
216
217
218
# File 'lib/hyde/page.rb', line 208

def parent
  parts = path.split('/') # ['', 'about', 'index.html']

  try = lambda { |newpath| p = self.class[newpath, project]; p if p && p.path != path }

  # Absolute root
  return nil  if index? and parts.size <= 2

  parent   = try[parts[0...-1].join('/')]  # ['','about'] => '/about'
  parent ||= try['/']                      # Home
end

#parent?Boolean

Returns:

  • (Boolean)


248
249
250
# File 'lib/hyde/page.rb', line 248

def parent?
  !parent.nil?
end

#pathObject

Returns the URL path for a page.



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/hyde/page.rb', line 48

def path
  path = @file.sub(File.expand_path(root_path), '')

  # if xx.haml (but not xx.html.haml), 
  if tilt?
    path = path.sub(/\.[^\.]*$/, "")
    path += ".#{default_ext}"  unless File.basename(path).include?('.')
  end

  path
end

#positionObject



74
75
76
# File 'lib/hyde/page.rb', line 74

def position
  meta[:position] || title
end

#root?Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/hyde/page.rb', line 252

def root?
  parent.nil?
end

#siblingsObject



233
234
235
236
237
238
# File 'lib/hyde/page.rb', line 233

def siblings
  pages = (p = parent and p.children)
  return Set.new  unless pages
  return Set.new  unless pages.include?(self)
  Set.new(pages)
end

#tilt(tilt_options = {}) ⇒ Object

Returns the tilt layout.



189
190
191
192
193
194
195
196
197
# File 'lib/hyde/page.rb', line 189

def tilt(tilt_options={})
  if tilt?
    parts
    # HAML options and such (like :escape_html)
    options = project.config.tilt_options_for(@file, tilt_options)
    offset = @offset || 1
    Tilt.new(@file, offset, options) { markup }
  end
end

#tilt?Boolean

Checks if the file is supported by tilt.

Returns:

  • (Boolean)


175
176
177
# File 'lib/hyde/page.rb', line 175

def tilt?
  !! tilt_engine
end

#tilt_engineObject

Returns the Tilt engine (eg Tilt::HamlEngine).



180
181
182
# File 'lib/hyde/page.rb', line 180

def tilt_engine
  Tilt[@file]
end

#tilt_engine_nameObject



184
185
186
# File 'lib/hyde/page.rb', line 184

def tilt_engine_name
  tilt_engine.name.match(/:([^:]*)(?:Template?)$/)[1]
end

#titleObject Also known as: to_s



68
69
70
# File 'lib/hyde/page.rb', line 68

def title
  (meta.title if tilt?) || path
end

#to_html(locals = {}, tilt_options = {}, &blk) ⇒ Object



138
139
140
141
142
# File 'lib/hyde/page.rb', line 138

def to_html(locals={}, tilt_options={}, &blk)
  html = content(locals, tilt_options, &blk)
  html = layout.to_html(locals, tilt_options) { html }  if layout?
  html
end

#valid?Boolean

Make sure that it’s in the right folder.

Returns:

  • (Boolean)


128
129
130
131
# File 'lib/hyde/page.rb', line 128

def valid?
  prefix = File.expand_path(root_path)
  prefix == File.expand_path(@file)[0...prefix.size]
end

#write(out = nil) ⇒ Object

Writes to the given output file.



163
164
165
166
167
168
169
170
171
172
# File 'lib/hyde/page.rb', line 163

def write(out=nil)
  out ||= project.path(:output, path)
  FileUtils.mkdir_p File.dirname(out)

  if tilt?
    File.open(out, 'w') { |f| f.write to_html({}, :build => true) }
  else
    FileUtils.cp file, out
  end
end