Revolutionizing the frontend, one function at a time

Published on March 14, 2016 by Jan Haderka

Today: dealing with resources

In previous posts I introduced json functions that help devs write templates and a frontend that consumes content from Magnolia in JSON format. Even before that, Tomas showed in his introduction of our new blogging platform how much extra creative freedom a web developer can gain by abandoning model classes and relying on various templating functions only.

In this post, I will introduce yet another set of functions that help solve another common problem on the frontend. What’s the issue this time around?

When developing modern web pages, you can't finish in a reasonable timeframe without help from external css and js libraries. To bring in the libraries, using build tools like NPM & webresource, a web developer can link all resources in their app. In a CMS like Magnolia, a web developer can also define themes and organize all libraries and other resources in the theme.

This is all good for bigger projects, but sometimes you need to walk the fine line in between, for example in a case where the design is defined externally, provided to you with libraries already, where all you need to do is incorporate it in the project and use it.

Or there is the simple problem of CLI tools offering good linkage for resources while the CMS offers extra caching capabilities ... Which do you choose? What do you sacrifice? And do you have to let go of anything at all?

So the problem at hand is resources: their location, including them in the templates, keeping them up to date and ensuring links are valid, while at the same time trying to take advantage of caching and all the other goodies a CMS can offer.


And the solution?

I'd like to think that it is simply another set of functions. There might be cases where you will stick to CLI or the CMS default solution. Hopefully there's a few situations where you would find the functions below more than just helpful. I've called those functions hcmcfn. fn stands for functions, just like every time. The hcmc part is just a reference to the location where those functions were written. Sorry, my imagination might be a bit lacking when it comes to naming.


Enough with the banter, how can you use those functions?


will print something like

<link rel="stylesheet" type="text/css" href="/magnoliaAuthor/travel/.resources/travel-demo-theme/css/travels-magnolia.css"/>

<link rel="stylesheet" type="text/css" href="/magnoliaAuthor/travel/.resources/travel-demo-theme/libs/slick-carousel/css/slick-theme.css"/>


As you can see, the function is using regex to specify what resources to print links for. You can have as many of those patterns defined as you want.


Similarly you can call


and end up with something like

<link rel="stylesheet" type="text/css" href="/magnoliaAuthor/travel/.resources/travel-demo-theme/css/travels-magnolia~2015-12-14-06-46-59-000~cache.css"/>

<link rel="stylesheet" type="text/css" href="/magnoliaAuthor/travel/.resources/travel-demo-theme/libs/slick-carousel/css/slick-theme~2015-12-14-06-46-59-000~cache.css"/>



Similarly to CSS functions, same set exists for JS:




All good, but you’ll quickly come to realize that this is not enough. How often do you have multiple CSS or JS files that need to be loaded in an exact order, not just randomly dumped in a page? Those functions do not perform any dependency analysis or any other kind of magic. Still they give you enough to find the best solution for your project.

Either you create one (or two or three) master css/js files where you include other libraries in the required order.

Or you take advantage of multiple patterns you can specify in each function call. Matches are evaluated from left to right, and hits are printed in that order. So first we will output all resources matched by the first pattern, then those matched by the second, then those matched by the third and so on. And from the latter matches we exclude the resources already printed by the earlier one. So you can simply define a set of patterns from the most restrictive ones to the most permissive ones to enforce an order of output while retaining freedom to include more at a later stage like shown below.

Neat, isn't it? 

For detailed installation instructions and documentation please refer to neat-resources github project.







{{item.userId}}   {{item.timestamp | timestampToDate}}

About the author Jan Haderka

Jan is Magnolia's Chief Technology Officer. He has been developing software since 1995. On this blog, he'll write about Magnolia's connectors, integrations and coding ...with the odd Magnolia usability and development tip thrown in for good measure. He lives in the Czech Republic with his wife and three children. Follow him on Twitter @rah003.

See all posts on Jan Haderka