What should be excluded in a WordPress gitignore file?

Since starting to use GitHub for version control a couple of years ago, I love the flexibility it offers. But what should you exclude from Git version control in a WordPress project?

Git allows you to add any files you want to ignore to a file in the root of the project to a file called .gitignoreGitHub has a default WordPress gitignore file, which is a great start:

.htaccess
.htaccess
wp-config.php
wp-content/uploads/
wp-content/blogs.dir/
wp-content/upgrade/
wp-content/backup-db/
wp-content/advanced-cache.php
wp-content/wp-cache-config.php
sitemap.xml
*.log
wp-content/cache/
wp-content/backups/
sitemap.xml
sitemap.xml.gz
.DS_Store

Let’s step over this to explain the logic.

Configuration files are specific

Broadly speaking, you always want to avoid including any configuration files in a repository, as chances are the settings on your local development environment aren’t the same as your live site, and you might have multiple developers using their own settings and development environments. As WordPress holds all configuration in the wp-config.php file, we exclude that in our WordPress gitignore. Each developer then has to create their own version, and a live version is created at launch.

Media and images

If you’re working with other developers with their own development environments, the way that WordPress stores images and media in general poses a bit of a problem. WordPress stores all uploaded images in the wp-content/uploads folder in sub-folders for each month. It also stores a unique reference to the uploaded image in the WordPress database.

The problem is that when you’re working with other developers, they’ll all have their own copies of the site database, so if you upload an image to your local development version and then commit it to the Git repository, the next time another developer pulls the repository they’ll have an orphaned image in their wp-content/uploads folder without an reference in their database. Not good. To avoid this we keep the entire uploads directory out of version control.

Caching, sitemaps and log files

There’s absolutely no need to version control cache files, sitemaps or log files – they’re all related to the specific install of WordPress you’re working on and there’s no need to share them with other project developers, so we leave these out too. The GitHub .gitignore file ignores some specific files that created by popular WordPress caching and sitemap plugins.

Some additions and improvements

Our WordPress hosting provider, WPEngine recommends to add a few more exclusions to the .gitignore files;

  • .DS_Store files generated by Mac OSX at the root of every folder and are redundant for anything else, so we remove them.
  • .svn and .cvs belong to other Subversion and CVS version control systems that may have been historically used on the project.

Should you version WordPress core? 

A good question. In theory, you probably shouldn’t as it’s never necessary to change the WordPress core code when developing your project. As a result those files don’t change, so there’s little need to version them. In practise though it depends on your setup. As WordPress updates every 3-4 months and it’s very important to keep it up-to-date for security reasons, you’ll probably find it better to keep the core files in Git – that way if a new developer pulls the repository to work on they’ll have the correct core code in place.

Our final WordPress gitignore file

*~
.DS_Store
.svn
.cvs
*.bak
*.swp
Thumbs.db
wp-config.php
wp-content/uploads/
wp-content/blogs.dir/
wp-content/upgrade/
wp-content/backup-db/
wp-content/advanced-cache.php
wp-content/wp-cache-config.php
wp-content/cache/*
wp-content/cache/supercache/*
*.log
wp-content/cache/
wp-content/backups/
sitemap.xml
sitemap.xml.gz

Hope that’s a helpful place to start when using Git on a WordPress development project!

How to see which WordPress page template is being used

When you’re working with custom page templates in WordPress, it’s often easy to get lost in the WordPress template hierarchy, which is pretty complex. As a result, you can get confused at which WordPress page template is being used by the page you’re looking at in a browser.

Since I tend to work alongside front-end developers on WordPress projects, to make it obvious which page template is being used I use this little snippet to output the current template path in the WordPress admin bar. Just add it to your functions.php file.

function show_me_the_template()
{
        if (current_user_can( 'manage_options' )) {
                global $template, $wp_admin_bar;
                get_currentuserinfo();
                if ( is_admin_bar_showing() ) {
                        $wp_admin_bar->add_menu( array(
                        'parent' => false,
                        'id' => 'template',
                        'title' => $template,
                        'href' => '#'
                        ));
                }
        }
}
add_action( 'wp_head', 'show_me_the_template');

That’s it – now when you refresh any page on your site you’ll see something like this:

Page template path
Showing the current page template in the admin bar

The current_user_can( ‘manage_options’ ) bit ensures that only administrator level users can see the page path in the WordPress admin bar. Other users such as subscribers will not. If you need to make this available to other user types, take a look at the Roles and Capabilities WordPress Codex entry – it’ll help you to decide what user capability you need to hook from.

 

Generate WordPress custom code with GenerateWP

Whenever I start a new WordPress project I’m constantly going back to my old projects to grab chunks of code – in particular for custom post type and taxonomy definitions, sidebars, menus and shortcodes. I’m not a big fan of using plugins to define this sort of stuff – I’d rather have them created and managed in code. I’ve often thought wouldn’t it be great if you could generate WordPress custom code for custom post types, taxonomies and other functionality quickly and easily?

Yesterday I found a tool that helps with this – GenerateWP. Simply, it allows you to generate WordPress code for any of the above functionality (and then some) quickly and easily. You change all settings and it spits out the code for you to copy and paste into your functions file.

Generate WordPress code quickly and easily
Generate WordPress code quickly and easily

I can see I’ll be using it a lot going forward – great idea. Wish I’d thought of it first!

Google Analytics virtual pageviews and Gravity Forms

I’ve been working quite a bit on Google Analytics virtual pageviews and event tracking recently, for both Smart Insights and First 10. A recent site required the ability for users to submit their own ‘Styles’ – a picture and description of themselves with tags to a public gallery on the site.

Using the fantastic Gravity Forms plugin along with another plugin – Gravity Forms +  Custom Post Types made this easy – you create your custom post type in WordPress and can then set up your Gravity Form to create a new post within it every time a user submits the form.

Redirecting to a thanks page

Once a user has submitted your form, in order to track a pageviews on Google Analytics you’ll generally want the user to be redirected and shown a ‘Thanks for submitting’ page. Gravity Forms makes this easy by allowing you to specify a page to redirect to within the main form settings, Confirmation tab;

Gravity Forms redirect

On submission, your user will be redirected to the thanks page and providing you’ve got Google’s asynchronous tracking installed and working on your site (I recommend Yoast’s SEO plugin if you haven’t) it will be tracked as a pageview in Google Analytics, and you’ve got nothing more to do.

In the case of the site I was working on, though – we wanted to redirect the user to the unique page for their submitted entry rather than a generic thanks page. Again – Gravity Forms makes this possible with the use of Merge Tags;

Gravity Forms merge tags

Breaking this down, we’ve;

  1. Changed the Redirect URL to the main site URL rather than a specific page – this is because our user’s submissions are new posts that are created from the site root – we need to find what the actual URL for them will be dynamically
  2. Chosen to append field data to the URL by inserting the merge tag p={post_id}

This will result in the user being redirected to a URL like http://www.mytestdomain.com/?p=134 with 134 being the unique WordPress post id assigned to the user’s submission. WordPress will then automatically change the URL to a pretty permalink on the fly, should you have them set up (and if you haven’t, you should).

Tracking a virtual pageview for the submission

If we put the Google virtual pageviews tracking code into the header of your single custom post template, it would be fired every time anyone visited that post. Not what we need at all – instead we only want the tracking code to be fired when a user first submits the form to create the new post.

To accomplish this, we make one final tweak to the Gravity Form settings:

Gravity form upload tracking

As you can see we’ve added &su=1 to the query parameters that will be appended to the URL on redirection. This will mean that the user ends up on a page with the following URL – http://www.mytestdomain.com/?p=134&su=1

It’s then easy for us to make a small change to the template file to check for the existence of this ‘su’ parameter and only fire the Google tracking code if it exists;

<!--?<span class="hiddenSpellError" pre=""-->php
/*
Style custom post type single page - single-style.php
*/
get_header();
// If we've been redirected here when the style has been uploaded, track it as a style upload in google analytics
if (isset($_GET['su'])) echo "<script type="text/javascript">// <![CDATA[
_gaq.push(['_trackPageview', '/thanks-for-submitting-your-style/'])
// ]]></script>";
?>

This will cause Google to track a pageview the first time any user is redirected to their new post submission. All other users will visit the post without the ‘su’ parameter in the URL, and tracking will not be fired.

One final word of advice – in order to check whether your tracking events are being fired, I’d strongly recommend using the for Chrome – it logs any tracking events directly to the browser Javascript console and takes the guesswork out of knowing if what you’d added is actually working!

On leaving First 10 Digital

From April 2nd 2013, I’ll no longer be anything to do with the company I co-founded three years ago, First 10 Digital. Well, not strictly true – I’ll still be doing bits and pieces of freelance work for it now and again. But I’ll no longer be a director or shareholder of something that I helped found and grow, from four individuals in a Regus office on the outskirts of Leeds, to a collection of twelve of the brightest and most talented people I’ve ever had the privilege to work with.

Why I’m leaving

Because it’s time. Time to leave the guys to get on with growing a thriving digital marketing agency – an end result that was never really the plan when we started the business, and not something that I ever really had an aspiration or desire to co-own. Time to focus on my other business, Smart Insights, which is doing well despite not having anyone working full time on it and could be doing a lot better still with some direct attention. Time to push the reset button and consider what it is I really want to do, what it is that I’m best at doing. And time to do something that allows me to maintain the sort of flexible work-life balance that I’ve come to realise is terrifically important when you have two young children that grow several centimeters in height seemingly every time you blink.

What’s next?

Smart Insights is the focus. There’s a tremendously long list of functionality and improvements we want to make to that site to really make it grow, and I can’t wait for the challenge. I’m also looking forward to being able to help out other businesses now and again – something that I loved as a freelancer but being shackled to a digital marketing agency makes kind of difficult. Finally, I want to be more active in the WordPress community. WordPress has provided the fuel behind First 10’s technical success – without it and the flexibility it brings, we couldn’t have delivered the quality of sites that we have over the last three years. I’d like to give some time back to the community as a small token of thanks.

On endings

It’s a weird feeling, leaving something you created. I’ve been involved in a failed start-up – but they go out with a bang, so it’s a concentrated explosion of emotion – it’s there and then it’s not. You deal with it and then you move on. Leaving something that still exists – thrives even – is very different. You go through this strange process of being slowly disconnected and weaned off from it. Realising that it’s no longer yours. Learning to let go. It’s without a doubt the strangest emotional process I’ve encountered in my 14 years of working.

In the last three years I’ve learned so much. I’ve learned how to manage and run an agency, to grow something from a collection of freelancers to a 12 person company. Learned how to work with clients like PUMA. Learned everything there is to know (and then some) about WordPress. I wish First 10 the absolute best and every success for the future. It, and everyone in it, will always hold a special place in my heart. I’ll miss working with the people on a full time basis greatly, even if I won’t miss the agency grind.

It’s been a tough decision and a painful process, but I feel good about the decision and about the future. It’s definitely time to move on. I’m looking forward to learning new things and being challenged again.