Search Engine Optimized breadcrumbs

I had a need to build some search engine optimized breadcrumbs for a project I’m working on right now.  I didn’t want to just use Yoast’s breadcrumbs, because I’m using Twitter Bootstrap, and I wanted to make use of the built-in breadcrumbs support, so I did a Google, found something, tweaked it and am using it on this project.  I wanted it to support both page and blog post hierarchy, the original source did not support page hierarchy, just post categories.  Everything works automagically, all you need to do is use the seo_breadcrumbs() php function.

Here are some screenshots of it in action:

Breadcrumbs in a post, when a page has been set for blog posts (other than the Home page)

Breadcrumbs in a post, when no page has been set for blog posts (default Reading setting)

Breadcrumbs in a page, when the page has a parent

Breadcrumbs in a page, when there is no parent page

Here’s the code:

Use Alfred to set up a WordPress theme based on _s and Twitter Bootstrap

I said a long time ago that I would never use another theme framework now that I have Museum Core.  Well, unfortunately for me, WordCamp SLC — particularly the presentations of Jake Spurlock, George Ortiz and Patrick Cox, as well as working on the theme which was based on _s — changed my mind on that.  I now think that the best solution for jumpstarting a new theme project is a combination of Twitter Bootstrap and _s.

But this post isn’t about what makes those two frameworks awesome (you can read about that on their respective sites, or just Google _s and Twitter Bootstrap for awesomesause).  I just wanted to share a quick Alfred extension I made that will setup a WordPress theme based on the _s theme framework that also loads Twitter Bootstrap assets into your theme’s directory.  Note: this doesn’t enqueue any of the styles or javascript.  I may add that later.  For now, this just sets up the directories and pulls the latest versions of each framework from their GitHub repositories.  It will also initialize a Git repo if you want to use Git for version control for your theme.  (Note for the uninitiated: Alfred Extensions require the Powerpack.)

Download the extension

Building plugin-like functionality into WordPress themes: to be, or not to be?


plugThere’s been a lot of talk in the WordPress world about whether or not theme developers should build plugin-like functionality into WordPress themes.  After my presentation at WordCamp SLC 2012, it was actually something I was asked about.  Seeing how it was a topic of discussion on via ManageWP, I thought I’d throw my 2 cents into the mix and why I feel strongly about this issue. Continue reading “Building plugin-like functionality into WordPress themes: to be, or not to be?”

Making theme options modular

Today I submitted version 1.1 of Museum Core to the WordPress theme repository for review. Originally this was going to just be a simple update with some bugfixes, but I had thought of a way to make it easier to build child themes that include some options settings from the parent theme (Museum Core) without having to include all of the options from the parent. It started out with this ticket I created on GitHub.

Now, the ticket evolved from that first sketch of an idea, and I ultimately abandoned the concept of using actions and remove_action to change what options get used. But the current approach is, I think, a pretty powerful way to approach theme options development so that things can be reused or abandoned in child themes and it isn’t something that I’ve seen other people doing. (To be fair, this is actually what’s described in the WordPress Codex, but I haven’t seen it in action on very many theme options pages, or any tutorials talking about how one would go about writing a theme options page, so I thought it was worth writing about.) And it reduces my entire theme options down to this code:

So let’s take a look at what we’re doing in ap_core_do_theme_options

First of all, I’ve pulled out all the code and put it into a new file called option-setup.php. This handles all the stuff that was previously where the _do_theme_options function is now but everything has been pretty drastically rewritten. First we have ap_core_do_theme_options which looks like this:

If you’ve tried or are currently using Museum Core, you’ll already know that the theme options page sports some tabs. So the first function we’re calling in _do_theme_options is the tab setup. This is a pretty straightforward function that just spits out the html needed to set up the tabs. The real meat is in the next three functions. We won’t look at every single function, we’ll just dig into the main highlights so you get an idea of what’s going on. Let’s peek at ap_core_general_settings which handles the, wait for it, general settings tab.

ap_core_general_settings looks an awful lot like ap_core_do_theme_options, with a bit of HTML thrown in to set up the table that’s going to hold the actual options. That uniformity is intentional, the idea is that you can swap functions in and out however you want. You can use your own modified version of ap_core_general_settings in your child theme, or you can do away with the tabs and just put all your options straight into ap_core_do_theme_options. Or you can mix and match options from the various settings tabs and create your own tabs, it’s up to you. Let’s take a look at what an individual option looks like now.

That’s got a bit more heft to it. But it’s still pretty basic. All I did here is pull the table row from the original theme-options.php and added it to this function. I’m using output buffering to store all the php/html as a variable and echoing the variable at the end which is what gets sent to the function calling this function (in this case ap_core_sidebar_option). I’m also calling the defaults and options from the database so our values are loaded and stored. This is done ad nauseum for each setting, so each setting gets called separately and can be isolated, grouped, cut out, whatever as needed by a child theme.

So what happens when I want to build a child theme and use some of these options? Here’s an example:

First what I’m going to do is start with a new theme options function. I’m keeping the 3 tabs from Core, but I’m adding a 4th tab. Since Core only supports 3 tabs, and I’ll need to set up the title for the fourth tab, I’m doing my own tabs. We’ll start by setting up the tabs. Remember, you don’t have to use the tabs at all; if you just want all of your options on the Theme Options page, you can just cut out the tabs function and then they’ll display normally, one on top of the other.

The two things that are changed are highlighted by the fact that the textdomain (‘museum-core’, ‘my-theme’) has changed. We don’t need to change the textdomain of the other tabs, because, assuming the text was translated in a language file, those would already be covered by the existing translation in Core — only the new translation strings need to be added (of course, none of this is necessary, really, if you don’t care about localization of your child theme). We changed “Typography & Fonts” to “Font Stuff” and added the fourth tab, “Custom Tab”. So far, so good. This is what it looks like:

20120511 8bgrj593pymrskawg7me5dky7y.medium Making theme options modular

Now that we’ve got the tabs, and we’ve added the options pages that we’re pulling from Core, it’s time to create our new settings page. We’ll do this really minimally and just add one option. We won’t add a bunch of function calls (although we could), we’ll just put our option straight into the new my_custom_theme_settings function. It looks something like this:

Now, in order for this to be actually functional, we’d need to define some new options for our theme so we could store them in the database, this is just meant to be an example and illustrate how we’re able to still pull functions from the parent theme and mix them into our custom theme functions. Here’s what that new tab looks like:

20120511 gjd8g2p9m9dw3a397wykaxw78g Making theme options modular

To summarize, what I’ve got is a modular way of calling individual settings that can be swapped in and out at will and replaced with custom settings (or not) however you want. If you have any thoughts or questions, feel free to post in the comments. If you’d like to dig into the source files, you can grab the latest version of Museum Core from GitHub. You can also take a look at the complete code from this tutorial on GitHub. And if you want to take a look at the files on your computer and hack them up, you can download the source files used to create the child theme in the screenshots here.

Museum Themes is one year old

Funny how time creeps up on you.

It wasn’t until I was preparing my presentation for this year’s upcoming WordCamp SLC that I realized that it was this time last year that we launched Museum Themes!

In our first year, we have released 14 WordPress themes (7 free themes and 7 Museum Themes), one display font and updated all of our Blogger templates.  This coming year will see a new, free, GPL core framework, and some massive updates to the themes to accommodate the shift in technology.  We’re also planning a few more niche themes based on some of the feedback we’ve received over the last year.  We’ve switched our checkout process from being based on WP eCommerce to Cart66, we’ve added and then upgraded our affiliate program, and we’ve switched our support forums to use Get Satisfaction.

It’s been a good year, and we’re just getting started.  Besides the core framework, plans for the coming year include releasing a few more plugins and making sure all of our code adheres to WordPress coding standards.  Things that we have been playing with and are excited about bringing to the next generation of Museum Themes are custom post types and post formats as well as updating our theme options pages to be based in the WordPress Settings API.

We hope that you continue to follow our development and support us as we continue to grow.  As always, our goal is to make beautiful WordPress themes that are functional, artistic, easy-to-use and entirely GPL-compliant.  And if you haven’t already, please follow us on Facebook and Twitter to stay up-to-date on everything we’re doing.