Class: Bridgetown::GeneratedPage

Inherits:
Object
  • Object
show all
Includes:
LayoutPlaceable, Localizable, Publishable, Transformable
Defined in:
lib/bridgetown-core/generated_page.rb

Direct Known Subclasses

PrototypePage

Constant Summary collapse

HTML_EXTENSIONS =

A set of extensions that are considered HTML or HTML-like so we should not alter them

%w(
  .html
  .xhtml
  .htm
).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Transformable

#transform_content, #transform_with_layout

Methods included from Publishable

#publishable?, #published?

Methods included from Localizable

#all_locales, #localeless_path, #matches_resource?

Methods included from LayoutPlaceable

#no_layout?, #place_in_layout?

Constructor Details

#initialize(site, base, dir, name, from_plugin: false) ⇒ GeneratedPage

Initialize a new GeneratedPage

rubocop:disable Metrics/ParameterLists

Parameters:

  • site (Bridgetown::Site)
  • base (String)

    path to the source

  • dir (String)

    path between the source and the file

  • name (String)

    filename of the file.

  • from_plugin (Boolean) (defaults to: false)

    true if the Page file is located in a Gem-based plugin folder



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bridgetown-core/generated_page.rb', line 36

def initialize(site, base, dir, name, from_plugin: false)
  @site = site
  @base = base
  @dir  = dir
  @name = name
  @ext = File.extname(name)
  @basename = File.basename(name, ".*")
  @path = from_plugin ? File.join(base, dir, name) : site.in_source_dir(base, dir, name)

  process

  self.data ||= HashWithDotAccess::Hash.new

  Bridgetown::Hooks.trigger :generated_pages, :post_init, self
end

Instance Attribute Details

#basenameObject

Returns the value of attribute basename.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def basename
  @basename
end

#contentObject

Returns the value of attribute content.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def content
  @content
end

#dataObject

Returns the value of attribute data.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def data
  @data
end

#dirString

The generated directory into which the page will be placed upon generation. This is derived from the permalink or, if permalink is absent, will be '/'

Returns:

  • (String)


77
78
79
80
81
82
83
84
# File 'lib/bridgetown-core/generated_page.rb', line 77

def dir
  if url.end_with?("/")
    url
  else
    url_dir = File.dirname(url)
    url_dir.end_with?("/") ? url_dir : "#{url_dir}/"
  end
end

#extObject Also known as: extname

Returns the value of attribute ext.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def ext
  @ext
end

#fast_refresh_orderBoolean (readonly)

Returns:

  • (Boolean)


15
16
17
# File 'lib/bridgetown-core/generated_page.rb', line 15

def fast_refresh_order
  @fast_refresh_order
end

#nameObject

Returns the value of attribute name.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def name
  @name
end

#original_resourceObject

Returns the value of attribute original_resource.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def original_resource
  @original_resource
end

#outputObject

Returns the value of attribute output.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def output
  @output
end

#paginatorObject

Returns the value of attribute paginator.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def paginator
  @paginator
end

#siteObject

Returns the value of attribute site.



11
12
13
# File 'lib/bridgetown-core/generated_page.rb', line 11

def site
  @site
end

Instance Method Details

#[](property) ⇒ Object

Accessor for data properties by Liquid

Parameters:

  • property (String)

    name of the property to retrieve

Returns:

  • (Object)


63
64
65
# File 'lib/bridgetown-core/generated_page.rb', line 63

def [](property)
  data[property]
end


99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/bridgetown-core/generated_page.rb', line 99

def add_permalink_suffix(template, permalink_style)
  template = template.dup

  case permalink_style
  when :pretty, :simple
    template << "/"
  else
    template << "/" if permalink_style.to_s.end_with?("/")
    template << ":output_ext" if permalink_style.to_s.end_with?(".*")
  end

  template
end

#converter_output_extObject



198
199
200
201
202
203
204
# File 'lib/bridgetown-core/generated_page.rb', line 198

def converter_output_ext
  if output_exts.size == 1
    output_exts.last
  else
    output_exts[-2]
  end
end

#convertersArray<Bridgetown::Converter>

Returns:



213
214
215
# File 'lib/bridgetown-core/generated_page.rb', line 213

def converters
  @converters ||= site.matched_converters_for_convertible(self)
end

#destination(dest) ⇒ String

Obtain destination path.

Parameters:

  • dest (String)

    path to the destination dir

Returns:

  • (String)


258
259
260
261
262
263
# File 'lib/bridgetown-core/generated_page.rb', line 258

def destination(dest)
  path = site.in_dest_dir(dest, Utils.unencode_uri(url))
  path = File.join(path, "index") if url.end_with?("/")
  path << output_ext unless path.end_with? output_ext
  path
end

#html?Boolean

Returns the Boolean of whether this Page is HTML or not.

Returns:

  • (Boolean)


283
284
285
# File 'lib/bridgetown-core/generated_page.rb', line 283

def html?
  HTML_EXTENSIONS.include?(output_ext)
end

#index?Boolean

Returns the Boolean of whether this Page is an index file or not.

Returns:

  • (Boolean)


288
289
290
# File 'lib/bridgetown-core/generated_page.rb', line 288

def index?
  basename == "index"
end

#inspectObject

Returns the object as a debug String.



278
279
280
# File 'lib/bridgetown-core/generated_page.rb', line 278

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

#layoutBridgetown::Layout

Layout associated with this resource This will output a warning if the layout can't be found.

Returns:



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/bridgetown-core/generated_page.rb', line 154

def layout
  return @layout if @layout
  return if no_layout?

  @layout = site.layouts[data.layout].tap do |layout|
    unless layout
      Bridgetown.logger.warn "Generated Page:", "Layout '#{data.layout}' " \
                                                "requested via #{relative_path} does not exist."
    end
  end
end

#mark_for_fast_refresh!Object



304
305
306
307
# File 'lib/bridgetown-core/generated_page.rb', line 304

def mark_for_fast_refresh!
  @fast_refresh_order = site.fast_refresh_ordering
  site.fast_refresh_ordering += 1
end

#output_extString

The output extension of the page.

Returns:

  • (String)


185
186
187
# File 'lib/bridgetown-core/generated_page.rb', line 185

def output_ext
  @output_ext ||= permalink_ext || converter_output_ext
end

#output_extsObject



206
207
208
209
210
# File 'lib/bridgetown-core/generated_page.rb', line 206

def output_exts
  @output_exts ||= converters.filter_map do |c|
    c.output_ext(extname)
  end
end

#pathObject

The path to the source file



172
173
174
175
# File 'lib/bridgetown-core/generated_page.rb', line 172

def path
  # TODO: is this trip really necessary?!
  data.fetch("path") { relative_path }
end

The full path and filename of the post. Defined in the YAML of the post body



95
96
97
# File 'lib/bridgetown-core/generated_page.rb', line 95

def permalink
  data&.permalink
end


189
190
191
192
193
194
195
196
# File 'lib/bridgetown-core/generated_page.rb', line 189

def permalink_ext
  page_permalink = permalink
  if page_permalink &&
      !page_permalink.end_with?("/")
    permalink_ext = File.extname(page_permalink)
    permalink_ext unless permalink_ext.empty?
  end
end

#place_into_layoutsObject



242
243
244
245
246
247
248
249
250
251
# File 'lib/bridgetown-core/generated_page.rb', line 242

def place_into_layouts
  Bridgetown.logger.debug "Placing in Layouts:", relative_path
  rendered_output = content.dup

  site.validated_layouts_for(self, data.layout).each do |layout|
    rendered_output = transform_with_layout(layout, rendered_output, self)
  end

  self.output = rendered_output
end

#processObject

Overide this in subclasses for custom initialization behavior



167
168
169
# File 'lib/bridgetown-core/generated_page.rb', line 167

def process
  # no-op by default
end

#relative_pathObject

The path to the page source file, relative to the site source



178
179
180
# File 'lib/bridgetown-core/generated_page.rb', line 178

def relative_path
  @relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).delete_prefix("/")
end

#slotsArray<Bridgetown::Slot>

Returns:



68
69
70
# File 'lib/bridgetown-core/generated_page.rb', line 68

def slots
  @slots ||= []
end

#templateString

The template of the permalink.

Returns:

  • (String)


116
117
118
119
120
121
122
123
124
# File 'lib/bridgetown-core/generated_page.rb', line 116

def template
  if !html?
    "/:dir/:basename:output_ext"
  elsif index?
    "/:dir/"
  else
    add_permalink_suffix("/:dir/:basename", site.permalink_style)
  end
end

#to_liquidBridgetown::Drops::GeneratedPageDrop

Liquid representation of current page



89
90
91
# File 'lib/bridgetown-core/generated_page.rb', line 89

def to_liquid
  @liquid_drop ||= Drops::GeneratedPageDrop.new(self)
end

#to_sObject

Returns the contents as a String.



54
55
56
# File 'lib/bridgetown-core/generated_page.rb', line 54

def to_s
  output || content || ""
end

#transform!Object

rubocop:todo Metrics



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/bridgetown-core/generated_page.rb', line 217

def transform! # rubocop:todo Metrics
  Bridgetown.logger.debug "Transforming:", relative_path

  internal_error = nil
  Signalize.effect do
    if !@fast_refresh_order && @previously_transformed_content
      self.content = @previously_transformed_content
      mark_for_fast_refresh! if site.config.fast_refresh && write?
      next
    end

    trigger_hooks :pre_render
    @previously_transformed_content ||= content
    self.content = transform_content(self)
    place_in_layout? ? place_into_layouts : self.output = content.dup
    trigger_hooks :post_render
  rescue StandardError, SyntaxError => e
    internal_error = e
  end

  raise internal_error if internal_error

  self
end

#trigger_hooks(hook_name, *args) ⇒ Object



292
293
294
# File 'lib/bridgetown-core/generated_page.rb', line 292

def trigger_hooks(hook_name, *args)
  Bridgetown::Hooks.trigger :generated_pages, hook_name, self, *args
end

#typeObject



296
297
298
# File 'lib/bridgetown-core/generated_page.rb', line 296

def type
  :generated_pages
end

#unmark_for_fast_refresh!Object



309
310
311
312
# File 'lib/bridgetown-core/generated_page.rb', line 309

def unmark_for_fast_refresh!
  @fast_refresh_order = nil
  original_resource&.unmark_for_fast_refresh!
end

#urlString Also known as: relative_url

The generated relative url of this page. e.g. /about.html.

Returns:

  • (String)


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/bridgetown-core/generated_page.rb', line 129

def url
  return @url if @url

  tmpl = permalink || template
  placeholders = { dir: @dir, basename:, output_ext: }

  results = placeholders.inject(tmpl) do |result, token|
    break result if result.index(":").nil?

    if token.last.nil?
      # Remove leading "/" to avoid generating urls with `//`
      result.gsub("/:#{token.first}", "")
    else
      result.gsub(":#{token.first}", token.last)
    end
  end.then { Addressable::URI.normalize_component _1 }

  @url = "/#{results.sub("#", "%23")}".gsub("..", "/").gsub("./", "").squeeze("/")
end

#write(dest) ⇒ Object

Write the generated page file to the destination directory.

Parameters:

  • dest (String)

    path to the destination dir



268
269
270
271
272
273
274
275
# File 'lib/bridgetown-core/generated_page.rb', line 268

def write(dest)
  path = destination(dest)
  FileUtils.mkdir_p(File.dirname(path))
  Bridgetown.logger.debug "Writing:", path
  File.write(path, output, mode: "wb")
  unmark_for_fast_refresh!
  Bridgetown::Hooks.trigger :generated_pages, :post_write, self
end

#write?Boolean

Returns:

  • (Boolean)


300
301
302
# File 'lib/bridgetown-core/generated_page.rb', line 300

def write?
  true
end