When starting new projects I always kept copying useful code from my last projects. Over time this started to annoy me as I always kept improving that shared code but usually didn't copy back. So I had copies of more or less the same code in different repositories.
As I'm a passionate user of Git for quite some time, I thought there must be a better way and finally I found the Git submodules. When starting to use those submodules I defined a structure to simplify sharing those modules between those projects - called 'modulekit'. I like to keep the modules small and simple.
The basic module is the repository you are looking at right now, which handles loading of modules, solving dependencies between the modules and some more general functions.
Files/directories in every project/module:
- modulekit.php - Definition of the project/module, list of include files, dependencies.
- inc/ - Include files for this project or if loaded as a submodule
- lib/ - Included libraries
- lib/modulekit/ - Included libraries of the modulekit series
- base/ - for example the modulekit-base library
- form/ - or the modulekit-form library
- lib/modulekit/ - Included libraries of the modulekit series
- modules/ - submodules this belong to this project
- modulekit/ - this basic 'modulekit' submodule (the very code you are reading right now)
Therefore files in the root directory of the project/module will be ignored by modulekit; you can have example-code there and a README or the index.php of your project. It even allows you to use your project as submodule for another project.
To start using modulekit, run the following commands. This clones the framework into the modulekit/-directory and the initializes the modules/-directory, where the submodules will be placed:
git submodule add https://github.com/plepe/modulekit.git modulekit mkdir modules/
Create a modulekit.php-file:
<?php $name="Name of this project/module"; // an ID to identify this module $id="id"; // optional: alias names $aliases=array("ID", "Id"); // An optional description $description="This module does this or that."; // A module can be in one (string) or more (array) categories (those can be selected for the configure page) $category="system"; // a version (see http://semver.org how to define versions) // it will be inherited to submodules if they are in the same repository $version="1.0.0"; // these modules should be loaded first // * needs at least version 1.0 of module 'lang' $depend=array("form", "lang"=>"1.0"); // these modules will also be loaded if this module is loaded, but // (preferably) after this $load=array("foo"); // these files will be included in this order: $include=array(); $include['php']=array( "inc/file1.php", "inc/file2.php", ); $include['js']=array( "inc/*.js", ); $include['css']=array( "inc/a_css_file.css", ); // optional: directories which will be searched for submodules #$modules_path = array("modules", "lib/modulekit");
optional: $error. If $error is set, this module can't be loaded and an exception with the message will be thrown. (e.g. for modules which have been out sourced to a separate repository).
- $error = "message";
Example-code for an index.php-file:
<?php include "conf.php"; /* load a local configuration */ ?> <?php include "modulekit/loader.php"; /* loads all php-includes */ ?> <html> <head> <title>Framework Example</title> <?php print modulekit_to_javascript(); /* pass modulekit configuration to JavaScript */ ?> <?php print modulekit_include_js(); /* prints all js-includes */ ?> <?php print modulekit_include_css(); /* prints all css-includes */ ?> </head> <body> </body> </html>
- Files included with $include may contain wildcards: e.g. *.php matches all files ending in .php .
- You can override the default $include setting by defining a $default_include, e.g. $default_include=array('foo'=>array("inc/*.foo")) which will be valid for all (child) modules not setting a $include setting
- You can define additional indexes for the $include (resp. $default_include) array. To load all files belonging to a specific index define a variable $modulekit_include_php with the index as value before including "modulekit/loader.php", resp. pass it as first argument to modulekit_include_js() resp. modulekit_include_css().
- You may define a variable $modulekit_load, which contains a list of modules to load (per default only those where a dependency of the main project is found will be loaded).
- You may override $modulekit_root and $modulekit_root_relative.
If you want to add an additional submodule run the following commands:
git submodule add https://github.com/plepe/modulekit-form.git lib/modulekit/form git add .gitmodules lib/modulekit/form git commit
If a module depends on more submodules, you don't add them to the submodule's modules-directory, but to the modules directory of your project.
Returns a relative or absolute path to a file specified by $path. $module is either the id of the module itself or the id used by the project (the modules/id/-path). No tests whether the file exist or not will be conducted.
Parameter $absolute_path:
- true: absolute path in filesystem (PHP) resp. from Domain (JS); e.g. "/path/to/repo/img/test.png" resp. "/user/repo/img/test.png"
- false (default): relative path from calling script; e.g. "../img/test.png"
- null: relative path from root of repository; e.g. "img/test.png"
- This function is also available in JavaScript, after calling "print modulekit_to_javascript()"
Available: PHP/JS
Returns the definition from modulekit.php, if the given module is loaded. Otherwise false.
Available: PHP/JS
Returns a string with <script>-tags with all files listed in the $include-arrays of all to-be-loaded modules with the $include_index-index. If $include_index is missing or null, "js" will be used. $suffix will be appended to the src-property, e.g. to force reloading after a software update. If $suffix is null, it will be created from modulekit['version'].
Example: print modulekit_include_js(null, "?1f725ab");
Available: PHP
Returns a string with <link rel='stylesheet'>-tags with all files listed in the $include-arrays of all to-be-loaded modules with the $include_index-index. If $include_index is missing or null, "js" will be used. $suffix will be appended to the href-property, e.g. to force reloading after a software update. If $suffix is null, it will be created from modulekit['version'].
Example: print modulekit_include_css(null, "?1f725ab");
Available: PHP
Returns a list of all files listed in the $include-arrays with the $include_index-index.
Available: PHP/JS
Returns a list of all files listed in the $include-array of the specified module with the $include_index-index.
Available: PHP/JS
You may define a variable $modulekit_debug for debugging purposes. $modulekit_debug may take the following values:
- false/null/0/undefined: All debug information will be discarded.
- true: All debug information will be printed to stderr.
- a positive integer: Some debug information will be printed to stderr; the higher the value the more information you will get.
- a callable: All debug information will be passed to the user-defined function. It will be passed a text and the level of the debug message.
Debug messages printed to stderr by modulekit will be prepended by "modulekit(LX):" where X is the level of the message.
Set $modulekit_nocache to true before including loader.php to disable caching.