Search code examples
crafter-cms

How to do URL mapping in Crafter 3.0


I was wondering if crafter (3.0) has the ability to do url mapping.

For example, to have a content at a given path like /site/website/foobar/mycontent/index.xml, and its url being /news/2017/11/17/my-content (notice the added / which can't be used in a file-name field since they are automatically converted to - in studio).

Thanks,

Nicolas


Solution

  • A built-in router is on our roadmap (https://github.com/craftercms/craftercms/issues/1622), but for now, you can add one to your blueprint easily:

    1. Create a component that contains a "routing table". This component has a repeating table where each entry is an inbound URL and outbound URL.
    2. Create a Groovy filter script that will intercept all calls and checks if the URL matches one of the inbound URLs. If it does, it forwards the request to the corresponding outbound URL. Below is the possible code for such filter:

      def routingTableItem = siteItemService.getSiteItem("/site/components/system/routing-table.xml")
      def routingTable = routingTableItem.urlRoutingTable.item
      def currentURL = request.requestURI
      
      def matchedEntry = routingTable.find { entry ->
          return currentURL == entry.inboundURL.text
      }
      
      if (matchedEntry) {
          def inboundURL = matchedEntry.inboundURL.text
          def outboundURL = matchedEntry.outboundURL.text
      
          logger.info("Forwarding URL ${inboundURL} to ${outboundURL}")
      
          request.getRequestDispatcher(outboundURL).forward(request, response)
      } else {
          filterChain.doFilter(request, response)
      }