8

WP Core Handbook > PHP Coding Standards > Naming Conventions suggests the following for naming files with classes:

Class file names should be based on the class name with class- prepended and the underscores in the class name replaced with hyphens, for example WP_Error becomes:

class-wp-error.php

While from the wording of the section it's primarily intended for core use, the coding style overall commonly does (and should in my opinion) apply to third party WP code.

However since core doesn't support namespaces (PHP 5.2, ugh) this doesn't account for such case.

What is the practical way to go for it from the perspectives of developer convenience? Support of autoloaders?

I could see multiple alternative ways:

  • ignoring namespace altogether
  • including namespace in file name
  • using namespaces as folder levels
  • using alternate naming scheme altogether, such as PSR
  • 3
    My honest opinion is that if you use PHP 5.3+ you are already violating WP core rules. Moreover consider that WP standards don't take into account interfaces or traits. So to me just make sense to pick a way that is convenient for you and to use an already established standard like PSR seems better choice in that case. – gmazzap Oct 27 '14 at 12:07
6

First, ignore the class- prefix. This comes from WordPress’ pure procedural code approach, classes are used as containers for procedural code, not for real objects, and most files do not contain classes at all or classes and other code together. It doesn’t make sense when all of your files contain just one class and nothing else.
If you would follow that pattern you would have to use interface-foo.php and trait-bar.php. That doesn’t just look ridiculous, it makes the auto-loading harder than necessary.

The easiest way to separate namespaces and class/interface/trait names is (by my experience) assigning namespaces to directory names and class names to file names. This makes it very easy to map the requested class to a given file structure in the auto-loader: Just convert \ to /, append .php and load the file.

This makes it also easy to cache the look-ups: for every directory/namespace you can fetch all existing files the first time that directory is requested, and for later calls you can take the reuse that list of file names without asking for file_exists() every time.

  • 4
    In other words: Make it PSR compatible :) – kaiser Oct 27 '14 at 12:15
2

I've made a class for this requirement, compatible with PSR-4 and following Wordpress coding standards.

You can reach it here: https://github.com/pablo-pacheco/wp-namespace-autoloader

The explanation is all there but basically it's a composer dependency. You just have to require it in your project:

"require": {    
    "pablo-pacheco/wp-namespace-autoloader": "dev-master"
}

And then call the class

<?php
new \WP_Namespace_Autoloader( array(    
    'directory'   => __DIR__,       // Directory of your project. It can be your theme or plugin. __DIR__ is probably your best bet.    
    'namespace'   => __NAMESPACE__, // Main namespace of your project. E.g My_Project\Admin\Tests should be My_Project. Probably if you just pass the constant __NAMESPACE__ it should work     
    'classes_dir' => 'src',         // (optional). It is where your namespaced classes are located inside your project. If your classes are in the root level, leave this empty. If they are located on 'src' folder, write 'src' here 
) );
1

I am generally going with the second half of your options:

  • using namespaces as folder levels
  • using alternate naming scheme altogether, such as PSR

If you use composer to register a PSR-4 autoloader you can stay close to WP naming conventions. Namespaces mapped to folder(s) that can contain underscores with files named like the class which can also contain underscores. Like:

<Namespace_Dir>/Class_Name.php

When WP moves on to php 5.3+ (it has to happen eventually, right?!) the guidelines need to be updated. Since PSR-0 is already deprecated PSR-4 should be at least recommended if not required.

0

pablo-s-g-pacheco's solution worked for me, autoloading relying on composer yet compatible with WordPress coding standards, however the url for the Github repo is:

https://github.com/pablo-sg-pacheco/wp-namespace-autoloader

and the package name is:

"require": {    
    "pablo-sg-pacheco/wp-namespace-autoloader": "dev-master"
}

Finaly, you will also need to add the following to your composer.json because the package is not available on packagist:

"repositories": [{
    "type": "vcs",
    "url": "https://github.com/pablo-sg-pacheco/wp-namespace-autoloader"
}] 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.