On Homemade Tools
Whether building websites and applications or repairing tractors, tools are at the center of life. Director of Development Bob Davidson believes in “the right tool for the right job,” but sometimes the right tool is not at hand. Sometimes it makes sense just to make your own.
As a person who spends a significant amount of time building websites and applications, repairing tractors, and occasionally putting up fences, tools are often at the center of life. I’m fond of the phrase, “the right tool for the right job.”
But sometimes the right tool is not at hand, or readily available. Sometimes it makes sense to just make your own.
Homemade tools can address minor inconveniences, or even become an integral part of your workflow, and quickly become an important part of any builder’s repertoire. We at Blend have amassed a small collection of our own, some of which we’ve released, and some of which will be released soon.
While it may not seem like a “tool,” per se, a good snippet library used by the entire team saves time. Perhaps more importantly, it also encourages consistency between projects.
At Blend, we have snippets for several simple, common scenarios, such as creating a new content class, or a new property within that class. For example:
<?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>Content Template</Title> <Shortcut>jcontent</Shortcut> </Header> <Snippet> <Imports> <Import> <Namespace>EPiServer.DataAnnotations</Namespace> </Import> </Imports> <Declarations> <Object> <ID>Name</ID> <Default>Name</Default> </Object> <Object> <ID>Description</ID> <Default>Description</Default> </Object> <Object> <ID>Guid</ID> <Default></Default> </Object> </Declarations> <Code Language="CSharp"> <![CDATA[[ContentType( DisplayName = "$Name$", GUID = "$Guid$", Description = "$Description$")]$end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets>
Tamper Monkey Scripts and Bookmarklets
For a tiny example, we have a Tamper Monkey script to add a right-click menu option to take you to the Optimizely Admin. Sure, the quick navigation button will take you to the CMS editor section, but if your destination is the Admin, this saves a click.
Most of our Tamper Monkey scripts are pretty specific to our environment and software stack, but my personal favorite (which copyright precludes me from sharing) is one that plays the “coin” sound from Super Mario Brothers when you mark a task done. Sometimes a tool is more about morale than efficiency.
We build all our new Optimizely sites using a common starting point, which we have formalized into a “dotnet new” template.
Certainly, we can use the Optimizely-provided templates as a starting point, but we’ve chosen to build our own for a few reasons.
First, these templates give us exactly what we need in a starter project, and nothing more. Alloy and Foundation are fine demos, but include quite a bit of complexity that just isn’t necessary for many projects, but will still require maintenance if not removed. On the flip side, the Empty CMS template is too barren and requires a ton of boilerplate copy/pasted. But a custom template is just right.
Additionally, our template enforces consistency across projects. When we decide that something is “the Blend way,” we put that decision in our templates (when possible). Now every project going forward will use that same solution.
We’re currently putting on the final touches of our internal templates and will be making the public, though I would recommend you look at them as a starting point and build your own templates that suit the needs of your team and clients.
Libraries and Add-Ons
As an implementer creates more and more sites, they’ll find that there are common “chunks” of code that seem to appear (often in various variations) across code bases. The obvious thing to do is to package them up into libraries that can be referenced. Blend is no stranger to doing this. In fact, we’ve released many of our more common libraries (and a few experimental ones) as open-source Nuget packages in Blend Labs. For Optimizely in particular, the Blend.Optimizely package, a collection of utilities and convenience extension methods, is installed by default on every site we build.
Maintaining a library of packages does require process. Each of our packages has an owner who oversees pull requests and maintenance tasks. We have processes around scheduling and making decisions about updates and features. Special care is taken not to break older implementations with new versions.
But the packages in Blend Labs are only the beginning. We’re working on more packages to release, including a couple of add-ons and plugins. We’re working on releasing some internal tools to ease content migration, display hidden metadata on pages, useful tag helpers, and more. (Watch our thoughts feed for new releases as they happen!)
Finally, we occasionally need something very small and specific. Something like a quick tool to convert a CSV to a tab-delimited file, or a job to mass-update and publish a section of a site. With these, it’s usually some quick and dirty code, thrown into either a command-line program, a dotnet-script, a LINQPad query, or maybe even a scheduled job embedded in a site. These tend to be short-lived but can be tremendously valuable in the amount of manual labor they save.
One of the strangely more useful homemade tools I've made specifically for Optimizely CMS development is a tiny Windows utility that makes generating GUIDs as easy as a single click, or a keystroke. "GuidToClip" is available on Github.
There's a temptation among developers to build homemade tools — call it the “Not Invented Here Syndrome” — and admittedly it can be a fun challenge and diversion from the daily grind.
But, it always boils down to the same question: do I get more value out of creating this tool, than not? Is there something out of the box I can use? Are there any other alternatives?
Given the right circumstances, homemade tools can save a lot of time. In the wrong circumstances, they can also waste a lot of time. The challenge is finding the right circumstances, or as I’m fond of saying, “the right tool for the right job.”