To get with the time and improve my coding practices, I’m starting to implementing namespaces in my own plugins moving forward since there are some advantages, such as eliminating ambiguity.
I found a similar question to help me set up my plugin template which worked for me. However, I’ve since modified it slightly. This is my setup:
In wp-plugin-template/wp-plugin-template.php
:
<?php
/**
* Plugin Name: WP Plugin Template
*/
# If accessed directly, exit
if ( ! defined( 'ABSPATH' ) ) exit;
# Call the autoloader
require_once( 'autoloader.php' );
use PluginTemplate\admin\Plugin_Meta;
new Plugin_Meta;
In wp-plugin-template/autoloader.php
:
<?php
spl_autoload_register( 'autoload_function' );
function autoload_function( $classname ) {
$class = str_replace( '\\', DIRECTORY_SEPARATOR, str_replace( '_', '-', strtolower($classname) ) );
# Create the actual file-path
$path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $class . '.php';
# Check if the file exists
if ( file_exists( $path ) ) {
# Require once on the file
require_once $path;
}
}
In wp-plugin-template/admin/plugin-meta.php
:
<?php
namespace PluginTemplate\admin;
class Plugin_Meta {
public function __construct() {
add_action( 'plugins_loaded', array($this, 'test' ) );
}
public function test() {
echo 'It works!';
}
}
When I try to activate the plugin template for testing, I get the following error:
Fatal error: Class
PluginTemplate\admin\Plugin_Meta
not found inwp-content/plugins/wp-plugin-template/wp-plugin-template.php
on line 11
In this case, line 11 is:
new Plugin_Meta;
I think this is due to me having the namespace named PluginTemplate
? What am I doing wrong? Just to reiterate, the previous question that I mentioned worked for me before I started to rename my files and directories.
2 Answers
The problem is with your Autoloader set-up. You need to convert your Camelcase namespacese to dashes for locating files as per your current folder structure.
I have added convert function and updated your autoloader function.
In wp-plugin-template/autoloader.php
:
<?php
spl_autoload_register( 'autoload_function' );
function autoload_function( $classname ) {
$class = str_replace( '\\', DIRECTORY_SEPARATOR, str_replace( '_', '-', strtolower(convert($classname)) ) );
# Create the actual file-path
$path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $class . '.php';
# Check if the file exists
if ( file_exists( $path ) ) {
# Require once on the file
require_once $path;
}
}
function convert($class){
$class = preg_replace('#([A-Z\d]+)([A-Z][a-z])#','\1_\2', $class);
$class = preg_replace('#([a-z\d])([A-Z])#', '\1_\2', $class);
return $class;
}
Also you have to update your top level namespace to WpPluginTemplate
in both wp-plugin-template.php
and admin/plugin-meta.php
as you are using wp-plugin-template as your plugin folder name.
UPDATE:
When autoloader tries to find Plugin_Meta
class, it will look into YOUR_PLUGIN_DIR/wp-plugin-template/admin/plugin-meta.php
In wp-plugin-template.php
<?php
/**
* Plugin Name: WP Plugin Template
*/
# If accessed directly, exit
if ( ! defined( 'ABSPATH' ) ) exit;
# Call the autoloader
require_once( 'autoloader.php' );
use WpPluginTemplate\admin\Plugin_Meta;
new Plugin_Meta;
In wp-plugin-template/admin/plugin-meta.php
<?php
namespace WpPluginTemplate\admin;
class Plugin_Meta {
public function __construct() {
add_action( 'plugins_loaded', array($this, 'test' ) );
}
public function test() {
echo 'It works!';
}
}