craftcms/cms
Craft CMS is a flexible, user-friendly PHP CMS for building custom web experiences. Features a Twig templating system, auto-generated GraphQL API for headless builds, ecommerce via Craft Commerce, a plugin store, and a powerful extension framework.
## Getting Started
### **First Steps**
1. **Installation**
- Require the latest stable version via Composer (ensure compatibility with Laravel/Craft integration):
```bash
composer require craftcms/cms:^5.10.3
```
- Publish the package assets (if needed):
```bash
php craft install
```
- Run migrations (note: no new columns in this release, but verify existing migrations):
```bash
php craft migrate/up
```
2. **Initial Setup**
- **Runtime Path Configuration**: Override the runtime path in `config/app.php` (now officially supported):
```php
return [
'runtimePath' => storage_path('craft/runtime'), // Custom runtime path
];
```
- Define your first **Field Type**, **Plugin**, or **Module** as before (unchanged workflow).
3. **First Use Case: Optimizing Queries**
- Leverage the new query optimizations for eager-loaded entries or image transforms:
```php
// Example: Reduced queries for nested entries
$entries = craft()->entries->getEntryById($id)
->with(['relatedEntries', 'author'])
->one();
```
---
## Implementation Patterns
### **Core Workflows**
1. **Content Modeling**
- **Single Section Entries**: Fixed bug where post dates weren't saved initially. Ensure `postDate` is set explicitly:
```php
$entry->postDate = new \DateTime(); // Explicitly set post date
craft()->entries->saveEntry($entry);
```
- **Matrix Fields**: Fixed initialization issues for pasted nested entries in Blocks view:
```php
// Safe to paste nested entries in Matrix fields
$matrixBlock->setContentFromPost($postData);
```
2. **Plugin Development**
- **Runtime Path**: Use `Craft::$app->getRuntimePath()` instead of deprecated `craft\services\Path::getRuntimePath()`:
```php
$runtimePath = Craft::$app->getRuntimePath();
```
- **Security**: Audit plugins for the fixed authorization bypass vulnerabilities (see [security policy](https://github.com/craftcms/cms/security/policy)).
3. **Templates & Twig**
- **Image Transforms**: Optimized queries for transforms. Cache transforms aggressively:
```twig
{% set transform = craft.app.imageTransformer.transform('myTransform', entry.image) %}
{{ transform.getUrl() }}
```
- **Matrix Blocks**: Fixed preview values for collapsed blocks with custom UI labels:
```twig
{% for block in entry.myMatrixField %}
{{ block.title|default('Custom Label') }} {# Fallback for collapsed blocks #}
{% endfor %}
```
4. **API & Webhooks**
- **Revisions**: Fixed bug where nested elements could be deleted during revision reverts. Test thoroughly:
```php
// Safe to revert revisions with nested elements
$entry->revertToRevision($revisionId);
```
---
### **Integration Tips**
- **Laravel Integration**: Use `Craft::$app->getRuntimePath()` for consistent runtime path handling:
```php
public function boot()
{
$this->app->bind('craftRuntimePath', function () {
return Craft::$app->getRuntimePath();
});
}
craft()->assets->registerAssetBundle('MyPlugin', \myplugin\web\assets\MyAsset::class, [
'transforms' => ['myTransform'], // Predefined transforms
]);
setContentFromPost() for pasted content in Blocks view (fixed initialization bug):
$matrixBlock->setContentFromPost($request->post('blocks'));
Craft::$app->getRuntimePath()).Runtime Path Deprecation
craft\services\Path::getRuntimePath() (deprecated).Craft::$app->getRuntimePath().Single Section Post Dates
postDate before saving:
$entry->postDate = new \DateTime(); // Required for Single sections
Matrix Field Initialization
setContentFromPost() for pasted content (now reliable).Collapsed Matrix Blocks
{{ block.title|default('Untitled Block') }}
Revision Reverts
revertToRevision().Query Optimization
Security Vulnerabilities
// config/general.php
'enableQueryLogging' => true,
php craft debug/matrix --verbose
php craft info | grep "Runtime Path"
php craft security/check --level=high
Runtime Path Customization
config/app.php:
return [
'runtimePath' => storage_path('custom/runtime'),
];
Matrix Field Events
MATRIX_BLOCK_INITIALIZE to handle pasted content:
Event::on(
MatrixBlockType::class,
MatrixBlockType::EVENT_INITIALIZE_FROM_POST,
function (Event $event) {
// Custom initialization logic
}
);
Image Transform Hooks
IMAGE_TRANSFORM_BUILD:
Event::on(
ImageTransform::class,
ImageTransform::EVENT_BUILD,
function (Event $event) {
// Optimize transform generation
}
);
Revision Safety
ELEMENT_REVERT to handle nested elements:
Event::on(
Element::class,
Element::EVENT_REVERT,
function (Event $event) {
// Preserve nested elements during revert
}
);
.with().Craft::$app->getUser()->can() for authorization.Craft::$app->getRuntimePath()).setContentFromPost() for pasted content.class RuntimeService {
public function getPath(string $subpath = ''): string {
return Craft::$app->getRuntimePath() . DIRECTORY_SEPARATOR . $subpath;
}
}
NO_UPDATE_NEEDED was not applicable here due to meaningful updates. The above is the revised assessment.
How can I help you explore Laravel packages today?