{"id":19506062,"url":"https://github.com/espocrm/ext-template","last_synced_at":"2025-04-26T02:32:18.789Z","repository":{"id":47773432,"uuid":"267808198","full_name":"espocrm/ext-template","owner":"espocrm","description":"Template repository for EspoCRM extensions","archived":false,"fork":false,"pushed_at":"2025-04-07T15:13:44.000Z","size":98,"stargazers_count":32,"open_issues_count":3,"forks_count":22,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-24T07:11:31.480Z","etag":null,"topics":["espocrm","php"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/espocrm.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}},"created_at":"2020-05-29T08:37:30.000Z","updated_at":"2025-04-11T05:38:09.000Z","dependencies_parsed_at":"2023-01-24T16:45:23.534Z","dependency_job_id":"7d8bf452-db7e-4049-9491-8a4c1373d8c2","html_url":"https://github.com/espocrm/ext-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/espocrm%2Fext-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/espocrm%2Fext-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/espocrm%2Fext-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/espocrm%2Fext-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/espocrm","download_url":"https://codeload.github.com/espocrm/ext-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250922127,"owners_count":21508279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["espocrm","php"],"created_at":"2024-11-10T22:35:30.549Z","updated_at":"2025-04-26T02:32:18.782Z","avatar_url":"https://github.com/espocrm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Template repository for EspoCRM extensions\r\n\r\nCreate a repository for your extension from this template.\r\n\r\n## Preparing repository\r\n\r\nRun:\r\n\r\n```\r\nphp init.php\r\n```\r\n\r\nIt will ask to enter an extension name and some other information.\r\n\r\nAfter that, you can remove `init.php` file from your repository. Commit changes and proceed to configuration \u0026 building.\r\n\r\n\r\n## Configuration\r\n\r\nCreate `config.json` file in the root directory. You can copy `config-default.json` and rename it to `config.json`.\r\n\r\nWhen reading, this config will be merged with `config-default.json`. You can override default parameters in the created config.\r\n\r\nParameters:\r\n\r\n* espocrm.repository - from what repository to fetch EspoCRM;\r\n* espocrm.branch - what branch to fetch (`stable` is set by default); you can specify version number instead (e.g. `5.9.2`);\r\n* database - credentials of the dev database;\r\n* install.siteUrl - site url of the dev instance;\r\n* install.defaultOwner - a webserver owner (important to be set right);\r\n* install.defaultGroup - a webserver group (important to be set right).\r\n\r\n\r\n## Config for EspoCRM instance\r\n\r\nYou can override EspoCRM config. Create `config.php` in the root directory of the repository. This file will be applied after EspoCRM installation (when building).\r\n\r\nExample:\r\n\r\n```php\r\n\u003c?php\r\nreturn [\r\n    'useCacheInDeveloperMode' =\u003e true,\r\n];\r\n```\r\n\r\n## Building\r\n\r\nAfter building, EspoCRM instance with installed extension will be available at `site` directory. You will be able to access it with credentials:\r\n\r\n* Username: admin\r\n* Password: 1\r\n\r\n### Preparation\r\n\r\n1. You need to have *node*, *npm*, *composer* installed.\r\n2. Run `npm install`.\r\n3. Create a database. Note that without the created database instance building will fail. The database name is set in the config file. You can change it.\r\n\r\n### Full EspoCRM instance building\r\n\r\nIt will download EspoCRM (from the repository specified in the config), then build and install it. Then it will install the extension.\r\n\r\nCommand:\r\n\r\n```\r\nnpm run all\r\n```\r\n\r\nNote: It will remove a previously installed EspoCRM instance, but keep the database intact.\r\n\r\nNote: If an error occurred, check `site/data/logs/` for details. It's often a database is not created.\r\n\r\n### Copying extension files to EspoCRM instance\r\n\r\nYou need to run this command every time you make changes in `src` directory and you want to try these changes on Espo instance.\r\n\r\nCommand:\r\n\r\n```\r\nnpm run copy\r\n```\r\n\r\nTo avoid running this command manually, use a file watcher in your IDE. The configuration for PhpStorm is included in this repository. See below about the file watcher.\r\n\r\n### Running after-install script\r\n\r\nAfterInstall.php will be applied for EspoCRM instance.\r\n\r\nCommand:\r\n\r\n```\r\nnode build --after-install\r\n```\r\n\r\n### Extension package building\r\n\r\nCommand:\r\n\r\n```\r\nnpm run extension\r\n```\r\n\r\nThe package will be created in `build` directory.\r\n\r\nNote: The version number is taken from `package.json`.\r\n\r\n### Installing addition extensions\r\n\r\nIf your extension requires other extensions, there is a way to install them automatically while building the instance.\r\n\r\nNecessary steps:\r\n\r\n1. Add the current EspoCRM version to the `config.php`:\r\n\r\n```php\r\n\u003c?php\r\nreturn [\r\n    'version' =\u003e '9.0.0',\r\n];\r\n\r\n```\r\n\r\n2. Create the `extensions` directory in the root directory of your repository.\r\n3. Put needed extensions (e.g. `my-extension-1.0.0.zip`) in this directory.\r\n\r\nExtensions will be installed automatically after running the command `node build --all` or `node build --install`.\r\n\r\n## Development workflow\r\n\r\n1. Do development in `src` dir.\r\n2. Run `npm run --copy`.\r\n3. Test changes in EspoCRM instance at `site` dir.\r\n\r\n## Using entity manager to create entities\r\n\r\nYou can block out new entity types right in Espo (using Entity Manager) and then copy generated custom files (`site/custom` dir) to the repository (`src` dir) using `copy-custom.js` script.\r\n\r\n1. Create entity types, fields, layouts, relationships in Espo (it should be available in `site` dir after building).\r\n2. Run `node copy-custom.js`. It will copy all files from `site/custom` to `src/files/custom/Espo/Modules/{ModuleName}` and apply needed modifications to files.\r\n3. Remove files from `site/custom`.\r\n4. Run `node build --copy`. It will copy files from the repository to Espo build (`site/custom//Espo/Modules/{ModuleName}` dir).\r\n5. Clear cache in Espo.\r\n6. Test in Espo.\r\n7. Commit changes.\r\n\r\nYou can remove `copy-custom.js` from the repository if you don't plan to use it future.\r\n\r\n## Using composer in extension\r\n\r\nIf your extension requires additional libraries, they can be installed by composer:\r\n\r\n1. Create a file `src/files/custom/Espo/Modules/{ModuleName}/composer.json` with your dependencies.\r\n2. Once you run `node build --all` or `node build --composer-install`, composer dependencies will be automatically installed.\r\n3. Create a file `src/files/custom/Espo/Modules/{ModuleName}/Resources/autoload.json`.\r\n\r\nNote: The extension build will contain only the `vendor` directory without the `composer.json` file.\r\n\r\nThe `autoload.json` file defines paths for namespaces:\r\n\r\n```json\r\n{\r\n    \"psr-4\": {\r\n        \"LibraryNamespace\\\\\": \"custom/Espo/Modules/{ModuleName}/vendor/\u003cvendor-name\u003e/\u003clibrary-name\u003e/path/to/src\"\r\n    }\r\n}\r\n```\r\n\r\n## Versioning\r\n\r\nThe version number is stored in `package.json` and `package-lock.json`.\r\n\r\nBumping version:\r\n\r\n```\r\nnpm version patch\r\nnpm version minor\r\nnpm version major\r\n```\r\n\r\n## Tests\r\n\r\nTo prepare the Espo instance:\r\n\r\n```\r\nnpm run prepare-test\r\n```\r\n\r\nFetches the instance and runs composer install. To be used for unit tests and static analysis in CI environment. Takes less time than the full installation.\r\n\r\n\r\n### Unit\r\n\r\nRun composer install for the site:\r\n\r\n```\r\n(cd site; composer install)\r\n```\r\n\r\nCommand to run unit tests:\r\n\r\n```\r\n(node build --copy; node build --composer-install; cd site; vendor/bin/phpunit tests/unit/Espo/Modules/{@name})\r\n```\r\n\r\nor\r\n\r\n```\r\nnpm run unit-tests\r\n```\r\n\r\n### Integration\r\n\r\nYou need to build a test instance first:\r\n\r\n1. `node build --copy`\r\n2. `(cd site; grunt test)`\r\n\r\nYou need to create a config file `tests/integration/config.php`:\r\n\r\n```php\r\n\u003c?php\r\n\r\nreturn [\r\n    'database' =\u003e [\r\n        'driver' =\u003e 'pdo_mysql',\r\n        'host' =\u003e 'localhost',\r\n        'charset' =\u003e 'utf8mb4',\r\n        'dbname' =\u003e 'TEST_DB_NAME',\r\n        'user' =\u003e 'YOUR_DB_USER',\r\n        'password' =\u003e 'YOUR_DB_PASSWORD',\r\n    ],\r\n];\r\n```\r\n\r\nCommand to run integration tests:\r\n\r\n```\r\n(node build --copy; node build --composer-install; cd site; vendor/bin/phpunit tests/integration/Espo/Modules/{@name})\r\n```\r\n\r\nor\r\n\r\n```\r\nnpm run integration-tests\r\n```\r\n\r\nNote that integration tests needs the full Espo installation.\r\n\r\n### Static analysis\r\n\r\nCommand to run:\r\n\r\n```\r\nnode build --copy; node build --composer-install; site/vendor/bin/phpstan\r\n```\r\n\r\nor\r\n\r\n```\r\nnpm run sa\r\n```\r\n\r\nIf your extension contains additional PHP packages, you also need to add `site/custom/Espo/Modules/{@name}/vendor` to the *scanDirectories* section in *phpstan.neon* config.\r\n\r\nNote: You can omit *composer-install* command if your extension does not contain PHP packages.\r\n\r\n## Configuring IDE\r\n\r\nYou need to set the following paths to be ignored in your IDE:\r\n\r\n* `build`\r\n* `site/build`\r\n* `site/custom/`\r\n* `site/client/custom/`\r\n* `site/tests/unit/Espo/Modules/{@name}`\r\n* `site/tests/integration/Espo/Modules/{@name}`\r\n\r\n### File watcher\r\n\r\nYou can set up a file watcher in the IDE to automatically copy and transpile files upon saving.\r\n\r\nFile watcher parameters for PhpStorm:\r\n\r\n* Program: `node`\r\n* Arguments: `build --copy-file --file=$FilePathRelativeToProjectRoot$`\r\n* Working Directory: `$ProjectFileDir$`\r\n\r\nNote: The File Watcher configuration for PhpStorm is included in this reposistory.\r\n\r\n## Using ES modules\r\n\r\nThe initialization script asks whether you want to use ES6 modules. It's recommended to choose \"YES\".\r\n\r\nIf you want to switch to ES6 later:\r\n\r\n1. Set *bundled* to true in `extension.json`.\r\n2. Set *bundled* and *jsTranspiled* to true in `src/files/custom/Espo/Modules/{@name}/Resources/module.json`.\r\n3. Add `src/files/custom/Espo/Modules/{@name}/Resources/metadata/app/client.json`\r\n    ```json\r\n    {\r\n        \"scriptList\": [\r\n            \"__APPEND__\",\r\n            \"client/custom/modules/{@nameHyphen}/lib/init.js\"\r\n        ]\r\n    }\r\n    ```\r\n\r\n## Javascript frontend libraries\r\n\r\nInstall *rollup*.\r\n\r\nIn `extension.json`, add a command that will bundle the needed library into an AMD module. Example:\r\n\r\n```json\r\n{\r\n    \"scripts\": [\r\n        \"npx rollup node_modules/some-lib/build/esm/index.mjs --format amd --file build/assets/lib/some-lib.js --amd.id some-lib\"\r\n    ]\r\n}\r\n```\r\n\r\nAdd the library module path to `src/files/custom/Espo/Modules/{@name}/Resources/metadata/app/jsLibs.json`\r\n\r\n```json\r\n{\r\n    \"some-lib\": {\r\n        \"path\": \"client/custom/modules/{@nameHyphen}/lib/some-lib.js\"\r\n    }\r\n}\r\n```\r\n\r\nWhen you build, the library module will be automatically included in the needed location.\r\n\r\nNote that you may also need to create *rollup.config.js* to set some additional Rollup parameters that are not supported via CLI usage.\r\n\r\n## License\r\n\r\nChange a license in `LICENSE` file. The current license is intended for scripts of this repository. It's not supposed to be used for code of your extension.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fespocrm%2Fext-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fespocrm%2Fext-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fespocrm%2Fext-template/lists"}