Add a custom page template to WordPress

We'd like to provide one of our upcoming themes with multiple screen layouts, for this we're going to add two custom templates:

  • Fullwidth: a fullwidth page
  • Contained: a boxed layout with a max-width column of content in the center of the screen.

To add a custom page template we will first clone page.php (in our theme directory). In this example we'll call ours template-fullwidth.php.

Once cloned, replace the contents of the top of the file.
You'll want to replace everything between the `get_header();` and the opening PHP tag with the following:

/* Template Name: Fullwidth
 * @package THEME_SLUG_HERE
 */

Now our new template will be available within WordPress, select the page template from the right side when editing a page:

Awesome, now your page will use the new template.

Expand the content to full width:

Now we're going to make the content wider than the template.
Each theme may be slightly different, find the container that's forcing the contained width. In our case it's the <div> below the closing of the page <header> section.

Note the following CSS which is used on the theme, this is what's restricting the width of our content:

div#content {
    margin: 100px auto 0;
    width: 1000px;
}

To edit the layout we're going to use CSS which is more specific.
If you'd like more information on CSS specificity, check out this article.

To be more 'specific' we're going to add another class to the front of the CSS, we'll then add this CSS to the theme.
Without being more specific our CSS may be overwritten by the themes CSS..

Note above the CSS classes that have been applied to the <body> tag. Due to the template we added, you'll now see 'page-template-template-fullwidth' as one of the classes applied (thanks WordPress!).

So, we'll prefix the CSS with the class .page-template-template-fullwidth and it's more specific than the theme's original styles:

.page-template-template-fullwidth div#content {
    width: 100;
}

In our theme we'd like to leave a small gap between the edges of the screen and the content, giving the content a 20px buffer on either side:

.page-template-template-fullwidth div#content {
    width: 100%;
    padding: 0 20px;
}

See below, our new CSS is overwriting the CSS style for 'width' that the theme declared:

All done, happy templating!

Force the browser to fetch a new style.css each time the page is loaded

I'm constantly making new changes and then migrating them to my live site, even minor adjustments!
This can however, be quite bad..

My clients, friends, random internet warlocks.. they all see old CSS, or none at all, for new content and containers.
HTML changes, PHP changes, CSS stays the same!

This is due to the cache time, your browser will use the default expiry time of a file that hasn't changed and with CSS this seems to be used even if changes were made!

 

In a previous post we went through how to add your own CSS file and make a browser fetch it each time, but why not the default style.css?
Well.. It's not good practice to force the user to fetch new stylesheets each time, this is not a long term solution..

 

Check your functions.php, where it references and enqueues your stylesheet we need to change the second to last value (the version) to:

time()

This will add the time as the version, so every second you go up a new version number!
Each time the page is reloaded you're sure to get a new CSS copy without clearing the cache or force refreshing.

Here's that in full.

wp_enqueue_style('freshlondon-style', get_stylesheet_uri(), array(), time(), false);

Enqueueing styles and scripts correctly in WordPress

In the past I've been creating themes while mistakenly adding scripts and stylesheets to the WordPress header.php file. I would now like to add these properly using wonderful built in WordPress functions.

Here's the WordPress default syntax for enqueueing styles and scripts:

https://gist.github.com/FreshLondon/3fc042ae077d35dd838a82a39e1bac3f

 

Parameters: wp_enqueue_script

Let's break these down..

$handle

(string) (Required) Name of the script. Should be unique.

This is most useful if you'll be registering and then enqueueing the script later, or what we'll be using it for: another scripts $deps (dependency).

$src

(string) (Optional) Full URL of the script, or path of the script relative to the WordPress root directory.

Default value: ' '

Specify the location of your script, remember we can use scripts located within the themes folders using built in functions. We'll touch in on this one later below!

$deps

(array) (Optional) An array of registered script handles this script depends on.

Default value: array()

The dependancies, what does this depend on? In short and simple: what should be loaded before this?

$ver

(string|bool|null) (Optional) String specifying script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added.

Default value: false

The given 'version' is mostly used for caching. A users browser will check if it needs to load new resources for a webpage and if a new version of a script or style has been added it'll fetch this.
Setting to the default value 'false' sets a cached script only to be renewed when the cache expiry time has been reached.
If you'd like to force the browser to ALWAYS load the script each time, use the PHP time() function.

$in_footer

(bool) (Optional) Whether to enqueue the script before </body> instead of in the <head>. Default 'false'.

Default value: false

This one here is self explanatory..

 

 

Parameters: wp_enqueue_style

Let's break these down..

$handle

(string) (Required) Name of the stylesheet. Should be unique.

Again this is most useful if you'll be registering and then enqueueing the style later, or what we'll be using it for: another styles $deps (dependency).

$src

(string) (Optional) Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory.

Default value: ' '

Specify the location of your stylesheet, remember we can use stylesheets located within the themes folders using built in functions. We'll touch in on this one later below!

$deps

(array) (Optional) An array of registered stylesheet handles this stylesheet depends on.

Default value: array()

The dependancies, what does this depend on? In short and simple: what should be loaded before this?
Remember: a stylesheet loaded after another will take precedence.

$ver

(string|bool|null) (Optional) String specifying stylesheet version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added.

Default value: false

The given 'version' is mostly used for caching. A users browser will check if it needs to load new resources for a webpage and if a new version of a script or style has been added it'll fetch this.
Setting to the default value 'false' sets a cached script only to be renewed when the cache expiry time has been reached.
If you'd like to force the browser to ALWAYS load the stylesheet each time, use the PHP time() function.

$media

(string) (Optional) The media for which this stylesheet has been defined. Accepts media types like 'all', 'print' and 'screen', or media queries like '(orientation: portrait)' and '(max-width: 640px)'.

Default value: 'all'

Is this stylesheet to be loaded on all @media types? Do you want to load it for printing, probably not!
A value such as 'screen' will load the stylesheet only for digital screens whereas a value of 'print' will load the stylesheet for printers only.

 

Conclusion

So thats the parameters explained, here's how that looks in play:

https://gist.github.com/FreshLondon/fcc79836d704377e4e67b8b40f8a14cb

Let's break down what we just used and see how it appears in the section of the page when rendered in a browser:

See how it turned time() into an actual timestamp?

 

Notice how

get_template_directory_uri() . '/assets/stylesheets/tomorrow-night.css

was turned into

http://www.freshlondon.digital/wp-content/themes/freshlondon/assets/stylesheets/tomorrow-night.css

 

Any comments or suggestions? Leave your thoughts!

Debugging: display the contents of an array

While using PHP it's hard to keep guessing the contents of any $value that you're playing about with.
Recently @nielslange showed me how to make this much easer with a simple debug function:

https://gist.github.com/FreshLondon/b376cd0815153b0449ec5ec2e8209f53

By placing this short snippet (I'd recommend in your functions.php file, then you can later use this debug again) you can then use:

debug($yourValueHere);

on any $value in your PHP to see the contents!

Here's an example:
https://gist.github.com/FreshLondon/037ba6c2328deea26509c3960c4598e9

Now reloading that PHP file shows the associated values to $images neatly within <pre> tags.
In my case, this showed the contents of $images as:
https://gist.github.com/FreshLondon/99c7a289543580a4029303ee1d938481

With the above information we can quickly write out our PHP without relying on guessing. Effective, thanks Niels!

WordPress jQuery conflict mode

If you're using JQuery in WordPress you'll hit a wall with their compatibility prevention.
The tricky thing here is that the particular copy of jQuery (shipped natively with WordPress) is in compatibility mode by default. That means that the typical $ shortcut for jQuery doesn't work, so it doesn't conflict with any other JavaScript libraries that also use the dollar sign!

If the script is being loaded in the footer (which you should be doing in the vast majority of cases) you can wrap the code in an anonymous function (technically any IIFE) where you pass in jQuery to be mapped to $:

https://gist.github.com/FreshLondon/b8eb9017ce04302d385bde3eb39826f1

If you need to load the scripts in the header, you'll probably need to use a document ready function. You can just pass in $ there:

https://gist.github.com/FreshLondon/8142d074dc86b57b057fe0da16766d31

 

WordPress menu from categories, subcategories and posts

Recently we needed to create a custom menu of posts in a hierarchy using the following format:

- category
-- posts
-- subcategory
--- posts
- category
-- subcategory
--- posts

Note that if a category doesn't have subcategories, the posts are listed in the same level as subcategories.

I discussed the issue with @nielslange and he approached it in the following fashion:

https://gist.github.com/nielslange/34378937127c476a6c5614c94415e534

I've then modified his code for use in a WordPress menu structure:

https://gist.github.com/FreshLondon/4f453217aca5c53ba2605640b41dc2c5

This results in the following:

Desktop

Mobile

I'll add the CSS soon!

© 2021 - FreshLondon