Class: Hyde::Page

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

Overview

page.write(‘~/foo.html’)

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:



112
113
114
115
116
# File 'lib/hyde/page.rb', line 112

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



274
275
276
277
# File 'lib/hyde/page.rb', line 274

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.



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

def file
  @file
end

#projectObject (readonly)

Returns the value of attribute project.



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

def project
  @project
end

Class Method Details

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



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/hyde/page.rb', line 77

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



187
188
189
190
191
192
# File 'lib/hyde/page.rb', line 187

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



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

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

#==(other) ⇒ Object



341
342
343
# File 'lib/hyde/page.rb', line 341

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


314
315
316
# File 'lib/hyde/page.rb', line 314

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

#childrenObject



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/hyde/page.rb', line 291

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 || project.ignored_files.include?(f) }.
    map { |f| self.class[f, project] }.
    compact.sort
end

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



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

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

#default_extObject



176
177
178
179
180
181
182
183
# File 'lib/hyde/page.rb', line 176

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



330
331
332
# File 'lib/hyde/page.rb', line 330

def depth
  breadcrumbs.size
end

#exists?Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/hyde/page.rb', line 194

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

#filepathObject

Returns a short filepath relative to the project path



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

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

#html?Boolean

Returns:

  • (Boolean)


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

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

#index?Boolean

Returns:

  • (Boolean)


318
319
320
# File 'lib/hyde/page.rb', line 318

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

#inspectObject



345
346
347
# File 'lib/hyde/page.rb', line 345

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

#layoutObject



215
216
217
218
219
# File 'lib/hyde/page.rb', line 215

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

#layout?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'lib/hyde/page.rb', line 225

def layout?
  !! layout
end

#markupObject



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

def markup
  parts.last
end

#metaObject



229
230
231
# File 'lib/hyde/page.rb', line 229

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

#mime_typeObject



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

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



334
335
336
337
338
339
# File 'lib/hyde/page.rb', line 334

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

#pageObject



221
222
223
# File 'lib/hyde/page.rb', line 221

def page
  self
end

#parentObject



279
280
281
282
283
284
285
286
287
288
289
# File 'lib/hyde/page.rb', line 279

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)


322
323
324
# File 'lib/hyde/page.rb', line 322

def parent?
  !parent.nil?
end

#pathObject

Returns the URL path for a page.



119
120
121
122
123
124
125
126
127
128
129
# File 'lib/hyde/page.rb', line 119

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



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

def position
  meta[:position] || title
end

#root?Boolean

Returns:

  • (Boolean)


326
327
328
# File 'lib/hyde/page.rb', line 326

def root?
  parent.nil?
end

#siblingsObject



307
308
309
310
311
312
# File 'lib/hyde/page.rb', line 307

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.



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

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)


246
247
248
# File 'lib/hyde/page.rb', line 246

def tilt?
  !! tilt_engine
end

#tilt_engineObject

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



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

def tilt_engine
  Tilt[@file]
end

#tilt_engine_nameObject



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

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

#titleObject Also known as: to_s



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

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

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



209
210
211
212
213
# File 'lib/hyde/page.rb', line 209

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)


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

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.



234
235
236
237
238
239
240
241
242
243
# File 'lib/hyde/page.rb', line 234

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