bridgetown-core 0.19.3 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bridgetown-core.gemspec +1 -1
- data/lib/bridgetown-core.rb +30 -11
- data/lib/bridgetown-core/cleaner.rb +7 -1
- data/lib/bridgetown-core/collection.rb +173 -77
- data/lib/bridgetown-core/commands/base.rb +9 -0
- data/lib/bridgetown-core/commands/configure.rb +4 -0
- data/lib/bridgetown-core/commands/console.rb +4 -0
- data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
- data/lib/bridgetown-core/concerns/site/configurable.rb +7 -3
- data/lib/bridgetown-core/concerns/site/content.rb +57 -15
- data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
- data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
- data/lib/bridgetown-core/concerns/site/writable.rb +11 -1
- data/lib/bridgetown-core/concerns/validatable.rb +1 -0
- data/lib/bridgetown-core/configuration.rb +39 -19
- data/lib/bridgetown-core/converter.rb +14 -0
- data/lib/bridgetown-core/converters/identity.rb +0 -9
- data/lib/bridgetown-core/converters/markdown.rb +14 -4
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +3 -0
- data/lib/bridgetown-core/current.rb +10 -0
- data/lib/bridgetown-core/document.rb +6 -14
- data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
- data/lib/bridgetown-core/drops/page_drop.rb +4 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +81 -0
- data/lib/bridgetown-core/drops/site_drop.rb +33 -8
- data/lib/bridgetown-core/drops/unified_payload_drop.rb +4 -0
- data/lib/bridgetown-core/entry_filter.rb +10 -23
- data/lib/bridgetown-core/errors.rb +0 -2
- data/lib/bridgetown-core/filters.rb +2 -1
- data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
- data/lib/bridgetown-core/layout.rb +2 -2
- data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
- data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
- data/lib/bridgetown-core/model/base.rb +138 -0
- data/lib/bridgetown-core/model/builder_origin.rb +40 -0
- data/lib/bridgetown-core/model/file_origin.rb +119 -0
- data/lib/bridgetown-core/model/origin.rb +38 -0
- data/lib/bridgetown-core/page.rb +9 -1
- data/lib/bridgetown-core/plugin_manager.rb +0 -2
- data/lib/bridgetown-core/publisher.rb +7 -1
- data/lib/bridgetown-core/reader.rb +25 -12
- data/lib/bridgetown-core/readers/data_reader.rb +3 -4
- data/lib/bridgetown-core/readers/post_reader.rb +1 -1
- data/lib/bridgetown-core/regenerator.rb +8 -1
- data/lib/bridgetown-core/related_posts.rb +1 -1
- data/lib/bridgetown-core/renderer.rb +5 -12
- data/lib/bridgetown-core/resource/base.rb +275 -0
- data/lib/bridgetown-core/resource/destination.rb +49 -0
- data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
- data/lib/bridgetown-core/resource/taxonomy_term.rb +25 -0
- data/lib/bridgetown-core/resource/taxonomy_type.rb +47 -0
- data/lib/bridgetown-core/resource/transformer.rb +173 -0
- data/lib/bridgetown-core/ruby_template_view.rb +4 -0
- data/lib/bridgetown-core/site.rb +9 -1
- data/lib/bridgetown-core/static_file.rb +33 -10
- data/lib/bridgetown-core/url.rb +1 -0
- data/lib/bridgetown-core/utils.rb +40 -40
- data/lib/bridgetown-core/utils/platforms.rb +1 -0
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/site_template/webpack.config.js.erb +8 -6
- metadata +28 -21
- data/lib/bridgetown-core/page_without_a_file.rb +0 -17
- data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
- data/lib/bridgetown-core/utils/exec.rb +0 -26
- data/lib/bridgetown-core/utils/internet.rb +0 -37
- data/lib/bridgetown-core/utils/win_tz.rb +0 -75
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Bridgetown
         | 
| 4 | 
            +
              module Resource
         | 
| 5 | 
            +
                class TaxonomyTerm
         | 
| 6 | 
            +
                  attr_reader :resource
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  attr_reader :label
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  attr_reader :type
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def initialize(resource:, label:, type:)
         | 
| 13 | 
            +
                    @resource = resource
         | 
| 14 | 
            +
                    @label = label
         | 
| 15 | 
            +
                    @type = type
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def to_liquid
         | 
| 19 | 
            +
                    {
         | 
| 20 | 
            +
                      label: label,
         | 
| 21 | 
            +
                    }
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Bridgetown
         | 
| 4 | 
            +
              module Resource
         | 
| 5 | 
            +
                class TaxonomyType
         | 
| 6 | 
            +
                  # @return [Bridgetown::Site]
         | 
| 7 | 
            +
                  attr_reader :site
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # @return [String] aka `category`, `tag`, `region`, etc.
         | 
| 10 | 
            +
                  attr_reader :label
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # @return [String] the key used in front matter
         | 
| 13 | 
            +
                  attr_reader :key
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # @return [HashWithDotAccess::Hash] any associated metadata
         | 
| 16 | 
            +
                  attr_reader :metadata
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # @param site [Bridgetown::Site]
         | 
| 19 | 
            +
                  # @param label [String]
         | 
| 20 | 
            +
                  # @param key [String]
         | 
| 21 | 
            +
                  def initialize(site:, label:, key:, metadata:)
         | 
| 22 | 
            +
                    @site = site
         | 
| 23 | 
            +
                    @label = label
         | 
| 24 | 
            +
                    @key = key
         | 
| 25 | 
            +
                    @metadata = metadata
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def terms
         | 
| 29 | 
            +
                    site.resources.map do |resource|
         | 
| 30 | 
            +
                      resource.taxonomies[label].terms
         | 
| 31 | 
            +
                    end.flatten.group_by(&:label).with_dot_access
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def inspect
         | 
| 35 | 
            +
                    "#<#{self.class} label=#{label}>"
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def to_liquid
         | 
| 39 | 
            +
                    {
         | 
| 40 | 
            +
                      "label"    => label,
         | 
| 41 | 
            +
                      "key"      => key,
         | 
| 42 | 
            +
                      "metadata" => metadata,
         | 
| 43 | 
            +
                    }
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,173 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Bridgetown
         | 
| 4 | 
            +
              module Resource
         | 
| 5 | 
            +
                class Transformer
         | 
| 6 | 
            +
                  # @return [Array<Hash>]
         | 
| 7 | 
            +
                  attr_reader :conversions
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  # @return [Bridgetown::Resource::Base]
         | 
| 10 | 
            +
                  attr_reader :resource
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  # @return [Bridgetown::Site]
         | 
| 13 | 
            +
                  attr_reader :site
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # @return [String]
         | 
| 16 | 
            +
                  attr_reader :output_ext
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def initialize(resource)
         | 
| 19 | 
            +
                    @resource = resource
         | 
| 20 | 
            +
                    @site = resource.site
         | 
| 21 | 
            +
                    execute_inline_ruby
         | 
| 22 | 
            +
                    @output_ext = output_ext_from_converters
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  # @return [String]
         | 
| 26 | 
            +
                  def final_ext
         | 
| 27 | 
            +
                    permalink_ext || output_ext
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def process!
         | 
| 31 | 
            +
                    Bridgetown.logger.debug "Transforming:", resource.relative_path
         | 
| 32 | 
            +
                    resource.around_hook :render do
         | 
| 33 | 
            +
                      run_conversions
         | 
| 34 | 
            +
                      resource.place_in_layout? ? place_into_layouts : resource.output = resource.content.dup
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def inspect
         | 
| 39 | 
            +
                    "#<#{self.class} Conversion Steps: #{conversions.length}>"
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  ### Utilities
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def permalink_ext
         | 
| 47 | 
            +
                    resource_permalink = resource.permalink
         | 
| 48 | 
            +
                    if resource_permalink &&
         | 
| 49 | 
            +
                        !resource_permalink.end_with?("/") &&
         | 
| 50 | 
            +
                        !resource_permalink.end_with?(".*")
         | 
| 51 | 
            +
                      permalink_ext = File.extname(resource_permalink)
         | 
| 52 | 
            +
                      permalink_ext unless permalink_ext.empty?
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  # @return [Array<Bridgetown::Converter>]
         | 
| 57 | 
            +
                  def converters
         | 
| 58 | 
            +
                    @converters ||= site.matched_converters_for_convertible(resource)
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  # @return [String]
         | 
| 62 | 
            +
                  def output_ext_from_converters
         | 
| 63 | 
            +
                    @conversions = converters.map do |converter|
         | 
| 64 | 
            +
                      {
         | 
| 65 | 
            +
                        converter: converter,
         | 
| 66 | 
            +
                        output_ext: converter.output_ext(resource.extname),
         | 
| 67 | 
            +
                      }
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    conversions
         | 
| 71 | 
            +
                      .reverse
         | 
| 72 | 
            +
                      .find do |conversion|
         | 
| 73 | 
            +
                        conversions.length == 1 ||
         | 
| 74 | 
            +
                          !conversion[:converter].is_a?(Bridgetown::Converters::Identity)
         | 
| 75 | 
            +
                      end
         | 
| 76 | 
            +
                      .fetch(:output_ext)
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  # @return [Array<Bridgetown::Layout>]
         | 
| 80 | 
            +
                  def validated_layouts
         | 
| 81 | 
            +
                    layout = site.layouts[resource.data.layout]
         | 
| 82 | 
            +
                    warn_on_missing_layout layout, resource.data.layout
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    layout_list = Set.new([layout])
         | 
| 85 | 
            +
                    while layout
         | 
| 86 | 
            +
                      layout_name = layout.data.layout
         | 
| 87 | 
            +
                      layout = site.layouts[layout_name]
         | 
| 88 | 
            +
                      warn_on_missing_layout layout, layout_name
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                      layout_list << layout
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    layout_list.to_a.compact
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  def warn_on_missing_layout(layout, layout_name)
         | 
| 97 | 
            +
                    if layout.nil? && layout_name
         | 
| 98 | 
            +
                      Bridgetown.logger.warn "Build Warning:", "Layout '#{layout_name}' " \
         | 
| 99 | 
            +
                      "requested via #{resource.relative_path} does not exist."
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  ### Transformation Actions
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                  def execute_inline_ruby
         | 
| 106 | 
            +
                    return unless site.config.should_execute_inline_ruby?
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                    Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource, self)
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  def run_conversions # rubocop:disable Metrics/AbcSize
         | 
| 112 | 
            +
                    input = resource.content.to_s
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                    # @param content [String]
         | 
| 115 | 
            +
                    # @param converter [Bridgetown::Converter]
         | 
| 116 | 
            +
                    resource.content = converters.each_with_index.inject(input) do |content, (converter, index)|
         | 
| 117 | 
            +
                      output = if converter.method(:convert).arity == 1
         | 
| 118 | 
            +
                                 converter.convert content
         | 
| 119 | 
            +
                               else
         | 
| 120 | 
            +
                                 converter.convert content, resource
         | 
| 121 | 
            +
                               end
         | 
| 122 | 
            +
                      conversions[index] = {
         | 
| 123 | 
            +
                        type: :content,
         | 
| 124 | 
            +
                        converter: converter,
         | 
| 125 | 
            +
                        output: Bridgetown.env.production? ? nil : output,
         | 
| 126 | 
            +
                        output_ext: conversions[index][:output_ext],
         | 
| 127 | 
            +
                      }
         | 
| 128 | 
            +
                      output
         | 
| 129 | 
            +
                    rescue StandardError => e
         | 
| 130 | 
            +
                      Bridgetown.logger.error "Conversion error:",
         | 
| 131 | 
            +
                                              "#{converter.class} encountered an error while "\
         | 
| 132 | 
            +
                                              "converting `#{resource.relative_path}'"
         | 
| 133 | 
            +
                      raise e
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  def place_into_layouts
         | 
| 138 | 
            +
                    Bridgetown.logger.debug "Placing in Layouts:", resource.relative_path
         | 
| 139 | 
            +
                    output = resource.content.dup
         | 
| 140 | 
            +
                    validated_layouts.each do |layout|
         | 
| 141 | 
            +
                      output = run_layout_conversions layout, output
         | 
| 142 | 
            +
                    end
         | 
| 143 | 
            +
                    resource.output = output
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  def run_layout_conversions(layout, output)
         | 
| 147 | 
            +
                    layout_converters = site.matched_converters_for_convertible(layout)
         | 
| 148 | 
            +
                    layout_input = layout.content.dup
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    layout_converters.inject(layout_input) do |content, converter|
         | 
| 151 | 
            +
                      next(content) unless [2, -2].include?(converter.method(:convert).arity)
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                      layout.current_document = resource
         | 
| 154 | 
            +
                      layout.current_document_output = output
         | 
| 155 | 
            +
                      layout_output = converter.convert content, layout
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      conversions << {
         | 
| 158 | 
            +
                        type: :layout,
         | 
| 159 | 
            +
                        layout: layout,
         | 
| 160 | 
            +
                        converter: converter,
         | 
| 161 | 
            +
                        output: Bridgetown.env.production? ? nil : layout_output,
         | 
| 162 | 
            +
                      }
         | 
| 163 | 
            +
                      layout_output
         | 
| 164 | 
            +
                    rescue StandardError => e
         | 
| 165 | 
            +
                      Bridgetown.logger.error "Conversion error:",
         | 
| 166 | 
            +
                                              "#{converter.class} encountered an error while "\
         | 
| 167 | 
            +
                                              "converting `#{resource.relative_path}'"
         | 
| 168 | 
            +
                      raise e
         | 
| 169 | 
            +
                    end
         | 
| 170 | 
            +
                  end
         | 
| 171 | 
            +
                end
         | 
| 172 | 
            +
              end
         | 
| 173 | 
            +
            end
         | 
    
        data/lib/bridgetown-core/site.rb
    CHANGED
    
    | @@ -26,6 +26,10 @@ module Bridgetown | |
| 26 26 | 
             
                # @return [Array<Page>]
         | 
| 27 27 | 
             
                attr_accessor :pages
         | 
| 28 28 |  | 
| 29 | 
            +
                # NOTE: Eventually pages will be deprecated once the Resource content engine
         | 
| 30 | 
            +
                # is default
         | 
| 31 | 
            +
                alias_method :generated_pages, :pages
         | 
| 32 | 
            +
             | 
| 29 33 | 
             
                attr_accessor :exclude, :include, :lsi, :highlighter, :permalink_style,
         | 
| 30 34 | 
             
                              :time, :future, :unpublished, :limit_posts,
         | 
| 31 35 | 
             
                              :keep_files, :baseurl, :data, :file_read_opts,
         | 
| @@ -46,7 +50,7 @@ module Bridgetown | |
| 46 50 |  | 
| 47 51 | 
             
                  ensure_not_in_dest
         | 
| 48 52 |  | 
| 49 | 
            -
                  Bridgetown. | 
| 53 | 
            +
                  Bridgetown::Current.site = self
         | 
| 50 54 | 
             
                  Bridgetown::Hooks.trigger :site, :after_init, self
         | 
| 51 55 |  | 
| 52 56 | 
             
                  reset   # Processable
         | 
| @@ -64,5 +68,9 @@ module Bridgetown | |
| 64 68 | 
             
                    end
         | 
| 65 69 | 
             
                  end
         | 
| 66 70 | 
             
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def inspect
         | 
| 73 | 
            +
                  "#<Bridgetown::Site #{metadata.inspect.delete_prefix("{").delete_suffix("}")}>"
         | 
| 74 | 
            +
                end
         | 
| 67 75 | 
             
              end
         | 
| 68 76 | 
             
            end
         | 
| @@ -4,7 +4,7 @@ module Bridgetown | |
| 4 4 | 
             
              class StaticFile
         | 
| 5 5 | 
             
                extend Forwardable
         | 
| 6 6 |  | 
| 7 | 
            -
                attr_reader :relative_path, :extname, :name, :data
         | 
| 7 | 
            +
                attr_reader :relative_path, :extname, :name, :data, :site, :collection
         | 
| 8 8 |  | 
| 9 9 | 
             
                def_delegator :to_liquid, :to_json, :to_json
         | 
| 10 10 |  | 
| @@ -25,8 +25,7 @@ module Bridgetown | |
| 25 25 | 
             
                # base - The String path to the <source>.
         | 
| 26 26 | 
             
                # dir  - The String path between <source> and the file.
         | 
| 27 27 | 
             
                # name - The String filename of the file.
         | 
| 28 | 
            -
                # rubocop: | 
| 29 | 
            -
                def initialize(site, base, dir, name, collection = nil)
         | 
| 28 | 
            +
                def initialize(site, base, dir, name, collection = nil) # rubocop:disable Metrics/ParameterLists
         | 
| 30 29 | 
             
                  @site = site
         | 
| 31 30 | 
             
                  @base = base
         | 
| 32 31 | 
             
                  @dir  = dir
         | 
| @@ -34,9 +33,15 @@ module Bridgetown | |
| 34 33 | 
             
                  @collection = collection
         | 
| 35 34 | 
             
                  @relative_path = File.join(*[@dir, @name].compact)
         | 
| 36 35 | 
             
                  @extname = File.extname(@name)
         | 
| 37 | 
            -
                  @data = @site.frontmatter_defaults.all(relative_path, type)
         | 
| 36 | 
            +
                  @data = @site.frontmatter_defaults.all(relative_path, type).with_dot_access
         | 
| 37 | 
            +
                  if site.uses_resource? && !data.permalink
         | 
| 38 | 
            +
                    data.permalink = if collection && !collection.builtin?
         | 
| 39 | 
            +
                                       "/:collection/:path.*"
         | 
| 40 | 
            +
                                     else
         | 
| 41 | 
            +
                                       "/:path.*"
         | 
| 42 | 
            +
                                     end
         | 
| 43 | 
            +
                  end
         | 
| 38 44 | 
             
                end
         | 
| 39 | 
            -
                # rubocop: enable Metrics/ParameterLists
         | 
| 40 45 |  | 
| 41 46 | 
             
                # Returns source file path.
         | 
| 42 47 | 
             
                def path
         | 
| @@ -51,8 +56,11 @@ module Bridgetown | |
| 51 56 | 
             
                #
         | 
| 52 57 | 
             
                # Returns destination file path.
         | 
| 53 58 | 
             
                def destination(dest)
         | 
| 54 | 
            -
                  dest =  | 
| 55 | 
            -
                   | 
| 59 | 
            +
                  dest = site.in_dest_dir(dest)
         | 
| 60 | 
            +
                  dest_url = url
         | 
| 61 | 
            +
                  dest_url = dest_url.delete_prefix(site.baseurl) if site.uses_resource? &&
         | 
| 62 | 
            +
                    site.baseurl.present? && collection
         | 
| 63 | 
            +
                  site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
         | 
| 56 64 | 
             
                end
         | 
| 57 65 |  | 
| 58 66 | 
             
                def destination_rel_dir
         | 
| @@ -118,6 +126,15 @@ module Bridgetown | |
| 118 126 | 
             
                  @basename ||= File.basename(name, extname).gsub(%r!\.*\z!, "")
         | 
| 119 127 | 
             
                end
         | 
| 120 128 |  | 
| 129 | 
            +
                def relative_path_basename_without_prefix
         | 
| 130 | 
            +
                  return_path = Pathname.new("")
         | 
| 131 | 
            +
                  Pathname.new(cleaned_relative_path).each_filename do |filename|
         | 
| 132 | 
            +
                    return_path += filename unless filename.starts_with?("_")
         | 
| 133 | 
            +
                  end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  (return_path.dirname + return_path.basename(".*")).to_s
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 121 138 | 
             
                def placeholders
         | 
| 122 139 | 
             
                  {
         | 
| 123 140 | 
             
                    collection: @collection.label,
         | 
| @@ -154,15 +171,21 @@ module Bridgetown | |
| 154 171 | 
             
                # be overriden in the collection's configuration in bridgetown.config.yml.
         | 
| 155 172 | 
             
                def url
         | 
| 156 173 | 
             
                  @url ||= begin
         | 
| 157 | 
            -
                     | 
| 174 | 
            +
                    newly_processed = false
         | 
| 175 | 
            +
                    special_posts_case = @collection&.label == "posts" &&
         | 
| 176 | 
            +
                      site.config.content_engine != "resource"
         | 
| 177 | 
            +
                    base = if @collection.nil? || special_posts_case
         | 
| 158 178 | 
             
                             cleaned_relative_path
         | 
| 179 | 
            +
                           elsif site.uses_resource?
         | 
| 180 | 
            +
                             newly_processed = true
         | 
| 181 | 
            +
                             Bridgetown::Resource::PermalinkProcessor.new(self).transform
         | 
| 159 182 | 
             
                           else
         | 
| 160 183 | 
             
                             Bridgetown::URL.new(
         | 
| 161 184 | 
             
                               template: @collection.url_template,
         | 
| 162 185 | 
             
                               placeholders: placeholders
         | 
| 163 186 | 
             
                             )
         | 
| 164 187 | 
             
                           end.to_s.chomp("/")
         | 
| 165 | 
            -
                    base  | 
| 188 | 
            +
                    newly_processed ? base : "#{base}#{extname}"
         | 
| 166 189 | 
             
                  end
         | 
| 167 190 | 
             
                end
         | 
| 168 191 |  | 
| @@ -174,7 +197,7 @@ module Bridgetown | |
| 174 197 | 
             
                # Returns the front matter defaults defined for the file's URL and/or type
         | 
| 175 198 | 
             
                # as defined in bridgetown.config.yml.
         | 
| 176 199 | 
             
                def defaults
         | 
| 177 | 
            -
                  @defaults ||=  | 
| 200 | 
            +
                  @defaults ||= site.frontmatter_defaults.all url, type
         | 
| 178 201 | 
             
                end
         | 
| 179 202 |  | 
| 180 203 | 
             
                # Returns a debug string on inspecting the static file.
         | 
    
        data/lib/bridgetown-core/url.rb
    CHANGED
    
    
| @@ -4,12 +4,9 @@ module Bridgetown | |
| 4 4 | 
             
              module Utils
         | 
| 5 5 | 
             
                extend self
         | 
| 6 6 | 
             
                autoload :Ansi, "bridgetown-core/utils/ansi"
         | 
| 7 | 
            -
                autoload :Exec, "bridgetown-core/utils/exec"
         | 
| 8 | 
            -
                autoload :Internet, "bridgetown-core/utils/internet"
         | 
| 9 7 | 
             
                autoload :RubyExec, "bridgetown-core/utils/ruby_exec"
         | 
| 10 8 | 
             
                autoload :Platforms, "bridgetown-core/utils/platforms"
         | 
| 11 9 | 
             
                autoload :ThreadEvent, "bridgetown-core/utils/thread_event"
         | 
| 12 | 
            -
                autoload :WinTZ, "bridgetown-core/utils/win_tz"
         | 
| 13 10 |  | 
| 14 11 | 
             
                # Constants for use in #slugify
         | 
| 15 12 | 
             
                SLUGIFY_MODES = %w(raw default pretty simple ascii latin).freeze
         | 
| @@ -74,38 +71,32 @@ module Bridgetown | |
| 74 71 | 
             
                  end
         | 
| 75 72 | 
             
                end
         | 
| 76 73 |  | 
| 77 | 
            -
                # Read array from the supplied hash  | 
| 78 | 
            -
                #  | 
| 74 | 
            +
                # Read array from the supplied hash, merging the singular key with the
         | 
| 75 | 
            +
                # plural key as needing, and handling any nil or duplicate entries.
         | 
| 79 76 | 
             
                #
         | 
| 80 | 
            -
                #  | 
| 81 | 
            -
                # singular_key  | 
| 82 | 
            -
                # plural_key  | 
| 83 | 
            -
                #
         | 
| 84 | 
            -
                 | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
                   | 
| 77 | 
            +
                # @param hsh [Hash] the hash to read from
         | 
| 78 | 
            +
                # @param singular_key [Symbol] the singular key
         | 
| 79 | 
            +
                # @param plural_key [Symbol] the plural key
         | 
| 80 | 
            +
                # @return [Array]
         | 
| 81 | 
            +
                def pluralized_array_from_hash(hsh, singular_key, plural_key)
         | 
| 82 | 
            +
                  array = [
         | 
| 83 | 
            +
                    hsh[singular_key],
         | 
| 84 | 
            +
                    value_from_plural_key(hsh, plural_key),
         | 
| 85 | 
            +
                  ]
         | 
| 89 86 |  | 
| 90 | 
            -
                  array << value
         | 
| 91 87 | 
             
                  array.flatten!
         | 
| 92 88 | 
             
                  array.compact!
         | 
| 89 | 
            +
                  array.uniq!
         | 
| 93 90 | 
             
                  array
         | 
| 94 91 | 
             
                end
         | 
| 95 92 |  | 
| 96 | 
            -
                def  | 
| 97 | 
            -
                   | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
                   | 
| 102 | 
            -
                    val | 
| 103 | 
            -
                    case val
         | 
| 104 | 
            -
                    when String
         | 
| 105 | 
            -
                      val.split
         | 
| 106 | 
            -
                    when Array
         | 
| 107 | 
            -
                      val.compact
         | 
| 108 | 
            -
                    end
         | 
| 93 | 
            +
                def value_from_plural_key(hsh, key)
         | 
| 94 | 
            +
                  val = hsh[key]
         | 
| 95 | 
            +
                  case val
         | 
| 96 | 
            +
                  when String
         | 
| 97 | 
            +
                    val.split
         | 
| 98 | 
            +
                  when Array
         | 
| 99 | 
            +
                    val.compact
         | 
| 109 100 | 
             
                  end
         | 
| 110 101 | 
             
                end
         | 
| 111 102 |  | 
| @@ -124,7 +115,7 @@ module Bridgetown | |
| 124 115 |  | 
| 125 116 | 
             
                # Determines whether a given file has
         | 
| 126 117 | 
             
                #
         | 
| 127 | 
            -
                #  | 
| 118 | 
            +
                # @return [Boolean] if the YAML front matter is present.
         | 
| 128 119 | 
             
                # rubocop: disable Naming/PredicateName
         | 
| 129 120 | 
             
                def has_yaml_header?(file)
         | 
| 130 121 | 
             
                  File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
         | 
| @@ -134,7 +125,7 @@ module Bridgetown | |
| 134 125 |  | 
| 135 126 | 
             
                # Determine whether the given content string contains Liquid Tags or Vaiables
         | 
| 136 127 | 
             
                #
         | 
| 137 | 
            -
                #  | 
| 128 | 
            +
                # @return [Boolean] if the string contains sequences of `{%` or `{{`
         | 
| 138 129 | 
             
                def has_liquid_construct?(content)
         | 
| 139 130 | 
             
                  return false if content.nil? || content.empty?
         | 
| 140 131 |  | 
| @@ -207,7 +198,7 @@ module Bridgetown | |
| 207 198 | 
             
                  slug.gsub!(%r!^\-|\-$!i, "")
         | 
| 208 199 |  | 
| 209 200 | 
             
                  slug.downcase! unless cased
         | 
| 210 | 
            -
             | 
| 201 | 
            +
             | 
| 211 202 | 
             
                  slug
         | 
| 212 203 | 
             
                end
         | 
| 213 204 |  | 
| @@ -347,7 +338,7 @@ module Bridgetown | |
| 347 338 |  | 
| 348 339 | 
             
                # Return an asset path based on the Webpack manifest file
         | 
| 349 340 | 
             
                # @param site [Bridgetown::Site] The current site object
         | 
| 350 | 
            -
                # @param asset_type [String] js or css
         | 
| 341 | 
            +
                # @param asset_type [String] js or css, or filename in manifest
         | 
| 351 342 | 
             
                #
         | 
| 352 343 | 
             
                # @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
         | 
| 353 344 | 
             
                # file isnt found
         | 
| @@ -363,21 +354,30 @@ module Bridgetown | |
| 363 354 | 
             
                  manifest = JSON.parse(File.read(manifest_file))
         | 
| 364 355 |  | 
| 365 356 | 
             
                  known_assets = %w(js css)
         | 
| 357 | 
            +
                  asset_path = nil
         | 
| 366 358 | 
             
                  if known_assets.include?(asset_type)
         | 
| 367 359 | 
             
                    asset_path = manifest["main.#{asset_type}"]
         | 
| 368 | 
            -
             | 
| 369 360 | 
             
                    log_webpack_asset_error(asset_type) && return if asset_path.nil?
         | 
| 370 | 
            -
             | 
| 371 | 
            -
                    asset_path =  | 
| 372 | 
            -
             | 
| 361 | 
            +
                  else
         | 
| 362 | 
            +
                    asset_path = manifest.find do |item, _|
         | 
| 363 | 
            +
                      item.sub(%r{^../(frontend/|src/)?}, "") == asset_type
         | 
| 364 | 
            +
                    end&.last
         | 
| 373 365 | 
             
                  end
         | 
| 374 366 |  | 
| 375 | 
            -
                   | 
| 376 | 
            -
             | 
| 367 | 
            +
                  if asset_path
         | 
| 368 | 
            +
                    static_frontend_path(site, ["js", asset_path])
         | 
| 369 | 
            +
                  else
         | 
| 370 | 
            +
                    Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
         | 
| 371 | 
            +
                    nil
         | 
| 372 | 
            +
                  end
         | 
| 377 373 | 
             
                end
         | 
| 378 374 |  | 
| 379 | 
            -
                def static_frontend_path(site)
         | 
| 380 | 
            -
                  path_parts = [ | 
| 375 | 
            +
                def static_frontend_path(site, additional_parts = [])
         | 
| 376 | 
            +
                  path_parts = [
         | 
| 377 | 
            +
                    site.config["baseurl"].to_s.gsub(%r(^/|/$), ""),
         | 
| 378 | 
            +
                    "_bridgetown/static",
         | 
| 379 | 
            +
                    *additional_parts,
         | 
| 380 | 
            +
                  ]
         | 
| 381 381 | 
             
                  path_parts[0] = "/#{path_parts[0]}" unless path_parts[0].empty?
         | 
| 382 382 | 
             
                  Addressable::URI.parse(path_parts.join("/")).normalize.to_s
         | 
| 383 383 | 
             
                end
         |