Managing overlay icons for Dropbox and TortoiseSVN and TortoiseGit

I imagine like many involved in web development, I rely heavily on a number of version control applications: I use Dropbox, Subversion (SVN) and Git.

For years I’ve used the TortoiseSVN client for Windows. It integrates with the Windows Explorer shell making it quick and easy to manage your version controlled code within Explorer.

I like that I don’t need a separate full-blown application that acts as an interface between the code on my PC and the SVN repository; I like that I don’t need to use a command prompt; but I love that TortoiseSVN adds overlay icons to tell me the state of each file (is it up to date, changed, added, etc.?).

These folders are all up to date, and in sync with the SVN repository.
These folders are all up to date, and in sync with the SVN repository.

Recently I’ve started using Git at work and so I’ve also installed TortoiseGit which does something similar.

This is the Bootstrap repo cloned to my PC.
This is the Bootstrap repo cloned to my PC.

And of course Dropbox does the same: it shows you which files have been synchronised with the cloud, and which are in the process of uploading.

My Dropbox folders are up-to-date, synchronized successfully with the Cloud
My Dropbox folders are up-to-date, synchronized successfully with the Cloud

The problem

The problem, though, is that each of these applications uses multiple overlay icons but Windows only uses the first 15.

TortoiseSVN and TortoiseGit both use the same nine icons:

Nine folder, each has an icon on top of it such as ticks, crosses or pluses.
TortoiseSVN and TortoiseGit both use nine icons.

Dropbox uses eight icon overlays. If you have OneDrive installed (which you will if you use Windows 8 or above) then it uses three. And Windows itself uses a few to indicate offline files or enhanced storage.

That’s 22 icon overlays, and like I said: Windows only uses the first 15.

So, inevitably you end up with some icons missing, and depending on which these are it can make life just that little bit harder when trying to figure out quickly whether a file is in sync or not, or whether it’s not even been added.

That means you need to make a choice about which icons you want to use and which you don’t.

How to fix it

The most straight-forward way to do this is by editing the Windows Registry.

The icon overlays can be found in the following key:

Computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer \ ShellIconOverlayIdentifiers

It turns out you can safely rename the folders which will reorder the icons. The folders are just containers for the real information contained within them.

1. Backup

Export (backup) the ShellIconOverlayIdentifiers folder in its entirety, in case you need to restore it later.

2. Prioritise which icons you need

My current preference is for the following:

  1. 1TortoiseNormal
  2. 2TortoiseModified
  3. 3TortoiseConflict
  4. 6TortoiseDeleted
  5. 7TortoiseAdded
  6. 8TortoiseIgnored
  7. 9TortoiseUnversioned
  8. DropboxExt1 (green Synced)
  9. DropboxExt2 (blue In progress)
  10. DropboxExt5 (red Sync problem)
  11. DropboxExt7 (grey Folder not synchronizing)
  12. EnhancedStorageShell
  13. SkyDrivePro1 (ErrorConflict)
  14. SkyDrivePro2 (SyncInProgress)
  15. SkyDrivePro3 (InSync)

You can use whatever naming convention you prefer. I rename the original folder names with a number prefix and an underscore, e.g. 01_1TortoiseNormal. Folders that I want to drop to the bottom I prefix with a simple x, e.g. x5TortoiseReadOnly.

In regedit it looks like this, with the unprioritized icons dropping to the bottom of the list.

List of registry keys
List of registry keys

3. Restart Explorer

  1. Close any Windows Explorer windows.
  2. Press Ctrl+Shift+Esc to open Task Manager.
  3. Look for Windows Explorer listed under “Background processes”.
  4. Right-click it and select “Restart”.

Your taskbar will disappear a couple of times as the Explorer process is restarted, but you should now see all the overlay icons you want within your folders.

(Currently I’m having issues with OneDrive — formerly SkyDrive — but as I don’t rely on it for too much I’m not that bothered, to be honest.)

Using Akismet on WordPress Multisite

Akismet is a WordPress plugin for dealing with comment spam. It’s pretty good and simple to set up:

  1. Sign up for an Akismet plan (from free for a personal site, to $50 per month for enterprise).
  2. Use the API key generated to activate your plugin.

The API key (like a license key) is in the format abcde1f23456.

And that’s fine if you have only one site, but if you’re running WordPress multisite then you don’t want to have to activate Akismet individually for each sub-site. That’s just tedious.

Wouldn’t it be much better if you could just add the API key once?

Akismet doesn’t offer that option within the user interface on Multisite. Undeterred, I went in search of a way to do it.

How to do it

The wonderful folks over at WPMU DEV have a really useful blog post from July 2013 about how to do this: How to use Akismet on WordPress Multisite with 1 license key.

The good news it’s really simple:

  1. Open wp-config.php in your favourite text editor.
  2. The WPMU DEV article recommends that you add the API code  below the comment /* That's all, stop editing! Happy blogging. */ but I prefer to add it below the define() block for Multisite. But you can add it where you like, really.
  3. Add the following code define('WPCOM_API_KEY','abcde1f23456');
  4. Save wp-config.php and upload it to your site.

Your wp-config.php file will then look something like this:

/** Multisite */
define('WP_ALLOW_MULTISITE', true );
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'www.example.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

/** Define WordPress.com API key for Akismet in WordPress Multisite */
define('WPCOM_API_KEY','abcde1f23456');

Like many things on this blog I’ve added this here primarily for my own reference, but I hope it helps you too.

The real credit on how to do this, of course, goes to Sarah Gooding from WPMU DEV: thank you.

Happy spam-free blogging!

Viewing Trello label titles on cards

It’s no secret that I’m a fan of Trello.

I use Trello pretty much exclusively on Google Chrome, as there are plenty of plugins written to extend its capabilities; far more than for Firefox, which surprises me a little.

One of my favourites is Scrum for Trello, which allows me to add Agile story points very simply. My new favourite is this: Card Color Titles for Trello.

Default labels

In Trello you may set an unlimited number of labels. Originally, there were only six, organised in the order of the original Apple logo.

Here are the labels that Trello themselves use for their development board.

Trello label names
Trello label names

When applied to cards, the labels appear as coloured bars at the top of each card.

Trello development board with standard labels.
Trello development board with standard labels.

The problem is, and particularly now with unlimited labels, it can be difficult to remember what each colour means—especially if you use different labels on different boards.

Card color titles for Trello

That’s where the Card Color Titles for Trello plugin comes in: it adds the name of the label to the label.

Labels, colours, titles—it all makes sense now
Labels, colours, titles—it all makes sense now

I’ve been using this for the last week and it has been so useful, particularly at work where we have labels for MoSCoW prioritisation. It has made re-ordering cards so much easier and quicker.

It’s definitely an extension to add if you use Trello on Chrome: Card Color Titles for Trello on Chrome web store.

Write! (beta) — a distraction-free text editor for Windows

Write! A distraction-free text editor for Windows. Here it is showing the navigation bar.
Write! A distraction-free text editor for Windows. Here it is showing the navigation bar.

A few months ago, while I was editing some documents in Markdown, I came across Write! — a new text editor (still in beta) that is being marketed as “writing instrument for digital age [sic]” and a “distraction-free text editor that does not suck”. So I downloaded it and took it out for a spin.

I like it, but…

For the most part I like Write! It’s clean, it’s fast, and it has a minimal set of usable features that don’t get in the way.

It’s like a prettier Notepad but with a spell checker, a navigation bar on the right-hand side (like Sublime Text), and a basic understanding of Markdown (so you can make text bold, for example, by typing **example**).

I have a couple of issues, though, which prevents me from using this as my text editor of choice for writing.

Proprietary format

My main niggle is that by default Write! saves to its own proprietary format. This is a zipped, XML-based file format (.wtt), and as far as I can tell this isn’t compatible with the OpenDocument text (.odt) format. The simple document above (showing the first chapter of JRR Tolkien’s The Lord of the Rings) contains the following files:

  • document.xml — the actual document, plus some meta data such as word count.
  • history.xml — an undo history.
  • package.xml — this seems to define the package format and encoding (UTF-8).

You can export to PDF, OpenDocument, plain text, and three flavours of Markdown (Textile, Markdown, and Wiki) but that has more of a disruptive workflow than simply tapping Ctrl+S every few minutes.

Similarly, it would be great to be able to associate Write! to open certain file types, such as text (.txt) or Markdown (.md, .mdown) files.

Not full Markdown support

By default I tend to use basic, vanilla Markdown rather than Textile or Wiki). By default Write! is configured to support a mixture of the other two. That’s not a problem as a quick visit to the settings will put that right.

Write! settings dialog
Write! settings dialog

But Write! only supports a small subset of Markdown:

Supports

  • Headers prefixed with hash (# for H1, ## for H2, etc.).
  • Unordered lists using minus (-) and plus (+).
  • Numbered lists.
  • Links (but you cannot easily edit the link, text or title).
  • Emphasis (italics and bold) using asterisks (*) or underscores (_).
  • Automatic links in the format <http://example.com/>.
  • Backslash escapes, e.g. \*literal asterisks\*.

Does not support

  • Setext style headers (underlined using equal signs or dashes).
  • Blockquotes.
  • Unordered lists using asterisk (*).
  • Code blocks — 1 tab, 4 spaces or three backticks (“`).
  • Inline code using single backticks (`.example {}`).
  • Horizontal rule.
  • Images.
  • Automatic links for email addresses, e.g. <address@example.com>.

Cannot type with help window open

This seems to be a basic requirement that has been overlooked: if I tap F1 to bring up the help text (shortcuts and markup) I cannot keep the help window open while typing into Write! If I start to type I get an irritated ‘bong!’ sound from my PC.

Surely I should be able to refer to the help text while typing.

Conclusion

If Write! supported at least:

  1. The ability to select which format to save to by default (even on a document-by-document basis); (MUST)
  2. The ability to open certain file types in Write! (MUST)
  3. Full support for Markdown. (MUST)
  4. Ability to type while referring to the help text. (SHOULD)

then I would without a doubt use this text editor for all sorts of small writing tasks, such as writing documentation, journalling, text editing, etc. Until then, I’ll just keep updating the beta and see what gets added in the future.

For me this is definitely one application to keep an eye on but it isn’t for production use quite yet.

Bonus

What is nice is that you can vote for future features from the website’s Feedback link. One of those suggestions is to save in plain text format; I’ve just submitted an idea to fully support Markdown.

Changing the Divi projects custom post type to anything you want

I’m currently building a website for a friend of Jane, using the Divi theme from Elegant Themes. The website is for a holiday property letting company. This post explains how I changed the built-in Projects content type to Properties, and how you can change it to anything you want.

The problem

Divi is a great theme to use: it’s very flexible, it’s responsive (so it works equally well on smartphones as well as huge desktop monitors), and it has the easiest, drag-and-drop editor that I’ve ever used for WordPress.

Divi comes with a built in content type called Projects; WordPress calls them ‘custom post types’. I use this content type on my own website to list the various projects that I’ve been involved in over the years.

As you can see from the WordPress admin menu ‘Projects’ appears on the list beneath Posts, Media, Pages, and Comments:

WordPress menu with Divi installed shows Projects
WordPress menu with Divi installed

Divi also ships with a number of attractive ways to display your projects using its Portfolio and Filtered Portfolio modules. You can even display these full-width or as a grid, such as this:

Demo of Divi's Filtered Portfolio module displayed as a grid.
Demo of Divi’s Filtered Portfolio module displayed as a grid.

These are exactly the features that I’d like to use on the property letting website:

  • Keep properties separate from pages and posts, using a custom post type.
  • Display all properties in a grid.
  • Allow users to filter properties based on the categories that are assigned to them.

So, I want all the features of Divi’s built-in Projects custom post type, but I don’t want them to be called Projects. I want them to be called Properties.

Use a child theme

First, I strongly recommend that you use a child theme when customising Divi (or indeed any other WordPress theme). A child theme inherits the functionality and styling of another theme, called the parent theme, and allows you to make local customisations to it which will not be overwritten when the theme updates.

Elegant Themes have a useful walkthrough on how to create a child theme, and why you should be using one.

The WordPress Codex also has useful information about child themes.

How to do it

This very useful post on the Elegant Tweaks blog: “Change Divi Projects URL-permalink” got me started, and about 95% of the way.

I copied the code, added it to the functions.php file in my child theme, and set about editing it.

remove_action / add_action

In a nutshell the code from Elegant Tweaks does two things:

  1. It defines a new function — called child_et_pb_register_posttypes() — that will redefine the characteristics of the Projects content type.
  2. It removes the default Projects custom post type contained in Divi, and replaces it with our one in the child theme.

This last point, I believe, is simply to be tidy: rather than clumsily overwriting the existing ‘project’ custom post type it gracefully removes the old one, and creates a redefined version in its place.

Labels

In that Elegant Themes post the author was only concerned with changing the URL from /projects/ to /photos/. So in his example, the names used in the WordPress admin screens still referred to projects: Edit Project, Add New Project, etc. But I want to change these too.

In the code for a custom post type these are referred to as ‘labels’ and are defined in the $labels array. This is what my code looks like now:

<?php
function child_et_pb_register_posttypes() {
    $labels = array(
        'add_new'            => __( 'Add New', 'Divi' ),
        'add_new_item'       => __( 'Add New Property', 'Divi' ),
        'all_items'          => __( 'All Properties', 'Divi' ),
        'edit_item'          => __( 'Edit Property', 'Divi' ),
        'menu_name'          => __( 'Properties', 'Divi' ),
        'name'               => __( 'Properties', 'Divi' ),
        'new_item'           => __( 'New Property', 'Divi' ),
        'not_found'          => __( 'Nothing found', 'Divi' ),
        'not_found_in_trash' => __( 'Nothing found in Trash', 'Divi' ),
        'parent_item_colon'  => '',
        'search_items'       => __( 'Search Properties', 'Divi' ),
        'singular_name'      => __( 'Property', 'Divi' ),
        'view_item'          => __( 'View Property', 'Divi' ),
    );

As you can see, something I find useful is to list the elements alphabetically. Personally, I find it easier to work this way; your mileage may vary.

Obviously, if you are customising this for your own requirements simply edit this to reflect your needs.

Custom post type options

Next, we define the arguments to be passed to the register_post_type function. These define not only how the custom post type is used but also how it is displayed in the WordPress admin menu: where it sits and what icon it uses.

Slug

The most important option here, for our purpose of customising it, is the 'slug' key. You must set its value (in single quotes) to whatever you need it to be. In my case 'slug' => 'property'. I’ve highlighted this in the snippet below.

Just make sure you don’t set the slug to the same name as an existing page.

Menu icon and position

One useful new addition to the code provided by Elegant Tweaks are the options to set the menu icon and where it sits on the menu.

As these are properties I decided to use the home dashicon.

House icon
dashicons-admin-home

I also decided to move it up a bit, from beneath Comments to immediately below Posts. WordPress uses numbers to specify where custom post types should sit, e.g.

  • 5 — below Posts (this is where I want it to appear)
  • 10 — below Media
  • 15 — below Links
  • 20 — below Pages
  • 25 — below Comments

A full list can be found in the WordPress Codex.

So, here is the code I now have; I’ve highlighed these new menu options plus the ‘slug’ (how it will appear in the URL):

    $args = array(
        'can_export'         => true,
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'labels'             => $labels,
        'menu_icon'          => 'dashicons-admin-home',
        'menu_position'      => 5,
        'public'             => true,
        'publicly_queryable' => true,
        'query_var'          => true,
        'show_in_nav_menus'  => true,
        'show_ui'            => true,
        'rewrite'            => apply_filters(
            'et_project_posttype_rewrite_args', array(
            'feeds'          => true,
            'slug'           => 'property',
            'with_front'     => false,
        )),
        'supports'           => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments', 'revisions', 'custom-fields' ),
    );

Register the post type

The next line now does the grunt work and registers this custom post type with WordPress.

    register_post_type( 'project', apply_filters(
        'et_project_posttype_args', $args )
    );

This tells WordPress to apply all of these options to the ‘project’ custom post type.

Because we are redefining this existing custom post type (by changing the URL, the menu labels, the menu icon and position) it means that everything else (the default project page layouts and portfolio modules) will work as expected without any further customization.

Categories and tags

The rest of the code I left untouched. This code defines the categories and tags to be used with the projects/properties custom post type.

How it looks now

Adding all the code (see below for the complete script) this is what my WordPress admin menu looks like:

Divi theme now with Properties instead of Projects
Divi theme now with Properties instead of Projects

That’s now working as I expect it. Job done.

Complete code

Here is the full code that I have in my child theme’s functions.php file:

<?php
function child_et_pb_register_posttypes() {
    $labels = array(
        'add_new'            => __( 'Add New', 'Divi' ),
        'add_new_item'       => __( 'Add New Property', 'Divi' ),
        'all_items'          => __( 'All Properties', 'Divi' ),
        'edit_item'          => __( 'Edit Property', 'Divi' ),
        'menu_name'          => __( 'Properties', 'Divi' ),
        'name'               => __( 'Properties', 'Divi' ),
        'new_item'           => __( 'New Property', 'Divi' ),
        'not_found'          => __( 'Nothing found', 'Divi' ),
        'not_found_in_trash' => __( 'Nothing found in Trash', 'Divi' ),
        'parent_item_colon'  => '',
        'search_items'       => __( 'Search Properties', 'Divi' ),
        'singular_name'      => __( 'Property', 'Divi' ),
        'view_item'          => __( 'View Property', 'Divi' ),
    );

    $args = array(
        'can_export'         => true,
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'labels'             => $labels,
        'menu_icon'          => 'dashicons-admin-home',
        'menu_position'      => 5,
        'public'             => true,
        'publicly_queryable' => true,
        'query_var'          => true,
        'show_in_nav_menus'  => true,
        'show_ui'            => true,
        'rewrite'            => apply_filters( 'et_project_posttype_rewrite_args', array(
            'feeds'          => true,
            'slug'           => 'property',
            'with_front'     => false,
        )),
        'supports'           => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments', 'revisions', 'custom-fields' ),
    );

    register_post_type( 'project', apply_filters( 'et_project_posttype_args', $args ) );

    $labels = array(
        'name'              => _x( 'Categories', 'Property category name', 'Divi' ),
        'singular_name'     => _x( 'Category', 'Property category singular name', 'Divi' ),
        'search_items'      => __( 'Search Categories', 'Divi' ),
        'all_items'         => __( 'All Categories', 'Divi' ),
        'parent_item'       => __( 'Parent Category', 'Divi' ),
        'parent_item_colon' => __( 'Parent Category:', 'Divi' ),
        'edit_item'         => __( 'Edit Category', 'Divi' ),
        'update_item'       => __( 'Update Category', 'Divi' ),
        'add_new_item'      => __( 'Add New Category', 'Divi' ),
        'new_item_name'     => __( 'New Category Name', 'Divi' ),
        'menu_name'         => __( 'Categories', 'Divi' ),
    );

    register_taxonomy( 'project_category', array( 'project' ), array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
    ) );

    $labels = array(
        'name'              => _x( 'Tags', 'Property Tag name', 'Divi' ),
        'singular_name'     => _x( 'Tag', 'Property tag singular name', 'Divi' ),
        'search_items'      => __( 'Search Tags', 'Divi' ),
        'all_items'         => __( 'All Tags', 'Divi' ),
        'parent_item'       => __( 'Parent Tag', 'Divi' ),
        'parent_item_colon' => __( 'Parent Tag:', 'Divi' ),
        'edit_item'         => __( 'Edit Tag', 'Divi' ),
        'update_item'       => __( 'Update Tag', 'Divi' ),
        'add_new_item'      => __( 'Add New Tag', 'Divi' ),
        'new_item_name'     => __( 'New Tag Name', 'Divi' ),
        'menu_name'         => __( 'Tags', 'Divi' ),
    );

    register_taxonomy( 'project_tag', array( 'project' ), array(
        'hierarchical'      => false,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
    ) );

    $labels = array(
        'name'               => _x( 'Layouts', 'Layout type general name', 'Divi' ),
        'singular_name'      => _x( 'Layout', 'Layout type singular name', 'Divi' ),
        'add_new'            => _x( 'Add New', 'Layout item', 'Divi' ),
        'add_new_item'       => __( 'Add New Layout', 'Divi' ),
        'edit_item'          => __( 'Edit Layout', 'Divi' ),
        'new_item'           => __( 'New Layout', 'Divi' ),
        'all_items'          => __( 'All Layouts', 'Divi' ),
        'view_item'          => __( 'View Layout', 'Divi' ),
        'search_items'       => __( 'Search Layouts', 'Divi' ),
        'not_found'          => __( 'Nothing found', 'Divi' ),
        'not_found_in_trash' => __( 'Nothing found in Trash', 'Divi' ),
        'parent_item_colon'  => '',
    );

    $args = array(
        'labels'             => $labels,
        'public'             => false,
        'can_export'         => true,
        'query_var'          => false,
        'has_archive'        => false,
        'capability_type'    => 'post',
        'hierarchical'       => false,
        'supports'           => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments', 'revisions', 'custom-fields' ),
    );

    register_post_type( 'et_pb_layout', apply_filters( 'et_pb_layout_args', $args ) );
}

function remove_et_pb_actions() {
    remove_action( 'init', 'et_pb_register_posttypes', 0 );
}

add_action( 'init', 'remove_et_pb_actions');
add_action( 'init', 'child_et_pb_register_posttypes', 1 );
?>

Final thoughts

Like many things on my blog I’m primarily putting it here for my own reference, but if you find it useful — or would like to suggest improvements or additional features — please leave a comment below.

Update

Friday 20 March 2015

I meant to say this in the article above. Sometimes WordPress gets a bit muddled when you play around with custom post types.

The way to fix this is to go to Settings > Permalinks > Save Changes.

That’s enough to flush the permalinks and your custom post type should work. I had to do that a couple of times while figuring out how to do this.

The wait is over, time now to lose the weight

Dumbbells

Between 2006–2007 I lost six inches (15 cm) off my waist, through a combination of changing what I ate, lifting weights, and regular cycling. My motivation was to get fit in anticipation of our IVF treatment working and us having children; we now have three.

Fast forward seven years and sadly I’ve put it all back on again. A combination of being on the parent-of-twins’ sleep deprivation programme, two back injuries (from lifting babies and pushing buggies), two neck injuries (what happens when twins jump onto your head from behind), and last year’s episode of meningitis.

Back in September my GP told me not to push myself: meningitis takes it out of you. He predicted that my stamina might return in January or February of this year. Now we’re approaching the end of February I feel it’s time to start working myself a little harder. The fact that it’s Lent — traditionally a time of increased discipline — should also help.

My plan is that I’m going to start gently and gradually build up my level of fitness. My immediate ground rules are:

  • Drink more water
  • Go to bed earlier (sleep is really important)
  • No chocolate
  • No fizzy drinks
  • Lift weights (dumb bells) 2–3 times a week
  • Cycling 1–2 times a week

I have to admit to feeling a little nervous. I know that I’ve done this before, but back then I was younger and I didn’t so easily experience the back and neck pain that I can now. I’ve never really been good at pacing myself, it’s time for a crash course (I guess, without actually crashing).

I’ll report back with my progress.