lib/loaf/view_extensions.rb in loaf-0.5.0 vs lib/loaf/view_extensions.rb in loaf-0.6.0
- old
+ new
@@ -1,9 +1,11 @@
-# encoding: utf-8
+# frozen_string_literal: true
-require 'loaf/crumb_formatter'
-require 'loaf/options_validator'
+require_relative 'breadcrumb'
+require_relative 'crumb'
+require_relative 'crumb_formatter'
+require_relative 'options_validator'
module Loaf
# A mixin to define view extensions
module ViewExtensions
include Loaf::CrumbFormatter
@@ -34,40 +36,89 @@
#
# @api public
def breadcrumb(name, url, options = {})
_breadcrumbs << Loaf::Crumb.new(name, url, options)
end
- alias_method :add_breadcrumb, :breadcrumb
+ alias add_breadcrumb breadcrumb
# Renders breadcrumbs inside view.
#
# @param [Hash] options
#
# @api public
- def breadcrumbs(options = {}, &block)
- # builder = Loaf::Builder.new(options)
- return enum_for(:breadcrumbs) unless block_given?
+ def breadcrumb_trail(options = {})
+ return enum_for(:breadcrumb_trail) unless block_given?
+
valid?(options)
options = Loaf.configuration.to_hash.merge(options)
_breadcrumbs.each do |crumb|
- name = format_name(crumb.name, options)
- url = url_for(_process_url_for(crumb.url))
- styles = ''
- if current_page?(url) || crumb.force
- styles << "#{options[:style_classes]}"
- end
- block.call(name, url, styles)
+ name = format_name(crumb.name, options)
+ path = url_for(_expand_url(crumb.url))
+ current = current_crumb?(path, crumb.match)
+
+ yield(Loaf::Breadcrumb[name, path, current])
end
end
+ # Check if breadcrumb is current based on the pattern
+ #
+ # @param [String] path
+ # @param [Object] pattern
+ # the pattern to match on
+ #
+ # @api public
+ def current_crumb?(path, pattern = :inclusive)
+ return false unless request.get? || request.head?
+
+ origin_path = URI.parser.unescape(path).force_encoding(Encoding::BINARY)
+
+ request_uri = request.fullpath
+ request_uri = URI.parser.unescape(request_uri)
+ request_uri.force_encoding(Encoding::BINARY)
+
+ # strip away trailing slash
+ if origin_path.start_with?('/') && origin_path != '/'
+ origin_path.chomp!('/')
+ request_uri.chomp!('/')
+ end
+
+ if %r{^\w+://} =~ origin_path
+ origin_path.chomp!('/')
+ request_uri.insert(0, "#{request.protocol}#{request.host_with_port}")
+ end
+
+ case pattern
+ when :inclusive
+ !request_uri.match(/^#{Regexp.escape(origin_path)}(\/.*|\?.*)?$/).nil?
+ when :exclusive
+ !request_uri.match(/^#{Regexp.escape(origin_path)}\/?(\?.*)?$/).nil?
+ when :exact
+ request_uri == origin_path
+ when :force
+ true
+ when Regexp
+ !request_uri.match(pattern).nil?
+ when Hash
+ query_params = URI.encode_www_form(pattern)
+ !request_uri.match(/^#{Regexp.escape(origin_path)}\/?(\?.*)?.*?#{query_params}.*$/).nil?
+ else
+ raise ArgumentError, "Unknown `:#{pattern}` match option!"
+ end
+ end
+
private
+ # Expand url in the current context of the view
+ #
# @api private
- def _process_url_for(url)
- if url.is_a?(String) || url.is_a?(Symbol)
- return respond_to?(url) ? send(url) : url
+ def _expand_url(url)
+ case url
+ when String, Symbol
+ respond_to?(url) ? send(url) : url
+ when Proc
+ url.call(self)
else
- return url
+ url
end
end
end # ViewExtensions
end # Loaf