bridgetown-core 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +42 -0
  3. data/bridgetown-core.gemspec +46 -0
  4. data/lib/bridgetown-core.rb +202 -0
  5. data/lib/bridgetown-core/cache.rb +190 -0
  6. data/lib/bridgetown-core/cleaner.rb +111 -0
  7. data/lib/bridgetown-core/collection.rb +279 -0
  8. data/lib/bridgetown-core/command.rb +106 -0
  9. data/lib/bridgetown-core/commands/build.rb +96 -0
  10. data/lib/bridgetown-core/commands/clean.rb +43 -0
  11. data/lib/bridgetown-core/commands/console.rb +56 -0
  12. data/lib/bridgetown-core/commands/doctor.rb +172 -0
  13. data/lib/bridgetown-core/commands/help.rb +34 -0
  14. data/lib/bridgetown-core/commands/new.rb +148 -0
  15. data/lib/bridgetown-core/commands/serve.rb +273 -0
  16. data/lib/bridgetown-core/commands/serve/servlet.rb +68 -0
  17. data/lib/bridgetown-core/configuration.rb +323 -0
  18. data/lib/bridgetown-core/converter.rb +54 -0
  19. data/lib/bridgetown-core/converters/identity.rb +39 -0
  20. data/lib/bridgetown-core/converters/markdown.rb +108 -0
  21. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +132 -0
  22. data/lib/bridgetown-core/converters/smartypants.rb +69 -0
  23. data/lib/bridgetown-core/convertible.rb +237 -0
  24. data/lib/bridgetown-core/deprecator.rb +50 -0
  25. data/lib/bridgetown-core/document.rb +475 -0
  26. data/lib/bridgetown-core/drops/bridgetown_drop.rb +32 -0
  27. data/lib/bridgetown-core/drops/collection_drop.rb +20 -0
  28. data/lib/bridgetown-core/drops/document_drop.rb +69 -0
  29. data/lib/bridgetown-core/drops/drop.rb +215 -0
  30. data/lib/bridgetown-core/drops/excerpt_drop.rb +19 -0
  31. data/lib/bridgetown-core/drops/page_drop.rb +14 -0
  32. data/lib/bridgetown-core/drops/site_drop.rb +62 -0
  33. data/lib/bridgetown-core/drops/static_file_drop.rb +14 -0
  34. data/lib/bridgetown-core/drops/unified_payload_drop.rb +26 -0
  35. data/lib/bridgetown-core/drops/url_drop.rb +132 -0
  36. data/lib/bridgetown-core/entry_filter.rb +108 -0
  37. data/lib/bridgetown-core/errors.rb +20 -0
  38. data/lib/bridgetown-core/excerpt.rb +202 -0
  39. data/lib/bridgetown-core/external.rb +62 -0
  40. data/lib/bridgetown-core/filters.rb +467 -0
  41. data/lib/bridgetown-core/filters/date_filters.rb +110 -0
  42. data/lib/bridgetown-core/filters/grouping_filters.rb +64 -0
  43. data/lib/bridgetown-core/filters/url_filters.rb +79 -0
  44. data/lib/bridgetown-core/frontmatter_defaults.rb +238 -0
  45. data/lib/bridgetown-core/generator.rb +5 -0
  46. data/lib/bridgetown-core/hooks.rb +103 -0
  47. data/lib/bridgetown-core/layout.rb +57 -0
  48. data/lib/bridgetown-core/liquid_extensions.rb +22 -0
  49. data/lib/bridgetown-core/liquid_renderer.rb +71 -0
  50. data/lib/bridgetown-core/liquid_renderer/file.rb +67 -0
  51. data/lib/bridgetown-core/liquid_renderer/table.rb +75 -0
  52. data/lib/bridgetown-core/log_adapter.rb +151 -0
  53. data/lib/bridgetown-core/log_writer.rb +60 -0
  54. data/lib/bridgetown-core/mime.types +867 -0
  55. data/lib/bridgetown-core/page.rb +214 -0
  56. data/lib/bridgetown-core/page_without_a_file.rb +14 -0
  57. data/lib/bridgetown-core/path_manager.rb +31 -0
  58. data/lib/bridgetown-core/plugin.rb +80 -0
  59. data/lib/bridgetown-core/plugin_manager.rb +60 -0
  60. data/lib/bridgetown-core/publisher.rb +23 -0
  61. data/lib/bridgetown-core/reader.rb +185 -0
  62. data/lib/bridgetown-core/readers/collection_reader.rb +22 -0
  63. data/lib/bridgetown-core/readers/data_reader.rb +75 -0
  64. data/lib/bridgetown-core/readers/layout_reader.rb +48 -0
  65. data/lib/bridgetown-core/readers/page_reader.rb +24 -0
  66. data/lib/bridgetown-core/readers/post_reader.rb +74 -0
  67. data/lib/bridgetown-core/readers/static_file_reader.rb +24 -0
  68. data/lib/bridgetown-core/regenerator.rb +195 -0
  69. data/lib/bridgetown-core/related_posts.rb +52 -0
  70. data/lib/bridgetown-core/renderer.rb +261 -0
  71. data/lib/bridgetown-core/site.rb +469 -0
  72. data/lib/bridgetown-core/static_file.rb +205 -0
  73. data/lib/bridgetown-core/tags/component.rb +34 -0
  74. data/lib/bridgetown-core/tags/highlight.rb +111 -0
  75. data/lib/bridgetown-core/tags/include.rb +220 -0
  76. data/lib/bridgetown-core/tags/link.rb +41 -0
  77. data/lib/bridgetown-core/tags/post_url.rb +107 -0
  78. data/lib/bridgetown-core/url.rb +164 -0
  79. data/lib/bridgetown-core/utils.rb +367 -0
  80. data/lib/bridgetown-core/utils/ansi.rb +57 -0
  81. data/lib/bridgetown-core/utils/exec.rb +26 -0
  82. data/lib/bridgetown-core/utils/internet.rb +37 -0
  83. data/lib/bridgetown-core/utils/platforms.rb +80 -0
  84. data/lib/bridgetown-core/utils/thread_event.rb +31 -0
  85. data/lib/bridgetown-core/utils/win_tz.rb +75 -0
  86. data/lib/bridgetown-core/version.rb +5 -0
  87. data/lib/bridgetown-core/watcher.rb +139 -0
  88. data/lib/site_template/.gitignore +6 -0
  89. data/lib/site_template/bridgetown.config.yml +21 -0
  90. data/lib/site_template/frontend/javascript/index.js +3 -0
  91. data/lib/site_template/frontend/styles/index.scss +17 -0
  92. data/lib/site_template/package.json +23 -0
  93. data/lib/site_template/src/404.html +9 -0
  94. data/lib/site_template/src/_data/site_metadata.yml +11 -0
  95. data/lib/site_template/src/_includes/footer.html +3 -0
  96. data/lib/site_template/src/_includes/head.html +9 -0
  97. data/lib/site_template/src/_includes/navbar.html +4 -0
  98. data/lib/site_template/src/_layouts/default.html +15 -0
  99. data/lib/site_template/src/_layouts/home.html +7 -0
  100. data/lib/site_template/src/_layouts/page.html +7 -0
  101. data/lib/site_template/src/_layouts/post.html +7 -0
  102. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +26 -0
  103. data/lib/site_template/src/about.md +11 -0
  104. data/lib/site_template/src/index.md +7 -0
  105. data/lib/site_template/webpack.config.js +60 -0
  106. data/rake/release.rake +30 -0
  107. metadata +106 -1
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Converter < Plugin
5
+ # Public: Get or set the highlighter prefix. When an argument is specified,
6
+ # the prefix will be set. If no argument is specified, the current prefix
7
+ # will be returned.
8
+ #
9
+ # highlighter_prefix - The String prefix (default: nil).
10
+ #
11
+ # Returns the String prefix.
12
+ def self.highlighter_prefix(highlighter_prefix = nil)
13
+ unless defined?(@highlighter_prefix) && highlighter_prefix.nil?
14
+ @highlighter_prefix = highlighter_prefix
15
+ end
16
+ @highlighter_prefix
17
+ end
18
+
19
+ # Public: Get or set the highlighter suffix. When an argument is specified,
20
+ # the suffix will be set. If no argument is specified, the current suffix
21
+ # will be returned.
22
+ #
23
+ # highlighter_suffix - The String suffix (default: nil).
24
+ #
25
+ # Returns the String suffix.
26
+ def self.highlighter_suffix(highlighter_suffix = nil)
27
+ unless defined?(@highlighter_suffix) && highlighter_suffix.nil?
28
+ @highlighter_suffix = highlighter_suffix
29
+ end
30
+ @highlighter_suffix
31
+ end
32
+
33
+ # Initialize the converter.
34
+ #
35
+ # Returns an initialized Converter.
36
+ def initialize(config = {})
37
+ @config = config
38
+ end
39
+
40
+ # Get the highlighter prefix.
41
+ #
42
+ # Returns the String prefix.
43
+ def highlighter_prefix
44
+ self.class.highlighter_prefix
45
+ end
46
+
47
+ # Get the highlighter suffix.
48
+ #
49
+ # Returns the String suffix.
50
+ def highlighter_suffix
51
+ self.class.highlighter_suffix
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Converters
5
+ # Identity converter. Returns same content as given.
6
+ # For more info on converters see https://bridgetownrb.com/docs/plugins/converters/
7
+ class Identity < Converter
8
+ priority :lowest
9
+
10
+ # Public: Does the given extension match this converter's list of acceptable extensions?
11
+ # Takes one argument: the file's extension (including the dot).
12
+ #
13
+ # _ext - The String extension to check (not relevant here)
14
+ #
15
+ # Returns true since it always matches.
16
+ def matches(_ext)
17
+ true
18
+ end
19
+
20
+ # Public: The extension to be given to the output file (including the dot).
21
+ #
22
+ # ext - The String extension or original file.
23
+ #
24
+ # Returns The String output file extension.
25
+ def output_ext(ext)
26
+ ext
27
+ end
28
+
29
+ # Logic to do the content conversion.
30
+ #
31
+ # content - String content of file (without front matter).
32
+ #
33
+ # Returns a String of the converted content.
34
+ def convert(content)
35
+ content
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Converters
5
+ # Markdown converter.
6
+ # For more info on converters see https://bridgetownrb.com/docs/plugins/converters/
7
+ class Markdown < Converter
8
+ highlighter_prefix "\n"
9
+ highlighter_suffix "\n"
10
+
11
+ def setup
12
+ return if @setup ||= false
13
+
14
+ unless (@parser = get_processor)
15
+ Bridgetown.logger.error "Markdown processor:", "#{@config["markdown"].inspect} \
16
+ is not a valid Markdown processor."
17
+ Bridgetown.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
18
+ Bridgetown.logger.error ""
19
+ raise Errors::FatalException, "Invalid Markdown processor given: #{@config["markdown"]}"
20
+ end
21
+
22
+ @cache = Bridgetown::Cache.new("Bridgetown::Converters::Markdown")
23
+ @setup = true
24
+ end
25
+
26
+ # RuboCop does not allow reader methods to have names starting with `get_`
27
+ # To ensure compatibility, this check has been disabled on this method
28
+ #
29
+ # rubocop:disable Naming/AccessorMethodName
30
+ def get_processor
31
+ case @config["markdown"].downcase
32
+ when "kramdown" then KramdownParser.new(@config)
33
+ else
34
+ custom_processor
35
+ end
36
+ end
37
+ # rubocop:enable Naming/AccessorMethodName
38
+
39
+ # Public: Provides you with a list of processors comprised of the ones we support internally
40
+ # and the ones that you have provided to us
41
+ #
42
+ # Returns an array of symbols.
43
+ def valid_processors
44
+ [:kramdown] + third_party_processors
45
+ end
46
+
47
+ # Public: A list of processors that you provide via plugins.
48
+ #
49
+ # Returns an array of symbols
50
+ def third_party_processors
51
+ self.class.constants - [:KramdownParser, :PRIORITIES]
52
+ end
53
+
54
+ # Does the given extension match this converter's list of acceptable extensions?
55
+ # Takes one argument: the file's extension (including the dot).
56
+ #
57
+ # ext - The String extension to check.
58
+ #
59
+ # Returns true if it matches, false otherwise.
60
+ def matches(ext)
61
+ extname_list.include?(ext.downcase)
62
+ end
63
+
64
+ # Public: The extension to be given to the output file (including the dot).
65
+ #
66
+ # ext - The String extension or original file.
67
+ #
68
+ # Returns The String output file extension.
69
+ def output_ext(_ext)
70
+ ".html"
71
+ end
72
+
73
+ # Logic to do the content conversion.
74
+ #
75
+ # content - String content of file (without front matter).
76
+ #
77
+ # Returns a String of the converted content.
78
+ def convert(content)
79
+ setup
80
+ @cache.getset(content) do
81
+ @parser.convert(content)
82
+ end
83
+ end
84
+
85
+ def extname_list
86
+ @extname_list ||= @config["markdown_ext"].split(",").map! { |e| ".#{e.downcase}" }
87
+ end
88
+
89
+ private
90
+
91
+ def custom_processor
92
+ converter_name = @config["markdown"]
93
+ self.class.const_get(converter_name).new(@config) if custom_class_allowed?(converter_name)
94
+ end
95
+
96
+ # Private: Determine whether a class name is an allowed custom
97
+ # markdown class name.
98
+ #
99
+ # parser_name - the name of the parser class
100
+ #
101
+ # Returns true if the parser name contains only alphanumeric characters and is defined
102
+ # within Bridgetown::Converters::Markdown
103
+ def custom_class_allowed?(parser_name)
104
+ parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(parser_name.to_sym)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,132 @@
1
+ # Frozen-string-literal: true
2
+
3
+ module Kramdown
4
+ # A Kramdown::Document subclass meant to optimize memory usage from initializing
5
+ # a kramdown document for parsing.
6
+ #
7
+ # The optimization is by using the same options Hash (and its derivatives) for
8
+ # converting all Markdown documents in a Bridgetown site.
9
+ class BridgetownDocument < Document
10
+ class << self
11
+ attr_reader :options, :parser
12
+
13
+ # The implementation is basically the core logic in +Kramdown::Document#initialize+
14
+ #
15
+ # rubocop:disable Naming/MemoizedInstanceVariableName
16
+ def setup(options)
17
+ @cache ||= {}
18
+
19
+ # reset variables on a subsequent set up with a different options Hash
20
+ unless @cache[:id] == options.hash
21
+ @options = @parser = nil
22
+ @cache[:id] = options.hash
23
+ end
24
+
25
+ @options ||= Options.merge(options).freeze
26
+ @parser ||= begin
27
+ parser_name = (@options[:input] || "kramdown").to_s
28
+ parser_name = parser_name[0..0].upcase + parser_name[1..-1]
29
+ try_require("parser", parser_name)
30
+
31
+ if Parser.const_defined?(parser_name)
32
+ Parser.const_get(parser_name)
33
+ else
34
+ raise Kramdown::Error, "kramdown has no parser to handle the specified " \
35
+ "input format: #{@options[:input]}"
36
+ end
37
+ end
38
+ end
39
+ # rubocop:enable Naming/MemoizedInstanceVariableName
40
+
41
+ private
42
+
43
+ def try_require(type, name)
44
+ require "kramdown/#{type}/#{Utils.snake_case(name)}"
45
+ rescue LoadError
46
+ false
47
+ end
48
+ end
49
+
50
+ def initialize(source, options = {})
51
+ BridgetownDocument.setup(options)
52
+
53
+ @options = BridgetownDocument.options
54
+ @root, @warnings = BridgetownDocument.parser.parse(source, @options)
55
+ end
56
+
57
+ # Use Kramdown::Converter::Html class to convert this document into HTML.
58
+ #
59
+ # The implementation is basically an optimized version of core logic in
60
+ # +Kramdown::Document#method_missing+ from kramdown-2.1.0.
61
+ def to_html
62
+ output, warnings = Kramdown::Converter::Html.convert(@root, @options)
63
+ @warnings.concat(warnings)
64
+ output
65
+ end
66
+ end
67
+ end
68
+
69
+ #
70
+
71
+ module Bridgetown
72
+ module Converters
73
+ class Markdown
74
+ class KramdownParser
75
+ def initialize(config)
76
+ @main_fallback_highlighter = config["highlighter"] || "rouge"
77
+ @config = config["kramdown"] || {}
78
+ @highlighter = nil
79
+ setup
80
+ load_dependencies
81
+ end
82
+
83
+ # Setup and normalize the configuration:
84
+ # * Create Kramdown if it doesn't exist.
85
+ # * Set syntax_highlighter
86
+ # * Make sure `syntax_highlighter_opts` exists.
87
+ def setup
88
+ @config["syntax_highlighter"] ||= highlighter
89
+ @config["syntax_highlighter_opts"] ||= {}
90
+ @config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
91
+ end
92
+
93
+ def convert(content)
94
+ document = Kramdown::BridgetownDocument.new(content, @config)
95
+ html_output = document.to_html
96
+ if @config["show_warnings"]
97
+ document.warnings.each do |warning|
98
+ Bridgetown.logger.warn "Kramdown warning:", warning
99
+ end
100
+ end
101
+ html_output
102
+ end
103
+
104
+ private
105
+
106
+ def load_dependencies
107
+ require "kramdown-parser-gfm" if @config["input"] == "GFM"
108
+
109
+ # `mathjax` emgine is bundled within kramdown-2.x and will be handled by
110
+ # kramdown itself.
111
+ if (math_engine = @config["math_engine"]) && math_engine != "mathjax"
112
+ Bridgetown::External.require_with_graceful_fail("kramdown-math-#{math_engine}")
113
+ end
114
+ end
115
+
116
+ # config[kramdown][syntax_higlighter] >
117
+ # config[highlighter]
118
+ def highlighter
119
+ return @highlighter if @highlighter
120
+
121
+ if @config["syntax_highlighter"]
122
+ return @highlighter = @config[
123
+ "syntax_highlighter"
124
+ ]
125
+ end
126
+
127
+ @highlighter = @main_fallback_highlighter
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kramdown
4
+ module Parser
5
+ class SmartyPants < Kramdown::Parser::Kramdown
6
+ def initialize(source, options)
7
+ super
8
+ @block_parsers = [:block_html, :content]
9
+ @span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
10
+ end
11
+
12
+ def parse_content
13
+ add_text @src.scan(%r!\A.*\n!)
14
+ end
15
+ define_parser(:content, %r!\A!)
16
+ end
17
+ end
18
+ end
19
+
20
+ module Bridgetown
21
+ module Converters
22
+ # SmartyPants converter.
23
+ # For more info on converters see https://bridgetownrb.com/docs/plugins/converters/
24
+ class SmartyPants < Converter
25
+ priority :low
26
+
27
+ def initialize(config)
28
+ Bridgetown::External.require_with_graceful_fail "kramdown" unless defined?(Kramdown)
29
+ @config = config["kramdown"].dup || {}
30
+ @config[:input] = :SmartyPants
31
+ end
32
+
33
+ # Does the given extension match this converter's list of acceptable extensions?
34
+ # Takes one argument: the file's extension (including the dot).
35
+ #
36
+ # ext - The String extension to check.
37
+ #
38
+ # Returns true if it matches, false otherwise.
39
+ def matches(_ext)
40
+ false
41
+ end
42
+
43
+ # Public: The extension to be given to the output file (including the dot).
44
+ #
45
+ # ext - The String extension or original file.
46
+ #
47
+ # Returns The String output file extension.
48
+ def output_ext(_ext)
49
+ nil
50
+ end
51
+
52
+ # Logic to do the content conversion.
53
+ #
54
+ # content - String content of file (without front matter).
55
+ #
56
+ # Returns a String of the converted content.
57
+ def convert(content)
58
+ document = Kramdown::Document.new(content, @config)
59
+ html_output = document.to_html.chomp
60
+ if @config["show_warnings"]
61
+ document.warnings.each do |warning|
62
+ Bridgetown.logger.warn "Kramdown warning:", warning.sub(%r!^Warning:\s+!, "")
63
+ end
64
+ end
65
+ html_output
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Convertible provides methods for converting a pagelike item
4
+ # from a certain type of markup into actual content
5
+ #
6
+ # Requires
7
+ # self.site -> Bridgetown::Site
8
+ # self.content
9
+ # self.content=
10
+ # self.data=
11
+ # self.ext=
12
+ # self.output=
13
+ # self.name
14
+ # self.path
15
+ # self.type -> :page or :post
16
+
17
+ module Bridgetown
18
+ module Convertible
19
+ # Returns the contents as a String.
20
+ def to_s
21
+ content || ""
22
+ end
23
+
24
+ # Whether the file is published or not, as indicated in YAML front-matter
25
+ def published?
26
+ !(data.key?("published") && data["published"] == false)
27
+ end
28
+
29
+ # Read the YAML frontmatter.
30
+ #
31
+ # base - The String path to the dir containing the file.
32
+ # name - The String filename of the file.
33
+ # opts - optional parameter to File.read, default at site configs
34
+ #
35
+ # Returns nothing.
36
+ # rubocop:disable Metrics/AbcSize
37
+ def read_yaml(base, name, opts = {})
38
+ filename = File.join(base, name)
39
+
40
+ begin
41
+ self.content = File.read(@path || site.in_source_dir(base, name),
42
+ **Utils.merged_file_read_opts(site, opts))
43
+ if content =~ Document::YAML_FRONT_MATTER_REGEXP
44
+ self.content = $POSTMATCH
45
+ self.data = SafeYAML.load(Regexp.last_match(1))
46
+ end
47
+ rescue Psych::SyntaxError => e
48
+ Bridgetown.logger.warn "YAML Exception reading #{filename}: #{e.message}"
49
+ raise e if site.config["strict_front_matter"]
50
+ rescue StandardError => e
51
+ Bridgetown.logger.warn "Error reading file #{filename}: #{e.message}"
52
+ raise e if site.config["strict_front_matter"]
53
+ end
54
+
55
+ self.data ||= {}
56
+
57
+ validate_data! filename
58
+ validate_permalink! filename
59
+
60
+ self.data
61
+ end
62
+ # rubocop:enable Metrics/AbcSize
63
+
64
+ def validate_data!(filename)
65
+ unless self.data.is_a?(Hash)
66
+ raise Errors::InvalidYAMLFrontMatterError,
67
+ "Invalid YAML front matter in #{filename}"
68
+ end
69
+ end
70
+
71
+ def validate_permalink!(filename)
72
+ if self.data["permalink"]&.to_s&.empty?
73
+ raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
74
+ end
75
+ end
76
+
77
+ # Transform the contents based on the content type.
78
+ #
79
+ # Returns the transformed contents.
80
+ def transform
81
+ _renderer.convert(content)
82
+ end
83
+
84
+ # Determine the extension depending on content_type.
85
+ #
86
+ # Returns the String extension for the output file.
87
+ # e.g. ".html" for an HTML output file.
88
+ def output_ext
89
+ _renderer.output_ext
90
+ end
91
+
92
+ # Determine which converter to use based on this convertible's
93
+ # extension.
94
+ #
95
+ # Returns the Converter instance.
96
+ def converters
97
+ _renderer.converters
98
+ end
99
+
100
+ # Render Liquid in the content
101
+ #
102
+ # content - the raw Liquid content to render
103
+ # payload - the payload for Liquid
104
+ # info - the info for Liquid
105
+ #
106
+ # Returns the converted content
107
+ def render_liquid(content, payload, info, path)
108
+ _renderer.render_liquid(content, payload, info, path)
109
+ end
110
+
111
+ # Convert this Convertible's data to a Hash suitable for use by Liquid.
112
+ #
113
+ # Returns the Hash representation of this Convertible.
114
+ def to_liquid(attrs = nil)
115
+ further_data = \
116
+ (attrs || self.class::ATTRIBUTES_FOR_LIQUID).each_with_object({}) do |attribute, hsh|
117
+ hsh[attribute] = send(attribute)
118
+ end
119
+
120
+ defaults = site.frontmatter_defaults.all(relative_path, type)
121
+ Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
122
+ end
123
+
124
+ # The type of a document,
125
+ # i.e., its classname downcase'd and to_sym'd.
126
+ #
127
+ # Returns the type of self.
128
+ def type
129
+ :pages if is_a?(Page)
130
+ end
131
+
132
+ # returns the owner symbol for hook triggering
133
+ def hook_owner
134
+ :pages if is_a?(Page)
135
+ end
136
+
137
+ # TODO: Depricated
138
+ # Used to determine CoffeeScript and Sass/SCSS files.
139
+ def asset_file?
140
+ false
141
+ end
142
+
143
+ # Determine whether the file should be rendered with Liquid.
144
+ #
145
+ # Returns true if the file has Liquid Tags or Variables, false otherwise.
146
+ def render_with_liquid?
147
+ return false if data["render_with_liquid"] == false
148
+
149
+ Bridgetown::Utils.has_liquid_construct?(content)
150
+ end
151
+
152
+ # Determine whether the file should be placed into layouts.
153
+ #
154
+ # Returns false if the document is an asset file or if the front matter
155
+ # specifies `layout: none`
156
+ def place_in_layout?
157
+ !(asset_file? || no_layout?)
158
+ end
159
+
160
+ # Checks if the layout specified in the document actually exists
161
+ #
162
+ # layout - the layout to check
163
+ #
164
+ # Returns true if the layout is invalid, false if otherwise
165
+ def invalid_layout?(layout)
166
+ !data["layout"].nil? && layout.nil? && !(is_a? Bridgetown::Excerpt)
167
+ end
168
+
169
+ # Recursively render layouts
170
+ #
171
+ # layouts - a list of the layouts
172
+ # payload - the payload for Liquid
173
+ # info - the info for Liquid
174
+ #
175
+ # Returns nothing
176
+ def render_all_layouts(layouts, payload, info)
177
+ _renderer.layouts = layouts
178
+ self.output = _renderer.place_in_layouts(output, payload, info)
179
+ ensure
180
+ @_renderer = nil # this will allow the modifications above to disappear
181
+ end
182
+
183
+ # Add any necessary layouts to this convertible document.
184
+ #
185
+ # payload - The site payload Drop or Hash.
186
+ # layouts - A Hash of {"name" => "layout"}.
187
+ #
188
+ # Returns nothing.
189
+ def do_layout(payload, layouts)
190
+ self.output = _renderer.tap do |renderer|
191
+ renderer.layouts = layouts
192
+ renderer.payload = payload
193
+ end.run
194
+
195
+ Bridgetown.logger.debug "Post-Render Hooks:", relative_path
196
+ Bridgetown::Hooks.trigger hook_owner, :post_render, self
197
+ ensure
198
+ @_renderer = nil # this will allow the modifications above to disappear
199
+ end
200
+
201
+ # Write the generated page file to the destination directory.
202
+ #
203
+ # dest - The String path to the destination dir.
204
+ #
205
+ # Returns nothing.
206
+ def write(dest)
207
+ path = destination(dest)
208
+ FileUtils.mkdir_p(File.dirname(path))
209
+ Bridgetown.logger.debug "Writing:", path
210
+ File.write(path, output, :mode => "wb")
211
+ Bridgetown::Hooks.trigger hook_owner, :post_write, self
212
+ end
213
+
214
+ # Accessor for data properties by Liquid.
215
+ #
216
+ # property - The String name of the property to retrieve.
217
+ #
218
+ # Returns the String value or nil if the property isn't included.
219
+ def [](property)
220
+ if self.class::ATTRIBUTES_FOR_LIQUID.include?(property)
221
+ send(property)
222
+ else
223
+ data[property]
224
+ end
225
+ end
226
+
227
+ private
228
+
229
+ def _renderer
230
+ @_renderer ||= Bridgetown::Renderer.new(site, self)
231
+ end
232
+
233
+ def no_layout?
234
+ data["layout"] == "none"
235
+ end
236
+ end
237
+ end