This post is very old and contains obsolete information.
Middleman extensions, like rails plugins, are packaged as gems. There are three main ways to extend middleman. You can add helpers, add middleman commands, or extend the sitemap generation in someway. Lets go through those in detail.
Creating the extension
Create a gem using
bundle gem _name_
middleman-core to your gem dependancies in the
Register your extension into middleman. Our gem will be activated in the sites
activate :graphviz and this is how middleman knows what to load.
Replace with your gem name!
Write the code that actually plugs into middleman. The we are going to add some helpers to the site, so let’s register them here. Create
Replace with your gem name!
Lets create a basic helper method now in the file
lib/middleman/graphviz/helpers.rb. This is going to accept one parameter and a block. We are going to get the content of that block and then spit it back directly for now.
These can be used like
<%%= basic_helper_example( "My Title") %>
or as a block
<%% block_helper( "My Title") do %> This is going to be in upcase <%% end %%>
Add it to an active middleman project
Have bundler reference this new gem inside of an existing middleman project.
Inside of the middleman project’s
config.rb activate it:
Now startup the middleman server, and use your helper in the page! Note that, just like when you use a helper defined in
config.rb you need to restart
middleman server to see your change take effect.
Adding configuration to your extension
If you want to include configurable options in your extension, here’s some skeleton code for
Adding additional middleman commands
The middleman command is built on thor, which as we know is awesome. To add a command to the middleman, use the following template for each
Then, inside of
Thor::Actions class gives you access to many different helper commands that make it easy to move, filter, template, and otherwise mangle files, and of course you have access to the full middleman app.
Manipulating the sitemap
The most awesomest way to extend middleman is by modifying the sitemap. This lets us create whole new URLs that are derived and generated from other sources. This is how the middleman-blog extension really works, and if you want to start an indepth exploration that’s a good place to start spelunking.
Lets build an extesion that creates pages from an external datasource. In this case, a CSV file, but you could imagine having this come out of a database instead. This lets us manipulate the sitemap of the site it’s been created, and will let us add and remove different pages based upon what middleman knows about the site.
First we add an
after_configuration handler to
Middleman::Graphviz::Extension to register our class as a
Then we create
initialized is called, we are grabbing references to the middleman app. We’ve hard coded two things in this example that should be from the options, the page name template, and the page template itself. Since the
page.html isn’t meant to be standalone, we tell middleman to ignore it in the sitemap with
manipulate_resource_list is called it is passed a list of resources that middleman currently knows about. We return a new list of resources based on that list. What we are doing in this example is loading up the list of pages from a file called
pages.csv, creating new pages based on that, and then returning the new list.
This example is contrived and we are loading in the list of pages from the filesystem. At this point in the rendering process we do have access to all of the pages, instead of loading up a file you could inspect the site map, go through all of the pages and make additional pages for subsets of those. The
middleman-blog does this for both
tag pages and
calendar pages. Instead of calling
::CSV.open it goes through all of the pages on the site and collects a dynamic list of pages based upon the metatag, either
tag or published dates.
Then we create the entries in the sitemap themselves. These first get proxied to our page template. Then we set the metadata of the particular page to be what we loaded in from the file.
Here’s an example template
%h1= row = row
This example is equivelent to looping over a file in
config.rb and setting up page proxies there. However in that case we don’t have access to the sitemap overall, so we couldn’t generate a dynamic list of new pages based upon existing pages. With this extension we can insert ourselves into the rendering process and add the awesome.
Building these extensions is a very complicated way to achive things that would be simplier if you just build the site in rails and had a database with you at runtime. But it works, and you can achieve plug into the rendering process to create a more dynamic static site. Helpers are by far the easiest way to package things together, and as you can see from the example I’m working through I’m working on an easy way to integrate Graphviz images in middleman documents without a seperate workflow. (Coming soon.)
Middleman CLI commands are also easy to build, though here you do start to need to know more about how the internals of how middleman is setup. Things like the
middleman-deploy gem are pretty amazing and can really help with the overall publishing workflow.
And sitemap manipulation is the most powerful, which lets you recreate pages based upon site and page metadata that is collected throughout the process. The entire
middleman-blog extention is build using this functionality.