Easy responsive design using Responsive Grid System

These days there is no excuse not to make your website design responsive, even if you aren’t a CSS guru. The easiest way is to use a fluid grid system with a few media queries to optimise the layout depending on the content. There are plenty to choose from.

I tried out Responsive Grid System from Graham Miller.

It really is super simple to use and lightweight. You can have a different number of columns in different parts of your page. First decide how many columns you want (up to 12). Then simply copy and paste a bit of HTML and CSS, put your content into your HTML and you’re done. It has breakpoints already included which you can change if you wish.

The rest is left up to you, so don’t forget to include the viewport meta tag

<meta name="viewport" content="width=device-width,initial-scale=1">

in your head to make sure the media queries work properly. This is because on many mobile devices one device pixel does not equal one css pixel.

Git basics quick reference

A quick reference for some basic git commands, with a few links to more detailed explanations.  If you need to learn git, the git documentation itself is excellent.

Terminology

branch – a moveable pointer to commits
HEAD – a special pointer that keeps track of which branch you’re on
tracking branch – tracks an upstream branch

What changed?

Show changes for files that are modified but not staged:
$ git diff

Show changes for files that are staged but not committed:
$ git diff --staged
$ git diff --cached

(staged is a synonym of cached)

What happened?

Show the git commit history
$ git log

What’s what?

$ git status

Branches

Create new branch:
$ git branch mybranch

Switch to a branch:
$ git checkout mybranch

Create a new branch and switch to it:
$ git checkout -b mybranch

Delete branch:
$ git branch -d mybranch

Merge back into your master branch:
$ git checkout master
$ git merge mybranch

List local branches:
$ git branch

List branches with last commit message:
$ git branch -v

You’ve created a local branch ‘mybranch’, and you want to push it to a new remote branch ‘origin/mybranch’ (and set the local one to track the remote one).
Push the local branch to a remote branch and set the remote branch as being the local branch’s upstream branch:
$ git push -u origin mybranch

Get remote branch from remote and switch to it:
$ git checkout -b otherbranch origin/otherbranch
(may need to do a git pull first)

Remote repositories

Copy a remote repository:
$ git clone repo directory
repo – the remote repository
directory – the local directory to copy to

List all remote repositories:
$ git remote

List all remote repositories, with more information (verbose):
$ git remote -v

Show even more details about a remote repository:
$ git remote show [remote-name]
$ git remote show origin

(origin – default name for remote repository)

Uh-oh, undo!

Undo last commit:
$ git reset HEAD^
(The caret (^) after HEAD moves head back through commits. HEAD^ is short for HEAD^1 and in the same way you can apply HEAD^2 to go back two commits ago.)

Undo uncommitted change:
$ git checkout <filename>

Revert committed and pushed changes:
$ git revert f4d8d2c2ca851c73176641109172780487da9c1d
(grab the commit identifier of the commit you want to revert from $ git log)

Introduction to SSH and SSH Keys

What is SSH?

SSH, or Secure Shell is an encrypted network protocol, to securely connect to another computer over a network. It can be used to execute commands on a remote machine, and also to copy or move files from one machine to another.

Using ssh on the command line

The command to connect to a remote machine is ssh. E.g.
$ ssh username@hostname

Copying files

Files can be copied using SCP (secure copy) e.g.
$ scp local_file username@hostname:destination_directory
or SFTP (SSH File Transfer Protocol).

SSH Keys

SSH Keys provide a more secure way to log in to a remote machine than using password authentication. To do this you create an SSH identity, which consists of a public-private key pair. A public key and a private key are generated on the client machine (e.g. your computer). Each key consists of a long string of characters, stored in a file such as id_rsa / id_rsa.pub. You then copy the public key to the remote machine that you wish to log in to. When you connect to the remote machine, ssh uses the two keys to authenticate.

What is RSA?

You may notice the terms SSH Keys and RSA keys being used interchangeably. RSA is simply the name of an algorithm for encryption (named after Rivest-Shamir-Adleman). An alternative encryption algorithm is DSA (Digital Signature Algorithm), but that is no longer recommended.

How to generate and use SSH Keys

There are many good resources that explain how to generate and use SSH keys.
Here’s a couple of good explanations:
Digital Ocean – How to set up SSH Keys (easy to follow)
Ubuntu – SSH Keys (more detailed)

If you are connecting to a provided service they most likely have a specific guide. Eg.
GithubBitbucket, Amazon EC2 etc.

Further Reading

If you are interested in how the public and private keys work together, read about public-key cryptography.

Note on migrations with Django

I experienced a problem when trying to rename a model field where the field was included in a multiple unique_together option.

Eg, changing this

class Ad(models.Model):
    day = models.DateField()
    ad_group = models.ForeignKey(AdGroup)

    class Meta:
        unique_together = ('day', 'ad_group')

to this

class Ad(models.Model):
    day = models.DateField()
    adgroup = models.ForeignKey(AdGroup)

    class Meta:
        unique_together = ('day', 'adgroup')

gives an error like this
django.db.models.fields.FieldDoesNotExist: Ad has no field named u'ad_group'

The solution was to do two separate migrations. First remove the unique_together option, then migrate. Next, change the field name and re-instate unique_togeher and migrate again.

Compare dates in Python when one is timezone aware

I’ve recently started using Python, and the other day I had to compare a stored date with today’s date. I got an error:
TypeError: can't compare offset-naive and offset-aware datetimes

It turns out that the stored date had a timezone (it is timezone-aware) but by default today’s date (datetime.today()) doesn’t (it is timezone-naive).

My stored date looks like this:
datetime.datetime(2015, 3, 26, 17, 10, 1, 257894, tzinfo=<UTC>)
Today’s date like this:
datetime.datetime(2015, 3, 26, 16, 19, 38, 442042)

In order to do a comparison you can either remove the timezone from one, or add it to the other.

Removing timezone information

The simplest option, if you’re sure the dates you are comparing are in the same timezone would be to simply remove the timezone information.

mydate = mydate.replace(tzinfo=None)

Adding timezone information

You can add timezone information to a datetime using the localize method of the pytz library.

from datetime import datetime
import pytz
now = datetime.today())
now_utc = pytz.utc.localize(now)

However, what if your timezone is not UTC? For example when the clocks go forward in the spring in the UK we are on UTC + 1, but in the winter we are back to UTC. Well, you can get the local timezone which is aware of the clocks going forward and back in spring and autumn.

uk = pytz.timezone('Europe/London')
now_uk = uk.localize(now)

It is also possible to convert from one timezone to another.

utc = pytz.utc
<ipdb> now_utc = now_uk.astimezone(utc)

Let’s try this out:
>>> from datetime import datetime
>>> import pytz
>>> uk = pytz.timezone('Europe/London')
>>> utc = pytz.utc
>>> now1 = datetime.today()
>>> now1
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149)
>>> now1_uk = uk.localize(now1)
>>> now1_uk
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now1_utc = now1_uk.astimezone(utc)
>>> now1_utc
datetime.datetime(2015, 6, 1, 10, 53, 50, 15149, tzinfo=)
>>> now2 = datetime.today()
>>> now2
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862)
>>> now2_uk = uk.localize(now2)
>>> now2_uk
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now2_utc = now2_uk.astimezone(utc)
>>> now2_utc
datetime.datetime(2015, 6, 1, 10, 56, 3, 22862, tzinfo=)
>>> now1_uk < now2_uk True >>> now1_uk < now2_utc True >>> now1_utc < now2_uk True >>> now1_utc < now2_utc True >>>

Here we created a datetime now1, and another a few minutes later now2. Then we create a UK and UTC version for each. The older date (now1) is correctly compared with the newer date (now2) in each case, even where the timezones are different.

For more information on using timezones in Python, see http://pytz.sourceforge.net/

Worpress queries: When to use WP_Query, get_posts, query_posts or pre_get_posts

When you’re creating a custom theme, at some point you may to want to bring back a set of results other than what WordPress defaults to. The question is, do you use WP_Query, get_postsquery_posts or pre_get_posts?

Scenario 1 – You just need an archive page
Soluion: None of the above

If something can be accomplished without writing code, let WordPress do it for you.

  • If you want to move your main blog posts archive (ie. list of all your posts, usually just the excerpts) from the front page to another page (eg. a page entitled ‘Blog’), all you need to do is:
    a) create a new page called ‘Blog’
    b) Go to Settings > Reading and select ‘Front page displays: A static page’ and select your posts page: Select Blog page
  • If you want an archive or single page for a custom post type, use the relevant templates from the template hierarchy. Eg. For a custom post type ‘books’, use archive-books.php.  The default loop will display all ‘books’ posts, and each individual post will be displayed with single-books.php.  The exact link will depend on your permalink structure. If you’re using the ‘post name’ option (see Settings > Permalinks) then http://yourdomain/books will automatically load your books archive template.

Scenario 2 – Your page already utilises a loop and you need an additional loop
Solutions: WP_Query or get_posts()

The difference between the two is that WP_Query returns an object and get_posts returns an array.  If the content you want is fairly lightweight, for example a list of titles, then you can use get_posts and loop through the array with a foreach.  If you want a fully blown WordPress Loop and the ability to use template tags such as the_content(), go for the WP_Query option.

Scenario 3 – you want to alter the main loop
Solutions: query_posts() or pre_get_posts

By the time WordPress loads your template and runs the code in your template, it has already run a query on the database and is holding the results ready for you to use in the loop.  If you use query_posts to modify the results, WordPress throws away the previous results and runs another query on the database to bring back your results.

Because of this, it is generally recommended to hook into pre_get_posts instead. To do this you would create a function in your theme’s functions.php.  This enables you to alter the query before it is run. However, this affects all of the queries on your site, front-end and admin, if you’re not careful.  Therefore you need to put in checks to make sure it’s not an admin page/it is the main loop/it is in fact the template you wanted to affect.

In this example I have created a custom post type called ‘product’, and have a custom field called ‘colour’. My WordPress front page is set to ‘Your latest posts’. WordPress will use the home.php template to display this if it is available. Here I am altering the query for the home page to only show Products that are red:

function bb_red_things( $query ) {

	if ( is_home() ) {
        // Set post type to 'product'
        $query->set( 'post_type', 'product' );
        // Limit to products with a custom field 'colour' set to 'red'
		$query->set( 'meta_key', 'colour');
		$query->set( 'meta_value', 'red');
    }

}
add_action( 'pre_get_posts', 'bb_red_things' );

Note that pre_get_posts doesn’t work with Pages. Also, some template tags will not work (as they’ve not been set up yet at this point). For example, is_front_page() will not work, although is_home() will work. See the Codex on pre_get_posts for more details and examples.

Editing CodeIgniter websites (a speedy guide)

In this post I cover the scenario where you’ve been asked to work on a CodeIgniter website, and you’ve only got 10 minutes to find out how it works! I’ll be brief but I’ll cover

  • What is CodeIniter?
  • What is MVC?
  • CodeIgniter structure and where to find js, css and images
  • How to find the page you want to edit
  • Other possibilities
  • Where to go next

What is CodeIgniter?

CodeIgniter is a powerful, lightweight PHP MVC framework. It makes it quick and easy to build web sites and applications.

What is MVC?

MVC is a software architecture and stands for Model-View-Controller. It enables the separation of presentation code, logic and data.

Models – You want some data? The model deals with that.

Views – This is where you put your HTML and presentation code.

ControllersTell you where to go, talk to views and models, and are generally in charge of what happens.

CodeIgniter structure and where to find js, css and images

Javascript, CSS and images are often found in their own folders in the root directory. A stylesheet in a css folder like this can then be linked to with the code

<link rel="stylesheet" type="text/css" href="<?php echo base_url(); ?>css/style.css" />

The very useful base_url() is set in application/config/config.php

The Models, Views and Controllers are found in

application/models/

application/views/

application/controllers/

Here’s a possible folder structure.

codeigniter folder structure

NB. The application and system folders may have been renamed and moved (to enhance security). To find out where they are look in index.php for $system_path and $application_folder.

How to find the page you want to edit

CodeIngiter URLs are made up of segments, which tell you which Controller to look at. The Controller then tells you which view to look at. It works like this:

example.com/controller/function/ID

(or example.com/index.php/controller/function/ID )

  1. controller segment tells you which controller to look at
  2. function segment tells you which function within that controller (optional)
  3. ID segment represents variables that are passed to the function (optional)

If there’s no function segment, look for the index function.

If there’s no controller segment, you need to find the default controller. Look in application/config/routes.php and find something like

$route['default_controller'] = "welcome";

This means that application/controllers/welcome.php is the default controller.

So, you’ve found the relevant function, now you need to find the view. Look for something like this:

$this->load->view('page1', $data);

This loads the view called page1. Look for application/views/page1.php. Et voila, here is the presentation code.

Other possibilities

If the site doesn’t conform to what I’ve described above, there may be some routing going on. See the CodeIgniter user guide on URI routing for more details on this.

Where to go next

One of the things I love about CodeIgniter is it’s really well documented and has a great community behind it. Check out the CodeIgniter User Guide.