How to see visitor’s real IP with Cloudways and Cloudflare

If you’re using Cloudflare in front of your Cloudways site, you’ll notice that all the visitors come through with the IP address of It’s easy enough to fix this. Cloudways posted a useful article about it, but it misses one critical thing – the WordPress configuration!

First, head to your server configuration on Cloudways, and choose Settings & Packages > Advanced:

Scroll down until you fine the WAF Module setting, and change that to Cloudflare:

You’ll also need to restart your Apache service.

Then, for each of your WordPress sites, you’ll need to add this code to your wp-config.php :

if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    $xffaddrs = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']); 
    $_SERVER['REMOTE_ADDR'] = $xffaddrs[0]; 

Once you’ve done that, look in the logs, or post yourself a test comment to verify that the IP address is coming through correctly. Should be all good!

Good password security

Good password security isn’t too hard, it just requires a change in your approach. The biggest factor to increasing password security is password length.

To see this in action, visit this link – – and type in one of your passwords as a test. Look at the last two Attack Scenarios. That’s how quickly it would take to break that current password. Have a look how quickly that changes when you simply increase the length of your password.

If the current strength is in weeks or days, it’s not a matter of “if” you get hacked, it’s a matter of “when”.

There are two good approaches to strong password security:

1. A strong known password scheme
2. A password manager software

#2 is my recommended option, but I’ll describe #1 first:

1. A password scheme

Pick three completely unrelated words. My street – “seaviewrd” – could be one of the words as it is not in any dictionary; this is ideal. Let’s pick the words ‘seaviewrd’, ‘great’, ‘Monday’. We also pick a couple of punctuation characters, perhaps ‘$’ and ‘!’. The reason you pick unrelated words, is that password cracking software tries common phrases, so words that don’t go together in a phrase are critical.

Then to create a password, put together the three words, the punctuation, and what it’s for:

Gmail: seavrewrdgreatMondaygmail!$
Braintree: seaviewrdgreatMondaybraintree!$
Paypal: seaviewrdgreatMondaypaypal!$

Take one of those passwords and type it into to see the difference….

They are easy for you to remember, but effectively impossible to crack. They are also easy to type, as your fingers are used to typing words.

The downside is that if someone ever finds out one of your passwords … it is trivial to guess the rest of them!

2. A password manager

My preferred approach is to use a password manager. The reason for this, is that you can use it to easily generate completely random new passwords, and it can remember them for you – your brain doesn’t have to manage it. It is a little more complicated to get used to though.

KeePass is the best option – (download the Professional Edition).

Create a master password for it using the method above. Write this down on a piece of paper! Keep the piece of paper safe until you’re sure that you remember the master password, and then shred it.

Every time you make a new entry, get it to generate a completely random password, of at least 20 characters length:

When you need to log into a website, you simply double-click on the password, and it copies it to your clipboard. Paste it into the website password field, and you’re done!

IMPORTANT: ​Make sure that you keep a few copies of this file around. If you were to lose it completely, that would be disastrous, as you would have none of your passwords! I keep mine in my Dropbox, and every now and then email myself a copy. That way it’s in three places – on my laptop, in my Dropbox, and in my email.

As long as your KeePass master password is strong, the database is unbreakable.

Cart doesn’t work with Flatsome, WooCommerce, and Varnish

This is a quick and easy one.

If you’re using the Flatsome3 theme with WordPress and you have Varnish cache running, you’ll find the cart doesn’t work. You add an item, and the sidebar pops up but then it disappears again straight away, and the cart is empty.

Turn off Varnish and problem solved… but that’s not good enough.

Flatsome has a mechanism where the DOM is replaced with AJAX after the initial load. It uses cookies to pass the cart information around, and Varnish caches those by default.

Add these two rules and you’re golden:

URL exclude ^/(cart|my-account|checkout|addons)

Cookies exclude .*woocommerce.*

My site is running on Cloudways (which I strongly recommend – my review here), and the config looks like this:

Paypal button not appearing with Braintree and WooCommerce

When trying to use Braintree with Paypal on my WooCommerce installation, I kept running into issues. Using Braintree by itself would work fine, but as soon as I enabled Paypal as well I received this following error on the checkout page.

Oops, something went wrong. Please try a different payment method.

The Paypal button would also not appear.

In some instances, in the Developer Console you might see this error:

PayPal error
Error: This PayPal integration does not support this currency
    at Object.i [as create] (
    at new r (
    at c.(anonymous function) (

The problem is that the JS library linked from the WooCommerce plugin is very old and doesn’t support many of the new Braintree features. (And this is the official plugin from WooCommerce…)

To fix the issue, you’ll need to make some changes to the plugin. Be aware: these will be overwritten on a plugin upgrade, and you may need to re-fix the issue.

Edit the file wp-content/plugins/woocommerce-gateway-paypal-powered-by-braintree/includes/class-wc-gateway-braintree.php :

Comment out line 108, and add in line 109 as below. You might want to check for the latest Braintree library.

	 * Enqueue the Braintree.js library prior to enqueueing gateway scripts
	 * @since 3.0.0
	 * @see SV_WC_Payment_Gateway::enqueue_scripts()
	 * @return bool
	public function enqueue_gateway_assets() {

		if ( $this->is_available() ) {

			// braintree.js library
			// COMMENT THIS OUT wp_enqueue_script( 'braintree-js', '', array(), WC_Braintree::VERSION, true );
			wp_enqueue_script( 'braintree-js', '', array(), WC_Braintree::VERSION, true );


Test it, and everything should be working!

My Braintree plugin setup looks like this. I didn’t need to add a Merchant Account ID to get this to work:

Connecting Google Tag Manager and s2Member

The helpful s2Member Google Analytics page doesn’t cover Google Tag Manager.

If you want to configure GTM with e-commerce transactions, you’ll need to use this code:

window.dataLayer = window.dataLayer || []
   'transactionId': '%%subscr_id%%',
   'transactionAffiliation': '%%cv0%%',
   'transactionTotal': %%initial%%,
   'transactionTax': 0,
   'transactionShipping': 0,
   'transactionProducts': [{
       'sku': '%%item_number%%',
       'name': '%%item_name%%',
       'category': '%%item_number%%',
       'price': %%initial%%,
       'quantity': 1
   'event' : 'transactionComplete'

Note the ‘event’ : ‘transactionComplete’  line at the bottom. You’re going to use that to make a custom trigger for your e-commerce tracking tag:

The reason for using the custom trigger is that it ensures that the transaction data has been picked up by GTM before the Transaction tag fires. Otherwise you potentially miss the data due to the order of your page load.

The developer guides tell you exactly what variables are required. Standard ecommerce tags have these variables:

Transaction Data

Variable Name Description Type
transactionId (Required) Unique transaction identifier string
transactionAffiliation (Optional) Partner or store string
transactionTotal (Required) Total value of the transaction numeric
transactionShipping (Optional) Shipping charge for the transaction numeric
transactionTax (Optional) Tax amount for the transaction numeric
transactionProducts (Optional) List of items purchased in the transaction array of product objects

Product Data

Variable Name Description Type
name (Required) Product name string
sku (Required) Product SKU string
category (Optional) Product category string
price (Required) Unit price numeric
quantity (Required) Number of items numeric

Creating custom Metadata Field Lists in Lightroom

When you’re in Lightroom’s Library mode, you are able to set the metadata for your photos based on some pre-defined field lists.

If you’re like me, you’ve probably found yourself switching between multiple different metadata field sets, for instance between Default, EXIF, and Location:

But as it turns out, there’s a way that you can set up your own custom field lists so that you can have one screen with every field that you commonly use.

Continue reading