Why read open source?
When folks write about open source, I think there is a strong emphasis on contributing to open source projects, which makes sense. Many software professionals are excited to give back to the community.
But beyond adding to your favorite project, open source philosophies have a number of other benefits in our daily lives. In particular, I love open source because it allows me to learn more about my tools when the documentation is out of date, incomplete, or leaves me with additional questions from my own curiosity.
This happened to me recently when I was working on https://about.gitlab.com, a static site built with Middleman. I needed to find a more comprehensive list of available callbacks in the Middleman lifecycle.
I hope this blog post is helpful if you're looking for existing Middleman callbacks, or if you're getting started reading through the source code of your favorite open source tools.
The task at hand
If you're getting started reading open source, I find it helps to have a specific task. Any unfamiliar codebase can be challenging to navigate. Having a goal in mind narrows your focus. Here was my task for Middleman:
I recently created a merge request to add Webpack devServer to the local development environment. I had to modify some existing behavior of our Middleman preview server and wanted to use one of the lifecycle callbacks to modify the preview server's log output.
However, the Middleman documentation does not currently list all available callbacks, nor where they happen in the lifecycle. The extension docs say:
Middleman extensions are Ruby classes which can hook into various points of the Middleman system, add new features and manipulate content. This guide explains some of what's available, but you should read the Middleman source and the source of plugins like middleman-blog to discover all the hooks and extension points.
I took them up on their advice and read through the Middleman source code to find the available callbacks. Here's what I found, and how I found them.
Callbacks available in Middleman Core
initialized: called before config is parsed, and before extensions are registered
configure: called to run any
configureblocks (once for current environment, again for the current mode)
before_extensions: called before the
before_instance_block: called before any blocks are passed to the configuration context
before_sitemap: called before the
SiteMap::Storeis instantiated, which initializes the sitemap
before_configuration: called before configuration is parsed, mostly used for extensions
after_configuration: called after extensions have worked
after_configuration_eval: called after the configuration is parsed, before the pre-extension callback
ready: called when everything is stable
before_build: called before the site build process runs
after_build: called after the builder is complete
before_shutdown: called in the
shutdown!method, which lets users know the application is shutting down
before: called before Rack requests
before_server: called before the
reload: called before the new application is initialized on a reload event
How to find Middleman Callbacks
- Clone the Middleman repository to your local machine.
- Open the Middleman directory in a text editor, IDE, or any tool that allows you to easily search through a folder's files for specific strings.
- Start with the existing documentation if it exists. Middleman lists the names of a few callbacks. You can search the directory for the string
- In this instance, you should be able to find that string used like so:
- You may also find it listed with other similar symbols in
- Read through the related blocks of code around these search results, you'll get some additional context for how they work, and you may find additional search terms that will be helpful.
- In the case of Middleman callbacks, you can continue to search for combinations of the
execute_callbacksmethod with any callback listed in
middleman-core/lib/middleman-core/application.rbto find where and when specific callbacks are used.
With this in-depth knowledge of your tool, you can be more productive at your day-to-day work, and you can contribute back to open source more easily.
In my case, I was able to identify the best callback for my usecase, and I now plan to check in with the Middleman team and ask if they would accept a contribution to their documentation with this information so it's easier for other folks to find in the future.