Building A WordPress Theme From Scratch

WordPress Development with LAMP

While I choose to develop for WordPress using LAMP there are alternatives such as MAMP, WAMP, XAMPP as well as services that provide a sandbox development environment such as Desktop Server and Local by Flywheel. This post only covers setting up WordPress using Ubuntu 20.04 Focal Fosa.

Installing WordPress for Local Development with LAMP

bash terminal illustration

LAMP must be installed prior to these steps I enjoy using this old tutorial. However, package names for PHP and others are outdated, be sure use the latest packages available for Ubuntu 20.04 Focal Fosa.

Begin by creating a folder in your hosting environment

Feel free to substitute scratch for your own folder name.

cd /var/www/html/
sudo mkdir scratch
cd scratch/
Creating a folder named scratch
Creating a folder named scratch to contain our WordPress website

Download and expand an archive of the latest version of WordPress.

sudo wget -c
sudo tar -xzvf latest.tar.gz
Downloading and expanding the WordPress archive
Downloading and expanding the WordPress archive

After everything expands the files will be contained in a folder named wordpress. Now we can delete latest.tar.gz and move the files into our scratch folder then remove the wordpress folder itself.

Warning: This is a good time to warn you about the dangers of the rm command. It is a command to delete files, while superuser you can remove an entire directory and its contents so be sure you are in the scratch directory and targeting the correct wordpress folder.

sudo rm latest.tar.gz
cd wordpress/
sudo mv * ..
cd ..
sudo rm -rf wordpress/
Removing the download archive and moving our WordPress files.

Setting folder permissions

This next couple commands will provide permission for WordPress to operate with read and write access in the scratch folder.

sudo chown -R www-data:www-data /var/www/html/scratch/
sudo chmod -R 755 /var/www/html/scratch/
Setting up folder permissions for WordPress
Setting up folder permissions for WordPress

Create a MySQL database for WordPress

sudo mysql -u root -p

Change your database name to match your naming convention. and use a unique and secure password in place of password used here.

CREATE USER 'scratch'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON wp_scratch.* TO 'scratch'@'localhost';
Creating a WordPress database and a unique user
Creating a WordPress database and a unique user

Configure Apache for WordPress

sudo vim /etc/apache2/apache2.conf

Editing the apache2.conf file to allow pretty permalinks.

<Directory /var/www/html/scratch/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
Configure Apache
Configure Apache

Run the following commands in the terminal to finish setting up Apache and then restart it along with MySQL

sudo a2enmod rewrite
sudo systemctl restart apache2.service
sudo systemctl restart mysql.service
Finish setting up Apache and restart services
Finish setting up Apache and restart services

If everything worked correctly you now have a localhost ready for WordPress development in using LAMP.

Visit http://localhost/scratch/ or the folder you used in place of scratch to complete the WordPress setup using the information you provided to MySQL.

Complete your WordPress Installation
Complete your WordPress Installation

Warning: If this server is intended to be used in a production environment use secure and unique passwords.

To the extent possible under law, Joseph Dickson has waived all copyright and related or neighboring rights to Building a WordPress Theme From Scratch. This work is published from: United States.

Building A WordPress Theme From Scratch

Building a WordPress Theme From Scratch

I’m a fan of using WordPress to build custom websites. So I’ve decided to start a tutorial series and share how I go about building a theme from scratch. No frameworks or starter themes.

The Sketch

Sketch of the theme's design
The layout sketch

Before even setting up my development environment I sketch a very basic layout for my theme. In this series we’ll use a simple layout that includes the following areas.

  • Site header & a primary navigation menu
  • Content area
  • Footer with secondary sidebar menu and a dynamic sidebar for widgets

The Outline

At any point you can review download or clone the repository which will possibly be a step or two ahead of the most recent post in the series.

All content will be offered free as in free beer as well as free software. The theme template files for Scratch JD are licensed under GPL3 and all content in this tutorial series is provided under Creative Commons Zero / Public Domain.

To the extent possible under law, Joseph Dickson has waived all copyright and related or neighboring rights to Building a WordPress Theme From Scratch. This work is published from: United States.

Tutorial WordPressaside

Attachment Image Snippet

This snippet for wp_get_attachment_image_src frequently appears in my theme development to select an image by its unique ID in the WordPress media library.

Handy for instances where logos, banners, or any other image frequently recurs on a website and you’d rather store that image in the media library where it can be replaced or modified dynamically.

// replace 7 with unique ID number of image
$image_attributes = wp_get_attachment_image_src( $attachment_id = 7, 'full' );

// retrieves alternative text from image information 
$alt = get_post_meta( $attachment_id , '_wp_attachment_image_alt', true );

if ( $image_attributes ) {
	echo '<img src="'. $image_attributes[0] .'" width="' . $image_attributes[1] . '" height="' . $image_attributes[2] . '" alt="' . $alt . '" />';

How it works

  • Set the unique id number in the snippet
  • Displays the image and relevant attributes

This code is based on the official Code References at for wp_get_attachment_image_src() and as get_post_meta().


Sort Archive Posts Alphabetically

I recently worked on a documentation project that required posts to be sorted alphabetically by title. The process can be done by using pre_get_posts() and the is_archive() conditional tag.

 * Order post archives by title in descending order
add_action( 'pre_get_posts', 'jd_archive_sort_alpha_title'); 

function jd_archive_sort_alpha_title($query){

	if(is_archive()) {

		// Set the order to ascending order
		$query->set( 'order', 'ASC' );

		// set the orderby to title
		$query->set( 'orderby', 'title' );



As always if you want to use this plugin on your website test it first in a safe environment to verify that it doesn’t create a conflict. Happy hacking. 🙂


Private Notes

The Private Notes WordPress plugin is in active development, I’m providing it here for the public to hack, tweak and learn from… Use at your own risk.

Private Notes allows users create and store notes on their personal website.

How Private Notes works

The Plugin creates a Notes section within the dashboard where you can create and maintain your notes.

A Custom Post Type is created to hold your content.

These notes are visible when logged into your website while the content remains hidden from a public guest who could be viewing the page.

What users can see when they’re logged in.
An example of what the public would see if they visit the post


The post’s title, author, date and other data will remain visible to the public. Additionally any media files such as images, videos, audio, and documents will remain visible from their attachment pages. Private Notes does not secure any files attached to the post! It only hides the post’s content area.

Creating a Private Note

After activating the private Private Notes plugin a notebook icon will appear in your admin menu under Posts. Simply Add New, type out some notes, add media, links, embeds or whatever you like. Then hit publish.

The Post Editor of a Note
The Post Editor of a Note

Although self hosting notes in WordPress isn’t as convenient as a dedicated note taking app it does allows personal control and ownership of my thoughts.