├── .nvmrc ├── phpstan.neon.dist ├── client └── dist │ ├── styles │ └── bundle.css │ └── js │ └── bundle.js ├── .eslintrc.js ├── .stylelintrc.js ├── _config └── config.yml ├── src └── readme.md ├── _config.php ├── templates └── README.md ├── phpunit.xml.dist ├── docs └── en │ └── README.md ├── .editorconfig ├── phpcs.xml.dist ├── webpack.config.js ├── composer.json ├── LICENSE ├── package.json └── README.md /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | paths: 3 | - src 4 | -------------------------------------------------------------------------------- /client/dist/styles/bundle.css: -------------------------------------------------------------------------------- 1 | .example-component{display:block} 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@silverstripe/eslint-config/.eslintrc'); 2 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@silverstripe/eslint-config/.stylelintrc'); 2 | -------------------------------------------------------------------------------- /_config/config.yml: -------------------------------------------------------------------------------- 1 | # see https://docs.silverstripe.org/en/developer_guides/configuration/configuration/ 2 | -------------------------------------------------------------------------------- /src/readme.md: -------------------------------------------------------------------------------- 1 | # Code 2 | 3 | Look over the [Developer Docs](https://docs.silverstripe.org) 4 | 5 | Make sure to remove this readme in your actual module! 6 | -------------------------------------------------------------------------------- /_config.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tests/php 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/en/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | Add your documentation in the `docs/en/` folder as markdown. Note the "en/" part of the path refers to the language (English in this case) used in the documentation you provide. 4 | If your documentation is vast, you can split it into many markdown files and sub folders. 5 | 6 | Look over the [guidance on documentation](https://docs.silverstripe.org/en/contributing/documentation/) 7 | 8 | Make sure to remove this readme in your actual module! 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in this file, 2 | # please see the EditorConfig documentation: 3 | # https://editorconfig.org/ 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | 16 | [*.{yml,js,json,css,scss}] 17 | indent_size = 2 18 | 19 | [composer.json] 20 | indent_size = 4 21 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeSniffer ruleset for Silverstripe coding conventions. 4 | 5 | src 6 | tests 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const Path = require('path'); 2 | const { JavascriptWebpackConfig, CssWebpackConfig } = require('@silverstripe/webpack-config'); 3 | 4 | const PATHS = { 5 | ROOT: Path.resolve(), 6 | SRC: Path.resolve('client/src'), 7 | }; 8 | 9 | const config = [ 10 | // main JS bundle 11 | new JavascriptWebpackConfig('js', PATHS) 12 | .setEntry({ 13 | bundle: `${PATHS.SRC}/bundles/bundle.js`, 14 | }) 15 | .getConfig(), 16 | // sass to css 17 | new CssWebpackConfig('css', PATHS) 18 | .setEntry({ 19 | bundle: `${PATHS.SRC}/styles/bundle.scss`, 20 | }) 21 | .getConfig(), 22 | ]; 23 | 24 | // Use WEBPACK_CHILD=js or WEBPACK_CHILD=css env var to run a single config 25 | module.exports = (process.env.WEBPACK_CHILD) 26 | ? config.find((entry) => entry.name === process.env.WEBPACK_CHILD) 27 | : config; 28 | -------------------------------------------------------------------------------- /client/dist/js/bundle.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var e={38:function(e,t,n){var o,u=(o=n(121))&&o.__esModule?o:{default:o};window.document.addEventListener("DOMContentLoaded",()=>{(0,u.default)()})},121:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=a(n(207)),u=a(n(525));function a(e){return e&&e.__esModule?e:{default:e}}t.default=()=>{o.default.component.registerMany({ExampleComponent:u.default})}},207:function(e){e.exports=Injector},525:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o,u=(o=n(594))&&o.__esModule?o:{default:o};t.default=()=>u.default.createElement("div",{className:"example-component"},"This is an example")},594:function(e){e.exports=React},607:function(e,t,n){var o=n(669);o(document).ready(()=>{})},669:function(e){e.exports=jQuery}},t={};function n(o){var u=t[o];if(void 0!==u)return u.exports;var a=t[o]={exports:{}};return e[o](a,a.exports,n),a.exports}n(607),n(38)}(); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "silverstripe-module/skeleton", 3 | "description": "A skeleton for Silverstripe CMS modules.", 4 | "type": "silverstripe-vendormodule", 5 | "keywords": [ 6 | "silverstripe", 7 | "CMS" 8 | ], 9 | "license": "BSD-3-Clause", 10 | "require": { 11 | "silverstripe/framework": "^6.0", 12 | "silverstripe/admin": "^3.0" 13 | }, 14 | "require-dev": { 15 | "phpunit/phpunit": "^11.3", 16 | "squizlabs/php_codesniffer": "^3.7", 17 | "silverstripe/standards": "^1", 18 | "phpstan/extension-installer": "^1.3" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "SilverStripeModule\\Skeleton\\": "src/", 23 | "SilverStripeModule\\Skeleton\\Tests\\": "tests/php/" 24 | } 25 | }, 26 | "extra": { 27 | "expose": [ 28 | "client/dist" 29 | ] 30 | }, 31 | "minimum-stability": "dev", 32 | "prefer-stable": true 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "silverstripe-module-skeleton", 3 | "engines": { 4 | "node": ">=18.x" 5 | }, 6 | "scripts": { 7 | "build": "yarn && yarn lint && yarn test && rm -rf client/dist/* && NODE_ENV=production webpack --mode production --bail --progress", 8 | "dev": "NODE_ENV=development webpack --progress", 9 | "watch": "NODE_ENV=development webpack --watch --progress", 10 | "css": "WEBPACK_CHILD=css npm run build", 11 | "test": "jest", 12 | "coverage": "jest --coverage", 13 | "lint": "yarn lint-js && yarn lint-sass", 14 | "lint-js": "eslint client/src", 15 | "lint-js-fix": "eslint client/src --fix", 16 | "lint-sass": "stylelint client/src" 17 | }, 18 | "dependencies": { 19 | "core-js": "^3.26.0", 20 | "react": "^18.2.0" 21 | }, 22 | "devDependencies": { 23 | "@babel/runtime": "^7.20.0", 24 | "@silverstripe/eslint-config": "^1.0.0", 25 | "@silverstripe/webpack-config": "^2.0.0", 26 | "@testing-library/react": "^14.0.0", 27 | "eslint": "^8.0.0", 28 | "eslint-plugin-react-hooks": "^4.3.0", 29 | "jest-cli": "^29.2.2", 30 | "jest-environment-jsdom": "^29.3.1", 31 | "react-dom": "^18.0.0", 32 | "webpack": "^5.74.0", 33 | "webpack-cli": "^5.0.0" 34 | }, 35 | "browserslist": [ 36 | "defaults" 37 | ], 38 | "jest": { 39 | "testEnvironment": "jsdom", 40 | "roots": [ 41 | "client/src" 42 | ], 43 | "moduleDirectories": [ 44 | "client/src", 45 | "node_modules", 46 | "../admin/client/src", 47 | "../admin/node_modules", 48 | "../silverstripe/admin/client/src", 49 | "../silverstripe/admin/node_modules", 50 | "../../silverstripe/admin/client/src", 51 | "../../silverstripe/admin/node_modules" 52 | ], 53 | "testMatch": [ 54 | "**/tests/**/*-test.js?(x)" 55 | ], 56 | "transform": { 57 | ".*": "babel-jest" 58 | } 59 | }, 60 | "babel": { 61 | "presets": [ 62 | "@babel/preset-env", 63 | "@babel/preset-react" 64 | ] 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Silverstripe CMS supported module skeleton 2 | 3 | A useful skeleton to more easily create a [Silverstripe CMS Module](https://docs.silverstripe.org/en/developer_guides/extending/modules/) that conform to the 4 | [Module Standard](https://docs.silverstripe.org/en/developer_guides/extending/modules/#module-standard). 5 | 6 | This README contains descriptions of the parts of this module base you should customise to meet you own module needs. 7 | For example, the module name in the H1 above should be you own module name, and the description text you are reading now 8 | is where you should provide a good short explanation of what your module does. 9 | 10 | Where possible we have included default text that can be included as is into your module and indicated in 11 | other places where you need to customise it 12 | 13 | Below is a template of the sections of your `README.md` you should ideally include to met the Module Standard 14 | and help others make use of your modules. 15 | 16 | ## Steps to prepare this module for your own use 17 | 18 | Ensure you read the 19 | ['publishing a module'](https://docs.silverstripe.org/en/developer_guides/extending/how_tos/publish_a_module/) guide 20 | and update your module's `composer.json` to designate your code as a Silversripe CMS module. 21 | 22 | - Clone this repository into a folder 23 | - Add your name/organisation to `LICENSE.md` 24 | - Update this README with information about your module. Ensure sections that aren't relevant are deleted and 25 | placeholders are edited where relevant 26 | - Review the README files in the various provided directories. You should ultimately delete these README files when you have added your code 27 | - Update the module's `composer.json` with your requirements and package name 28 | - Update (or remove) `package.json` with your requirements and package name. Run `yarn install` (or remove `yarn.lock`) to 29 | ensure dependencies resolve correctly 30 | - Clear the git history by running `rm -rf .git && git init` 31 | - Add and push to a VCS repository 32 | - Either [publish](https://getcomposer.org/doc/02-libraries.md#publishing-to-packagist) the module on packagist.org, or add a [custom repository](https://getcomposer.org/doc/02-libraries.md#publishing-to-a-vcs) to your main `composer.json` 33 | - Require the module in your main `composer.json` 34 | - If you need to build your css or js and are using components, injector, scss variables, etc from `silverstripe/admin`: 35 | - Ensure that `silverstripe/admin` is installed with `composer install --prefer-source` instead of the default `--prefer-dist` (you can use `composer reinstall silverstripe/admin --prefer-source` if you already installed it) 36 | - If you are relying on additional dependencies from `silverstripe/admin` instead of adding them as dependencies in your `package.json` file, you need to install third party dependencies in `silverstripe/admin` by running `yarn install` in the `vendor/silverstripe/admin/` directory. 37 | - Start developing your module! 38 | 39 | ## License 40 | 41 | See [License](LICENSE.md) 42 | 43 | This module template defaults to using the "BSD-3-Clause" license. The BSD-3 license is one of the most 44 | permissive open-source license and is used by most Silverstripe CMS module. 45 | 46 | To publish your module under a different license: 47 | 48 | - update the [`license.md`](LICENSE.md) file 49 | - update the `license' key in your [`composer.json`](composer.json). 50 | 51 | You can use [choosealicense.com](https://choosealicense.com) to help you pick a suitable license for your project. 52 | 53 | You do not need to keep this section in your README file - the `LICENSE.md` file is sufficient. 54 | 55 | ## Installation 56 | 57 | Replace `silverstripe-module/skeleton` in the command below with the composer name of your module. 58 | 59 | ```sh 60 | composer require silverstripe-module/skeleton 61 | ``` 62 | 63 | **Note:** When you have completed your module, submit it to Packagist or add it as a VCS repository to your 64 | project's composer.json, pointing to the private repository URL. 65 | 66 | ## Documentation 67 | 68 | - [Documentation readme](docs/en/README.md) 69 | 70 | Add links into your `docs/` folder here unless your module only requires minimal documentation 71 | in that case, add here and remove the docs folder. You might use this as a quick table of content if you 72 | mhave multiple documentation pages. 73 | 74 | ## Example configuration 75 | 76 | If your module makes use of the config API in Silverstripe CMS it's a good idea to provide an example config 77 | here that will get the module working out of the box and expose the user to the possible configuration options. 78 | Though note that in many cases simply linking to the documentation is enough. 79 | 80 | Provide a syntax-highlighted code examples where possible. 81 | 82 | ```yaml 83 | Page: 84 | config_option: true 85 | another_config: 86 | - item1 87 | - item2 88 | ``` 89 | --------------------------------------------------------------------------------