How to split DOM-based Routing in multiple files


#1

I’ve been working on my own version of the Sage theme for a while now,
customising it to suit my basic project needs.

The Sage implementation of DOM-based Routing is excellent,
but for larger projects I like to split the routing to be one class/route per file

##My solution

1. Every route has it’s own JS file:
assets/scripts/routing/example.js contains:

var routingExample = {
    // All pages with body class 'example'
    'example': {
        init: function() {
            // JavaScript to be fired on all pages
        },
        finalize: function() {
            // JavaScript to be fired on all pages, after page specific JS is fired
        }
    }
};

2. Every route’s JS file is added as a file dependency:
assets/manifest.json contains the following main.js dependency, before scripts/main.js:

"main.js": {
  "files": [
    "scripts/routing/common.js",
    "scripts/routing/example.js",
    "scripts/main.js"
  ], 
  "main": true
},

3. Object content of every route’s JS file is merged in Sage variable
assets/scripts/main.js contains the following variable for :

var Sage = $.extend(
   routingCommon,
   routingExample,
);

##My questions

  • Has anyone solved the problem of splitting routing in separate files in a different way?
  • Does anyone have proposals to make the splitting/merging more efficient?

#2

I like your solution, but i prefer to split the javascript “components”. For example (following your process):

1. Every component has it’s own JS file:
assets/scripts/products-carousel.js contains:

function productCarousel() {
  ...
}

2. Every component’s JS file is added as a file dependency:
assets/manifest.json contains the following main.js dependency, before scripts/main.js:

"main.js": {
  "files": [
    "scripts/products-carousel.js",
    "scripts/main.js"
  ], 
  "main": true
},

3. Every component’s function is called in Sage routes
assets/scripts/main.js calls function in different routes:

var Sage = {
    'common': {
      init: function() {
      }
    },
    'template_page_products': {
      init: function() {
        productCarousel();
      }
    }
  };

What do you think of this approach?


#3

The best thing would be to have a single JS file per component in witch declare its routing.


#4

I’m very new to Sage (also, not really experienced in javascript) and I’m trying to figure out the best way to write maintainable JS.
I feel like yours is a great solution, with only one problem: since I need to use jQuery in my script I have to wrap my extras.js’s code in an anonymous function “(function($) { … })(jQuery);”.
This also means I won’t be able to access the variables I define on that file in the main.js router. Is there any way to solve this?


#5

This is really only relevant to Sage 8, where routing took place in a single file. In Sage 9, there is a routes directory, in which you can declare your route-based JS in separate files and import into a main.js file.