TwentyTen CRM

This theme is here for archival purposes only. My CRM that’s actively developed is Genesis CRM.

Download the theme on GitHub

by Bill Erickson, Andrew Norcross, Jared Atchison


TwentyTen CRM is a child theme for TwentyTen specifically designed as a Customer Relationship Management tool. It creates a series of taxonomies and custom meta boxes to collect relevant data, displays the data in a useful Dashboard page template, features a Download page template that can be used to copy/paste all the data to Excel for more advanced analysis, and is easily customized to your specific needs. Oh, and it’s free.


About six months ago I started to become overwhelmed by the number of prospective client inquiries I received. It’s a great problem to have, but a lot of prospects were falling through the cracks. I tried Salesforce for about a week, and SugarCRM for about 3 weeks (I must thank Schipul for spending an afternoon walking me through how their company manages their contacts with Sugar).

The two problems I had with all of these CRMs were that it was difficult to put the information I wanted in the system (and leave out the information I didn’t care about), and it was difficult to analyze that data. I wanted a tool that I could customize to my own needs and modify as time went on. As a WordPress developer, I chose the tool I’m most comfortable with.

This theme isn’t perfect for everyone, but it can easily be customized to your specific needs using standard WordPress code, which is exactly what I wanted. I recommend you see this as a starting point, not an end point.


First, due to the type of content we’re putting in this site, I highly recommend you either run it locally, or use a plugin like Registered Users Only to ensure it isn’t public.

  1. Download the theme
  2. Add it to your themes directory and activate. Since it is a child theme of TwentyTen, you must have TwentyTen in your themes directory as well.
  3. I recommend you fill in the Categories, Points of Contact, and Sources taxonomies first.
    1. Categories must contain Prospect (slug “prospect”), Active Project (slug “active-project”) and Closed (slug “closed”) to function correctly. Alternatively  you could modify the theme files to use different categories for the sections of the Dashboard.
    2. I use Point of Contact as the method the client initially contacted me (Email form, Email, Phone…). I’d recommend you only use one POC per project as it will mess up the stats in the dashboard if you use multiple.
    3. I use Sources as the person or website that sent the prospect to me. Mine include CodePoet, StudioPress, DIYThemes, Google, Other Referral (you can specify the Other Referral in the custom meta boxes), Unknown…
  4. Go to Appearances > Widgets and populate the three homepage widget areas with widgets. I recommend “Old Prospects” in Column 1, “Active Projects” in Column 2, and everything else in Column 3.
  5. Start collecting data! Just go to Posts > Add New to add a new prospect.


While my default setup might work fine for you, one of the best features of this theme (and WordPress in general) is how easy you can customize it.

There’s two features you should attempt customizing: Taxonomies and Custom Meta Boxes. Note: I’m assuming you are a web developer and are already comfortable coding these types of things. If not, you might want to hire someone to do it.

Taxonomies – Go to twentyten-crm/functions.php. On line 93 you see // Register Taxonomies. This is the code I’m using to create the taxonomies. You can modify the two default taxonomies here, or create additional ones. See the Codex for more information. And of course you can add additional taxonomy terms using the appropriate section of the backend (ex: Posts > Sources).

Custom Meta Boxes – I’m using a wonderful piece of code that Andrew Norcross recently contributed to generate the meta boxes. To see all the meta box options you have, go to /twentyten-crm/lib/metabox/example-functions.php. To modify the existing metaboxes or add more, go to /twentyten-crm/functions.php on line 165.

Once you’ve modified the data you collect on the backend, you’ll want to modify the frontend display of that data. Here’s the three files you should edit:

  • home.php – This is the Dashboard page template.
  • download.php – This is the Download page template.
  • single.php – This is the Single page template

Looking through the code on those pages, you should be able to figure out how to add what you want.

More Customization Tips

  • We’ve added a “Top Panel” to the top that gives you two menus, both editable from Appearance > Menus. If you’d like to replace this with the admin bar (assuming you’re running WP 3.1), uncomment lines 523-525 (look for “Top Panel instead of Admin Bar”).
  • The post editor has been moved into a meta box so you can drag it around and put it wherever you like. If you don’t want to use it, click Screen Options and uncheck “Notes”.
  • I’ve created a bunch of useful widgets for the homepage. If you’d like to create your own, just put them in the /lib/widgets folder. I also added two hooks that some of the widgets use: crm_pre_stat_loop and crm_stat_loop. This loop goes through all the posts in the site and is used to calculate statistics. If your widget needs to loop through them as well, I’d recommend using this instead of doing your own loop in your widget. This way there’s only one loop rather than one for each widget. Look into a widget like widget-other-stats.php for an example on how to use this.


  • 1.3 (2/21/11) A large release with many changes. Here’s a few notable ones:
    • Made the dashboard the homepage (so you don’t need to create a page, set page template, then set as homepage). Widgetized the homepage so you can control what boxes show up where.
    • Lots of tweaks to the backend. Moved post editor into meta box, renamed “Post” to “Contact”, reordered/removed admin menu items, removed dashboard widgets (will create some in a future release), and customized the Contacts column view to include Status, Point of Contact, and Source.
    • Cleaned up the code so it runs better. It should work with debug mode on now! (Thanks Mark Jaquith for the tips)
  • 1.2 (2/5/11)
    • Added isset() to variables in /metabox/init.php and improved method of hiding post editor, based on recommendations by Mark Jaquith
    • Used global variable $prefix to be used in generating custom fields in meta box as well as in the page templates. If you want to use a different prefix, change it once without editing a bunch of files.
  • 1.1 (2/3/11) – Updated the metabox code based on improvements by Jared Atchinson
  • 1.0 (1/31/11) – Initial release

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson


  1. Christine Green says

    This is amazing! I’ve been struggling with the same issues trying to find a CRM that fit my needs. Thanks so much for creating this free CRM theme!

  2. Sakib says

    I would like to give a BIG hugs and thanks. Amazing share, wordpress created a platform, where people love to share their knowledge, experiences and as well cool works with entire world. Thanks so much bill, great creation.

  3. Kate Mag says

    Do you have a plan to put the TwentyTenCRM theme to repository?
    I liked this idea, the theme looks awesome. Thanks for sharing this theme

    • Bill Erickson says

      I’ve actually spoken with Otto about this (one of the reviewers) and I’d love to get it in there. I originally submitted it to the repo before posting it on here, but it didn’t make it because it was a child theme. Otto said he could get it around that, but we’re trying to decide if we want to continue building it off of TwentyTen or make it a standalone theme.

      So yes, we should have it in the repo soon, but we need to figure out how best to approach it.

      • Matthew McGarity says

        My preference would be for this to be stand-alone — that way, one is not dependent on the parent theme being there, being updated, not having issues, etc.

        Good work!

  4. RIch says

    Hey mate awesome job.

    Any chance of writing a outlook csv contact import script?
    Also, I am collecting date from my site in terms of applicants for jobs, and bookings for events, with two seperate plugins for each purpose.
    I suppose intergating that data into TwentyTenCRM would not be an easy task…?

    • Bill Erickson says

      There’s no plans of writing an outlook contact importer, but if you (or a developer you hire) build one as a plugin I’d be happy to promote it here.

      I don’t think it would be too difficult to collect that type of data with TwentyTen CRM. Here’s some approaches, in increasing difficulty:
      – Set up two independent installs of TwentyTen CRM. This gives you the ability to collect the relevant data for each contact type and analyze it.
      – Set up one install and add a taxonomy “Interest” (or something similar) with the terms “job applicant” and “event booking”. The downside to this is all the widgets will display aggregate data of both, so I’m not sure how useful it would be.
      – Change the “Contacts” label to “Applicants” and create a post type called “Event Bookings”. You can then create relevant meta boxes for each, to collect the data you want. You would also need to modify all the widgets, possibly adding a “post type” option to select what data source to use. You could then have two of every widget – one for each post type.

  5. Andrew says

    Bill or anyone, not sure if this is the right place but I think I missed a setup step. If I open the panel and go to “Active” or “Prospects” it gives me a 404 trying to get to /twentytencrm/prospects/ for example. Is there a page or post I should setup with some shortcode?

    Thanks for such a cool theme and great idea!

    • Bill Erickson says

      Good catch. I think Andrew Norcoss had those pages in his install and hardcoded it that way. Basically both menus in the top panel are WordPress menus, editable from Appearance > Menus. If you don’t create any menus, there’s a fallback menu in functions.php on line 22 that has those links hardcoded. In the next version I’ll have it link to category archive pages rather than actual pages, since most people won’t have a page called Prospects.

      On my install I run the default admin bar so I never noticed it.

      • Andrew says

        Thanks. Very simple and works great! I also noticed in loop.php the isset on line 21 got loose and escaped from the () so it just needs to be wrangled back in there to get the category display page back in order. Thanks so much for sharing all this!

  6. Josh says

    Had a really odd problem when I tried to install this on a brand new WP install (3.1 native install).

    Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /nfs/c07/h02/mnt/100054/domains/ on line 60

    The problem appears to be with this:

    class cmb_Meta_Box {
    protected $_meta_box;

    If I comment out the 2nd line (protected $_meta_box;), then the theme runs fine but none of the metaboxes show when trying to add a new contact.

    Wondering if I accidentially screwed something up??

    • Bill Erickson says

      I’m pretty sure the issue is that you’re running PHP4, and that bit of code you found depends on PHP5. WordPress is dropping support for PHP4 and switching to PHP5 with the next release (3.2), so this might be a good time to upgrade.

      • Josh says

        You hit it on the head. I was thinking “Surely, that’s not possible!” and then I checked my server settings and that domain was the ONLY one on PHP4. Thanks for the info. Fantastic contribution btw – thanks so much for sharing this. I’m EXACTLY in the same boat – I keep losing track of clients, potentials ,etc but the simplest system to use was Zoho and it was still a pain in the a$$ 🙂

  7. James says

    Was using version 1.2 and wanted to check out 1.3 replace 1.2 with 1.3 but none of the data entered using Version 1.2 is visible in 1.3 looks like the field names were modified and on a lessor note the .css file still shows the Version as 1.2.


    • Bill Erickson says

      Were the fields names changed or just the prefix? You can set the prefix in functions.php. I thought we left all the field names the same but I could be wrong (I can’t find a copy of 1.2 on my server).

      Here’s a few solutions:
      – Using phpMyAdmin or Sequel Pro, change the field names to those used in TwentyTen CRM 1.3. Something like : UPDATE wp_postmeta SET meta_key = replace(meta_key, 'client_phone', 'crm_client_phone');
      – Edit the theme files to use your old field names. If all that needs changing is removal of the crm_ prefix, just set $prefix = ''; right before the metaboxes are created in functions.php. If the fields need more changes, replace the actual field names in all the theme files.

      I don’t plan to release a new version of this any time soon, so don’t worry about changing the theme files. We’re considering rebuilding the whole theme to be independent of TwentyTen. When we do this, you’ll be able to customize the theme by creating a child theme of it (rather than TwentyTen CRM being a child theme of TwentyTen).