Module: DuckMap::Mapper
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/duck_map/mapper.rb
Overview
Add functionality to ActionDispatch::Routing::Mapper The purpose of this module is to provide methods that can be used within config/routes.rb to define sitemaps and configure sitemap options.
Instance Method Summary collapse
- #run_filter(sitemap_route_name = nil, start_point = 0) ⇒ Object
-
#sitemap(name = :sitemap, options = {}, &block) ⇒ Nil
Defines a sitemap for a Rails app.
Instance Method Details
#run_filter(sitemap_route_name = nil, start_point = 0) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/duck_map/mapper.rb', line 127 def run_filter(sitemap_route_name = nil, start_point = 0) total = 0 # assign the sitemap_route_name to the sitemap_route_name attribute of every route that has just been added during the execution of the above block. start_point.upto(@set.routes.length + 1) do |index| # this is where the actual filtering of routes occurs and is based on the current sitemap filter settings. # if the route passes the criteria, then, it is "marked" as part of the sitemap. # no need to evaluate it every time a sitemap is requested. evaluate it now and mark it. unless @set.routes.routes[index].blank? if @set.routes.routes[index].sitemap_route_name.blank? @set.routes.routes[index].sitemap_route_name = sitemap_route_name @set.routes.routes[index].available = @set.include_route?(@set.routes.routes[index]) total += @set.routes.routes[index].is_available? ? 1 : 0 end end end return total end |
#sitemap(name = :sitemap, options = {}, &block) ⇒ Nil
Defines a sitemap for a Rails app.
You can find a few examples and apps at:
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/duck_map/mapper.rb', line 21 def sitemap(name = :sitemap, = {}, &block) = name.kind_of?(Hash) ? name : name = name.kind_of?(String) || name.kind_of?(Symbol) ? name : :sitemap config = {controller: :sitemap, url_limit: nil}.merge() sitemap_raw_route_name = "#{name}_sitemap" sitemap_route_name = name_for_action(sitemap_raw_route_name, nil) begin unless @set.routes.find {|route| route.name.eql?(sitemap_route_name)} # create a route for the sitemap using the name that was passed to the sitemap method inside config/routes. match %(/#{name}.:format), controller: config[:controller], action: name, via: [:get], as: sitemap_raw_route_name # if not found here, then, there must be a real problem. # later, i will implement an exception, etc. sitemap_route = @set.routes.find {|route| route.name.eql?(sitemap_route_name)} # identify the route as a "sitemap" route and build it's full name. sitemap_route.is_sitemap = true sitemap_route.url_limit = config[:url_limit] sitemap_route.sitemap_route_name = sitemap_route_name sitemap_route.sitemap_raw_route_name = sitemap_raw_route_name # this is how I am faking to always point to the SitemapController # regardless of namespace sitemap_route.defaults[:controller] = "sitemap" end rescue ArgumentError => e unless e..include?("Invalid route name") raise e end end # now, find the route again, because, we need to set the following boolean and there might be several # calls to sitemap without a block. if we were to set this boolean in the code above when checking # if the route already exists, then, the boolean may never be set. sitemap_route = @set.routes.find {|route| route.is_sitemap? && route.name.eql?(sitemap_route_name) } # once a sitemap route has been flagged as being defined with a block, then, you should never set it back to false. # one of the features is to be able to encapsulate a set of routes within a sitemap as many times as you need. # meaning, you might want to wrap five routes at the top of the file, three in the middle, and two at the bottom and # have all of them included in the default sitemap. # Since all routes within a sitemap block will be marked with the same name, # I am not keeping track of sitemaps being defined with or without a block, so, all I need to know is about one of them. unless sitemap_route.sitemap_with_block? sitemap_route.sitemap_with_block = true if block_given? end # DuckMap::SitemapControllerHelpers is a module that is included in SitemapBaseController and contains # methods such as sitemap_build, etc. Define a method to handle the sitemap on DuckMap::SitemapControllerHelpers # so that method is visible to the default sitemap controller as well as any custom controllers that inherit from it. # originally, I was simply defining the method directly on SitemapBaseController, however, it was causing problems # during the development cycle of edit and refresh. Defining methods here seemed to cure that problem. # for example, the default sitemap: /sitemap.xml will define a method named: sitemap # on the DuckMap::SitemapControllerHelpers module. unless DuckMap::SitemapControllerHelpers.public_method_defined?(name) DuckMap::SitemapControllerHelpers.send :define_method, name do if DuckMap::Config.attributes[:sitemap_content].eql?(:xml) sitemap_build end respond_to do |format| format.xml { render } end end end # determine if the sitemap definition included a block. if block_given? # the starting point would be after the current set of routes and would be length plus one. # however, the starting point index is the length of routes, since arrays are zero based. start_point = @set.routes.length # push a copy of the current filter settings onto an array. # this will allow you to specify criteria setting within a sitemap definition without affecting # the default settings after the block is finished executing. @set.sitemap_filters.push # yield to the block. all standard route code should execute just fine and define namespaces, resource, matches, etc. yield total = run_filter(sitemap_route.sitemap_route_name, start_point) # knock the current filter setting off of the stack @set.sitemap_filters.pop DuckMap.logger.debug %(total routes filtered: #{@set.routes.length - start_point} included? #{total}) @set.routes.each do |route| DuckMap.logger.debug %( Route name: #{route.name}) if route.sitemap_route_name.eql?(sitemap_route.sitemap_route_name) end end return nil end |