craftcms/cms
Craft CMS is a flexible, user-friendly PHP content management system for building custom websites and applications. It combines a clean authoring experience with powerful templating, structured content, and an extensible plugin ecosystem for developers.
Installation
composer require craftcms/cms
php craft install
php craft migrate/up
Initial Setup
config/app.php (Craft’s core config file).config/app.php under components or via CLI:
php craft plugin/install my-plugin
First Use Case: Creating a Custom Field
craft\fields\BaseField to build a reusable field type.// plugins/MyPlugin/fields/MyField.php
namespace myplugin\fields;
use craft\fields\BaseField;
class MyField extends BaseField {
public $type = 'myField';
public static function displayName(): string { return 'My Custom Field'; }
}
config/app.php:
'components' => [
'fields' => [
'myField' => \myplugin\fields\MyField::class,
],
],
Content Modeling
// config/sections/mySection.php
return [
'type' => \craft\sections\Channel::class,
'handle' => 'mySection',
'name' => 'My Section',
'entryTypes' => ['myEntryType'],
];
$entries = craft()->elements->getContentByType('myEntryType');
Plugin Development
Plugin.php:
public function init()
{
parent::init();
$this->setComponents([
'myService' => \myplugin\services\MyService::class,
]);
}
craft\web\Controller for API routes:
public function actionMyAction()
{
return $this->asJson(['success' => true]);
}
Templates & Twig
{% set entries = craft.entries.section('mySection').all() %}
{% for entry in entries %}
{{ entry.title }}
{% endfor %}
templates/_layouts/ or templates/_includes/.API & Webhooks
config/general.php:
'enableApi' => true,
ELEMENT_SAVE):
Event::on(
Entry::class,
Entry::EVENT_AFTER_SAVE,
function (Event $event) {
// Handle saved entry
}
);
public function boot()
{
$this->app->bind('myLaravelService', function () {
return new \App\Services\MyService();
});
}
craft()->assets->registerAssetBundle('MyPlugin', \myplugin\web\assets\MyAsset::class);
dispatch(new \myplugin\jobs\ProcessDataJob($data));
Caching Quirks
php craft clear-caches/all
craft()->cache->clear() in plugins for dynamic updates.Element Query Pitfalls
.preferRelatedElements() or .with():
$entries->with(['relatedField']);
.limit() or .offset().Plugin Autoloading
composer.json has correct autoload:
{
"autoload": {
"psr-4": {
"myplugin\\": "plugins/my-plugin/src"
}
}
}
composer dump-autoload after changes.Migration Conflicts
--dry-run to preview changes:
php craft migrate/diff --dry-run
storage/logs/ for Craft-specific logs.index.php entry point.config/general.php:
'devMode' => true,
'templateDebugMode' => true,
ELEMENT_CHANGE, USER_LOGIN):
Event::on(
User::class,
User::EVENT_AFTER_LOGIN,
function (Event $event) {
// Custom logic
}
);
craft()->cp->addDashboardWidget([
'class' => \myplugin\widgets\MyWidget::class,
]);
FIELD_LAYOUT_REGISTER event:
Event::on(
FieldLayout::class,
FieldLayout::EVENT_REGISTER_LAYOUT_TYPES,
function (Event $event) {
$event->sender->layoutTypes[] = 'myCustomLayout';
}
);
craft()->config->get() for dynamic config values.craft()->elements->getCriteria() for reusable queries.php craft test (if using Pest/PHPUnit).t() function for translations:
craft()->i18n->getTranslation('my-plugin', 'my-key');
How can I help you explore Laravel packages today?