PHPackages                             locomotivemtl/charcoal-cms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. locomotivemtl/charcoal-cms

ActiveLibrary[Framework](/categories/framework)

locomotivemtl/charcoal-cms
==========================

Charcoal CMS (Content Management System) Module

0.10.0.5(6mo ago)529.0k7[1 issues](https://github.com/locomotivemtl/charcoal-cms/issues)[1 PRs](https://github.com/locomotivemtl/charcoal-cms/pulls)3MITPHPPHP &gt;7.1CI failing

Since Feb 17Pushed 6mo ago14 watchersCompare

[ Source](https://github.com/locomotivemtl/charcoal-cms)[ Packagist](https://packagist.org/packages/locomotivemtl/charcoal-cms)[ Docs](https://charcoal.locomotive.ca)[ RSS](/packages/locomotivemtl-charcoal-cms/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (10)Dependencies (14)Versions (76)Used By (3)

Charcoal CMS
============

[](#charcoal-cms)

The CMS Charcoal Module (*Content Management System*). Provides basic objects to build a website. Notably, `Section` (or *page*), `News`, `Event` and `Faq` as well as to ather user data, notably `ContactInquiry`.

This module is heavily dependant on [`charcoal-object`](https://github.com/locomotivemtl/charcoal-object) (and therefore `charcoal-core`) which provides the base `Content` class the CMS objects are dependant on, as well as many trait / interface behaviors.

How to install
==============

[](#how-to-install)

The preferred (and only supported) way of installing *charcoal-cms* is with **composer**:

```
★ composer require locomotivemtl/charcoal-cms
```

For a complete, ready-to-use project, start from the [`charcoal project boilerplate`](https://github.com/locomotivemtl/charcoal-project-boilerplate):

```
★ composer create-project locomotivemtl/charcoal-project-boilerplate:@dev --prefer-source
```

Dependencies
------------

[](#dependencies)

- [`PHP 5.6+`](http://php.net)
    - PHP 7 is recommended for security and performance reasons.
- [`locomotivemtl/charcoal-attachment`](https://github.com/locomotivemtl/charcoal-attachment)
    - Content blocks are provided with *attachments*.
- [`locomotivemtl/charcoal-core`](https://github.com/locomotivemtl/charcoal-core)
    - Core charcoal models and storage class.
    - Provides base Model, which depends on Storable and Describable.
- [`locomotivemtl/charcoal-object`](https://github.com/locomotivemtl/charcoal-object)
    - CMS objects are based on `\Charcoal\Object\Content`.
- [`locomotivemtl/charcoal-translator`](https://github.com/locomotivemtl/charcoal-translator)
    - Localization is provided by symfony translator (charcoal).

### Recommended dependencies

[](#recommended-dependencies)

- [`locomotivemtl/charcoal-admin`](https://github.com/locomotivemtl/charcoal-admin)
    - The backend (admin panel).

Objects
=======

[](#objects)

- **Core objects**
    - [Section](#section-object)
    - [Tag](#tag-object)
- **CMS objects**
    - [Event](#event-object)
    - [FAQ](#faq-object)
    - [News](#news-object)

Core objects
============

[](#core-objects)

- [Section](#section-object)
- [Tag](#tag-object)

Section object
--------------

[](#section-object)

A **section**, in Charcoal, is a reachable *page* on the website, as part of the full hierarchical site map. They can be displayed in menus or breadcrumbs and be reached with a unique URL (`routable`).

Types of sections:

- `blocks`
    - Blocks sections define their content as a structured map of blocks.
- `content`
    - Content sections define their content in a single, simple *HTML* property.
- `empty`
    - Empty sections are linked to a template but do not require any custom content.
- `external`
    - External sections are simply a redirect to an external (or internal) URL.

All section types, except *external*, make use of a `Template` object to be rendered. Typically, a charcoal `view` make sure of linking the `template` (by default, *mustache*

> Sections are standard Charcoal `Model`, meaning they are *describable* with a `Metadata` object (which define a map of `properties`) and *storable* with a `Source` object.

Base section properties:

InterfaceNameL10nTypeDescriptionSection**section\_type**choiceSection**title**✔stringSection**subtitle**✔htmlSection**summary**✔htmlSection**image**✔imageSection**template\_ident**stringSection**template\_options**structureSection**content**✔htmlSection**attachments**✔multi-objectSection**external\_url**✔urlFor external URLs. Note that all content-related properties are ignored if this property is set.Content**id**idThe model's `key`.Content**active**boolInactive events should not appear in public API / frontend.Content**position**intDefault order property.Authorable**created\_by**stringAdmin user.Authorable**last\_modified\_by**stringAdmin user.Authorable**required\_acl\_permissions**arrayTo do...Timestampable**created**date-timeTimestampable**last\_modified**date-timeHierarchical**master**object`SectionInterface`.Routable**slug**✔stringPermalink. Auto-generated from title.### Interfaces

[](#interfaces)

From model:

- `Describable`: The objects can be defined by Metadata.
- `Storable`: Objects have unique IDs and can be stored in storage / database.

From content:

- `Content`: A "managed" charcoal model (describable with metadata / storable).
- `Authorable`: Creation and modification user (admin) are kept in the storage.
- `Revisionable`: Copy of changes will be kept upon each object update in the storage.
- `Timestampable`: Creation and modification time are kept into the storage.

From charcoal-object

- `Hierarchicale`: The objects can be stacked hierarchically.
- `Publishable`: Objects have publish status, date and expiry. Allows moderation.
- `Routable`: Objects are reachable through a URL.

From charcoal-cms:

- `Metatag`: The objects have meta-information for SEO purpose.
- `Searchable`: Extra keywords can be used to help search engine.
- `Templateable`: The objects can be rendered with a template / controller / config combo.

### Extending the section object

[](#extending-the-section-object)

The `\Charcoal\Cms\Section\*` objects are `final`. To extend, use the `\Charcoal\Cms\AbstractSection` base object instead, to make sure no metadata conflicts arise.

Tag object
----------

[](#tag-object)

**Tag** objects link any objects together by providing an extra taxonomy layer. Tags may also be used to enhance internal search engines.

CMS objects
===========

[](#cms-objects)

- [Event](#event-object)
- [FAQ](#faq-object)
- [News](#news-object)

Event object
------------

[](#event-object)

Charcoal **Event** is a specialized content object to describe an event, which typically happens at a given date in a certain location.

Base events properties:

InterfaceNameL10nTypeDescriptionEvent**title**✔stringEvent**subtitle**✔htmlEvent**summary**✔htmlEvent**content**✔htmlEvent**image**✔imageEvent**start\_date**date-timeEvent**end\_date**date-timeEvent**info\_url**✔imageContent**id**idThe model's `key`.Content**active**boolInactive events should not appear in public API / frontend.Content**position**intDefault order property.Authorable**created\_by**stringAdmin user.Authorable**last\_modified\_by**stringAdmin user.Authorable**required\_acl\_permissions**arrayTo do...Timestampable**created**date-timeTimestampable**last\_modified**date-timeCategorizable**category**✔object`EventCategory`, or custom.Publishable**publishDate**date-timePublishable**expiryDate**date-timePublishable**publishStatus**string`draft`, `pending`, or `published`.Routable**slug**✔stringPermalink. Auto-generated from title.Metatag**meta\_title**✔stringMetatag**meta\_description**✔stringMetatag**meta\_image**✔imageMetatag**meta\_author**✔stringTemplateable**controller\_ident**stringTemplateable**template\_ident**stringTemplateable**template\_options**structure### Interfaces

[](#interfaces-1)

From model:

- `Describable`: The objects can be defined by Metadata.
- `Storable`: Objects have unique IDs and can be stored in storage / database.

From content:

- `Content`: A "managed" charcoal model (describable with metadata / storable).
- `Authorable`: Creation and modification user (admin) are kept in the storage.
- `Revisionable`: Copy of changes will be kept upon each object update in the storage.
- `Timestampable`: Creation and modification time are kept into the storage.

From charcoal-object:

- `Categorizable`: The objects can be put into a category.
- `Publishable`: Objects have publish status, date and expiry. Allows moderation.
- `Routable`: Objects are reachable through a URL.

From charcoal-cms:

- `Metatag`: The objects have meta-information for SEO purpose.
- `Searchable`: Extra keywords can be used to help search engine.
- `Templateable`: The objects can be rendered with a template / controller / config combo.

### Extending the event object

[](#extending-the-event-object)

The `\Charcoal\Cms\Event` object is `final`. To extend, use the `\Charcoal\Cms\AbstractEvent` base object instead, to make sure no metadata conflicts arise.

### Event categories

[](#event-categories)

**Event category** objects are simple `charcoal/object/category` used to group / categorize events. The default type is `Charcoal\Cms\EventCategory`.

*Events* implement the `Categorizable` interface, from charcoal-object.

FAQ object
----------

[](#faq-object)

**FAQ** objects are a special content type that is split in a "question" / "answer" format.

### FAQ categories

[](#faq-categories)

**FAQ category** objects are simple `charcoal/object/category` used to group / categorize FAQ objects. The default type is `Charcoal\Cms\FaqCategory`.

*FAQs* implement the `Categorizable` interface, from charcoal-object.

News object
-----------

[](#news-object)

News object are a special content type that with a specific news date.

Base news properties:

InterfaceNameL10nTypeDescriptionNews**title**✔stringNews**subtitle**✔htmlNews**summary**✔htmlNews**content**✔htmlNews**image**✔imageNews**news\_date**date-timeNews**info\_url**✔imageContent**id**idThe model's `key`.Content**active**boolInactive news should not appear in public API / frontend.Content**position**intDefault order property.Authorable**created\_by**stringAdmin user.Authorable**last\_modified\_by**stringAdmin user.Authorable**required\_acl\_permissions**arrayTo do...Timestampable**created**date-timeTimestampable**last\_modified**date-timeCategorizable**category**✔object`NewsCategory`, or custom.Publishable**publishDate**date-timePublishable**expiryDate**date-timePublishable**publishStatus**string`draft`, `pending`, or `published`.Routable**slug**✔stringPermalink. Auto-generated from title.Metatag**meta\_title**✔stringMetatag**meta\_description**✔stringMetatag**meta\_image**✔imageMetatag**meta\_author**✔stringTemplateable**controller\_ident**stringTemplateable**template\_ident**stringTemplateable**template\_options**structure### Interfaces

[](#interfaces-2)

From model:

- `Describable`: The objects can be defined by Metadata.
- `Storable`: Objects have unique IDs and can be stored in storage / database.

From content:

- `Content`: A "managed" charcoal model (describable with metadata / storable).
- `Authorable`: Creation and modification user (admin) are kept in the storage.
- `Revisionable`: Copy of changes will be kept upon each object update in the storage.
- `Timestampable`: Creation and modification time are kept into the storage.

From charcoal-object:

- `Categorizable`: The objects can be put into a category.
- `Publishable`: Objects have publish status, date and expiry. Allows moderation.
- `Routable`: Objects are reachable through a URL.

From charcoal-cms:

- `Metatag`: The objects have meta-information for SEO purpose.
- `Searchable`: Extra keywords can be used to help search engine.
- `Templateable`: The objects can be rendered with a template / controller / config combo.

### Extending the news object

[](#extending-the-news-object)

The `\Charcoal\Cms\News` object is `final`. To extend, use the `\Charcoal\Cms\AbstractNews` base object instead, to make sure no metadata conflicts arise.

### News categories

[](#news-categories)

**News category** objects are simple `charcoal/object/category` used to group / categorize events. The default type is `Charcoal\Cms\NewsCategory`.

*News* implement the `Categorizable` interface, from charcoal-object.

Development
===========

[](#development)

To install the development environment:

```
$ composer install --prefer-source
```

API documentation
-----------------

[](#api-documentation)

- The auto-generated `phpDocumentor` API documentation is available at
- The auto-generated `apigen` API documentation is available at [https://codedoc.pub/locomotivemtl/charcoal-cms/master/](https://codedoc.pub/locomotivemtl/charcoal-cms/master/index.html)

Development dependencies
------------------------

[](#development-dependencies)

- `phpunit/phpunit`
- `squizlabs/php_codesniffer`
- `satooshi/php-coveralls`

Continuous Integration
----------------------

[](#continuous-integration)

ServiceBadgeDescription[Travis](https://travis-ci.org/locomotivemtl/charcoal-cms)[![Build Status](https://camo.githubusercontent.com/79cdc9cf5e4a1fec52aeef5fa1ac58c465d964845a37c89e661b32916d3f90dc/68747470733a2f2f7472617669732d63692e6f72672f6c6f636f6d6f746976656d746c2f63686172636f616c2d636d732e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/locomotivemtl/charcoal-cms)Runs code sniff check and unit tests. Auto-generates API documentation.[Scrutinizer](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-cms/)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/133330fa13c3a0cda4f218d9ecb3c8c59a5d59eb44e5146d553a5cc2df3a3d7a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6c6f636f6d6f746976656d746c2f63686172636f616c2d636d732f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/locomotivemtl/charcoal-cms/?branch=master)Code quality checker. Also validates API documentation quality.[Coveralls](https://coveralls.io/github/locomotivemtl/charcoal-cms)[![Coverage Status](https://camo.githubusercontent.com/1f5b275ca5ea091478dcf6d2d2b9f4f36778f1912b5415897ddedd8c739b6460/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6c6f636f6d6f746976656d746c2f63686172636f616c2d636d732f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/locomotivemtl/charcoal-cms?branch=master)Unit Tests code coverage.[Sensiolabs](https://insight.sensiolabs.com/projects/533b5796-7e69-42a7-a046-71342146308a)[![SensioLabsInsight](https://camo.githubusercontent.com/5a9794e4ffdda19f4892e255785026c67188b635d267f7f10e469f2e76a21432/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f34346438643236342d323037622d343137642d626362642d6464353232373466633230312f6d696e692e706e67)](https://insight.sensiolabs.com/projects/44d8d264-207b-417d-bcbd-dd52274fc201)Another code quality checker, focused on PHP.Coding Style
------------

[](#coding-style)

The `charcoal-cms` module follows the Charcoal coding-style:

- [*PSR-1*](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
- [*PSR-2*](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
- [*PSR-4*](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md), autoloading is therefore provided by *Composer*.
- [*phpDocumentor*](http://phpdoc.org/) comments.
- Read the [phpcs.xml](phpcs.xml) file for all the details on code style.

> Coding style validation / enforcement can be performed with `composer phpcs`. An auto-fixer is also available with `composer phpcbf`.

Authors
=======

[](#authors)

- [Locomotive](https://locomotive.ca)

License
=======

[](#license)

Charcoal is licensed under the MIT license. See [LICENSE](LICENSE) for details.

###  Health Score

50

—

FairBetter than 96% of packages

Maintenance68

Regular maintenance activity

Popularity34

Limited adoption so far

Community28

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~46 days

Recently: every ~304 days

Total

70

Last Release

189d ago

PHP version history (2 changes)0.1PHP &gt;=5.6.0

0.9.1PHP &gt;7.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfb071c0ff7ce9500c528a003a2c53124248debc3e5bf367c17f89f5e6136125?d=identicon)[mducharme](/maintainers/mducharme)

![](https://www.gravatar.com/avatar/0a4f39523b4b2837562ba0848a0327b8d340118d1ba87cb0f5d59b1d5cb6beba?d=identicon)[mcaskill](/maintainers/mcaskill)

![](https://www.gravatar.com/avatar/b806b936695bdb12bf55e0e805bdaef15507502a07a16e34d43c5aad17390468?d=identicon)[dominiclord](/maintainers/dominiclord)

---

Top Contributors

[![JoelAlphonso](https://avatars.githubusercontent.com/u/10762266?v=4)](https://github.com/JoelAlphonso "JoelAlphonso (94 commits)")[![mducharme](https://avatars.githubusercontent.com/u/12157?v=4)](https://github.com/mducharme "mducharme (89 commits)")[![mcaskill](https://avatars.githubusercontent.com/u/29353?v=4)](https://github.com/mcaskill "mcaskill (88 commits)")[![dominiclord](https://avatars.githubusercontent.com/u/1775204?v=4)](https://github.com/dominiclord "dominiclord (31 commits)")[![BeneRoch](https://avatars.githubusercontent.com/u/3017380?v=4)](https://github.com/BeneRoch "BeneRoch (27 commits)")[![losted](https://avatars.githubusercontent.com/u/165665?v=4)](https://github.com/losted "losted (11 commits)")[![veve40](https://avatars.githubusercontent.com/u/7537381?v=4)](https://github.com/veve40 "veve40 (2 commits)")

---

Tags

charcoalcmscontent-management-systemphpcmscharcoal

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/locomotivemtl-charcoal-cms/health.svg)

```
[![Health](https://phpackages.com/badges/locomotivemtl-charcoal-cms/health.svg)](https://phpackages.com/packages/locomotivemtl-charcoal-cms)
```

###  Alternatives

[locomotivemtl/charcoal-app

Charcoal application, based on Slim 3

1320.3k12](/packages/locomotivemtl-charcoal-app)[locomotivemtl/charcoal-admin

The Charcoal Administration Dashboard

1110.8k8](/packages/locomotivemtl-charcoal-admin)[sproutcms/cms

Enterprise content management and framework

241.6k4](/packages/sproutcms-cms)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
