{"id":51110546,"url":"https://github.com/newfold-labs/wp-module-loader","last_synced_at":"2026-06-24T17:01:47.659Z","repository":{"id":45731521,"uuid":"467495626","full_name":"newfold-labs/wp-module-loader","owner":"newfold-labs","description":"A module that handles registration and management of Newfold modules used within our WordPress plugins.","archived":false,"fork":false,"pushed_at":"2026-03-18T19:02:28.000Z","size":492,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":9,"default_branch":"main","last_synced_at":"2026-03-19T08:35:04.569Z","etag":null,"topics":["composer","php","press-1","wp"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/newfold-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-08T12:06:18.000Z","updated_at":"2026-02-05T21:10:00.000Z","dependencies_parsed_at":"2025-08-11T14:13:50.592Z","dependency_job_id":null,"html_url":"https://github.com/newfold-labs/wp-module-loader","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/newfold-labs/wp-module-loader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newfold-labs%2Fwp-module-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newfold-labs%2Fwp-module-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newfold-labs%2Fwp-module-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newfold-labs%2Fwp-module-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/newfold-labs","download_url":"https://codeload.github.com/newfold-labs/wp-module-loader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newfold-labs%2Fwp-module-loader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34741320,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["composer","php","press-1","wp"],"created_at":"2026-06-24T17:01:46.377Z","updated_at":"2026-06-24T17:01:47.653Z","avatar_url":"https://github.com/newfold-labs.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://newfold.com/\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://newfold.com/content/experience-fragments/newfold/site-header/master/_jcr_content/root/header/logo.coreimg.svg/1621395071423/newfold-digital.svg\" alt=\"Newfold Logo\" title=\"Newfold Digital\" align=\"right\" \nheight=\"42\" /\u003e\n\u003c/a\u003e\n\n# WordPress Module Loader\n\n[![Version Number](https://img.shields.io/github/v/release/newfold-labs/wp-module-loader?color=21a0ed\u0026labelColor=333333)](https://github.com/newfold/wp-module-loader/releases)\n[![License](https://img.shields.io/github/license/newfold-labs/wp-module-loader?labelColor=333333\u0026color=666666)](https://raw.githubusercontent.com/newfold-labs/wp-module-loader/master/LICENSE)\n\nThis loader instantiates Newfold WordPress Modules inside our WordPress Plugins.\n\n* \u003ca href=\"#newfold-wordpress-modules\"\u003eWhat are modules?\u003c/a\u003e\n* \u003ca href=\"#creating--registering-a-module\"\u003eCreating/registering modules\u003c/a\u003e\n* \u003ca href=\"#installing-from-our-satis\"\u003eInstalling from our Satis\u003c/a\u003e\n* \u003ca href=\"#local-development\"\u003eLocal development notes\u003c/a\u003e\n* \u003ca href=\"#understanding-the-module-lifecycle\"\u003eUnderstanding the module lifecycle\u003c/a\u003e\n* \u003ca href=\"#module-loader-api\"\u003eModule Loader API\u003c/a\u003e\n\n## Module Responsibilities\n- Provides a dependency injection container for shared dependencies across the brand plugin modules.\n- Provides a framework for registering, unregistering, activating, deactivating, and checking if a module is active.\n- Provides a plugin class that makes getting basic plugin information simple.\n\n## Critical Paths\n- The dependency injection container should be created by the brand plugin and successfully shared across all other modules.\n- Calling the `register()` function should successfully register the module and run the code on the `after_setup_theme` action hook.\n\n## Newfold WordPress Modules\n\nNewfold WordPress modules are PHP packages intended to be installed in WordPress plugins via Composer from our Satis\nregistry.\n\nModules essentially function as WordPress plugins we can reuse in Newfold products and control programmatically.\n\nModules can be **required/forced, optional, hidden** and **can be toggled** by code and (sometimes) by users.\n\n## Creating \u0026 Registering a Module\n\nModules will eventually be created from templates, but for now here are some key things to know.\n\n* Modules should contain a `bootstrap.php` file that should get autoloaded by Composer. Functionality should load\n  from `/includes`.\n* Modules are loaded on the `after_setup_theme` hook with a priority of `100`.\n* Module registration should tap the `plugins_loaded` hook.\n* If a plugin registers a dependency injection container, then that container will be accessible to the registered\n  modules. If the plugin doesn't register a container, an empty container will be passed to the module.\n\n### Module Registration\n\nBelow is an example of how to register a module within the `bootstrap.php` file:\n\n```php\n\u003c?php\n\nuse NewfoldLabs\\WP\\ModuleLoader\\Container;\nuse function NewfoldLabs\\WP\\ModuleLoader\\register;\n\nif ( function_exists( 'add_action' ) ) {\n\n\tadd_action(\n\t\t'plugins_loaded',\n\t\tfunction () {\n\n\t\t\tregister(\n\t\t\t\t[\n\t\t\t\t\t'name'     =\u003e 'sso',\n\t\t\t\t\t'label'    =\u003e __( 'SSO', 'newfold-sso-module' ),\n\t\t\t\t\t'callback' =\u003e function ( Container $container ) {\n\t\t\t\t\t\trequire __DIR__ . '/includes/sso.php';\n\t\t\t\t\t},\n\t\t\t\t\t'isActive' =\u003e true,\n\t\t\t\t\t'isHidden' =\u003e true,\n\t\t\t\t]\n\t\t\t);\n\n\t\t}\n\t);\n\n}\n\n```\n\nNotice that a dependency injection container is passed to the callback function. You can leverage this container in \nthe callback function, or you can use the `NewfoldLabs\\WP\\ModuleLoader\\container` function to fetch the container \nfrom any location.\n\n### Installing from our Satis\n\nOur modules are sourced from our 3rd-party package repository (Satis).\n\n#### 1. Make sure to register our repository in the `composer.json`\n\nVia command line: `composer config repositories.newfold composer https://newfold-labs.github.io/satis/`\n\nOR\n\n```json\n{\n  \"repositories\": [\n    {\n      \"type\": \"composer\",\n      \"url\": \"https://newfold-labs.github.io/satis/\",\n      \"only\": [\n        \"newfold-labs/*\"\n      ]\n    }\n  ]\n}\n```\n\n#### 2. `composer require [satis-package-identifier]`\n\n#### 3. `composer install`\n\n### Local Development\n\n1. Use a dev environment for a Newfold Brand Plugin [wp-plugin-web, wp-plugin-hostgator, etc].\n2. Open the plugin root directory.\n3. Modify the `composer.json` in a text editor.\n\t1. Add a new object to the \"repositories\" top-level property. _All local repositories should go at the beginning of the array declaration to supercede priority from the satis declarations._\n\t2. The `url` path is relative to the current folder -- go up two directories for the `/wp-content` folder.\n\t3. The symlink option set to false will copy files instead and wont update without manual intervention.\n\t4. \n\t\t1. If this is a new module, add it to the `\"require\"` property with a version of `@dev`.\n\t\t2. if this is an existing module, modify the entry in `\"require\"` to `@dev`.\n```json\n{\n\"repositories\": [\n  {\n     \"type\": \"path\",\n     \"url\": \"../../path-in-wp-content-directory\",\n     \"options\": {\n       \"symlink\": true\n     }\n   },\n   {\n      \"type\": \"composer\",\n      \"url\": \"https://newfold-labs.github.io/satis/\",\n      \"only\": [\n        \"newfold-labs/*\"\n      ]\n    }\n],\n\"require\": {\n  \"newfold-labs/wp-module-magic\": \"@dev\",\n  \"newfold-labs/wp-module-loader\": \"x.y.z\"\n  }\n}\n\n```\n\nFinally, you may want to run a `composer update` routine or remove your `composer.lock` file and `composer install`.\n\n## Understanding the module lifecycle\n\n### How It Works\n\n0. During plugin release, a `composer install` is run, creating autoloader files and pulling in composer dependencies --\n   which include Newfold modules.\n1. A request is made to WordPress, firing Core hooks.\n2. The plugin containing modules is loaded during `do_action('plugins_loaded')`. WordPress loads plugins alphabetically.\n3. In the plugin, the composer autoloader is required and executes. This isn't attached to an action hook, but is\n   effectively running during `plugins_loaded`.\n4. Each module defines a `bootstrap.php` that is explicitly set to autoload, so when the main plugin's autoloader fires,\n   each module's bootstrap.php is loaded -- again outside the hook cascade, but these files are effectively run\n   during `plugins_loaded`.\n5. In the `boostrap.php` for each module, the module is registered with the module loader module using\n   `NewfoldLabs\\WP\\ModuleLoader\\Module\\make()`. Most modules should be registered in `do_action('plugins_loaded')`\n   and before the `do_action('init')` hook.\n6. In `newfold-labs/wp-module-loader`, the loader runs on `do_action('after_theme_setup')` with a priority of\n   `100`.\n7. Any code in a module that is instantiated via `bootstrap.php` can now access the WordPress Action Hook system,\n   starting with `init`.\n\n#### Hooks available to modules:\n\n* `init` (first available)\n* `wp_loaded`\n* `admin_menu`\n* `admin_init`\n* etc\n\n#### Hooks not available to modules\n\n* `plugins_loaded`\n* `set_current_user`\n* `setup_theme`\n* `after_theme_setup`\n\n## Module Loader API\n\nThe following functions are namespaced with `NewfoldLabs\\WP\\ModuleLoader`.\n\n### register( $attributes )\n\n\u003e Register a new module.\n\u003e\n\u003e Required attributes:\n\u003e  - name (string) - The internal module name; should be lowercase with dashes.\n\u003e  - label (string) - The user-facing module name\n\u003e  - callback (callable) - The callback that kicks off the module's functionality.\n\u003e  - isActive (bool) - Whether the module defaults to active.\n\u003e  - isHidden (bool) - Whether the module should be hidden from users in the UI.\n\n### unregister( $name )\n\n\u003e Unregister a module. The `$name` is the internal module name.\n\n### activate( $name )\n\n\u003e Activate a module by name.\n\n### deactivate( $name )\n\n\u003e Deactivate a module by name.\n\n### isActive( $name )\n\n\u003e Check if a module is active by name.\n\n### container( $container )\n\n\u003e Register a container that should be shared with all modules.\n\u003e\n\u003e Currently, the container must be an instance of [`NewfoldLabs\\WP\\ModuleLoader\\Container`](https://github.com/wp-forge/container).\n\u003e\n\u003e A container should be registered within the WordPress plugin and should be done like this:\n\u003e\n\u003e ```php\n\u003e use NewfoldLabs\\WP\\ModuleLoader\\Container;\n\u003e use NewfoldLabs\\WP\\ModuleLoader\\Plugin;\n\u003e use function NewfoldLabs\\WP\\ModuleLoader\\container as setContainer;\n\u003e \n\u003e setContainer( \n\u003e   new Container(\n\u003e     [\n\u003e       'plugin' =\u003e new Plugin(\n\u003e         [\n\u003e           'id'   =\u003e 'bluehost', // Used for data module integration\n\u003e           'file' =\u003e __FILE__,\n\u003e         ]\n\u003e       ),\n\u003e     ]\n\u003e   );\n\u003e );\n\u003e ```\n\u003e \n\u003e Documentation on how to use the container exists here: https://github.com/wp-forge/container\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnewfold-labs%2Fwp-module-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnewfold-labs%2Fwp-module-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnewfold-labs%2Fwp-module-loader/lists"}