Create a Self-signed Certificate on Windows for Local Development

The era of insecure domain names (unencrypted communication over http) is over. Welcome to the era of secure domains (https) with TLS based encryption.

Unencrypted transfer of information over http is not necessarily a bad thing, there are plenty of sites that still server pages without https protocol. If all you need to do is serve information without any need to process forms, then http should be fine. However the norm is now https even for simple sites and Google encourages it, so https it is.

There are free services like Let’s Encrypt to generate TLS certificates, otherwise you have to pay for certificates from Certified Authorities on live production servers. Alternatively you can also serve https pages on a sub-domain like https://yoursite.googleapps.com which is given to you by Google App Engine for your use.

OK, back to the task at hand. We need to a create self-signed certificate for local development so that the local development server behaves similar to a live production server. Additionally the certificate must not generate warnings in the browser (Chromium based browsers only) that the certificate is self-signed and can’t be trusted.

Goal: Create an imaginary domain pdb.oak.san with a self-signed certificate that works on major browsers (except Firefox) without generating a warning. Works great on Chromium based browsers like Chrome, Canary, Microsoft Edge and Opera, IE.

Step 1: Setup hostname

  • Open Notepad in Administrator mode: Click Windows Start icon in task bar and start typing Notepad, right click the Notepad icon and click Run as administrator
  • Inside Notepad, open the file: C:\Windows\System32\drivers\etc\hosts
  • We want to create an imaginary domain: pdb.oak.san, add the following line to the hosts file:
127.0.0.1    pdb.oak.san
  • Save the file and close

Step 2: Create a client-side self-signed certificate

  • Open PowerShell in Administrator mode: Click Windows Start icon in task bar and start typing PowerShell, right click the PowerShell icon and click Run as administrator
  • Type the following to generate a self-signed certificate for domain pdb.oak.san with friendly name pdb.oak.san that expires after 10 years:
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "pdb.oak.san" -FriendlyName "pdb.oak.san" -NotAfter (Get-Date).AddYears(10)
  • You should get the following output

Step 3: Copy the certificate created in Step 2 to Trusted Root Certification Authorities, then export it

  • Open Management Console for Certificates: Click Windows Start icon and start typing certificates, click Manage computer certificates
  • On the left panel, click Personal -> Certificates, you should see the client-side certificate for pdb.oak.san created above in Step 2
  • On the left panel, open the tree for (but don’t left click the folder) Certification Authorities -> Certificates
  • With the right mouse button, drag and drop the certificate to the location opened in the previous step
  • Now export the certificate: right-click the certificate, All Tasks -> Export…
  • Welcome screen appears, click Next
  • Select Yes, export the private key, click Next
  • Keep the default values for .PFX, click Next
  • Type a password for the private key, click Next
  • Browse for a location and give the certificate a name (cert.pfx), click Next
  • Finally click Finish
  • You will get a notice that the export was successful

Step 4: Create the server-side certificate and key

  • Pre-requisite: you need to have OpenSSL https://www.openssl.org/ installed. Since you are a developer and on Windows, it’s highly likely you already have https://git-scm.com/ installed, so you should also have OpenSSL installed. Otherwise we recommend installing Git for Windows with Git Bash support – this will automatically also install OpenSSL.
  • Open Command Prompt and change directory to the location where you exported the certificate with .PFX extension cert.pfx in Step 3 above.
  • Type the following commands in the Command Prompt one by one. When prompted for password, type the password you used in Step 3 above when exporting the .PFX certificate.
$ openssl pkcs12 -in cert.pfx -nocerts -out key.pem -nodes
$ openssl pkcs12 -in cert.pfx -nokeys -out cert.pem
$ openssl rsa -in key.pem -out server.key
  • You should now have the following files in the folder, we will be using the cert.pem and server.key files. You can delete the other files if you want to.
cert.pem    --> KEEP
server.key  --> KEEP
cert.pfx  
key.pem  

Step 5: Test

  • You can use Apache or Nginx to test the https connection for the pdb.oak.san domain. We will create a simple Go server as it can be created really fast with a few lines of code. Create a file called main.go and type the code below. Make sure cert.pem and server.key is in the same folder as the main.go file.
package main

import (
    "fmt"
    "net/http"
)

func handleHome(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprintln(w, "Home page to test the TLS cert and secure https connection")
}

func main() {
    http.HandleFunc("/", handleHome)
    s:=http.Server{}
    _ = s.ListenAndServeTLS("cert.pem", "server.key")
}
  • Build and run the Go server: go build main.go, then run the resulting executable program main.exe
  • Now if we visit https://pdb.oak.san/ in a browser, we can see the home page with the following content: “Home page to test the TLS cert and secure https connection”
  • We can also check the certificate by clicking on the lock icon in the browser address bar:

For Nginx Users

To test on Nginx instead of writing Go code, you can use the configuration below.

  • Make sure to copy your cert.pem and server.key to the locations for ssl_certificate and ssl_certificate_key.
  • Folder paths like C:\Users\sanji\pdn\pdb.oak.san\www should of course match the locations in your own computer.
server {
    listen          443 ssl;

    server_name     pdb.oak.san;
    root            C:\Users\sanji\pdn\pdb.oak.san\www;
    access_log      C:\Users\sanji\pdn\pdb.oak.san\logs\access.log;
    error_log       C:\Users\sanji\pdn\pdb.oak.san\logs\error.log;
    index           index.html;

    ssl_certificate     C:\Users\sanji\pdn\pdb.oak.san\ssl\cert.pem;
    ssl_certificate_key C:\Users\sanji\pdn\pdb.oak.san\ssl\server.key;
}

The Definitive 4-Step Short Guide to Implementing WordPress Language Files

WordPress: 5.5.1

The reason to call this post “definitive” is because it contains the exact information (without adding anything extra) for implementing WordPress language files (aka internationalization).

The 4-Steps

1. The plugin entry point “.php” file needs the following Text Domain WordPress directive, considering foo-bar as the plugin name:

* Text Domain: foo-bar

Where is the The Text Domain used? For example, in the 2nd argument of _e() and __() functions.

The Domain Path directive didn’t need to be specified even though the plugin wasn’t part of the official WordPress plugin directory as specified here: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/

2. Create a “lang” folder (to put all your .mo and .po translation files) under your plugin folder:

~/wp-content/plugins/foo-bar/lang 

Folder name “lang” is preferred to “languages” because it’s shorter.

3. Create the .mo and .po language translation files via PoeEdit and make sure to prefix them with the plugin name:

  • foo-bar-en_US.mo
  • foo-bar-en_US.po
  • foo-bar-fr_FR.mo
  • foo-bar-fr_FR.po

PoeEdit is a bit awkward to use at first, but it gets the job done. Beginners need to refer to a quick-guide on how to generate the .mo and .po files.

4. Load the language translation files from the plugin entry point “.php” file like this (the folder pointing to the language files is a relative path):

add_action('plugin_loaded', function () { 
    load_plugin_textdomain('foo-bar', false, 'foo-bar/lang'); 
}); 

For better code organization a static function under a class is highly recommended, instead of the anonymous function above (the 2nd argument to add_action).

2 Common Mistakes to Avoid

  • Don’t forget to prefix the language files with the plugin name (see step 1 above).
  • Don’t forget to specify relative folder and not absolute folder (see step 4 above).

Getting Started with Phaser 3

A barebones Phaser 3 getting started demo.

5 Easy Steps

See the comments in index.html in the Github repo.

  1. Include the JS file phaser-arcade-physics.min.js
  2. Declare the config var
  3. Create a new Phaser.Game
  4. Preload the 4 game assets (images) in preloadFoo() function
  5. Create the game in createFoo() function
    • add background image
    • create a particles emitter
    • create the ball boss
    • attach the emitter to the boss

For more information see the official Getting Started page here: https://phaser.io/tutorials/getting-started-phaser3

Turn Off Windows Sound Notification Banner

Operating System: Windows 10

In an earlier article I posted how to How to Disable Windows Volume Popup, but that required a small 300 KB program to be installed.

In my opinion the real-offensive element is actually the browser notification banner that gets attached to the media control popup. This is what I mean:

Both Chrome and Firefox notification banner attaches to this volume popup. Disable it like this:

Chrome

  1. In Chrome address bar, type chrome://flags/
  2. Then find the setting Hardware Media Key Handling and set it to Disabled.

Firefox

  1. In Firefox address bar, type about:config
  2. Then set media.hardwaremediakeys.enabled to false

Enjoy just the volume control bar without the ugly offensive banner!

Add Gitignore in Visual Studio

Objective: You have multiple Visual Studio projects (using the same technology stack) under a single git repository and you need to manually add a .gitignore file.

Instead of copy/pasting an existing .gitignore file, let Visual Studio generate it for you.

2 Steps to Add the .gitignore File via Visual Studio

  1. Inside Visual Studio, open your solution and click the tab “Team Explorer”
  2. Then click “Add” under Ignore & Attributes Files -> Ignore File
Steps to add .ignore file in the Team Explorer tab
After successfully adding the .gitignore file

This will add the .gitignore file in your root git repository folder. So you should not need to repeat the projects for other Visual Studio projects in the same folder (provided they are all using the same technology stack).

Upgrade Phoenix Framework

The following shows a minor upgrade within version 1.5.x. If you need to upgrade 1.4.x to 1.5.x, please see: https://gist.github.com/chrismccord/e53e79ef8b34adf5d8122a47db44d22f

To upgrade a Phoenix project, edit mix.exs, look for the line (was upgraded from 1.5.1 to 1.5.4):

{:phoenix, "~> 1.5.4"},

To upgrade the Phoenix installer itself, run in the terminal (example shows upgrading phx_new 1.5.3 to phx_new 1.5.4):

> mix local.phx
Resolving Hex dependencies...
Dependency resolution completed:
New:
  phx_new 1.5.4
* Getting phx_new (Hex package)
All dependencies are up to date
Compiling 10 files (.ex)
warning: redefining module Mix.Tasks.Local.Phx (current version loaded from ~/.mix/archives/phx_new-1.5.3/phx_new-1.5.3/ebin/Elixir.Mix.Tasks.Local.Phx.beam)
  lib/mix/tasks/local.phx.ex:1

Generated phx_new app
Generated archive "phx_new-1.5.4.ez" with MIX_ENV=prod
Found existing entry: ~/.mix/archives/phx_new-1.5.3
Are you sure you want to replace it with "phx_new-1.5.4.ez"? [Yn] y
* creating c:/Users/sanji/.mix/archives/phx_new-1.5.4

> mix phx.new --version
Phoenix v1.5.4

Finally, if you updated mix.exs file for any project, run:

> mix deps.clean --all
> mix deps.get
> mix

Write a list comprehension that finds all the Pythagorean triples for right triangles with sides shorter than 100

Write a list comprehension that finds all the Pythagorean triples for right triangles with sides shorter than 100. A Pythagorean triple is three integers a, b, and c, where a² + b² = c².

In Elixir it takes a line of code with pattern-matching to produce this.

Note the 3 patterns below, nested loops, scary I know. But at least rather than starting from 1 each time, we loop through 1 more than the last value of the outer loop.

  • a<-1..99,
  • b<-(a+1)..99,
  • c<-(b+1)..99

And the final pattern which make it all work like magic:

a*a + b*b == c*c

File: pythag.exs

for a<-1..99, b<-(a+1)..99, c<-(b+1)..99, a*a + b*b == c*c, do: IO.puts "#{a}² + #{b}² = #{c}²"

Output: console

> elixir pythag.exs
3² + 4² = 5²
5² + 12² = 13²
6² + 8² = 10²
7² + 24² = 25²
8² + 15² = 17²
9² + 12² = 15²
9² + 40² = 41²
10² + 24² = 26²
11² + 60² = 61²
12² + 16² = 20²
12² + 35² = 37²
13² + 84² = 85²
14² + 48² = 50²
15² + 20² = 25²
15² + 36² = 39²
16² + 30² = 34²
16² + 63² = 65²
18² + 24² = 30²
18² + 80² = 82²
20² + 21² = 29²
20² + 48² = 52²
21² + 28² = 35²
21² + 72² = 75²
24² + 32² = 40²
24² + 45² = 51²
24² + 70² = 74²
25² + 60² = 65²
27² + 36² = 45²
28² + 45² = 53²
30² + 40² = 50²
30² + 72² = 78²
32² + 60² = 68²
33² + 44² = 55²
33² + 56² = 65²
35² + 84² = 91²
36² + 48² = 60²
36² + 77² = 85²
39² + 52² = 65²
39² + 80² = 89²
40² + 42² = 58²
40² + 75² = 85²
42² + 56² = 70²
45² + 60² = 75²
48² + 55² = 73²
48² + 64² = 80²
51² + 68² = 85²
54² + 72² = 90²
57² + 76² = 95²
60² + 63² = 87²
65² + 72² = 97²

Write a function even_length? that uses pattern matching only to return false if the list you pass it has an odd number of elements, true otherwise.

Write a function even_length? that uses pattern matching only to return false if the list you pass it has an odd number of elements, true otherwise.

This is a fun little exercise in Elixir. First we match a single item in the list (odd number) which is false. Then match exactly two items (even number) and return true. Then the 3rd function matches the first 2 elements (as throwaway) and recursively tails the list to match the first two patterns.

defmodule Lists do
  def even_length?([_a]), do: false
  def even_length?([_a, _b]), do: true
  def even_length?([_a, _b | t]), do: even_length?(t)
end

Some testing below in IEx:

iex> Lists.even_length? [1]
false
iex> Lists.even_length? [1, 2]
true
iex> Lists.even_length? [1, 2, 3]
false
iex> Lists.even_length? [1, 2, 3, 4]
true

Dark Mode for Sumatra PDF

Windows: version 10
Sumatra PDF: version 3.2 64-bit

A dark mode for Sumatra PDF is really easy – you just need to tinker with 3 lines of code in the settings.

Why Use Sumatra PDF?

In my opinion, it’s the best PDF reader. It’s small in size, super-fast and doesn’t have any annoying cruft.

Why a Dark Mode (Night Mode)?

If you code for long periods of time, then it’s really great to have your code editor run in dark mode. This greatly reduces the strain on the eyes.

But let’s say you are also following along an e-book, maybe a PDF and you switch to Sumatra PDF. The default setting is black text on white background. Immediately your eyes are shocked with bright luminescent white light. It’s as if you were relaxing in a room with the lights switched off and suddenly someone walked in and abruptly turned the lights on.

As you are coding along you have to switch back and forth multiple times between your PDF reader and code editor. It can be really jarring for the eyes and nerves.

How to Enable Dark Mode?

In Sumatra PDF, click on the Menu -> Settings -> Advanced Options

This should open the SumatraPDF-settings.txt file in your text editor. Change the following 3 lines under the heading FixedPageUI:

TextColor = #eeeeee
BackgroundColor = #111111
GradientColors = #000000

TextColor changes the text color of the PDF document. Background color changes, well the background color of the PDF document. GradientColors will change the background window of Sumatra PDF.

XAMPP Upgrade Tasks

I usually have 3 simple and separate tasks for a XAMPP upgrade or any general development environment migration (for example when moving to a new Windows or Mac hardware).

  1. Moving the source codes, files and assets: copy the www folder with all the project source codes local virtual host domains
  2. Apache configuration: edit the httpd.conf and httpd-vhosts.conf files
  3. MySQL migration: migrate the database

Source files

Usually I have a separate www folder configured with vhosts.

Apache Configuration

I only change the following line in httpd.conf because I like to develop on port 8080.

Listen 8080

And as a habit (Debian and FreeBSD) check if the vhosts file is included:

Include conf/extra/httpd-vhosts.conf

The httpd-vhosts.conf file has multiple entries (for each project or local domain name):

<VirtualHost *:8080>
    ServerName client1.san
    ServerAlias www.client1.san
    DocumentRoot C:/xampp/www/client1
</VirtualHost>

MySQL Migration

A fresh copy of a pristine MySQL installation with PHPMyAdmin has the following databases:

  • information_schema
  • mysql
  • performance_schema
  • phpmyadmin
  • test

So when migrating I try to avoid copying over those five databases / schema.

Preview(opens in a new tab)

While it might be OK to dump the database via PHPMyAdmin, it’s not a good idea to restore it via a web interface. For example my combined database size is almost 1 GB.

So ensure you have a decent max_allowed_packet size in specified in my.ini:

max_allowed_packet=16M

Then run the database restore command manually from the command line. For example:

mysql -u root < databases_to_migrate.sql