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