Solutions Log

So I only have to figure things out once.

Display the Number of Comments on a Blog Post in EE and WP

ExpressionEngine
1
<a href="{comment_url_title_auto_path}#comments">{comment_total} {if comment_total == 1}Comment{if:else}Comments{/if}</a>
WordPress
1
<?php comments_popup_link('0 Comments', '1 Comment', '% Comments'); ?>

Remove a Git Submodule

  1. Delete the relevant line from the .gitmodules file.
  2. Delete the relevant section from .git/config.
  3. Run git rm --cached path/to/submodule (no trailing slash).
  4. Commit and delete the now untracked submodule files.

Source

  • Chat conversation with JTJ.

My Git Workflow

Local Branches

There are some common hickups I see in the day-to-day use of Git that can be fairly easily remedied by the liberal use of local branches.

When I start any new work (or at the very least before I commit my work), I create a new local branch named for the feature on which I’m working.

git co -b feature-branch

I might work on that feature for a few minutes, or it could take several days. In the meantime, I can keep up with what my coworkers are doing with the same repository without it ever conflicting with what I’m doing.

When I want to pull in other people’s changes, I simply go to my local tracking branch and pull in the changes.

git co my-local-tracking-branch
git pull

In order to keep my new feature branch up-to-date with the rest of the repository, I simply rebase against it periodically.

git co feature-branch
git rebase my-local-tracking-branch

This is a potentially dangerous way of “merging” in changes, but as long as you never push your feature branch anywhere (until you do merge it into the tracking branch), it’s perfectly safe. The reason it can be dangerous is that it does a bit of history re-writing. A rebase takes all your feature branch changes and rewrites them as if they took place after all the changes from everyone else. I think this is good for a couple of reasons:

  1. Your commits for your feature branch will show up at the top of git log. As soon as you push your changes to the shared branch, you’ll see all your stuff first (as opposed to interspersed throughout the log depending on the time you made the commits).
  2. You can pretty much stop seeing commit messages that are automatically generated ”Merge branch 'whatever' into 'whatever-else',” since you rebased instead of merged.

When I’ve finished working on the feature branch and rebased in everyone else’s changes a last time, I’ll merge it into the tracking branch.

git co my-local-tracking-branch
git merge feature-branch

Since the feature branch has everything in that’s in the tracking branch, it doesn’t create a new merge commit. Everything’s just happy. Push your changes and get rolling on the next feature.

Amend

In order to really keep my commits clean, I try to limit myself to a single commit for a feature (or ticket). I continue to commit obsessively (as is my nature), but all that ever shows up in the public repository is a single commit. That’s because I use:

git commit --amend

As with rebasing, you should only ever do this on commits that haven’t been pushed anywhere. As long as you’re doing this on your feature branch, you’ll be safe.

Doing this is even easier if you use GitX: just click the “Amend” checkbox.

By using amend, you can keep adding changes to the same commit, and revise the commit message as you do more and more things.

Dealing With the IE 7 (and 8) Transparency Bug With jQuery

I found out this morning that you can’t use jQuery’s fadeIn or fadeOut in IE 7 or 8 on elements that have transparent pngs as backgrounds because the animation will make the transparency turn black. It’s a good thing browser detection is built into jQuery(!).

if ($.browser.msie && $.browser.version < 9 ) {
    $('#whatever').hide();
} else {
    $('#whatever').fadeOut();
}

Excellent.

Sources

Creating a Happy Git Environment on OS X Leopard

Configure things:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global alias.co checkout
git config --global apply.whitespace nowarn

Setup an SSH key

ssh-keygen

Hit return a couple of times – leave password blank if you want.

cat ~/.ssh/id_rsa.pub | pbcopy

Paste that code into your settings page on your repository host(s).

Set up Global Git Config on your GitHub account page (the same place you pasted your SSH key). You’ll type in some stuff that looks like this:

git config --global github.user [your_username]
git config --global github.token [your_token]

Get happy Git colors. Paste the following into your ~/.gitconfig file:

[color]
    branch = auto
    diff = auto
    status = auto
[color "branch"]
    current = yellow reverse
    local = yellow
    remote = green
[color "diff"]
    meta = yellow bold
    frag = magenta bold
    old = red bold
    new = green bold
[color "status"]
    added = yellow
    changed = green
    untracked = cyan

Create a ~/.gitexcludes file and paste in this:

.DS_Store

There, now you don’t have to ignore that every time.

Bash Fanciness

Add the following to your ~/.bash_profile or ~/.bashrc:

source /usr/local/git/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='[\u@mbp \w$(__git_ps1)]\$ '

That will add tab auto-completion for Git branches, display the current branch on your prompt, and show a ‘*’ after the branch name if there are unstaged changes in the repository, and a ‘+’ if there are staged (but uncommitted) changes. It will look something like this:

[user@computer ~/Sites/example.com (master*)]$ 

Bonus

If you want to have a different email address for a particular project (a personal project on your work computer, perhaps?), just run this command inside that project’s folder:

git config user.email "you@example.com"

It’s the same command as before, this time just omitting the --global.

Sources

Setting Up a Tracking Branch in Git

If you have an open source repository, or you’re sharing code with a team, you’ll probably want to pull in changes from other people and merge them into your code. Here’s how to do it.

git remote add [persons_name] [url_to_repository]
git fetch [persons_name]
git branch --track [persons_name] [persons_name]/master
git merge [persons_name]
git push

This sets up a local branch that’s only job is to track the other person’s repository. Any time you want to pull in their changes and merge them with yours:

git co [persons_name]
git pull
git co master
git merge [persons_name]

Sources

The Absolute Least You Need to Do to Use Virtual Hosts on OS X Leopard

Enable Web Sharing in System Preferences > Sharing.

Edit these files:

  • /etc/apache2/httpd.conf
  • /etc/hosts
  • /etc/apache2/users/your-username.conf

(I keep these files in a TextMate project so I can get at them quickly and don’t have to remember which files I need.)

In httpd.conf, uncomment this line:

LoadModule php5_module        libexec/apache2/libphp5.so

In hosts, add your local sites in the format:

127.0.0.1   your-site-name.dev

In /etc/apache2/users/your-username.conf, add this line to the very top of the file:

NameVirtualHost *:80

Change None to All in this line (to allow for things like mod_rewrite):

AllowOverride All

Add FollowSymlinks to this line:

Options Indexes MultiViews FollowSymlinks

Add new sites in the same file in this format:

<VirtualHost *:80>
   ServerName your-site-name.dev
   DocumentRoot "/Users/your-username/Sites/your-site-name/"
</VirtualHost>

Any time you make changes to any of these files, you’ll need to run this command:

sudo apachectl graceful

Check out this script for an easy way to add new sites (and feel free to fork it and adapt it to your uses).

Display Children of One-To-Many or Many-To-Many Relationships in Your Django Templates

For items you’ve defined in the parent model, such as this:

class Project(models.Model):
    tasks = models.ManyToManyField(Task, blank=True)

You use parent.children.all, like so:

For items defined outside of the parent model with a foreign key pointing back to the parent model, such as this:

class Picture(models.Model):
    project = models.ForeignKey(Project)

You use parent.children_set.all, like so:

Sources