Class: Lifer::Entry
- Inherits:
-
Object
- Object
- Lifer::Entry
- Defined in:
- lib/lifer/entry.rb
Overview
An entry is a Lifer file that will be built into the output directory. There are more than one subclass of entry: Markdown entries are the most traditional, but HTML and text files are also very valid entries.
This class provides a baseline of the functionality that all entry subclasses should implement. It also provides the entry generator for all entry subclasses.
Defined Under Namespace
Constant Summary collapse
- DEFAULT_DATE =
We provide a default date for entries that have no date and entry types that otherwise could not have a date due to no real way of getting that metadata.
Time.new(1900, 01, 01, 0, 0, 0, "+00:00")
- FILENAME_DATE_FORMAT =
If a filename contains a date, we should expect it to be in the following format.
/^(\d{4}-\d{1,2}-\d{1,2})-/- TAG_DELIMITER_REGEX =
If tags are represented in YAML frontmatter as a string, they’re split on commas and/or spaces.
/[,\s]+/- TRUNCATION_THRESHOLD =
We truncate anything that needs to be truncated (summaries, meta descriptions) at the following character count.
120
Class Attribute Summary collapse
-
.include_in_feeds ⇒ Object
Returns the value of attribute include_in_feeds.
-
.input_extensions ⇒ Object
Returns the value of attribute input_extensions.
-
.output_extension ⇒ Object
Returns the value of attribute output_extension.
Instance Attribute Summary collapse
-
#collection ⇒ Object
readonly
Returns the value of attribute collection.
-
#file ⇒ Object
readonly
Returns the value of attribute file.
Class Method Summary collapse
-
.generate(file:, collection:) ⇒ Lifer::Entry
The entrypoint for generating entry objects.
-
.manifest ⇒ Array<Lifer::Entry>
Whenever an entry is generated it should be added to the entry manifest.
-
.supported?(filename, file_extensions = supported_file_extensions) ⇒ Boolean
Checks whether the given filename is supported entry type (using only its file extension).
Instance Method Summary collapse
-
#authors ⇒ Array<String>
Given the entry’s frontmatter, we should be able to get a list of authors.
-
#body ⇒ String
This method returns the full text of the entry, only removing the frontmatter.
- #feedable? ⇒ Boolean
-
#frontmatter ⇒ Hash
Frontmatter is a widely supported YAML metadata block found at the top of text–often Markdown–files.
-
#full_text ⇒ String
The full text of the entry.
-
#initialize(file:, collection:) ⇒ Lifer::Entry
constructor
When a new entry is initialized we expect the file to already exist, and we expect to know which ‘Lifer::Collection` it belongs to.
-
#path ⇒ String
The expected, absolute URI path to the entry.
-
#permalink(host: Lifer.setting(:global, :host)) ⇒ String
Using the current Lifer configuration, we can calculate the expected permalink for the entry.
-
#published_at ⇒ Time
The entry’s publication date.
-
#summary ⇒ String
If given a summary in the frontmatter of the entry, we can use this to provide a summary.
-
#tags ⇒ Array<Lifer::Tag>
Locates and returns all tags defined in the entry.
-
#title ⇒ String
Returns the title of the entry.
- #to_html ⇒ Object
-
#updated_at(fallback: nil) ⇒ Time
The entry’s last updated date.
Constructor Details
#initialize(file:, collection:) ⇒ Lifer::Entry
When a new entry is initialized we expect the file to already exist, and we expect to know which ‘Lifer::Collection` it belongs to.
122 123 124 125 |
# File 'lib/lifer/entry.rb', line 122 def initialize(file:, collection:) @file = Pathname file @collection = collection end |
Class Attribute Details
.include_in_feeds ⇒ Object
Returns the value of attribute include_in_feeds.
19 20 21 |
# File 'lib/lifer/entry.rb', line 19 def include_in_feeds @include_in_feeds end |
.input_extensions ⇒ Object
Returns the value of attribute input_extensions.
20 21 22 |
# File 'lib/lifer/entry.rb', line 20 def input_extensions @input_extensions end |
.output_extension ⇒ Object
Returns the value of attribute output_extension.
21 22 23 |
# File 'lib/lifer/entry.rb', line 21 def output_extension @output_extension end |
Instance Attribute Details
#collection ⇒ Object (readonly)
Returns the value of attribute collection.
52 53 54 |
# File 'lib/lifer/entry.rb', line 52 def collection @collection end |
#file ⇒ Object (readonly)
Returns the value of attribute file.
52 53 54 |
# File 'lib/lifer/entry.rb', line 52 def file @file end |
Class Method Details
.generate(file:, collection:) ⇒ Lifer::Entry
The entrypoint for generating entry objects. We should never end up with ‘Lifer::Entry` records: only subclasses.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/lifer/entry.rb', line 61 def generate(file:, collection:) error!(file) unless File.exist?(file) if (new_entry = subclass_for(file)&.new(file:, collection:)) Lifer.entry_manifest << new_entry new_entry. end new_entry end |
.manifest ⇒ Array<Lifer::Entry>
Whenever an entry is generated it should be added to the entry manifest. This lets us get a list of all generated entries.
76 77 78 79 80 |
# File 'lib/lifer/entry.rb', line 76 def manifest return Lifer.entry_manifest if self == Lifer::Entry Lifer.entry_manifest.select { |entry| entry.class == self } end |
.supported?(filename, file_extensions = supported_file_extensions) ⇒ Boolean
Checks whether the given filename is supported entry type (using only its file extension).
89 90 91 |
# File 'lib/lifer/entry.rb', line 89 def supported?(filename, file_extensions= supported_file_extensions) file_extensions.any? { |ext| filename.end_with? ext } end |
Instance Method Details
#authors ⇒ Array<String>
Given the entry’s frontmatter, we should be able to get a list of authors. We always prefer authors (as opposed to a singular author) because it makes handling both cases easier in the long run.
The return value here is likely an author’s name. Whether that’s a full name, a first name, or a handle is up to the end user.
135 136 137 |
# File 'lib/lifer/entry.rb', line 135 def Array(frontmatter[:author] || frontmatter[:authors]).compact end |
#body ⇒ String
This method returns the full text of the entry, only removing the frontmatter. It should not parse anything other than frontmatter.
143 144 145 146 147 |
# File 'lib/lifer/entry.rb', line 143 def body return full_text.strip unless frontmatter? full_text.gsub(Lifer::FRONTMATTER_REGEX, "").strip end |
#feedable? ⇒ Boolean
149 150 151 152 153 154 155 156 |
# File 'lib/lifer/entry.rb', line 149 def feedable? if (setting = self.class.include_in_feeds).nil? raise NotImplementedError, I18n.t("entry.feedable_error", entry_class: self.class) end setting end |
#frontmatter ⇒ Hash
Frontmatter is a widely supported YAML metadata block found at the top of text–often Markdown–files. We attempt to parse all entries for frontmatter.
163 164 165 166 167 168 169 170 |
# File 'lib/lifer/entry.rb', line 163 def frontmatter return {} unless frontmatter? Lifer::Utilities.symbolize_keys( YAML.load full_text[Lifer::FRONTMATTER_REGEX, 1], permitted_classes: [Time] ) end |
#full_text ⇒ String
The full text of the entry.
175 176 177 |
# File 'lib/lifer/entry.rb', line 175 def full_text @full_text ||= File.readlines(file).join if file end |
#path ⇒ String
The expected, absolute URI path to the entry. For example:
/index.html
/blog/my-trip-to-toronto.html
210 |
# File 'lib/lifer/entry.rb', line 210 def path = permalink(host: "/") |
#permalink(host: Lifer.setting(:global, :host)) ⇒ String
Using the current Lifer configuration, we can calculate the expected permalink for the entry. For example:
https://example.com/index.html
https://example.com/blog/my-trip-to-toronto.html
This would be useful for indexes and feeds and so on.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/lifer/entry.rb', line 188 def permalink(host: Lifer.setting(:global, :host)) cached_permalink_variable = "@entry_permalink_" + Digest::SHA1.hexdigest(host) instance_variable_get(cached_permalink_variable) || instance_variable_set( cached_permalink_variable, File.join( host, Lifer::URIStrategy.find(collection.setting :uri_strategy) .new(root: Lifer.root) .output_file(self) ) ) end |
#published_at ⇒ Time
The entry’s publication date. The published date can be inferred in a few ways. The priority is:
1. the frontmatter's `published_at` field
2. the frontmatter's `published` field
3. the frontamtter's `date` field
4. The date in the filename.
Since text files would only store dates as simple strings, it’s nice to attempt to convert those into Ruby date or datetime objects.
225 226 227 228 229 230 231 |
# File 'lib/lifer/entry.rb', line 225 def published_at date_for frontmatter[:published_at], frontmatter[:published], frontmatter[:date], filename_date, missing_metadata_translation_key: "entry.no_published_at_metadata" end |
#summary ⇒ String
If given a summary in the frontmatter of the entry, we can use this to provide a summary.
Since subclasses may have more sophisticated access to the document, they may override this method with their own distinct implementations.
240 241 242 |
# File 'lib/lifer/entry.rb', line 240 def summary return frontmatter[:summary] if frontmatter[:summary] end |
#tags ⇒ Array<Lifer::Tag>
Locates and returns all tags defined in the entry.
247 248 249 250 |
# File 'lib/lifer/entry.rb', line 247 def ||= candidate_tag_names .map { Lifer::Tag.build_or_update(name: _1, entries: [self]) } end |
#title ⇒ String
Returns the title of the entry. Every entry subclass must implement this method so that builders have access to some kind of title for each entry.
256 257 258 |
# File 'lib/lifer/entry.rb', line 256 def title raise NotImplementedError, I18n.t("shared.not_implemented_method") end |
#to_html ⇒ Object
260 261 262 |
# File 'lib/lifer/entry.rb', line 260 def to_html raise NotImplementedError, I18n.t("shared.not_implemented_method") end |
#updated_at(fallback: nil) ⇒ Time
The entry’s last updated date. In the frontmatter, the last updated date can be specified using one of two fields. In priority order:
1. the `updated_at` field
2. the `updated` field
The developer could set a fallback value as a fallback. For example, when building RSS feeds one might want the value of ‘#published_at` if there is no last updated date.
278 279 280 281 282 |
# File 'lib/lifer/entry.rb', line 278 def updated_at(fallback: nil) date_for frontmatter[:updated_at], frontmatter[:updated], default_date: fallback end |