Ways to custom WordPress with PHP code

If you want to custom function of WordPress itself, an existing plugin, or the current using theme, there are two ways — a child theme or creating your own plugin.

Do custom in a child theme is easy, just drop your code in its functions.php file.

If you are not using a child theme or your work is not related to theme, then you may write your own plugin to do that. It is pretty simple.

Note, directly making changes to the source code is a bad idea. They mess the code and once the source code gets updated, your changes get lost or the update may fail for file permissions.

Before you start

No matter either way you use, it is important to prefix your functions or define them inside a class to avoid same name conflicts.

Create your own plugin

Here is how to create a new plugin.

Create a plugin folder named my-plugin-example in your local site’s plugins folder.

Inside the folder, create a file with the same name as the folder.

my-plugin-example.php may looks like this:

<?php
/*
 * Plugin Name: My plugin example
 * Description: A plugin to do some custom.
 * Author: Gloomic
 * Version: 0.1
 */

if ( ! defined( 'WPINC' ) ) {
    die( 'No direct access.' );
}


// Your code

If you want to publish your plugin some day, you can add more meta information, like

<?php
/*
 * Plugin Name: My plugin example
 * Description: A plugin to do some custom.
 * Author: John
 * Version: 0.1
 * Author URI: https://myexample.com
 * License: GPLv2
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 */

Test it in your local site to make sure every thing is fine, then transfer it to your real site.

An example to customize an existing plugin

If there is a filter for you to do the custom, just add your callback to the filter. You can also remove a function registered to a filter or action hook.

Note if you want to remove a function registered to a hook, you need to make sure your code run after the function has been registered. You can not remove a function which has not been registered yet.

Here is an example.

There is a function registered to an action by a plugin with some code like:

add_action('wp_head', 'print_emoji_script', 7);

You want to remove the function. Then you can do that in the plugins_loaded action:

function mycustom_disable_emoji() {
    // Note use the exact priority used when adding
    // the original action callback.
    remove_action('wp_head', 'print_emoji_script', 7);
}
add_action('plugins_loaded', 'mycustom_disable_emoji');

plugins_loaded action hook fires once activated plugins have loaded. Therefore when my_disable_emoji runs, the print_emoji_script has been registered.

Note

The plugins_loaded action hook fires early, and precedes the setup_themeafter_setup_themeinit and wp_loaded action hooks. If print_emoji_script is registered by a theme, then you need to remove it in an action that fires later like init.

add_action('init', 'mycustom_disable_emoji');

More examples:

Resource

Removing the canonical URLs in WordPress

The canonical tag specifies a URL to indicate the original page URL if there are multiple pages (or URLs) of the same content. Its purpose is to help the search engines to index only the original pages. Some SEO plugins like Yoast, it generates a self-referencing URL in a canonical tag on your all pages.

Issues of putting a canonical tag across all pages

Most of the time, putting a canonical tag in all pages does not cause problems because search engines like Google can handle that fine. But that is not a good idea for Bing.

Bing may refuse to index a page that has a canonical URL pointing to itself because it considers the page as a duplicated one as below. Even Bing used to index that page before.

URL cannot be indexed by Bing

The URL is not indexable as the page is an alternate version
of the similar page which you have specified as canonical version
using a  ``tag. Bing does not index the
alternate version.

Note

If your site is removed from Bing index, get more ideas about how to fix it at Bing Webmaster Guidelines (Updated in 2020).

1. Remove the canonical URLs added by Yoast

The canonical URLs can be generated by the WordPress or/and an SEO tool like Yoast. Newer version of Yoast (like v19.0) generates a canonical tag with a class property which looks like:

<link rel="canonical" href="http://example.com/a/" 
  class="yoast-seo-meta-tag">

Yoast allows you to edit the canonical URL on a page. But if you do not want Yoast put a canonical tag on all pages, you need to remove all of them programmatically.

Yoast SEO provides the wpseo_canonical filter (old version like v13.4 use ) for you to custom the function which returns the canonical URL of a page (see Yoast SEO Canonical URLs API). To remove the canonical URLs, you can add your own callback that returns NULL to the filter like:

function no_canonical_url () {
    return NULL;
}

add_filter( 'wpseo_canonical', 'no_canonical_url' );

Or

add_filter( 'wpseo_canonical', '__return_false' );

__return_false is a WordPress API which just returns false, note there are double _ at the beginning.

Note

Old version of Yoast does not provide such a filter for you to custom. Like Yoast v13.4.1 directly generates a canonical tag with below code:

add_action( 'wpseo_head', [ $this, 'canonical' ], 20 );

In such case, you can use remove_action() to remove the callback for wpseo_head action like:

remove_action( 'wpseo_head', 
    [ WPSEO_Frontend::get_instance(), 'canonical' ], 20 );

However, directly make changes in the the Yoast’s folder is not a good idea. If Yoast gets updated, the changes will be lost. For the moment, the best way to custom a plugin is to write a new plugin in which you can make customization to the original plugin. See more at Ways to custom WordPress .

Here is the plugin file looks like:

remove-canonical-urls.php

<?php
/*
 * Plugin Name: Remove Canonical URLs
 * Description: A plugin to remove the canonical URLs genereated by Yoast. SEO
 * Author: Gloomic
 * Version: 0.1
 */

if ( ! defined( 'WPINC' ) ) {
    die( 'No direct access.' );
}

// Custom Yoast's function which generates a canonical URL tag
// to make Yoast not genretate canonical URLs.
add_filter( 'wpseo_canonical', '__return_false' );

Create a folder with the same name remove-canonical-urls under your site’s plugins folder then active the plugin.

Or you can either put it the functions.php of a child theme if you are using one.

2. Remove the canonical URLs added through get_canonical_url hook

WordPress’s get_canonical_url filter hook filters the canonical URL for a post.

It is much similar to that described in the previous section.

add_filter( 'get_canonical_url', '__return_false' );

Similarly, put your code in a child theme or your own plugin.

Resource

  • Yoast SEO Canonical URLs – API documentation

  • Filter get_canonical_url

    Filters the canonical URL for a post.

  • Early in 2011, Duane Forrester from Bing has said:

    > “Something else you need to keep in mind when using the rel=canonical is that it was never intended to appear across large numbers of pages. We’re already seeing a lot of implementations where the command is being used incorrectly.”

Exporting data to csv in WordPress with PHP

In WordPress plugin development, sometimes you may need to export data to a csv file. Here we share how to implement it with PHP code.

How to export a csv file with PHP code

header() is used to send a raw HTTP header. To export a generated csv file, use below headers to tell the browser display a save dialog.

header( 'Content-Type: text/csv' ); // Supply the mime type
header( 'Content-Disposition: attachment; filename="downloaded.pdf"' ); // Supply a file name to save

Note:

There is not official RFC document for CSV files. text/csv is not a standard mime type, but it is more clear and works fine. application/octet-stream can also be used for csv files. However it is a very generous and it does not hint which application should be used to open the file.

Use two more headers to tell the content should not be cached by browser or any caches between the server and the browser.

header( "Cache-Control: no-cache, must-revalidate" );
header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // Date in the past

Then echo the generated csv content directly:

echo $csv;
exit;

Note:

Any actual content must be output after header(). One common error is outputting content before header() by include or require a file. See more about header().

Example: Export data to csv in WordPress

Below is the full example which exports a table-like data to a CSV file for the user to download.

Add an export button in an page, below code adds a button for an admin page:

<a href="admin.php?page=export_example&export=table&noheader=1">Export</a>

Don’t forget to replace the page=export_example to your own page on which you want to do data exporting. The last two parameters in the URL:

  • export=table, it is used to tell the PHP code in the page to do the export. In this example, the code displayed below will check it and then do the CSV exporting. You can replace it with your own as long as you replace the parameter in the code as well.

  • nohead=1 Note without noheader parameter, the CSV content will directly be printed and there will be no Save dialog box popping up in the browser.

In the same page, we process the export in the start of the file as below:

<?php
$table_head = array( 'column1', 'column2', 'column3' );
$table_body = array(
    array( 'a', 'b', 'c' ),
    array( 'd', 'e', 'f' )
);

// Process export
if( isset( $_GET['export'] ) ) {
    $csv = implode( $table_head, ',' );
    $csv .= "n"; // important! Make sure to use use double quotation marks.
    foreach( $table_body as $row ) {
        $csv .= implode( $row, ',' );
        $csv .= "n";
    }

    $filename = 'table.csv';
    header( 'Content-Type: text/csv' ); // tells browser to download
    header( 'Content-Disposition: attachment; filename="' . $filename .'"' );
    header( 'Pragma: no-cache' ); // no cache
    header( "Expires: Sat, 26 Jul 1997 05:00:00 GMT" ); // expire date

    echo $csv;
    exit;
}
?>
<a href="admin.php?page=export_example&export=table&noheader=1">Export</a>

For simplicity, we export a simple two-dimensional data with columns ['column1', 'column2', 'column3'], and 2 rows ['a', 'b', 'c'], ['d', 'e', 'f']. In the practical situation, you may need to export data from a database or a table HTML element which contains the data.

This example works well on Firefox, IE, Chrome.

Export data with Unicode characters to utf-8 bom csv

If your data contains Unicode characters, you may want to export a utf-8 bom csv that Excel will read properly. To achieve that, just output the BOM mark before data:

echo "xEFxBBxBF"; // UTF-8 BOM
echo $csv;
exit;