Webxopt

Turn a Website into a Business

T 07 3103 3259
M +61 409 825 759
E info@webxopt.com

  • Home
  • Why Us?
  • What We Do
  • B2B Websites
    • Case Study
  • REST API
  • Cybersecurity
  • Consulting
  • Articles
  • Contact
    • Privacy
    • Help Page

Replacing reCAPTCHA in Gravity Forms

August 15, 2020

UPDATE 2: If you are a fan of HCAPTCHA, and why wouldn’t you be, I have a much easier solution. Rather than Gravity Forms, try the also excellent Forminator from WPMU (https://wordpress.org/plugins/forminator/). I have the Pro version on a couple of sites and that has an HCAPTCHA setting along side reCAPTCHA.

Nice one WPMU – We salute you for offering a non-tracking alternative! It’s also a pretty nice alternative to Gravity Forms!


UPDATE: The G-Forms hCaptcha seemed to stop working on my site. There were no settings showing and the Gravity Forms system wasn’t showing hCAPTCHA. To make things worse it also disappeared from my site. For the moment I’ve had to suck it up and go back to the big bad CAPTCHA.

If you are having trouble with reCAPTCHA you are not the only one. I have multiple sites using reCAPTCHA in Gravity Forms where the reCAPTCHA code loads multiple times for reasons best known to Google.

I have asked Gravity Forms to look at this and their answer is always that they have no control over what Google is doing, but as you can see from the below, a single form with reCAPTCHA can add significantly to a sites downloads: –

Note that this is a single form and recaptcha_en.js is loading 4 times.

If this was one site having this problem I’d think it was the site, but I see it on multiple different systems and different sites.

Alternatives to reCAPTCHA

In Gravity Forms the main alternative would be Really Simple CAPTCHA. I like this system because it’s light weight and easy for users. However, I have found 2 issues. These are: –

  1. It can have issues with cache that prevent the code images from showing and therefore your forms can’t get completed. I don’t see this a lot, but occasionally this can be a problem.
  2. It seems that it’s increasingly not stopping spam. I’ve now started to see a lot of spam arriving from these forms. Not so much as it’s likely to be bots, but enough that I’m thinking they are becoming too easy to guess.

The latest alternative is hCAPTCHA. This came to my attention after I heard that Cloudflare had started to use it. So what is hCAPTCHA? Essentially it’s like reCAPTCHAv2, but with better privacy and customisable CAPTCHA subjects.

In your form it looks like: –

When you select that you are human, you get a similar grid of images to reCAPTCHAv2: –

You can see this working on my site contact form.

I have tested for downloads and this is what I found: –

reCAPTCHA – 0.172MB, but may load multiple times for no obvious reason.
hCAPTCHA – 0.25MB and loads that size for as many forms as you have on the page.

Note that although neither of these has a huge effect on the DOM load time, the weird thing is that Google might well punish you for a large page size due to their poor product!

Obviously what this means is that if you have multiple forms on a page, I would perhaps think seriously about using either of these systems over Really Simple CAPTCHA, but for a single form, the fact that hCAPTCHA’s size to download is consistent, puts it way ahead of reCAPTCHA.

How to Install hCAPTCHA in Gravity Forms

Actually this is the easy part. Just install G-Forms hCaptcha and follow the instructions to create an hCAPTCHA account. Then in Gravity Forms, set your secret key in Gravity Forms settings. You can then just drag the hCAPTCHA field into the form and delete the old CAPTCHA.

The one gotcha I did find is that you have to set a site key in the Advanced Tab of the hCAPTCHA gravity form field: –

You get that Site Key by adding the site into your account at https://www.hcaptcha.com/.

Conclusion

I would definitely recommend switching over from reCAPTCHA to hCAPTCHA if you have a single or maybe even 2 forms on your page. The signup process is quicker and easier, and you don’t need a credit card on your account (unlike Google) and there is good integration with Gravity Forms via a plugin.

The user experience of the hCAPTCHA system is similar to that of reCAPTCHAv2, but has the advantages that there is more focus on privacy, and you can set broad subjects for the CAPTCHA’s that match your sites subject matter.

Filed Under: Articles

Adding Time Dependent Content in WordPress Theme Templates

May 21, 2019

I have been looking at an site with a custom post type to advertise jobs and custom fields to represent all the fields that need to be filled in by the site admin.

One of the fields is an expiry date that is set using the ACF (Advanced Custom Fields) date picker. What I wanted to do was disable the application form on the job at the expiry date, without having to have a custom form for every job.

There are various plugins to do things like this, but in my case they didn’t seem to work that well and a few hadn’t been updated in a long time. However, it turns out that as this is to go in the template, rather than on the WordPress page, it’s actually pretty easy to write in PHP and just include that in the template.

The code snippet follows: –

<?php 
// For US format dates use $date1 = date("m/d/y")
$date1 = date("d-m-Y"); 
$closing1 = get_field('closing_date');
$date2 = strtotime($date1);
$expires1 = strtotime($closing1);
if ($date2 < $expires1) {
	echo "<p>Todays Date - " . $date1 ."</p>";
	echo "<p>This will expire on " . $closing1 . "</p>";
} else {
	echo "<p>Todays Date - " . $date1 ."</p>";
	echo "<p>This expired on " . $closing1 . "</p>";
}
?>

To explain this, the first line sets the variable $date1 as the current date from the server. Note the date format is d-m-Y. This is the standard for European format dates as per https://www.php.net/manual/en/datetime.formats.php but for US format you will want m/d/y. Note the different order and slashes not dashes.

The second line sets a variable of $closing1 which retrieves my ACF field closing_date. Note that the ACF field has to be set up to the same date format or you will need to do some extra php work get it into this format. My ACF field settings look like the below: –

ACF Date picker settings

Once you have these variables set, that is most of the hard work done.

Lines 3 and 4 take the above 2 variables and convert them into a standard form the server will understand and be able to work with (the number of seconds since January 1 1970 00:00:00 UTC).

After that we have a simple if statement comparing the 2 times and customising content to suit. In this case if todays date is less than the expiry date show the first content, if it’s after show the second content. Just substitute in what you need.

In my case I am going to put the Gravity Forms shortcode in the top section, so the application for will show if the expiry hasn’t past. In the bottom section I will put a message saying the the expiry date has passed, but if they want to contact HR, the details are shown.

Next step will be to move the job to draft a couple of days after the expiry date!

Filed Under: Articles

Tablepress CSS Column Selector

June 1, 2018

Tablepress CSS Column Selector Plugin adds the number of columns in a Tablepress table as a class on the table. This then allows the table to be styled with standard CSS based on the number of columns.

The origin of this plugin was when I had a page with many tables, and the columns just didn’t line up how I wanted. My options were to manually add the column widths in tablepress or to style them with CSS.

Result

Initial Code
<table id=”tablepress-2-no-107″ class=”tablepress tablepress-id-2″>

After Plugin (for a 3 column table)
<table id=”tablepress-2-no-107″ class=”tablepress tablepress-id-2 column-3“>

Typical CSS

You will need to manually add the CSS as per your requirement, but can now target the number of table columns. In the example below I have the last column always set to 20% (in this particular case it was so a button in the table displayed in a single column).

table.tablepress-id-2.column-2 td.column-1{width:80%;}
table.tablepress-id-2.column-2 td.column-2{width:20%;}
table.tablepress-id-2.column-3 td.column-1{width:54%;}
table.tablepress-id-2.column-3 td.column-2{width:26%;}
table.tablepress-id-2.column-3 td.column-3{width:20%;}
table.tablepress-id-2.column-4 td.column-1{width:54%;}
table.tablepress-id-2.column-4 td.column-2{width:13%;}
table.tablepress-id-2.column-4 td.column-3{width:13%;}
table.tablepress-id-2.column-4 td.column-4{width:20%;}

To download this plugin (it got stuck in WordPress review and I haven’t been able to get in touch with the person that keeps emailing me). You can download directly from https://www.dropbox.com/s/kpzfgggqjscf2k6/tablepress-css-col-selector.zip?dl=1

Please note that this is not the greatest thing to do securitywise! The code though is below if you want to copy and paste it into your functions.php file instead.

// JavaScript Document
jQuery(document).ready(function(){
		var numbertablesonpage = jQuery("table.tablepress").length;

var tableid = [];
jQuery("table.tablepress").each(function () {
   tableid.push(jQuery(this).attr("id"));
});
		
	jQuery.each( tableid, function( index, value ){
    	var tableidnow = tableid[index];
		var colclass1 = jQuery("table#" + tableidnow + " tr.row-2 td:last-child").attr('class');
		jQuery("table#" + tableidnow ).addClass(colclass1);
	});
	
});

This is a javascript document containing some jquery that should be saved separately in the active theme file /js/ tablecolresizer.js

You can see that all it does is looks at a table that is loading, then it takes the last cell of the second row, and copies the class, which is the column number. It them applies that same class to the top level table, giving you an way to style the table based on the number of columns it contains.

To add this file into your theme, add the following into your themes functions.php file.

// The following adds the script that allows a tablepress table to check the number of columns int he table
function tp-col-indicator() {
    wp_enqueue_script( 'tp-col-indicator', 'https://YOUR-SITE/wp-content/themes/YOUR-THEME/js/tablecolresizer.js', array( 'jquery' ), 1.0, true );
}
add_action( 'wp_enqueue_scripts', 'tp-col-indicator' );

Obvious replace YOUR-SITE and YOUR-THEME in the code above.

Filed Under: Articles

Analytics Content Grouping Using WordPress Categories and Not using Googles Tag Manager

October 9, 2017

Analytics Content Grouping can be very useful to see how a range of products is doing in the market in a quick and intuitive way and also allows for some interesting insights that are hard to get to in any other ways.

In the past I have relied on manual tagging of pages, but over time as new pages are added, this manual tagging drifts and the ‘not set’ category increases. As a way to automatically group pages a great way would be to use WordPress categories and group based on category names.

Before I go any further I should add that most of the pages I want to group are product pages and all of them are in multiple categories. For example a product might be in a categories for products, industrial, steel and more. This method is based on picking out a few of those categories only as groups. In this case Industrial is the group I want to add this to. If you have pages with 1 category only, there are other methods that are even more automated (see below).

I should add that this method is loosely based on the article of https://www.highposition.com/blog/how-to-send-author-content-groups-wordpress-google-analytics/ and I will follow the same steps that they take you through: –

Step 1 – Configuring Content Groups

Log into your analytics account and click on the Admin link in the top menu bar. Select the account and property you want and in the View section on the left, you should see Content Grouping: –

analytics-content-groups-setup1

We then need to create a new Content Group

Click the “Create New Content Grouping” button at the top.

Add in the title of your Group, in our case “Categories”.. but you can call it anything you wish.

Just below the title is where you select the tracking method you wish to use, we will be tracking via the GA javascript code, so click the first option, “Group By Tracking Code”, you don’t need to change anything on this screen, just press “Done” at the bottom.

Now do the same process again for any others you want to add to a maximum of 5, but when clicking the tracking code implementation option, make sure you change the “Index Number” option, so they are unique.

Step 2 – Modifying the Analytics Tracking Code

This article assumes that you are using the universal analytics code that Google has been pushing for some time. The code you have running on your site should therefore look something like this: –

<script>
(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-XXXXXX-X’, ‘auto’);
ga(‘send’, ‘pageview’);

</script>

We want to change it to add an extra line as shown below (in this case to add the category name, which is industrial to contentGroup4, which is the one I set up in the step above: –

<script>
(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-XXXXXX-X’, ‘auto’);
ga(‘set’, ‘contentGroup4’, ‘Industrial’);
ga(‘send’, ‘pageview’);

</script>

 

Find this code in your site. In theory it should be in the head section, but I load mine in the footer just in case Google is slow (which is quite often). You will often find this code in either the theme settings, a wordpress plugin or in the footer.php or header.php of the theme you are using. The code should look exactly as the top example above, so, after backing up, make a space between the ga(‘create’, ‘UA-XXXXXX-X’, ‘auto’); and ga(‘send’, ‘pageview’); lines to type in your new code to add the content groups.

The code I am using assumes that you know the groups you want to track, you have a page in multiple categories (see below if you have 1 category) and you don’t have many groups (as each one needs a line of code).

<?php
if(in_category(’19’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial’);\n”;}
elseif(in_category(’16’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial2’);\n”;}
elseif(in_category(’18’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial3’);\n”;}
elseif(in_category(’11’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial4’);\n”;}
?>

So this is very simple, each line checks to see if the page is in a particular category and if it is adds the analytics code to tag to page. In more detail:

if(in_category(‘19‘)) – Checks to see if the page is in category 19. You can get the category number easily by going to the category page in WordPress (under Posts), finding the particular category you want, then hovering your mouse over the top. In most browsers you will see the url of the link you would go to if you clicked. In that url you will see “tag_ID=19” in this case, but the number is the number you need to enter here.

{echo “ga(‘set’, ‘contentGroup4’, ‘Industrial’);\n”;} – This bit is just the code from analytics, but I have manually written in the category name. In this case Industrial. You could do this in code, but if I am setting the category ID for an individual line, you might as well just add it in manually. \n gives you the line break.

If you add that in to your analytics code it should look like the below: –

<script>
(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);

ga(‘create’, ‘UA-XXXXXX-X’, ‘auto’);
<?php
if(in_category(’19’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial’);\n”;}
elseif(in_category(’16’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial2’);\n”;}
elseif(in_category(’18’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial3’);\n”;}
elseif(in_category(’11’)){echo “ga(‘set’, ‘contentGroup4’, ‘Industrial4’);\n”;}
?>
ga(‘send’, ‘pageview’);

</script>

Once you load up a page this should then be tagged appropriately with the categories you have set.

Step 3 – Viewing Your Data

Once this new data has begun flowing in to your GA account, head over to your All Pages Report….  Behaviour -> Site Content -> All Pages

analytics-content-groups-setup2You will see a new option appear at the top of the report asking which content group you would like to see your pages grouped by. You should now see your groups in there. Select the group you want and it will show you pages together with useful on-site behavioural metrics. This can be very useful to see how certain sections or product ranges are performing against site stats over time.

Another interesting way to display this information is in a Dashboard. I particularly like to use the map view on the dashboard so I can see how particular groups are performing in different parts of the country or the world: –

 

 

If you have Single Category for Each Page

If each of your pages only has a single category, and you have a much larger range of categories. You may want to use this code instead as it automatically fetches the 1st category the post is in. Note that this is for Universal Analytics and also creates a group for the first tag. If you don’t want the tag group, just delete that section: –

<?php if (is_single()){
while(have_posts() ) : the_post();

$category = get_the_category();
if ($category && !empty($category[0]->cat_name)){
echo “ga(‘set’, ‘contentGroup4’, ‘”.$category[0]->cat_name.”‘);\n”;
}

$tag = get_the_tag();
if ($tag && !empty($tag[0]->tag_name)){
echo “ga(‘set’, ‘contentGroup5’, ‘”.$tag[0]->tag_name.”‘);\n”;
}

endwhile; // end of the loop.
}
?>

Explanation

<?php if (is_single()){
while(have_posts() ) : the_post();

………..

endwhile; // end of the loop.
}
?>

This section just makes sure that the page includes a single post only.

$category = get_the_category();

This section creates a group (array) of categories.

if ($category && !empty($category[0]->cat_name)){

This makes sure there is a category assigned and if there is applies the category name rather than the ID number or slug.

echo “ga(‘set’, ‘contentGroup4’, ‘”.$category[0]->cat_name.”‘);\n”;

This is the section that actually writes the line into the page html (echo). In this case the start of that is all just text from Google analytics. Change contentGroup5 to whatever content group you have set in the Analytics admin panel. The options are basically contentGroup1 to contentGroup5. The next bit ‘”.$category[0]->cat_name.”‘ is really the crucial bit that pulls in the category name. This will be the first category on the list you see in the pages, All pages list in WordPress.

Filed Under: Articles Tagged With: Tech Comment, Web Development

Retrieve REST Posts for Specific Pages

October 9, 2017

After a lot of research I have finally found a way to retrieve specific pages from a WordPress REST site using it’s JSON feed. I should note that this is not complicated at all, just frustratingly badly documented!

http://www.mysite.com/wp-json/wp/v2/pages?include=8,528

In this case the link would go to mysite.com and retrieve the pages with ID’s of 8 and 528 only. Very useful for doing something like related pages.

As I said it’s not rocket science, but it’s taken me a really long time to find this!

Filed Under: Articles Tagged With: JSON, REST, Web Development

  • « Previous Page
  • 1
  • 2
  • 3
  • Next Page »

Recent Posts

  • Cybersecurity for Australian Small/Micro Business – Networks 2 – DNS
  • Cybersecurity for Australian Small/Micro Business – Networks 1 – Routers
  • Cybersecurity for Australian Small/Micro Business – Mobile, Part 2
  • Cybersecurity for Australian Small/Micro Business – Mobile, Part 1
  • Cybersecurity for Australian Small/Micro Business – Introduction

Advanced Help

Enter your code in here. You will need to contact me first for a code!

Simon Griffiths in San Francisco

Webxopt was formed in 2009 by Simon Griffiths, who was at the time working as the Marketing Manager of a medium sized company in the electrical industry. Simons background includes study of both … Read More

  • Email
  • Twitter

Awards – Graduate Certificate in Cybersecurity

Robina Town Centre - Webxopt

Webxopt Pty Ltd
PO Box 16
Robina Town Centre
QLD 4230, Australia

T 07 3103 3259
E info@webxopt.com
ABN: 24 624 264 951

© 2023 · Webxopt · Built on the Genesis Framework