{"id":19110169,"url":"https://github.com/locomotivemtl/charcoal-project-boilerplate","last_synced_at":"2025-07-31T06:34:46.823Z","repository":{"id":28635445,"uuid":"32154357","full_name":"locomotivemtl/charcoal-project-boilerplate","owner":"locomotivemtl","description":"A skeleton to get started with Charcoal.","archived":false,"fork":false,"pushed_at":"2023-04-19T20:13:32.000Z","size":1362,"stargazers_count":26,"open_issues_count":2,"forks_count":3,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-07-10T13:06:46.793Z","etag":null,"topics":["boilerplate","charcoal","charcoal-admin","cms","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/locomotivemtl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2015-03-13T12:21:58.000Z","updated_at":"2024-11-13T18:38:20.000Z","dependencies_parsed_at":"2024-11-09T04:24:58.614Z","dependency_job_id":null,"html_url":"https://github.com/locomotivemtl/charcoal-project-boilerplate","commit_stats":{"total_commits":205,"total_committers":15,"mean_commits":"13.666666666666666","dds":0.6097560975609756,"last_synced_commit":"2c25ca9da43d5bf982b231a0fbb7053f26debed2"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/locomotivemtl/charcoal-project-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-project-boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-project-boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-project-boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-project-boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/locomotivemtl","download_url":"https://codeload.github.com/locomotivemtl/charcoal-project-boilerplate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/locomotivemtl%2Fcharcoal-project-boilerplate/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267998737,"owners_count":24178609,"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","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"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":["boilerplate","charcoal","charcoal-admin","cms","php"],"created_at":"2024-11-09T04:23:54.409Z","updated_at":"2025-07-31T06:34:46.796Z","avatar_url":"https://github.com/locomotivemtl.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Charcoal Project Boilerplate\n============================\n\n\u003e ⚠️ This skeleton is built for [`locomotivemtl/charcoal-*`](https://packagist.org/packages/locomotivemtl/) and is deprecated in favour of [`charcoal/boilerplate`](https://github.com/charcoalphp/boilerplate).\n\nThe goal of this project is to provide a fully working \"boilerplate\" (empty _skeleton_ project) using the Charcoal framework.\n\nIt can also optionally set up the [Locomotive Boilerplate](https://github.com/locomotivemtl/locomotive-boilerplate) for the frontend.\n\n# Table of Content\n\n- [How to Install](#how-to-install)\n    + [1. Installing boilerplate](#1-installing-boilerplate)\n    + [2. Test your installation](#2-test-your-installation)\n    + [3. Set up a database storage](#3-set-up-a-database-storage)\n    + [4. Set the project name](#4-set-the-project-name)\n    + [5. Set up `charcoal-admin`](#5-set-up-charcoal-admin)\n    + [6. (Optional) Install `locomotive-boilerplate`](#6-optional-install-locomotive-boilerplate)\n- [Going further](#going-further)\n    + More config customizations\n    + Creating a custom template\n    + Using objects\n    + Customizing the backend\n- [Dependencies and requirements](#dependencies-and-requirements)\n    + [The charcoal modules](#the-charcoal-modules)\n        - [Status matrix](#status-matrix)\n- [What's inside this Boilerplate](#whats-inside-this-boilerplate)\n- [Development](#development)\n    + [Development dependencies](#development-dependencies)\n    + [Continuous Integration](#continuous-integration)\n    + [Coding Style](#coding-style)\n    + [Authors](#authors)\n\n# Intended scope\n\nAlthough it is fully ready to use, this boilerplate is still incomplete. \nIt does not _yet_ showcase all of the Charcoal features and therefore require a lot of manual tinkering for options.\n\nHere is a short \"mission statement\" of what is expected to be accomplished with this project:\n\n- A fully automated setup process.\n    - Optionally install `locomotive-boilerplate` for the frontend.\n- Translation (l10n) fully working with `charcoal-translator`.\n    - Default data also provided in english and french.\n    - ...and spanish and more...\n- A working \"backend\" with `charcoal-admin`.\n    - User set up automatically.\n    - With a default configuration that allows to manage CMS objects (sections, news, events, blogs, locations, etc.)\n    - Permission system working and enabled.\n    - Notification system working and enabled.\n    - Revisioning system working and enabled.\n    - Media library working and enabled.\n    - Built-in help (doc) system working and enabled.\n- A few default, common templates (mustache) built-in.\n    - Home page, with a few options and widgets (like carousel) or similar.\n    - News list / news details, with attachment support.\n    - Calendar (event list) with ajax options / event details, with attachment support.\n    - Blog / article details, with attachment support and options to enable comments, and ajax actions\n    - Contact, with a contact form that saves to a database and send a confirmation email depending to category options, with ajax actions.\n    - Map, with locations by categories.\n- Metadata 100% fully working on every pages and for every objects.\n    - Use objects' metadata information, which all are editable in `charcoal-admin`.\n- Provide an optimized set of SEO features.\n- Search enabled\n    - Results returned for all types of cms objects (sections, news, events, blogs, locations, etc.)\n    - Used keywords, which all are editable in `charcoal-admin`.\n    - Also search in attachments.\n    - Auto-complete enabled and working.\n- 100% tested with PHPUnit.\n\n# How to Install\n\nTo start a Charcoal project with this Boilerplate, simply:\n\n## 1. **Installing boilerplate**\n\nCharcoal uses the Composer `create-project` command to install the boilerplate:\n\n```shell\n★ composer create-project --prefer-dist locomotivemtl/charcoal-project-boilerplate acme\n```\n\nReplace \"acme\" with the desired directory name for your new project.\n\n\u003e **About the Document Root**\n\u003e\n\u003e 👉 The project should *not* be cloned directly in a web-accessible directory. \n\u003e The web server should be configured to serve the `www/` folder directly (or through a symlink). \n\u003e The other folders (`vendor/`, `src/`, `templates/`, `metadata/`, `config/`, etc.) should therefore not be available from the web server (kept outside the document root).\n\n\n## 2. **Test your installation**\n\nA quick server can be started using the PHP builtin server:\n\n```shell\n★ cd www\n★ php -S localhost:8080\n```\n\nPoint your browser to `http://localhost:8080/` and you should see the boilerplate's default home page.\n\n![Boilerplate homepage](docs/images/boilerplate-home.png)\n\nHow to change the default page and add routes/templates is explained later in this README. \n\n\u003e Hint: the recommended way is from the admin, by adding pages (sections).\n\n## 3. **Set up a database storage**\n\nThe next step requires a custom configuration file. \nIt is recommended to use `config/config.local.json` and making sure it is not committed to source control:\n\n```shell\n★ cp config/config.sample.json config/config.local.json\n```\n\nThen edit the `config/config.local.json` file with this information.\n\nIf your project does not require any database storage, use a database in memory such as SQLite by adding the following to the `config/config.local.json` file:\n\n```json\n{\n    \"databases\": {\n        \"default\": {\n            \"type\": \"sqlite\",\n            \"database\": \":memory:\"\n        }\n    },\n    \"default_database\": \"default\"\n}\n```\n\nIf your project uses MySQL, create an empty database and ensure a SQL user has the proper permissions for this database. Then add the following to the `config/config.local.json` file:\n\n```json\n{\n    \"databases\": {\n        \"default\": {\n            \"type\": \"mysql\",\n            \"hostname\": \"127.0.0.1\",\n            \"database\": \"foobar\",\n            \"username\": \"foo_bar\",\n            \"password\": \"F00$BâR123\"\n        }\n    },\n    \"default_database\": \"default\"\n}\n```\n\n## 4. **Set the project name**\n\nBy default, the project is named \"Acme\" and namespaced under `App` and is autoloaded by Composer using the [PSR-4 autoloading standard](https://www.php-fig.org/psr/psr-4/).\n\nThere are a few occurrences of \"Acme\" in the boilerplate:\n\n- [config/admin.json](config/admin.json): See `admin.title`.\n- [config/config.json](config/config.json): See `project_name` and `cache.prefix`.\n\nYou should also change the information of the Composer package:\n\n- [composer.json](composer.json): See `name`.\n\n## 5. **Set up charcoal-admin**\n\nA quick-and-dirty script is provided to install charcoal-admin automatically:\n\n```shell\n★ sh ./build/scripts/install-charcoal-admin.sh\n```\n\nPoint your browser to http://localhost:8080/admin and you should see the Charcoal's admin login screen.\n\n![Admin login](docs/images/admin-login.png)\n\nThe next step to customize the _backend_ is to configure the main menu, as well as the various admin options. \nSee the `config/admin.json` file for details. \n\n\u003e Refer to the `charcoal-admin` help for more information.\n\n\n## 6. **(Optional) Install `locomotive-boilerplate`)**\n\nAnother quick-and-dirty script is provided to install the locomotive frontend, from its github repository.\n\n```shell\n★ sh ./build/scripts/install-locomotive-boilerplate.sh\n```\n\n\u003e For more information about the `locomotive-boilerplate` frontend module: \n\u003e visit [https://github.com/locomotivemtl/locomotive-boilerplate](https://github.com/locomotivemtl/locomotive-boilerplate)\n\n\n# Dependencies and Requirements\n\n- [`PHP 7.4+`](http://php.net)\n    + `ext-json`\n    + `ext-pdo`\n    + `ext-spl`\n    + `ext-mbstring`\n\n## External libraries\n\nMost Charcoal features are built on top of proven, open-source technologies:\n\n- **Composer** (Deployment and auto-loading)\n- **Slim** (PSR-7 App Framework)\n- **FastRoute** (Router)\n- **Pimple** (DI Container, from symfony)\n- **Mustache** (Templating Engine)\n  - Optionally supports **Twig**, from symfony\n- **PDO / MySQL** (Database Storage)\n- **Stash** (PSR-6 Cache)\n- **CLImate** (Terminal Utility, from the php league)\n- **Flysystem** (File system abstraction, from the php league)\n- **Symfony Translation** (Localization Tools)\n- **Laminas ACL** (Permissions Management)\n- **PHPmailer** (Email Transport)\n- **Monolog** (PSR-3 Logger)\n- **PHPUnit** (Unit Testing)\n- **APIGen** (API Documentation)\n- **PHP Code Sniffer** (Coding Standards)\n- **jQuery** (Javascript Framework)\n- **Bootstrap** (CSS Framework)\n- **TinyMCE** (HTML Editor)\n- **elFinder** (File Manager)\n- **Github** (Source control)\n- **Travis** (Continuous Integration)\n\n## The Charcoal modules\n\n- [charcoal-admin](https://github.com/locomotivemtl/charcoal-admin)\n    + The backend, or control panel.\n- [charcoal-app](https://github.com/locomotivemtl/charcoal-app)\n    + App components based on Slim.\n- [charcoal-attachment](https://github.com/locomotivemtl/charcoal-attachment)\n    + Additional attachments to content objects.\n- [charcoal-cms](https://github.com/locomotivemtl/charcoal-cms)\n    + CMS objects (Section, News, Events, etc.)\n- [charcoal-config](https://github.com/locomotivemtl/charcoal-config)\n    + Base configuration system.\n- [charcoal-core](https://github.com/locomotivemtl/charcoal-core)\n    + Core objects, Model, Source.\n- [charcoal-email](https://github.com/locomotivemtl/charcoal-email)\n    + Email utilities, based on phpmailer.\n- [charcoal-factory](https://github.com/locomotivemtl/charcoal-factory)\n    + Dynamic objects creation.\n- [charcoal-image](https://github.com/locomotivemtl/charcoal-image)\n    + Image manipulation and effects.\n- [charcoal-object](https://github.com/locomotivemtl/charcoal-object)\n    + Object definition (Content and UserData; based on Model), behaviors and tools.\n- [charcoal-property](https://github.com/locomotivemtl/charcoal-property)\n    + Metadata's properties.\n- [charcoal-translator](https://github.com/locomotivemtl/charcoal-translator)\n    + Translation utilities, based on Symfony.\n- [charcoal-ui](https://github.com/locomotivemtl/charcoal-ui)\n    + Ui objects (Form, Menu, Dashboard, Layout, etc.)\n- [charcoal-user](https://github.com/locomotivemtl/charcoal-user)\n    + User definition, authentication and authorization (based on Laminas ACL).\n- [charcoal-validator](https://github.com/locomotivemtl/chracoal-validator)\n    + Data validation.\n- [charcoal-view](https://github.com/locomotivemtl/charcoal-view)\n    + View renderer. (mustache, twig, etc.)\n\n### Status matrix\n\n| Module          | Version | Travis | Scrutinizer | Insights | Coveralls | PHPDoc | ApiGen |\n| --------------- | ------- | ------ | ----------- | -------- | --------- | ------ | ------ |\n| **admin**       | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-admin.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-admin.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-admin) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-admin/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-admin/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/00402be5-f8bb-4279-89b8-3e1e3248178a/mini.png)](https://insight.sensiolabs.com/projects/00402be5-f8bb-4279-89b8-3e1e3248178a) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-admin/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-admin?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-admin/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-admin/apigen/master/) |\n| **app**         | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-app.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-app.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-app) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-app/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-app/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a/mini.png)](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-app/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-app?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-app/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-app/apigen/master/) |\n| **attachment**  | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-attachment.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-attachment.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-attachment) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-attachment/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-attachment/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/09876d95-da9d-4c23-896f-904be3368c99/mini.png)](https://insight.sensiolabs.com/projects/09876d95-da9d-4c23-896f-904be3368c99) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-attachment/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-attachment?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-attachment/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-attachment/apigen/master/) |\n| **cms**         | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-cms.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-cms.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-cms) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-cms/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-cms/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/44d8d264-207b-417d-bcbd-dd52274fc201/mini.png)](https://insight.sensiolabs.com/projects/44d8d264-207b-417d-bcbd-dd52274fc201) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-cms/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-cms?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-cms/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-cms/apigen/master/) |\n| **config**      | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-config.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-config.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-config) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-config/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-config/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/27ad205f-4208-4fa6-9dcf-534b3a1c0aaa/mini.png)](https://insight.sensiolabs.com/projects/27ad205f-4208-4fa6-9dcf-534b3a1c0aaa) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-config/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-config?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-config/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-config/apigen/master/) |\n| **core**        | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-core.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-core.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-core) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-core/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-core/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/ab15f6b0-2063-445e-81d7-2575b919b0ab/mini.png)](https://insight.sensiolabs.com/projects/ab15f6b0-2063-445e-81d7-2575b919b0ab) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-core/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-core?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-core/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-core/apigen/master/) |\n| **email**       | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-email.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-email.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-email) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-email/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-email/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/54058388-3b5d-47e3-8185-f001232d31f7/mini.png)](https://insight.sensiolabs.com/projects/54058388-3b5d-47e3-8185-f001232d31f7) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-email/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-email?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-email/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-email/apigen/master/) |\n| **factory**     | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-factory.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-factory.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-factory) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-factory/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-factory/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/0aec930b-d696-415a-b4ef-a15c1a56509e/mini.png)](https://insight.sensiolabs.com/projects/0aec930b-d696-415a-b4ef-a15c1a56509e) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-factory/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-factory?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-factory/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-factory/apigen/master/) |\n| **image**       | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-image.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-image.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-image) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-image/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-image/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/87c9621d-3b2e-4e71-a42f-e69ebca4672e/mini.png)](https://insight.sensiolabs.com/projects/87c9621d-3b2e-4e71-a42f-e69ebca4672e) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-image/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-image?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-image/docs/master/) |  [ApiGen](http://locomotivemtl.github.io/charcoal-image/apigen/master/) |\n| **object**      | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-object.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-object.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-object) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-object/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-object/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/ef771c49-8c05-448b-a112-069737b380dc/mini.png)](https://insight.sensiolabs.com/projects/ef771c49-8c05-448b-a112-069737b380dc) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-property/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-property?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-object/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-object/apigen/master/) |\n| **presenter**   | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-presenter.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-presenter.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-property) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-presenter/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-presenter/?branch=master) | - | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-presenter/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-presenter?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-presenter/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-presenter/apigen/master/) |\n| **property**    | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-property.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-property.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-property) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-property/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-property/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/f3bdff38-c300-4207-8342-da002e64a6e1/mini.png)](https://insight.sensiolabs.com/projects/f3bdff38-c300-4207-8342-da002e64a6e1) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-property/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-property?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-property/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-property/apigen/master/) |\n| **queue**       | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-queue.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-queue.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-queue) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-queue/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-queue/?branch=master) | - | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-queue/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-queue?branch=master) | [PHPDoc](http://locomotivemtl.github.io/charcoal-queue/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-queue/apigen/master/) |\n| **translator**  | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-translator.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-translator.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-translator) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-translator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-translator/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/2758c820-e73a-4d0e-b746-552a3e3a92fa/mini.png)](https://insight.sensiolabs.com/projects/2758c820-e73a-4d0e-b746-552a3e3a92fa) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-translator/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-translator?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-translator/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-translator/apigen/master/) |\n| **ui**          | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-ui.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-ui.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-ui) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-ui/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-ui/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/ad5d1699-07cc-45b5-9ba4-9b3b45f677e0/mini.png)](https://insight.sensiolabs.com/projects/ad5d1699-07cc-45b5-9ba4-9b3b45f677e0) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-ui/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-ui?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-ui/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-ui/apigen/master/) |\n| **user**        | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-user.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-user.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-user) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-user/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-user/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/5b05fad5-5e2d-41d3-acd3-12822b354892/mini.png)](https://insight.sensiolabs.com/projects/5b05fad5-5e2d-41d3-acd3-12822b354892) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-ui/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-ui?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-user/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-user/apigen/master/) |\n| **validator**   | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-validator.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-validator.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-view) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-validator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-vialidator/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/5c21a1cf-9b21-41c8-82a8-90fbad808a20/mini.png)](https://insight.sensiolabs.com/projects/5c21a1cf-9b21-41c8-82a8-90fbad808a20) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-validator/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-validator?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-validator/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-validator/apigen/master/) |\n| **view**        | ![version](https://img.shields.io/github/tag/locomotivemtl/charcoal-view.svg?style=flat\u0026label=release) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-view.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-view) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-view/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-view/?branch=master) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/396d2f06-82ba-4c79-b8cc-762f1e8bda29/mini.png)](https://insight.sensiolabs.com/projects/396d2f06-82ba-4c79-b8cc-762f1e8bda29) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-view/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-view?branch=master)  | [PHPDoc](http://locomotivemtl.github.io/charcoal-view/docs/master/) | [ApiGen](http://locomotivemtl.github.io/charcoal-view/apigen/master/) |\n\n\n# What's inside this Boilerplate?\n\nLike all Charcoal projects / modules, the main components are:\n\n- **Autoloader**\n    - Provided by Composer.\n- **Config**\n    - As JSON or PHP files in the [`config/`](config/) directory.\n    - Use [`locomotivemtl/charcoal-config`](https://github.com/locomotivemtl/charcoal-config)\n- **Front Controller**\n    - See [`www/.htaccess`](www/.htaccess) and [`www/index.php`](www/index.php) for details.\n    - Route dispatcher\n        - See [`config/routes.json`](config/routes.json) for route configuration.\n- **Script Controller (Charoal Binary)**\n    - Installed from `charcoal-app` as `vendor/bin/charcoal`.\n    - Many useful scripts are provided with the `charcoal-admin` module.\n- **PHP scripts**\n    - PSR-1, PSR2 and PSR-4 compliant scripts are located in [`src/`](src/)\n    - There are typically 3 types of controllers:\n        - _Templates_\n        - _Actions_\n        - _Scripts_\n    - ... 2 types of object\n        - Objects based on _Content_\n        - Objects based on _UserData_\n    - ... and all other types of scripts (services, helpers, configs, factories, etc.)\n- **Assets**\n    - Assets are files required to be on the webserver root\n    - Scripts, in `src/scripts/` and compiled in `www/assets/scripts/`\n    - Styles , with Sass in `src/styles/` and compiled CSS in `www/assets/styles/`\n    - Images, in `www/assets/images/`\n\n\n# Development\n\nTo install the development environment:\n\n```shell\n★ composer install --prefer-source\n```\n\nTo run the scripts (phplint, phpcs and phpunit):\n\n```shell\n★ composer test\n```\n\n## Development dependencies\n\n- `phpunit/phpunit`\n- `squizlabs/php_codesniffer`\n- `satooshi/php-coveralls`\n\n## Continuous Integration\n\n| Service | Badge | Description |\n| ------- | ----- | ----------- |\n| [Travis](https://travis-ci.org/locomotivemtl/charcoal-project-boilerplate) | [![Build Status](https://travis-ci.org/locomotivemtl/charcoal-project-boilerplate.svg?branch=master)](https://travis-ci.org/locomotivemtl/charcoal-project-boilerplate) | Runs code sniff check and unit tests. Auto-generates API documentation. |\n| [Scrutinizer](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-project-boilerplate/) | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-project-boilerplate/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-project-boilerplate/?branch=master) | Code quality checker. Also validates API documentation quality. |\n| [Coveralls](https://coveralls.io/github/locomotivemtl/charcoal-project-boilerplate) | [![Coverage Status](https://coveralls.io/repos/github/locomotivemtl/charcoal-project-boilerplate/badge.svg?branch=master)](https://coveralls.io/github/locomotivemtl/charcoal-project-boilerplate?branch=master) | Unit Tests code coverage. |\n| [Sensiolabs](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a) | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a/mini.png)](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a) | Another code quality checker, focused on PHP. |\n\n## Coding Style\n\nThe charcoal-project-boilerplate module follows the Charcoal coding-style:\n\n- [_PSR-1_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)\n- [_PSR-2_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)\n- [_PSR-4_](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), autoloading is therefore provided by _Composer_.\n- [_phpDocumentor_](http://phpdoc.org/) comments.\n- Read the [phpcs.xml](phpcs.xml) file for all the details on code style.\n\n\u003e Coding style validation / enforcement can be performed with `composer phpcs`. An auto-fixer is also available with `composer phpcbf`.\n\n## Authors\n\n- [Locomotive, a Montreal Web agency](https://locomotive.ca)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocomotivemtl%2Fcharcoal-project-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocomotivemtl%2Fcharcoal-project-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocomotivemtl%2Fcharcoal-project-boilerplate/lists"}