application.js) on all pages, then all you need to do is put the following lines of code in your layout file:
email.js to be loaded on the contact page. It turns out that there’s a simple way to add things dynamically to layout files – instance variables. These can be set in the routes and then refererred to in the views. I use the instance variable
I can then add an extra line to my layout file that will include the relevant script tag if the
@js variable has been set.
@js array, why not just add scripts that will appear on all pages (application.js and JQuery) to the array as well? This can be achieved by creating another array, using Sinatra’s
settings method, called
These two arrays need to be added together to create one big array to iterate over. The uniq method is used to avoid any repetition in case a file gets added to the
@js array that has already been placed in the
This amount of logic in a view looks messy, which is always a bad sign. The best way to deal with lots of view logic is to abstract it into a helper method. Helpers are easy to set up in Sinatra, you simply open up a block and place the methods inside. These methods are then available inside routes and views. Here’s a helper that can be used to clean up the layout:
Now all that’s needed in the layout file is this line:
- In the layout file using the
- In the handler using the
We can improve on this further by using a helper method to set the
@js instansce method. Rather than setting it directly in the handler, we can use a helper method called
js that could be used to add any custom js files that are required for that route. This is also a good opportunity to clean up the
js helper method means that things look a bit neater when called in the handler. This is especially true since the files are no longer required to be placed inside an array:
To finish off, let’s make it easier to add JQuery and other popular libraries when they’re required. This involves writing another helper method that uses shortcut symbols in place of the full url:
Now if you want to add a specific library all you need is the following code inside a route handler:
path_to helper method.
With the helper method working how we want, it’s time to go modular and move it into a separate file. We first need to create a file called
Sinatra (which is considered best practice when extending Sinatra with modules). The last thing to do is make sure to require
Sinatra::Base at the top of the file.
To use these helper methods, all you need is the following line of code in the main application file (
More Helper Methods
I’ve taken the whole concept further and built a module called
HeadCleaner that has a helper method for all the common items found inside the head of an html page such as
webfonts etc. This means that you can just use method calls to create a very minimal looking head section of the layout file such as the one shown below:
You can see the code here.
It’s by no means perfect and I’d appreciate any feedback or help in developing this further (fork the code on github!). Ideas that I have for developing this are:
- Have a separate yaml file with the shortcuts to external libraries in it so that it can be easily edited
I hope these helpers are, well, helpful. If you’ve developed any helpers in your Sinatra development, do tell in the comments. Cheers!
(Main Image courtesy of Shutterstock)