Category archive


Simplest Method to Insert a YouTube Video to WordPress Site

in WordPress

Quick Guide:

Find embed code of the video, insert it into post or page as plain html.


Detailed Guide:

I. Open the YouTube video you want to insert

II. Find the EMBED code

  1. Below the lower right corner of the video, click SHARE;
  2. On the lower right corner of the poped up box, click EMBED;

How to embed YouTube Video


3. When the Embed Video box pops up, as shown in the picture below, click COPY in the lower right corner.

Copy embed video code from youtube

II. Insert into post/page

  1. Go to the post/page you want to insert the video to;
  2. Click Text on the upper right corner of the main editing area, right next to Visual;
    (This switchs the editor to html model, you may see some html code here if you have some other contents. Don’t panic.)
  3. Paste the code you copied from the previous step to where you want to insert it to.
  4. Once you done all editing, click Publish/Update as how you normally publish post.

Insert embed code to wordpress post.

All done. Here’s an example:

Change Domain of WordPress Site with SSL on RHEL/CentOS

in WordPress

RHEL/CentOS 7 w/ EPEL, Apache 2.4 Multi vHosts, PHP 5.6, MySQL 5.6/MarinaDB 10, WordPress 4.6, LetsEncrypt/Certbot 0.9.
May need modifications for configurations differ than above.

1. Change Site Address in wp-admin

https://$, login with admin credentials.
In Settings/General, change WordPress Address (URL), and Site Address (URL) to the new site/blog domain.

2. Change DNS Record

How to change DNS record is out of scope of this tutorial, see your domain providers instructions. One example:

3. Change Apache vHost Settings

sudo vi /etc/httpd/sites-available/$yoursite.conf
Change ServerName & ServerAlias for both http and https vHosts, make sure to include both $yourdomain and www.$yourdomain.
Save and quit, then sudo systemctl reload httpd

4. Get a new SSL Certificate

This step will be significantly different or may not even necessary if you are using a SSL provider other than Let’s Encrypt, if so, check with your SSL provider’s documents about this step.

sudo certbot certonly --webroot -w /var/www/$your_site_directory -d $yourdomain -d www.$yourdomain
Be aware of the rate limit of Let’s Encrypt, it’s 5 certs/week/domain at the time this article been written.

If this step fails,

Failed authorization procedure … Error: The client lacks sufficient authorization

– DNS record settings for both $yourdomain and www.$yourdomain
– File permission of /var/www/$your_site_diectory/.well-known/
– File permission of /var/www/$your_site_diectory/.well-known/acme-challenge if exsist.
– File permission of key files under /var/www/$your_site_diectory/.well-known/acme-challenge
to make sure user Apache:Apache(or the username whoever owns the Apache process if different) has the permission to read key files.

The key files said above is automatically generated by certbot, and will be deleted after the process, regardless success or fail. Thus, to monitor its permissions during the process, launch a separate ssh session, watch 'ls -al /var/www/$your_site_diectory/' will give you a 2~3 seconds window to observe what’s happening there.

5. Disable the old SSL Certificate

The best practice is too keep record all all certificate issued. Thus, we archive instead of delete old certificates.
sudo mv /etc/letsencrypt/live/$old /etc/letsencrypt/archive/live – If this is the 1st time doing this, create archive/live directory first.
sudo mv /etc/letsencrypt/renewal/$old /etc/letsencrypt/archive/renewal – If this is the 1st time doing this, create archive/renewal directory first.

6. Enable the new SSL Certificate

sudo vi /etc/httpd/sites-available/$yoursite.conf
SSLCertificateFile to /etc/letsencrypt/live/$yourdomain/cert.pem
SSLCertificateKeyFile to /etc/letsencrypt/live/$yourdomain/privkey.pem
SSLCertificateChainFile to /etc/letsencrypt/live/$yourdomain/chain.pem
Save & quit, then sudo systemctl reload httpd


Fix: Apache failed to start in FreeBSD

in IT

When getting the following error message:

AH00557: httpd: aprsockaddrinfo_get() failed for roc
AH00558: httpd: Could not reliably determine the server’s fully qualified domain name, using Set the ‘ServerName’ directive globally to suppress this message

EDIT /usr/etc/apacheXX/httpd.conf — XX is version number
Change the ServerName line to ServerName you_server_name:80

Save, quit, restart apache.

Turn Xcode into vim-like editor

in IT

A detailed instruction about configuring XVim to work with Xcode, such that you can use vim-like key bindings in Xcode.

This article is based on Xcode 8 and XVim 52485d8.
This article is an expansion/simplification based on the official install instruction, with emphasis on mistakes or problems I encountered when follow the official instruction. The official instruction can be found at:

1. Quit Xcode
2. Resign Xcode
a. Create a code siging certificate

(Skip this step if you already have one.)

Open Keychain /Applications/Utilities/Keychain Access
Select login
Create a new certificate Top bar -> Keychain Access -> Certificate Assistant -> Create a Certificate
with the following info:

Name: <whatever_name_you_like>  
Identity Type: Self Signed Root  
Certificate Type: CodeSigning  

For more details on this step:

b. Resigning Xcode:

$ sudo codesign -f -s <The_same_name_as_used_above> /Applications/
(Replace the path to if yours is different.)

If codesign can not find vaild identity: Go to keychain access, trust the newly created certificate. Right click on certificate -> Details -> Trust -> Code Signing -> Always Trust
If codesign started resigning but stuck: Wait a long time, till the system pops up request permission to access keychain dialog, then click Allow.

3. Build XVim
a. Download it

Do NOT sudo: Must download to directory owned by current user, or there will be trouble.

curl --output

OR if you already have git installed:
git clone

b. Build it

Again, do NOT sudo.
Check xcode-select path: xcode-select-p, it should show:
If it doesn’t, then use xcode-select -s to make it correct.

cd into XVim directory

if it says

XVim hasn't confirmed the compatibility with your Xcode, Version X.X  
Do you want to compile XVim with support Xcode Version X.X at your own risk?  

Type in yes, or you can’t install it. It will work.

4. Load XVim

a. Open Xcode
b. A dialog box will pop up ask for if you want to load the new plug in, choose Load the bundle

Xcode editor should behave like vim now.


To customize XVim

vi ~/.xvimrc

To uninstall

rm -rf "~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/XVim.xcplugin

Ghost Blog Update Script

in IT

A basic sh script to update Ghost blog.

This script is written for use in FreeBSD 10.x, and MAY be good for other BSDs and Mac OS X as well. It can also be used for other Unix-like system(such as Linux) with proper modification.

This script assumes:
1. You use system service(rc) to manage your ghost server, and have stop and start as rc commands for halting and launching ghost server. If you don’t know how to do so, read section 5 of this article.
2. Your ghost software is installed in /var/www/ghost
Otherwise, some modifications may be needed before run this script.

Not suitable for version jump update.

# Copyright (c) 2016 Mo Zhang
# Licensed under the MIT License.

#! /bin/sh
service ghost stop  
cd /var/www  
cp -R ghost ghost_backup  
curl -LOk  
unzip -d ghost_new  
cd ghost  
rm -R core  
rm index.js  
rm *.md  
rm *.json  
cp -R ../ghost_new/core .  
cp ../ghost_new/index.js .  
cp ../ghost_new/*.json .  
cp ../ghost_new/*.md .  
cp -R ../ghost_new/content/themes/casper ./content/themes  
cd ..  
chown -R ghost:ghost *  
cd ghost  
npm install --production  
service ghost start  

Setup Ghost Blog in FreeBSD Jail, with single IP

in IT

This tutorial will guide you through setup a FreeBSD jail, install ghost blog inside it, and configure to allow the blog to share the IP address with the main system.
It is written for FreeBSD 10.x, and MAY be adopted for other versions.

It assumes:
1. Your firewall is PF: if you use ipfw, modifications will be needed.
2. Your text editor is vi: if you are not comfortable with vi, subside with something you like. Keep in mind, if using any editor other than vi, you will need to install a copy inside the jail, too. vi(not vim) is the only editor comes with the OS.
3. Assume the ghost blog will share a single IP with the main server.

We will use ezjail for jail management, if ezjail is not yet installed, run:
sudo pkg install ezjail
sudo ezjail-admin install – install base jail
sudo cp /etc/resolv.conf /usr/jails/newjail/etc/ – make sure jails share the same DNS configurations as the main server.
Note: ezjail is the recommonded method because it saves time and get the job done well. However, if you would rather do the jail manually, please read FreeBSD Jails the Hardway in the Extended Reading section at the end of this post.

1. Allow ezjail to run at startup,
& Create a loopback network for hosting the blog:

Run sudo vi /etc/rc.conf to add the following lines to /etc/rc.conf:

#Jail Settings

This creates a lo1 subnet of 8 addresses, start from ( is used to identify the subnet). /29 is the subnet mask, it is the equivalent to

2. Setup jail for ghost

sudo ezjail-admin create blog
sudo ezjail-admin start blog

3. Setup port forwarding with PF:

Run sudo vi /etc/pf.conf to add the following lines to /etc/pf.conf:

this="vtnet0" #change vtnet0 to your network interface if different  

# Allow outgoing connection from jails
nat on $this from lo1:network to any -> ($this)

# Redirect ghost traffic to jail
rdr pass on $this proto tcp from any to $ip_pub port 2368 ->  

Note: rdr pass will immediately pass all traffic on port 2368 to jail, without further firewall filtrations. If firewall filtration desired, delete the keyword passhere, and add corresponding PF rules. How to write such rules is a complicated topic beyond the scope of this tutorial. If you are interested in this topic, please refer to the extended reading section below.

Then run:
pfctl -sn – check if the above rules are set correctly.
sudo service pf reload – load new PF rules.

4. Install ghost

sudo ezjail-admin console blog – switch to the jail console

4.1 Install Dependencies

At the time this tutorial being written(Aug. 2016), the ghost version is 0.9, and it requires npm2, node4, and sqlite3 to run. In the future, be sure to check with Ghost’s official website for updated dependencies requirements.

pkg install node4 – node.js is the runtime environment in which ghost will be running
pkg install npm2 – npm is the package management tool for node.js
pkg install sqlite3 – sqlite is the default database system for ghost
pkg install curl – we will need curl to download ghost software
pkg install sudo – the ghost user will need sudo privilege to run ghost

4.2 Create a ghost user

It is best practice not to run ghost server as the root user.
adduser ghost, then follow promoted instructions to fill up your info.

4.3 Download ghost

We will install ghost in /var/www, you can modify to target a different location if you want.
mkdir -p /var/www
cd /var/www
curl -L --output
unzip -d ghost
chown -R ghost:ghost ghost

4.4 Install ghost

su ghost
cd ghost
npm install sqlite3 --sqlite=/usr/local
npm install --production – this step installs ghost
cp config.example.js config.js
vi config.js, then change the url in line 14 to your url.

4.5 Checkpoint

Now, your ghost blog is ready to run manually, let’s check if all things went right so far:
npm start --production – this starts the ghost service.

Launch a browser that supports javascript(most modern browsers do, Lynx is an example that DOESN’T), and go to http://your_server's_ip_address:2368.

You should be able to see the ghost welcome page as shown below. If not, sometime went wrong, go back and debug.

Then, configure your DNS settings to point your domain to your new Ghost blog.

5. Let Ghost run automatically at system boot

Because Ghost is running on top of node.js, it can not just autostart the same way as native applications. It will require a tool called forever to keep up.
exit – you were in ghost user in last step, exit to root user (of the jail).
npm install forever -g – install forever globally.
vi /usr/local/etc/rc.d/ghost – create startup(rc) script for ghost.
Now paste the following script into this file:

# Copyright (c) 2016 Mo Zhang
# Licensed under the MIT License.


#PROVIDE: ghost
#KEYWORD: shutdown

. /etc/rc.subr

# variables


load_rc_config ghost  
: ${ghost_enable:="NO"}


  sudo -u ghost sh -c "NODE_ENV=production forever start -al $log $ghost/index.js"

  sudo -u ghost sh -c "NODE_ENV=production forever stop $ghost/index.js"


run_rc_command "$1"  

chmod +x /usr/local/etc/rc.d/ghost – make the new script executable
touch /var/www/ghost/ghost.log – create log file
chown -R /var/www/ghost – make sure the log file is owned by ghost user
vi /etc/rc.conf, then add the line:

And last run service ghost start to start ghost.

Also should test the following command:
service ghost stop
service ghost restart

Extended Reading:

Ghost Official Documents:
Jail Official Documents:
FreeBSD Jails the Hard Way:
ezjail Official Documents:
PF Official Documents:
Note: The FreeBSD PF is different than the OpenBSD PF.

Go to Top