Author: Pinaki Bisi

WordPress: Add plugin settings link to Plugins page

When creating a plugin that has its own settings page, it’s frequently helpful to make a connection to the settings page straight from the Plugins list – this spares clients the time it takes to discover where precisely your module shows up in the administrator menu. Here is a basic code scrap that makes the settings interface for you.

function plugin_add_settings_link( $links ) {
    $settings_link = '<a href="options-general.php?page=plugin_name">' . __( 'Settings' ) . '</a>';
    array_push( $links, $settings_link );
  	return $links;
$plugin = plugin_basename( __FILE__ );
add_filter( "plugin_action_links_$plugin", 'plugin_add_settings_link' );

Just replace the href attribute with the link to the plugin settings page and rename the function to something slightly more unique.


WooCommerce edit Myaccount page navigation

Add this code in your theme function.php

function wc_limit_account_menu_items(){
 $items = array(
 // 'dashboard' => __( 'Dashboard', 'woocommerce' ),
 'orders' => __( 'Orders', 'woocommerce' ),
 // 'downloads' => __( 'Downloads', 'woocommerce' ),
 'edit-address' => __( 'Address', 'woocommerce' ),
 // 'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
 'edit-account' => __( 'Edit Account', 'woocommerce' ),
 // 'customer-logout' => __( 'Logout', 'woocommerce' )

 return $items;
add_filter( 'woocommerce_account_menu_items', 'wc_limit_account_menu_items' );

WordPress add error message on password protected page

WordPress stored the latest entered password  as a secure hash in a cookie named 'wp-postpass_' . COOKIEHASH.

When the password form is called, that cookie has been validated already by WordPress. So you just have to check if that cookie exists: If it does and the password form is displayed, the password was wrong.

add_filter( 'the_password_form', 'wpse_71284_custom_post_password_msg' );

 * Add a message to the password form.
 * @wp-hook the_password_form
 * @param string $form
 * @return string
function wpse_71284_custom_post_password_msg( $form )
 // No cookie, the user has not sent anything until now.
 if ( ! isset ( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) )
 return $form;

 // Translate and escape.
 $msg = esc_html__( 'Sorry, your password is wrong.', 'your_text_domain' );

 // We have a cookie, but it doesn’t match the password.
 $msg = "<p class='custom-password-message'>$msg</p>";

 return $msg . $form;

WooCommerce checkout template by hooks

 * Add a content block after all notices, such as the login and coupon notices.
 * Reference:
add_action( 'woocommerce_before_checkout_form', 'skyverge_add_checkout_content', 12 );
function skyverge_add_checkout_content() {
 echo 'This content that you can use to tell customers stuff. You could make it a div class="checkout-message" and style it if you wanted.';

 * Add a content in a notice instead. Let's add it before other notices with a priority = 9
 * Reference:
add_action( 'woocommerce_before_checkout_form', 'skyverge_add_checkout_success', 9 );
function skyverge_add_checkout_success() {
 wc_print_notice( __( 'A success message with high priority.', 'woocommerce' ), 'success' );

 * Add an info notice instead. Let's add it after other notices with priority = 11
 * Reference:
add_action( 'woocommerce_before_checkout_form', 'skyverge_add_checkout_notice', 11 );
function skyverge_add_checkout_notice() {
 wc_print_notice( __( 'A notice message instead.', 'woocommerce' ), 'notice' );

 * Add add a notice before the payment form - let's use an eror notice. Could also use content, etc.
 * Reference:
add_action( 'woocommerce_review_order_before_payment', 'skyverge_before_paying_notice' );
function skyverge_before_paying_notice() {
 wc_print_notice( __( 'An error message.', 'woocommerce' ), 'error' );

WooCommerce hide unavailable veriations from dorpdown

If there are greater than 20 variations in the product, it will use ajax to find matches and won’t hide combinations (because doing so would mean loading all variations before display).

Use is code in your functions.php

function custom_wc_ajax_variation_threshold( $qty, $product ) {
	return 10;

add_filter( 'woocommerce_ajax_variation_threshold', 'custom_wc_ajax_variation_threshold', 10, 2 );


Change the return value as per your number of combination.

Hide other shipping methods when FREE SHIPPING is available

 * woocommerce_package_rates is a 2.1+ hook
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
 * Hide shipping rates when free shipping is available
 * @param array $rates Array of rates found for the package
 * @param array $package The package array/object being shipped
 * @return array of modified rates
function hide_shipping_when_free_is_available( $rates, $package ) {
 	// Only modify rates if free_shipping is present
  	if ( isset( $rates['free_shipping'] ) ) {
  		// To unset a single rate/method, do the following. This example unsets flat_rate shipping
  		unset( $rates['flat_rate'] );
  		// To unset all methods except for free_shipping, do the following
  		$free_shipping          = $rates['free_shipping'];
  		$rates                  = array();
  		$rates['free_shipping'] = $free_shipping;
	return $rates;

Show only free shipping in all states except…

Show only free shipping in all states except exclusion list, hide free shipping if the customer is in one of the states listed:

 * Hide ALL shipping options when free shipping is available and customer is NOT in certain states
 * Hide Free Shipping if customer IS in those states
 * Change $excluded_states = array( 'AK','HI','GU','PR' ); to include all the states that DO NOT have free shipping
add_filter( 'woocommerce_package_rates', 'hide_all_shipping_when_free_is_available' , 10, 2 );

 * Hide ALL Shipping option when free shipping is available
 * @param array $available_methods
function hide_all_shipping_when_free_is_available( $rates, $package ) {
	$excluded_states = array( 'AK','HI','GU','PR' );
	if( isset( $rates['free_shipping'] ) AND !in_array( WC()->customer->shipping_state, $excluded_states ) ) :
		// Get Free Shipping array into a new array
		$freeshipping = array();
		$freeshipping = $rates['free_shipping'];
		// Empty the $available_methods array
		unset( $rates );
		// Add Free Shipping back into $avaialble_methods
		$rates = array();
		$rates[] = $freeshipping;
	if( isset( $rates['free_shipping'] ) AND in_array( WC()->customer->shipping_state, $excluded_states ) ) {
		// remove free shipping option
		unset( $rates['free_shipping'] );

	return $rates;

Enable Shipping Methods on a per Class / Product Basis

If you want to have more flexibility, we recommend you to use this free plugin!


Set, get and destroy cookies in WordPress

You can either retrieve and manipulate cookies on the server side using PHP or client side, using JavaScript.

In PHP, you set cookies using setcookie(). Note that this must be done before any output is sent to the browser which can be quite the challenge in WordPress. You’re pretty much limited to some of the early running hooks which you can set via a plugin or theme file

add_action('init', function() {
    // yes, this is a PHP 5.3 closure, deal with it
    if (!isset($_COOKIE['my_cookie'])) {
        setcookie('my_cookie', 'some default value', strtotime('+1 day'));

Retrieving cookies in PHP is much easier. Simply get them by name from the $_COOKIE super global’

$cookieValue = $_COOKIE['my_cookie'];

Unsetting a cookie requires setting one with an expiration date in the past, something like

setcookie('my_cookie', null, strtotime('-1 day'));