middleman-core 4.4.3 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47a1d9d5037e308781c5d071bdbd012631dffec9f2439e1c73b6bf8b6e9d27ff
4
- data.tar.gz: fe51eb33932856df3019ad8ad8a41a4abf80266b814da9c716f0aeeda4db74c9
3
+ metadata.gz: 955d0ea89728b170a8a5e7b94dadbf9c7e848ac05c41ee69e8d6932e531c6d45
4
+ data.tar.gz: 1c59256a26b181e745b0a263514411c61aa6887fff9c293b5a9dba0ebb10f665
5
5
  SHA512:
6
- metadata.gz: df1e1c37ccb433f391dcc05122297f83c3a9d19bef1a8b4c8738f40d156ddd014affa6ecd583a358f9b749ad891afa4d788d7d837aef0d3c42eaa6e79d899029
7
- data.tar.gz: 1cfdb65af805d4599b34b939d8dc1377a2d29f830d8aa21692e6e851cce5d6ff612d9122865aa67f8f4e142c46644b334eacccf9d0b1a9586add6d72539aac90
6
+ metadata.gz: 6a7956f26e7c55806f06ab7dc18e5fb544f3f91a43b814011edb5aecec5fa0d9124cd873b402a04d65edabba4f0d3f32750d963be889d3379a0f17bb1356428a
7
+ data.tar.gz: a6f6e1038e04ea990628b2a6a62b59fdfb4da77acfa46f49a07ac3774c2f706c1ff7366a1f745e0a70ccd1dbe4f18ad276664a616bb05da4f0033186b3fe292e
data/.simplecov CHANGED
@@ -1,7 +1,7 @@
1
- SimpleCov.start do
1
+ SimpleCov.configure do
2
2
  add_filter '/fixtures/'
3
3
  add_filter '/features/'
4
4
  add_filter '/spec/'
5
5
  add_filter '/step_definitions/'
6
6
  add_filter '/lib/vendored-middleman-deps/'
7
- end
7
+ end
@@ -123,8 +123,10 @@ Feature: i18n Builder
123
123
  | hello.html |
124
124
  And the file "en/index.html" should contain "Howdy"
125
125
  And the file "en/hello.html" should contain "Hello World"
126
+ And the file "en/fallback.html" should contain "Fallback"
126
127
  And the file "es/index.html" should contain "Como Esta?"
127
128
  And the file "es/hola.html" should contain "Hola World"
129
+ And the file "es/fallback.html" should contain "Fallback"
128
130
 
129
131
  Scenario: Running localize with the subset config
130
132
  Given a fixture app "i18n-test-app"
@@ -211,3 +211,97 @@ Feature: i18n Paths
211
211
  Then I should see 'Current: /es/article.html'
212
212
  Then I should see 'Other: /article.html'
213
213
  Then I should see 'Current with anchor: /es/article.html#test-anchor'
214
+
215
+ Scenario: Using url_for with the no mount config
216
+ Given a fixture app "empty-app"
217
+ And a file named "data/pages.yml" with:
218
+ """
219
+ - hello.html
220
+ """
221
+ And a file named "locales/en.yml" with:
222
+ """
223
+ ---
224
+ en:
225
+ msg: Hello
226
+ """
227
+ And a file named "locales/es.yml" with:
228
+ """
229
+ ---
230
+ es:
231
+ paths:
232
+ hello: "hola"
233
+ msg: Hola
234
+ """
235
+ And a file named "source/localizable/hello.html.erb" with:
236
+ """
237
+ Page: <%= t(:msg) %>
238
+ <% data.pages.each_with_index do |p, i| %>
239
+ Current: <%= url_for "/#{p}" %>
240
+ Other: <%= url_for "/#{p}", locale: ::I18n.locale == :en ? :es : :en %>
241
+ <% end %>
242
+ """
243
+ And a file named "source/localizable/article.html.erb" with:
244
+ """
245
+ Page Lang: Default
246
+
247
+ Current: <%= url_for "/article.html" %>
248
+ Other: <%= url_for "/article.html", locale: ::I18n.locale == :en ? :es : :en %>
249
+ Current with anchor: <%= url_for "/article.html", :anchor => "test-anchor" %>
250
+ """
251
+ And a file named "source/localizable/article.es.html.erb" with:
252
+ """
253
+ Page Lang: Spanish
254
+
255
+ Current: <%= url_for "/article.html" %>
256
+ Other: <%= url_for "/article.html", locale: :en %>
257
+ Current with anchor: <%= url_for "/article.html", :anchor => "test-anchor" %>
258
+ """
259
+ And a file named "source/localizable/post.en.html.erb" with:
260
+ """
261
+ Page Lang: English
262
+
263
+ Current: <%= url_for "/post.html" %>
264
+ Other: <%= url_for "/post.html", locale: :es %>
265
+ Current with anchor: <%= url_for "/post.html", :anchor => "test-anchor" %>
266
+ """
267
+ And a file named "source/localizable/post.es.html.erb" with:
268
+ """
269
+ Page Lang: Spanish
270
+
271
+ Current: <%= url_for "/post.html" %>
272
+ Other: <%= url_for "/post.html", locale: :en %>
273
+ Current with anchor: <%= url_for "/post.html", :anchor => "test-anchor" %>
274
+ """
275
+ And a file named "config.rb" with:
276
+ """
277
+ activate :i18n, mount_at_root: false
278
+ """
279
+ Given the Server is running
280
+ When I go to "/en/hello.html"
281
+ Then I should see "Page: Hello"
282
+ Then I should see 'Current: /en/hello.html'
283
+ Then I should see 'Other: /es/hola.html'
284
+ When I go to "/es/hola.html"
285
+ Then I should see "Page: Hola"
286
+ Then I should see 'Current: /es/hola.html'
287
+ Then I should see 'Other: /en/hello.html'
288
+ When I go to "/en/article.html"
289
+ Then I should see "Page Lang: Default"
290
+ Then I should see 'Current: /en/article.html'
291
+ Then I should see 'Other: /es/article.html'
292
+ Then I should see 'Current with anchor: /en/article.html#test-anchor'
293
+ When I go to "/es/article.html"
294
+ Then I should see "Page Lang: Spanish"
295
+ Then I should see 'Current: /es/article.html'
296
+ Then I should see 'Other: /en/article.html'
297
+ Then I should see 'Current with anchor: /es/article.html#test-anchor'
298
+ When I go to "/en/post.html"
299
+ Then I should see "Page Lang: English"
300
+ Then I should see 'Current: /en/post.html'
301
+ Then I should see 'Other: /es/post.html'
302
+ Then I should see 'Current with anchor: /en/post.html#test-anchor'
303
+ When I go to "/es/post.html"
304
+ Then I should see "Page Lang: Spanish"
305
+ Then I should see 'Current: /es/post.html'
306
+ Then I should see 'Other: /en/post.html'
307
+ Then I should see 'Current with anchor: /es/post.html#test-anchor'
@@ -1,4 +1,4 @@
1
- = content_for :from_template do
2
- = "I am the yielded content haml <s>with html tags</s>"
1
+ - content_for :from_template do
2
+ != "I am the yielded content haml <s>with html tags</s>"
3
3
 
4
4
  %p I am in the template
@@ -1,4 +1,5 @@
1
1
  ---
2
2
  en:
3
3
  greetings: "Howdy"
4
- hi: "Hello"
4
+ hi: "Hello"
5
+ fallback: "Fallback"
@@ -0,0 +1 @@
1
+ <%= I18n.t(:fallback) %>
@@ -1,3 +1,4 @@
1
+ require 'addressable/uri'
1
2
  require 'pathname'
2
3
  require 'fileutils'
3
4
  require 'tempfile'
@@ -229,7 +230,7 @@ module Middleman
229
230
  if resource.binary?
230
231
  export_file!(output_file, resource.file_descriptor[:full_path])
231
232
  else
232
- response = @rack.get(::WEBrick::HTTPUtils.escape(resource.request_path))
233
+ response = @rack.get(Addressable::URI.encode(resource.request_path))
233
234
 
234
235
  # If we get a response, save it to a tempfile.
235
236
  if response.status == 200
@@ -151,7 +151,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
151
151
  new_resources = []
152
152
 
153
153
  file_extension_resources = resources.select do |resource|
154
- parse_locale_extension(resource.path)
154
+ # Ignore resources which are outside of the localizable directory
155
+ File.fnmatch?(File.join(options[:templates_dir], '**'), resource.path) &&
156
+ parse_locale_extension(resource.path)
155
157
  end
156
158
 
157
159
  localizable_folder_resources = resources.select do |resource|
@@ -190,10 +192,61 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
190
192
  resource.ignore!
191
193
  end
192
194
 
193
- @lookup = new_resources.each_with_object({}) do |desc, sum|
194
- abs_path = desc.source_path.sub(options[:templates_dir], '')
195
- sum[abs_path] ||= {}
196
- sum[abs_path][desc.locale] = '/' + desc.path
195
+ # This generates a lookup hash that maps the real path (as seen by the web
196
+ # page user) to the paths of the localized versions. The lookup is later
197
+ # used by `url_for '/some/page.html', :locale => :en` and other url
198
+ # helpers.
199
+ #
200
+ # For example (given :mount_at_root => :es) and localized paths:
201
+ #
202
+ # @lookup['/en/magic/stuff.html'] = {:en => '/en/magic/stuff.html', :de => '/de/magisches/zeug.html', :es => '/magico/cosas.html'}
203
+ # @lookup['/de/index.html'] = {:en => '/en/index.html', :de => '/de/index.html', :es => '/index.html'}
204
+ # @lookup['/en/index.html'] = {:en => '/en/index.html', :de => '/de/index.html', :es => '/index.html'}
205
+ # @lookup['/index.html'] = {:en => '/en/index.html', :de => '/de/index.html', :es => '/index.html'}
206
+ #
207
+ # We do this by grouping by the source paths with the locales removed. All
208
+ # the localized pages with the same content in different languages get the
209
+ # same key.
210
+ #
211
+ @source_path_group = new_resources.group_by do |resource|
212
+ # Try to get source path without extension
213
+ _locale, path, _page_id = parse_locale_extension(resource.source_path)
214
+
215
+ # If that fails, there is no extension, so we use the original path. We
216
+ # can not use resource.path here, because .path may be translated, so the
217
+ # file names do not match up.
218
+ path ||= resource.source_path
219
+
220
+ # This will contain the localizable/ directory, but that does not matter,
221
+ # because it will be contained in both alternatives above, so the
222
+ # grouping key will be correct.
223
+ path
224
+ end
225
+
226
+ # Then we walk this grouped hash and generate the lookup table as given
227
+ # above.
228
+ @lookup = {}
229
+ @source_path_group.each do |src_path, resources|
230
+ # For each group we generate a list of the paths the user really sees
231
+ # (e.g. ['/en/index.html', '/de/index.html', '/index.html'])
232
+ exposed_paths = resources.map(&:path)
233
+
234
+ # We also generate a map with the same infos, but with the locales as keys.
235
+ # e.g. {:en => '/en/index.html', :de => '/de/index.html', :es => '/index.html'}
236
+ locale_map = resources.each_with_object({}) do |resource, map|
237
+ map[resource.locale] = '/' + resource.path
238
+ end
239
+
240
+ # Then we add those to the lookup table, so every path has a
241
+ # cross-reference to any other path in other locales.
242
+ exposed_paths.each do |path|
243
+ @lookup['/' + path] = locale_map
244
+ end
245
+
246
+ if @mount_at_root == false
247
+ src_path = src_path.sub(options[:templates_dir] + '/', '')
248
+ @lookup["/#{src_path}"] = locale_map
249
+ end
197
250
  end
198
251
 
199
252
  new_resources.reduce(resources) do |sum, r|
@@ -236,7 +289,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
236
289
 
237
290
  # Reset fallbacks to fall back to our new default
238
291
  if ::I18n.respond_to?(:fallbacks)
239
- ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new(@mount_at_root)
292
+ ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new(::I18n.default_locale)
240
293
  end
241
294
  end
242
295
 
@@ -1,3 +1,4 @@
1
+ require 'addressable/uri'
1
2
  require 'middleman-core/util'
2
3
  require 'middleman-core/rack'
3
4
 
@@ -87,7 +88,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
87
88
  else
88
89
  # Render through the Rack interface so middleware and mounted apps get a shot
89
90
  response = @rack_client.get(
90
- ::WEBrick::HTTPUtils.escape(resource.destination_path),
91
+ Addressable::URI.encode(resource.destination_path),
91
92
  'bypass_inline_url_rewriter_asset_hash' => 'true'
92
93
  )
93
94
 
@@ -6,6 +6,7 @@ class Middleman::Extensions::ExternalPipeline < ::Middleman::Extension
6
6
  option :source, nil, 'Path to merge into sitemap', required: true
7
7
  option :latency, 0.25, 'Latency between refreshes of source'
8
8
  option :disable_background_execution, false, "Don't run the command in a separate background thread"
9
+ option :ignore_exit_code, false, 'Ignore exit code for restart or stop of a command'
9
10
 
10
11
  def initialize(app, config={}, &block)
11
12
  super
@@ -65,7 +66,7 @@ class Middleman::Extensions::ExternalPipeline < ::Middleman::Extension
65
66
 
66
67
  @current_thread.wait
67
68
 
68
- if !@current_thread.exitstatus.nil? && @current_thread.exitstatus != 0
69
+ if !options[:ignore_exit_code] && !@current_thread.exitstatus.nil? && @current_thread.exitstatus != 0
69
70
  logger.error '== External: Command failed with non-zero exit status'
70
71
  exit(1)
71
72
  end
@@ -3,7 +3,7 @@ require 'rack/file'
3
3
  require 'rack/lint'
4
4
  require 'rack/head'
5
5
  require 'rack/utils'
6
- require 'webrick'
6
+ require 'addressable/uri'
7
7
 
8
8
  require 'middleman-core/util'
9
9
  require 'middleman-core/logger'
@@ -87,7 +87,7 @@ module Middleman
87
87
  def process_request(env, req, res)
88
88
  start_time = Time.now
89
89
 
90
- request_path = WEBrick::HTTPUtils.unescape(env['PATH_INFO'].dup)
90
+ request_path = Addressable::URI.unencode(env['PATH_INFO'].dup)
91
91
  if request_path.respond_to? :force_encoding
92
92
  request_path.force_encoding('UTF-8')
93
93
  end
@@ -29,12 +29,18 @@ module Middleman
29
29
  def prepare; end
30
30
 
31
31
  def evaluate(scope, locals, &block)
32
- options = {}.merge!(@options).merge!(filename: eval_file, line: line, context: @context || scope)
32
+ options = {}.merge!(@options).merge!(context: @context || scope)
33
33
  if options.include?(:outvar)
34
34
  options[:buffer] = options.delete(:outvar)
35
35
  options[:save_buffer] = true
36
36
  end
37
- @engine = ::Haml::Engine.new(data, options)
37
+ if Object.const_defined?('::Haml::Template') # haml 6+
38
+ @engine = ::Haml::Template.new(eval_file, line, options) { data }
39
+ else
40
+ options[:filename] = eval_file
41
+ options[:line] = line
42
+ @engine = ::Haml::Engine.new(data, options)
43
+ end
38
44
  output = @engine.render(scope, locals, &block)
39
45
 
40
46
  output
@@ -46,8 +52,12 @@ module Middleman
46
52
  def initialize(app, options={}, &block)
47
53
  super
48
54
 
49
- ::Haml::Options.defaults[:context] = nil
50
- ::Haml::Options.send :attr_accessor, :context
55
+ if Object.const_defined?('::Haml::Options') # Haml 5 and older
56
+ ::Haml::Options.defaults[:context] = nil
57
+ ::Haml::Options.send :attr_accessor, :context
58
+ else # Haml 6+
59
+ ::Haml::Engine.define_options context: nil
60
+ end
51
61
  if defined?(::Haml::TempleEngine)
52
62
  ::Haml::TempleEngine.define_options context: nil
53
63
  end
@@ -55,12 +65,31 @@ module Middleman
55
65
  # rubocop:disable NestedMethodDefinition
56
66
  [::Haml::Filters::Sass, ::Haml::Filters::Scss, ::Haml::Filters::Markdown].each do |f|
57
67
  f.class_exec do
58
- def self.render_with_options(text, compiler_options)
59
- modified_options = options.dup
60
- modified_options[:context] = compiler_options[:context]
61
-
62
- text = template_class.new(nil, 1, modified_options) { text }.render
63
- super(text, compiler_options)
68
+ if respond_to?(:template_class) # Haml 5 and older
69
+ def self.render_with_options(text, compiler_options)
70
+ modified_options = options.dup
71
+ modified_options[:context] = compiler_options[:context]
72
+
73
+ text = template_class.new(nil, 1, modified_options) { text }.render
74
+ super(text, compiler_options)
75
+ end
76
+ else # Haml 6+
77
+ def initialize(options = {})
78
+ super
79
+ @context = options[:context]
80
+ end
81
+
82
+ def compile_with_tilt(node, name, indent_width: 0)
83
+ options = { context: @context }
84
+ source = node.value[:text]
85
+ result = ::Tilt["t.#{name}"].new(nil, 1, options) { source }.render
86
+
87
+ temple = [:multi, [:static, result.gsub(/^/, ' ' * indent_width)]]
88
+ source.lines.size.times do
89
+ temple << [:newline]
90
+ end
91
+ temple
92
+ end
64
93
  end
65
94
  end
66
95
  end
@@ -1,7 +1,7 @@
1
1
  require 'middleman-core/rack'
2
2
  require 'rspec/expectations'
3
3
  require 'capybara/cucumber'
4
- require 'webrick'
4
+ require 'addressable/uri'
5
5
 
6
6
  Given /^a clean server$/ do
7
7
  @initialize_commands = []
@@ -73,11 +73,11 @@ Given /^a template named "([^\"]*)" with:$/ do |name, string|
73
73
  end
74
74
 
75
75
  When /^I go to "([^\"]*)"$/ do |url|
76
- visit(WEBrick::HTTPUtils.escape(url))
76
+ visit(Addressable::URI.encode(url))
77
77
  end
78
78
 
79
79
  Then /^going to "([^\"]*)" should not raise an exception$/ do |url|
80
- expect{ visit(WEBrick::HTTPUtils.escape(url)) }.to_not raise_exception
80
+ expect { visit(Addressable::URI.encode(url)) }.to_not raise_exception
81
81
  end
82
82
 
83
83
  Then /^the content type should be "([^\"]*)"$/ do |expected|
@@ -118,9 +118,17 @@ module Middleman
118
118
  # @return [Hash]
119
119
  Contract String, Pathname => Hash
120
120
  def parse_yaml(content, full_path)
121
+ permitted_classes = [Date, Symbol]
121
122
  c = begin
122
123
  ::Middleman::Util.instrument 'parse.yaml' do
123
- ::YAML.load(content)
124
+ allowed_parameters = ::YAML.method(:safe_load).parameters
125
+ if allowed_parameters.include? [:key, :permitted_classes]
126
+ ::YAML.safe_load(content, permitted_classes: permitted_classes)
127
+ elsif allowed_parameters.include? [:key, :whitelist_classes]
128
+ ::YAML.safe_load(content, whitelist_classes: permitted_classes)
129
+ else
130
+ ::YAML.safe_load(content, permitted_classes)
131
+ end
124
132
  end
125
133
  rescue StandardError, ::Psych::SyntaxError => error
126
134
  warn "YAML Exception parsing #{full_path}: #{error.message}"
@@ -4,7 +4,6 @@ require 'uri'
4
4
  require 'addressable/uri'
5
5
  require 'memoist'
6
6
  require 'tilt'
7
- require 'webrick'
8
7
 
9
8
  require 'middleman-core/contracts'
10
9
 
@@ -34,7 +33,7 @@ module Middleman
34
33
  Contract String => String
35
34
  def normalize_path(path)
36
35
  # The tr call works around a bug in Ruby's Unicode handling
37
- WEBrick::HTTPUtils.unescape(path).sub(%r{^/}, '').tr('', '')
36
+ Addressable::URI.unencode(path).sub(%r{^/}, '').tr('', '')
38
37
  end
39
38
  memoize :normalize_path
40
39
 
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  # Current Version
3
3
  # @return [String]
4
- VERSION = '4.4.3'.freeze unless const_defined?(:VERSION)
4
+ VERSION = '4.5.0'.freeze unless const_defined?(:VERSION)
5
5
  end
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.license = 'MIT'
10
10
  s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Karl Freeman']
11
11
  s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'karlfreeman@gmail.com']
12
- s.homepage = 'http://middlemanapp.com'
12
+ s.homepage = 'https://middlemanapp.com'
13
13
  s.summary = 'Hand-crafted frontend development'
14
14
  s.description = 'A static site generator. Provides dozens of templating languages (Haml, Sass, Compass, Slim, CoffeeScript, and more). Makes minification, compression, cache busting, Yaml data (and more) an easy part of your development cycle.'
15
15
 
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'simplecov'
2
2
  SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/..'))
3
- # SimpleCov.start
3
+ SimpleCov.start
4
4
 
5
5
  require 'aruba/api'
6
6
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.3
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Reynolds
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-11-09 00:00:00.000000000 Z
13
+ date: 2023-05-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -873,6 +873,7 @@ files:
873
873
  - fixtures/i18n-test-app/source/layouts/layout.erb
874
874
  - fixtures/i18n-test-app/source/localizable/_state.en.erb
875
875
  - fixtures/i18n-test-app/source/localizable/_state.es.erb
876
+ - fixtures/i18n-test-app/source/localizable/fallback.html.erb
876
877
  - fixtures/i18n-test-app/source/localizable/hello.html.erb
877
878
  - fixtures/i18n-test-app/source/localizable/images/flag.en.svg
878
879
  - fixtures/i18n-test-app/source/localizable/images/flag.es.svg
@@ -1570,7 +1571,7 @@ files:
1570
1571
  - spec/middleman-core/util_spec.rb
1571
1572
  - spec/spec_helper.rb
1572
1573
  - spec/support/given.rb
1573
- homepage: http://middlemanapp.com
1574
+ homepage: https://middlemanapp.com
1574
1575
  licenses:
1575
1576
  - MIT
1576
1577
  metadata: {}
@@ -1589,7 +1590,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1589
1590
  - !ruby/object:Gem::Version
1590
1591
  version: '0'
1591
1592
  requirements: []
1592
- rubygems_version: 3.3.7
1593
+ rubygems_version: 3.4.10
1593
1594
  signing_key:
1594
1595
  specification_version: 4
1595
1596
  summary: Hand-crafted frontend development