Jump to content

ClassLoader and custom PagesTypes.

Recommended Posts



I have been using a module approach to include my custom Pages Types and other classes that extend Page class. In PW 3.0.152 we got the ability to specify custom Page classes without modules or manual include.
So what I'm trying to do is basically load my custom pages types via classLoader.



<?php namespace ProcessWire;

class Products extends PagesType

	 * Construct the Products manager for the given parent and template
	 * @param Template|int|string|array $templates Template object or array of template objects, names or IDs
	 * @param int|Page|array $parents Parent ID or array of parent IDs (may also be Page or array of Page objects)
	public function __construct($templates = array(), $parents = array()) {
		parent::__construct($templates, $parents);

	public function dumbMethod() {
		return 'test';
// init.php
wire('classLoader')->addSuffix('PagesType', wire('config')->paths->classes);
$products = new Products();
wire('products', $products, true);

I get 

Fatal Error: Uncaught Error: Class 'Products' not found 

Autoload debug panel output:

 Advanced issue found
 Advanced issue found
Class File/Details
SystemUpdater Handled by modules loader
FieldtypeModule Handled by modules loader
FieldtypeRepeaterMatrix Handled by modules loader
FieldtypeText Handled by modules loader (via FieldtypeTextarea > FieldtypeTextarea)
FieldtypeTextarea Handled by modules loader
FieldtypeInteger Handled by modules loader
FieldtypeEmail Handled by modules loader
FieldtypeFieldsetOpen Handled by modules loader
FieldtypeFieldsetClose Handled by modules loader
FieldtypeFile Handled by modules loader
FieldtypeImage Handled by modules loader
FieldtypeURL Handled by modules loader
FieldtypeNotifications Handled by modules loader
FieldtypePassword Handled by modules loader
FieldtypePageHitCounter Handled by modules loader
FieldtypeTextareas Handled by modules loader
FieldtypeDatetime Handled by modules loader
FieldtypeFieldsetGroup Handled by modules loader
FieldtypeTextareaLanguage Handled by modules loader
FieldtypeTextLanguage Handled by modules loader
FieldtypePageTitleLanguage Handled by modules loader
FieldtypeToggle Handled by modules loader
DefaultPage Unable to locate file for this class
HomePage Unable to locate file for this class
AdminPage Unable to locate file for this class
RolePage Unable to locate file for this class
UserPage Unable to locate file for this class
FieldtypePageTitle Handled by modules loader
PagefilesManager /wire/core/PagefilesManager.php
PageAccess /wire/core/PageAccess.php
PermissionPage Unable to locate file for this class
WireInputDataCookie /wire/core/WireInputDataCookie.php
Debugger Unable to locate file for this class
InputfieldsArray /wire/core/InputfieldsArray.php
Pagefiles /wire/core/Pagefiles.php (via Pageimages)
Pageimages /wire/core/Pageimages.php
CategoryPage Unable to locate file for this class
CategoriesPage Unable to locate file for this class
InputfieldSelect Handled by modules loader (via InputfieldAsmSelect > InputfieldAsmSelect > InputfieldSelectMultiple > InputfieldSelectMultiple)
InputfieldSelectMultiple Handled by modules loader (via InputfieldAsmSelect > InputfieldAsmSelect)
InputfieldAsmSelect Handled by modules loader
JqueryCore Handled by modules loader
JqueryUI Handled by modules loader
InputfieldText Handled by modules loader
InputfieldEmail Handled by modules loader
InputfieldTextarea Handled by modules loader (via InputfieldCKEditor > InputfieldCKEditor)
InputfieldCKEditor Handled by modules loader
WireDebugInfo /wire/core/WireDebugInfo.php
ProcessPageView Handled by modules loader
ProductPage /site/classes/ProductPage.php
ProductsPage Unable to locate file for this class
MarkupSrcSet Handled by modules loader
FileLog /wire/core/FileLog.php
TextformatterEntities Handled by modules loader
Pagefile /wire/core/Pagefile.php (via Pageimage)
Pageimage /wire/core/Pageimage.php
ImageSizer /wire/core/ImageSizer.php
ImageSizerEngine /wire/core/ImageSizerEngine.php
MarkupQA /wire/core/MarkupQA.php
MenuPage Unable to locate file for this class
SalesPage Unable to locate file for this class
BasicPagePage Unable to locate file for this class
BlogPage Unable to locate file for this class
PartnersPage Unable to locate file for this class
ContactsPage Unable to locate file for this class
SearchPage Unable to locate file for this class
WireTextTools /wire/core/WireTextTools.php
Imagick Unable to locate file for this class
PageimageDebugInfo /wire/core/PageimageDebugInfo.php
PageimageVariations /wire/core/PageimageVariations.php
MenusPage Unable to locate file for this class


What I'm doing wrong? 

Share this post

Link to post
Share on other sites

Is your init.php in the ProcessWire namespace? The error seems to indicate that you're trying to load the Products class in the global namespace instead of ProcessWire\Products.

In this case, you can fix this by adding the ProcessWire namespace to your init.php, importing the Products class or using the fully-qualified class name:

$products = new \ProcessWire\Products();


  • Like 1

Share this post

Link to post
Share on other sites

@MoritzLost Thanks for the answer.

You are right, I forgot to set namespace in init.php

But it doesn't help, nom I get error

Class 'ProcessWire\Products' not found

I went through WireClassLoader.php and from findClassInPaths method in looks like the class name should be the same as its filename. 

So, I changed ProductsPagesType.php to 

class ProductsPagesType extends PagesType

and then if I call it will work

$products = new ProductsPagesType();
wire('products', $products, true);

But I want to use "Products" and not "ProductsPages" or "ProductsPagesType" as classname and it look like the only way to do it via classLoader is to load it maually 


In this case even if classname is not equal to its filename like

// ProductsPagesTypes.php

class Products extends PagesType

it will load it and I this code will work

$products = new Products();
wire('products', $products, true);

Am I right or I missed something? 

Share this post

Link to post
Share on other sites

The class files should always be named the same as the class by convention, yes. So either use ProductsPagesType -> ProductsPagesType.php or Products -> Products.php. This is in accordance with PSR-4, but it's also just for your sanity. If you want to find something when you come back to this project after some time, having a direct mapping between the class namespace & classname and the folders / files they're located in will be a huge timesaver in finding what you're looking for. Especially if you start to use sub-namespaces.

If you want to use Products as your classname, why not just name the file Products.php as well?

I don't completely understand what classLoader->addSuffix does by it's documentation, but you could just go the easy route and add your classes directory to the autoloader for the ProcessWire namespace:

wire('classLoader')->addNamespace('ProcessWire', '/path/to/classes/');

This way you don't have to load classes manually and can add as many as you want.

I don't know how this all interacts with the page classes support in 3.0.152, but the autoloader stuff should work in any case. By the way, the PagesType is an older feature, the new classes directory is for custom Page types, not PagesType classes as far as I understood it ... maybe that's why ProcessWire is not loading your classes correctly.

Hope this helps!

  • Like 3

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...