Skip to content


Folders and files

Last commit message
Last commit date

Latest commit



3 Commits

Repository files navigation


Pixel Union's very own Tumblr theme skeleton and build system, now open to everyone. Pangolin was built to help facilitate the rapid development of themes for the Tumblr platform. It provides a heavily opinionated suite of tools for every stage of the project.

Pangolin also includes pre-built functionality for Open Graph meta, Disqus and Facebook commenting, Google Analytics integration, Apple touch icons, 20+ social accounts, live load and click-to-load posts, support for a marketing script, and so much more. :)

Our Stack


For overall asset watching, compiling, and serving. Middleman is used to serve styles and scripts, and a variety of Ruby helpers are used for templating and Tumblr settings.


We preprocess our HTML using Slim.


We prefer CoffeeScript for JavaScript preprocessing. Additionally, we use class-based Backbone (+ jQuery and Underscore) for MVC. Views are available for Instagram, Flickr, and Twitter feeds.


We preprocess CSS with SCSS and Compass. By default, Normalize.css is used for cross-browser style resets.

PXU Photoset Extended

Additionally, the PXU Photoset Extended plugin is included in the source for custom Tumblr photosets.

Theme Development

To get started on a new or existing Tumblr theme, use the following steps.

  1. Clone this repo in to a new folder (or the repo of an existing theme).
  2. bundle install to pull in the required gems.
  3. Set the theme name in config.rb. (Not required if you're working on an existing theme.)
  4. Start the development server with bundle exec rake server.

Develop! Middleman is now serving your CSS at http://localhost:4567/styles/style.css and your JavaScript at http://localhost:4567/scripts/script.js.

Because Tumblr doesn't support local theme development, you will need to paste the theme code in to your theme's Customize HTML area each time you change the markup. You can copy the theme code to your clipboard on every .slim file change with bundle exec rake auto_build.

Note: Tumblr now enforces assets to be served over HTTPS when in the Customize Theme screen, which Middleman does not do. This means that, for the moment, you won't be able to develop and live-customize your theme at the same time.

Rake Tasks

The following Ruby rake commands are available for building the theme files.

  • bundle exec rake server runs the Middleman development server at port 4567. It auto-builds and serves static assets for "local" development.
  • bundle exec rake auto_build automatically builds the development file and copies it to the clipboard when any slim file is changed.
  • bundle exec rake build builds all files, including assets. This minifies the styles and scripts.
  • bundle exec rake build_development builds the development theme file and copies it to clipboard.
  • bundle exec rake build_production builds only the production theme file.


Use config.rb to configure your development environment and theme settings.

theme and version

These are used when creating the theme's build filename (for example, mytheme-v1.0.0.html), the masthead (generated in lib/theme_helpers.rb), and in the footer.

style_url and script_url

After making changes to styles or scripts, you will need to upload the assets to Tumblr's static asset CDN. Once uploaded, update these two variables and build out the theme file. Your local static assets can be found at your-theme/build/scripts|styles.

developer_name, developer_url, and purchase_url

These are used in both the masthead and footer for informative and marketing purposes.

demo_url and marketing_url

Both of these variables are used in a themeInfo object. marketing_url should point to a script that can be injected on the page for marketing purposes. See Marketing Helper for more information.

Ruby Helpers


Inserts a masthead into the code, with the theme name and version from config.rb.


A helper for inserting Tumblr blocks into the code. Usage:

== block 'PreviousPage' do
a.previous href="{PreviousPage}" {lang:Newer}

will output:

{block:PreviousPage}<a class="previous" href="{PreviousPage}">lang:Newer</a>{/block:PreviousPage}


This provides a nice way to handle Tumblr's customize screen options. For in-depth usage see the _TumblrOptions.slim partial. The add method adds an option with the given type, name, and optionally a default value. The :output option determines whether or not a text option will be rendered literally by the to_tumblr_json method (which will break if the text option contains single quotes).

The to_tumblr_json method outputs all the options added to the instance so far as a javascript object, inside of script tags. It becomes available as Theme.options.

The Theme object

By default, theme is instantiated as a new Theme object. This object contains everything that powers the theme's core JavaScript on the page. Here's a run down of everything contained in the object:

*View and PostTypes.*View

As Backbone is used as Pangolin's JavaScript framework, these members are methods used to instantiate new Backbone views. Found in: source/scripts/theme.js and source/scripts/Theme/*


Various methods used to manipulate the page. Found in: source/scripts/Theme/


Contains all publicly accessible theme options. See the Ruby helper TumblrOptions for more information. Found in: source/layouts/_TumblrOptions.slim.

Marketing Helper

Pixel Union has developed a custom script that, when injected in to the DOM and the user is viewing either the Customize page or Demo URL, displays a small marketing widget. You are welcome to build your own, but make sure you set demo_url and marketing_url.

Pixel Union's theme marketing widget

See the source of source/layouts/_MarketingWidget.slim for more information.



This layout file contains the basic structure of the page (everything inside the body tags). It references quite a few partials (found in layouts/).


Other than index.html.slim, all the layouts are in this folder.

  • layout.slim contains the "outer" portion of the theme, everything outside the body tags, plus the script inclusions that go at the end of the body.
  • _TumblrOptions.slim contains all the customization screen options. Any JavaScript variables or CSS properties dependent on the customization options should be in here too.
  • _PermalinkContent.slim contains comments, notes, and anything else that should only show on the permalink page.
  • _PostMeta.slim contains commment counts, timestamps, and any other post metadata.
  • _Social.slim contains the links to social media accounts.
  • _MarketingWidget.slim is for the marketing widget that is displayed on theme demos and on the customization screen.
  • _OpenGraph.slim contains the Open Graph meta for supporting Facebook sharing.


This folder contains the partial for each post type.


This folder contains all the JavaScript/CoffeeScript.

  • script.js contains the "root" script file. All it does is require the rest of the javascript: jQuery, Underscore.js, Backbone.js, the plugins, the theme code.
  • libs/ stores any non-plugin JavaScript libraries in use.
  • plugins.js for requiring any jQuery plugins.
  • plugins/ for storing any jQuery plugins.
  • external-feeds/ contains CoffeeScript for social feeds.
  • theme.js just requires the Theme object and initializes the ThemeView.
  • Theme/ contains all the theme code.
    • is the "root" view that sets everything up. It checks some settings and gets things going.
    • is the superclass of all our posts. It contains any functionality shared by all post types.
    • PostTypes/* is the functionality specific to each post type.
    • handles setting up the post views, infinite scrolling, etc.
    • contains any utility functions that need to be added.


All the stylesheets!

  • style.css.scss includes the normalize styles, the clearfix, and pulls in all the theme styles.
  • _Theme.scss includes the global theme styles and variables.
  • _Mixins.scss for handy mixins.
  • _Post.scss includes styles for all post types.
  • PostTypes/ includes styles for each individual post type.
  • extras/ for any additional styles. For example: the photoset plugin.

Special Thanks

Pangolin has been touched by nearly every developer to walk through Pixel Union's doors, but it wouldn't be where it is today without the help of Jared Norman, Gray Gilmore, and Philip McLaughlin.


When contributing to Pangolin, keep a few things in mind:

  • Take care to maintain the existing coding style, including indentation and naming conventions.
  • If updating styles or scripts, be sure to build_production, upload the respective stylesheet or script to Tumblr's static asset CDN, and update the URL within config.rb.
  • If updating markup, be sure to use the block helpers (== block 'PreviousPage' do) over standard Tumblr blocks ({block:PreviousPage}...{/block:PreviousPage}) when possible.