An example plugin for WordPress, using good practices and Composer.
- A basic WordPress plugin entrance file, to keep things concise
- An object oriented plugin design
- Takes advantage of PHP7 hinting (some areas don't use it, but can easily be added)
- Helpers for connecting to a PDO capable database. Currenly, it is assumed it is a MySQL database, so if you want other database engines, you might need to subclass / add custom support.
- Helpers for loading .ini, .json, .js, .css, and various other file handling
- Hooks and actions that this plugin can hook to AND provide for OTHER plugins to hook
- Custom plugin roles/capabilities that are added to WordPress to be used for plugin authorization.
- A rudimentary ORM using a base class and common column/field naming in a class
- Support for i18n localization with a PHP helper class, and output of localization data (and loading of i18n with helper functions for JavaScript)
- A basic enum class to simulate Enums, as PHP doesn't natively support them.
- A SQL loading class, for handling SQL files. This currently ONLY supports MySQL syntax / escaping, but it can be subclassed / extended to add other languages.
- A rudimentary template system, with an implicit data loading PHP for each page via a page template
- Management of plugin generated pages, CSS, JS, dependencies on other WordPress plugins, and plugin integrity checks
- STRONGLY uses the WordPress lifecycle for plugin operations
- Adds support for SRI for JS / CSS that WordPress doesn't support natively (as far as I can tell)
- Has a function to easily hide assets uploaded to wp_content from the normal WordPress Media Gallery
- Custom CSS / JS script tag output functions, to include SRI and other cross-origin attributes.
- Includes Helpers for AWS S3 and RDS usage
- A class for managing WordPress options for this plugin
- Organization for AJAX endpoints (admin and user-side), data structures, and easy way to generate responses with/without a nonce
- A utility functions class with various helpful functions
- A TypeScript JavaScript module for the plugin
- Setup for RequireJS module loader
- Includes an object-oriented jQuery widget module, for easy widget creation
- Uses
yarn
Node package manager (improves upon NPM). More info about yarn here.
You can find a document with the project structure here.
- User Role Editor by Vladimir Garagulya - For managing roles of users, and allowing multiple roles to be assigned. If you don't use these, this cna be removed, but then you will only be able to assign ONE user role to a WordPress user.
- WordPress will always load the entrance file for this plugin whenever this plugin has a "context" (showing in the plugins menu, installing, activating, admin menus, pages, etc)
- Due to the above, the "require" directive for the composer autoloader will always be present for any file of the plugin (assuming normal WordPress lifecycle of course)
- When adding dependencies using composer, make sure to call
composer dump-autoload
to refresh the autoloader - When adding your own files, ensure PHP files are named EXACTLY as the class name, or the autoloader won't find the class file
- Add namespaces in composer.json for directories / new files you want to include in the plugin
- You can optimize the autoloader and force it to build a classmap and only use a classmap for loading of class files
- Further usage tips / instruction for composer can be foudn on the official site.
- You should test your compilation of TypeScript in your IDE when deploying / making changes. You might need to configure / reference the TypeScript library/compiler to enable support if the IDE doesn't support it out-of-the-box.
- I currently have used YUICompressor for CSS and UglifyJS for JS minifictaion. There are likely newer tools, as both of these are likely not as robust.
- There IS a bug with YUICompressor and
calc
usage in CSS. If you have a statement like the following:calc(50% + 15px)
it will INCORRECTLY minify it tocalc(50%+15px)
which will fail to execute in the browser (the + needs spaces). You can "fix" this by subtracting a negative, eg:calc(50% - -15px)
and it'll honor the spacing. The bug is documented here. - There IS a bug with YUICompressor that will incorrectly minify transform and animation states. I haven't found a good fix without much manual work, but the bug is documented here.
- These bugs are VERY UNLIKELY to be fixed, so other minifier tools are likely the best option, i just put up with these for this project to avoid too many distractions.
- A common error with this is when you load a JS file AFTER requireJS, using a standard script tag. This can cause an exception because the module is loaded in a way that bypasses the module loader. This is documented here and usually has the message of
Error: Mismatched anonymous define() module:
. - Ensure that no extra imports are done BEFORE the requirejs method call when loading modules (ONLY modules should use imports - not script tags). Sometimes the IDE can add these automatically if it's "trying" to be helpful, so check this first.
- Ensure WordPress or other plugins/etc aren't loading files AFTER your scripts. This can be done with a special function to ensure your "enqueue scripts" function is called last in the chain in the footer. This is already used by the plugin here.