Archives: Snippets | Page 12

WordPress .gitignore File

The .gitignore file tells Git not to track certain files in the project. For WordPress, here is a recommended .gitignore file you can modify for your project. For more on the mu-plugins directory included in the file, see the linked guide.

# -----------------------------------------------------------------
# .gitignore for WordPress
# -----------------------------------------------------------------

# ignore everything in the root except the "wp-content" directory.
/*
!wp-content/

# ignore all files starting with .
.*

# track this file .gitignore (i.e. do NOT ignore it)
!.gitignore

# track .editorconfig file (i.e. do NOT ignore it)
!.editorconfig

# track readme.md in the root (i.e. do NOT ignore it)
!readme.md

# ignore all files that start with ~
~*

# ignore OS generated files
ehthumbs.db
Thumbs.db

# ignore Editor files
*.sublime-project
*.sublime-workspace
*.komodoproject

# ignore log files and databases
*.log
*.sql
*.sqlite

# ignore compiled files
*.com
*.class
*.dll
*.exe
*.o
*.so

# ignore packaged files
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# ignore everything in the "wp-content" directory, except:
# "mu-plugins" directory
# "plugins" directory
# "themes" directory
wp-content/*
!wp-content/mu-plugins/
!wp-content/plugins/
!wp-content/themes/

# ignore these plugins from the core
wp-content/plugins/hello.php
wp-content/plugins/akismet/

# ignore specific themes
wp-content/themes/twenty*/

# ignore node/grunt dependency directories
node_modules/

Set Permalink Structure from functions.php

I do not see a reason you would want to do this, but you can set the WordPress permalink structure via code. To do this, add the following code to your theme’s functions.php file and change the permalink structure as needed:

function set_permalink(){
     global $wp_rewrite;
     $wp_rewrite->set_permalink_structure('/%year%/%monthnum%/%postname%/');
}
add_action('init', 'set_permalink');

Note that mod_rewrite must be active on the server in this case as well.

More on WordPress permalink structure in this post: Choosing the best permalink structure for SEO.

Display Tag Cloud in WordPress Templates

Although we see less and less use of tag clouds on WordPress sites, here is how to add one using code in WordPress templates. This is the same tag cloud that appears in the widgets area of the WordPress admin.

Add the following code where you want in your template and change the parameters as needed:

<?php wp_tag_cloud(array(
     'smallest' => 10, // size of least used tag
     'largest' => 18, // size of most used tag
     'unit' => 'px', // unit for sizing
     'orderby' => 'name', // alphabetical
     'order' => 'ASC', // starting at A
     'exclude' => 6 // ID of tag to exclude from list
     ));
?>

For more on tags and taxonomies, see Taxonomies in WordPress.

Show Post Thumbnails in RSS Feed

If you want to display the post featured image in the RSS feed (essential if you use RSS for Mailchimp for example), add the following code to your functions.php file:

// Put post thumbnails into rss feed
function savvy_feed_post_thumbnail($content) {
    global $post;
    if(has_post_thumbnail($post->ID)) {
        $content = '' . $content;
    }
    return $content;
}
add_filter('the_excerpt_rss', 'savvy_feed_post_thumbnail');
add_filter('the_content_feed', 'savvy_feed_post_thumbnail');

Change Payment Icons on WooCommerce Checkout

Here is an example of how to change the default PayPal icon on the WooCommerce checkout page. Live example:

<?php
/**
 * Add custom gateway icons
 * 
 * @param  string $icon       Image HTML.
 * @param  string $gateway_id Gateway ID.
 * 
 * @return string
 */
function custom_wc_gateway_icons( $icon, $gateway_id ) {
	// Example for PayPal:
	if ( 'paypal' == $gateway_id ) {
		$icon = '<img src="' . WC_HTTPS::force_https_url( 'http://your-site.com/image.png' ) . '" alt="' . __( 'PayPal' ) . '" />'
	}
	return $icon;
}
add_filter( 'woocommerce_gateway_icon', 'custom_wc_gateway_icons', 10, 2 );

For a complete WooCommerce setup guide, see Create a Virtual Store with WooCommerce.

Change Number of Items on WooCommerce Orders Page

To change the number of items on the WooCommerce orders page (on the front end), use the following code where X is the maximum number of items to display (functions.php):

function custom_my_account_orders( $args ) {
    $args['posts_per_page'] = X;
    return $args;
}
add_filter( 'woocommerce_my_account_my_orders_query', 'custom_my_account_orders', 10, 1 );

More on managing and handling orders in WooCommerce sites in the post Managing orders in WooCommerce.

Add a Link to Yoast SEO Breadcrumbs

The wpseo_breadcrumb_links filter lets you add, remove or reorder items in the Yoast SEO breadcrumbs trail. A common case is adding a link to the blog right after the Home link on single posts, so the trail reads Home › Blog › Post title.

To remove the breadcrumb structured data instead, see remove Yoast breadcrumbs schema. To turn off all of Yoast’s schema, see disable Yoast SEO schema.

The Code

Add this to your child theme’s functions.php file or to a custom plugin. Change the URL and text to match your blog page:

function yoast_seo_breadcrumb_append_link( $links ) {
    if ( ! is_singular( 'post' ) ) {
        return $links;
    }

    $breadcrumb[] = array(
        'url'  => home_url( '/blog/' ),
        'text' => 'Blog',
    );

    array_splice( $links, 1, 0, $breadcrumb );

    return $links;
}
add_filter( 'wpseo_breadcrumb_links', 'yoast_seo_breadcrumb_append_link' );

How It Works

Yoast passes the whole trail to wpseo_breadcrumb_links as an array, just before it renders it. Index 0 is the Home link and the last item is the current page.

Each item is an array with url and text. Yoast adds an extra key that tells you what the item is: id for posts and pages, term_id and taxonomy for terms, and ptarchive for post type archives.

array_splice( $links, 1, 0, $breadcrumb ) inserts the new item at position 1, right after Home, without removing anything. The third argument must be 0. Any other value, such as -2, silently deletes items from longer trails.

The is_singular( 'post' ) check limits the change to blog posts. Without it, the Blog link would also show up on the home page, on regular pages and on archives.

The same array feeds both the visible trail and Yoast’s BreadcrumbList schema, so your new item appears in the structured data too.

Check the Built-in Setting First

If the homepage is a static page and a Posts page is set under Settings > Reading, you may not need code at all.

Under Yoast SEO > Settings > Advanced > Breadcrumbs, Show blog page in breadcrumbs adds that page to the trail on single posts.

Use the filter when there’s no Posts page (for example, a blog index built as a custom page template), or when you need a link the settings don’t offer.

More wpseo_breadcrumb_links Examples

This version adds a hub page before the current item on a custom post type. A negative offset counts from the end, so -1 puts it right before the last crumb:

add_filter( 'wpseo_breadcrumb_links', function( $links ) {
    if ( ! is_singular( 'snippet' ) ) {
        return $links;
    }

    $new_crumb = array(
        array(
            'url'  => home_url( '/resources/' ),
            'text' => 'Resources',
        ),
    );

    array_splice( $links, -1, 0, $new_crumb );

    return $links;
} );

This one removes category crumbs from the trail:

add_filter( 'wpseo_breadcrumb_links', function( $links ) {
    foreach ( $links as $i => $link ) {
        if ( isset( $link['taxonomy'] ) && 'category' === $link['taxonomy'] ) {
            unset( $links[ $i ] );
        }
    }
    return array_values( $links );
} );

A few rules keep the filter safe:

  • Always return an array. Anything else is ignored, and Yoast logs a “doing it wrong” notice.
  • Give every item both url and text. If one is missing, Yoast drops the BreadcrumbList schema for that page.
  • Yoast prints text as-is, so wrap dynamic values like post titles in esc_html().

For a broader look at breadcrumb options, read how to add breadcrumbs to WordPress sites. The filter itself is defined in Yoast’s breadcrumbs generator source.

FAQs

Common questions about the wpseo_breadcrumb_links filter:

Does wpseo_breadcrumb_links change the breadcrumb schema too?
Yes. Yoast builds both the HTML trail and the BreadcrumbList JSON-LD from the filtered array. Filters like wpseo_breadcrumb_single_link and wpseo_breadcrumb_output only change the HTML.
Is there a Yoast breadcrumbs shortcode?
Yes, [wpseo_breadcrumb]. In PHP templates use yoast_breadcrumb( '<p id="breadcrumbs">', '</p>' ), which only prints when "Enable breadcrumbs for your theme" is on or the theme declares support for it. The filter applies to all of them.
Why is my new breadcrumb item not showing?
Check that your condition matches the page (for example is_singular( 'post' ) won't run on pages), that the function returns $links, and purge any page cache. Also confirm the trail on the page actually comes from Yoast and not from your theme or WooCommerce.

Increase Maximum Execution Time in WordPress

“Maximum execution time of 30 seconds exceeded” means a PHP script ran longer than the max_execution_time setting allows. In WordPress it usually hits during updates, imports and backups.

Below are the ways to increase max_execution_time and how to tell which one your server honors. For a quick fix of the error itself, see Fix Maximum Execution Time Exceeded in WordPress.

Check the Current Value First

Go to Tools > Site Health > Info and open the Server section.

  • PHP time limit is the current max_execution_time in seconds.
  • PHP SAPI tells you which method will work: apache2handler is Apache mod_php, fpm-fcgi is PHP-FPM, litespeed is LiteSpeed.

Recheck this screen after each change to confirm PHP picked up the new value.

Increase max_execution_time in WordPress

Pick the method that matches your PHP SAPI. The examples use 300 seconds, the limit WordPress core sets for itself during updates.

1. wp-config.php (works on any server)

Add this to wp-config.php, above the /* That's all, stop editing! */ line:

if ( function_exists( 'set_time_limit' ) ) {
	set_time_limit( 300 );
}

Keep the function_exists() check. Since PHP 8, a function blocked with disable_functions counts as undefined, so a bare call crashes the site on hosts that disable it.

2. .user.ini (PHP-FPM and CGI)

On PHP-FPM, the most common setup today, create a .user.ini file next to wp-config.php:

max_execution_time = 300
max_input_time = 300

PHP rereads this file every 5 minutes by default (user_ini.cache_ttl), so the change may not show immediately.

3. .htaccess (Apache mod_php or LiteSpeed)

Back up .htaccess first, then add this line:

php_value max_execution_time 300

This only works with Apache mod_php or LiteSpeed. On Apache with PHP-FPM, php_value is an unknown directive and the site returns a 500 error, so remove it and use .user.ini.

4. php.ini (VPS or dedicated server)

If you control the server, set it in php.ini and restart PHP-FPM or Apache. On shared hosting, use the PHP settings screen in your control panel.

max_execution_time = 300

How max_execution_time Works

The directive caps how many seconds a script may run (30 by default). Calling set_time_limit() changes the limit at runtime and restarts the counter from zero.

On Linux, standard PHP builds count only the script’s own execution time. Database queries and remote API calls don’t count, so a request can run past 30 seconds without this error.

max_input_time is the separate limit for parsing request input such as POST data and uploads. Its default of -1 means it uses max_execution_time. It can’t be changed with set_time_limit() or ini_set(), only in .user.ini, .htaccess or php.ini.

When Raising the PHP Limit Isn’t Enough

If long requests still die after raising the limit, another layer is cutting them off, usually with a 502, 504 or 524 error.

  • PHP-FPM’s request_terminate_timeout kills the worker after a set time. It’s off by default, but many hosts enable it.
  • Nginx’s fastcgi_read_timeout defaults to 60 seconds.
  • Cloudflare returns a 524 if the origin doesn’t respond within 125 seconds on non-Enterprise plans.

Your host has to raise these. For one-off heavy jobs, use WP-CLI instead: on the command line max_execution_time defaults to 0, meaning no limit.

WP-Cron runs as a web request, so web limits apply. For long scheduled tasks, disable WP-Cron and use a real server cron job that runs wp cron event run --due-now.

See also Optimizing WordPress configuration with wp-config.php and the directive reference in the PHP manual.

FAQs

Common questions about the PHP time limit in WordPress:

What is the default max_execution_time in WordPress?
WordPress doesn't set a global value. It inherits the PHP setting, which defaults to 30 seconds, though many hosts use 60 to 300. Core raises the limit temporarily with set_time_limit() during updates.
Why doesn't php_value max_execution_time in .htaccess work?
php_value is only understood by Apache mod_php and LiteSpeed. On PHP-FPM it causes a 500 error. Check PHP SAPI in Site Health and use .user.ini if it says fpm-fcgi.
How do I increase max_input_time in WordPress?
Set max_input_time = 300 in .user.ini or php.ini, or php_value max_input_time 300 in .htaccess on mod_php. It can't be changed from wp-config.php because PHP doesn't allow it at runtime.
Can I set max_execution_time to 0?
Yes, 0 removes the PHP limit, but a stuck script can then hold a PHP worker until a server timeout kills it. A finite value like 300 is safer on a live site.